一、背景

e9d4c24d13fd9ac61863bf166e2feb34.png

apiserver是k8s的中枢组件,每次api访问请求都需要认证,例如可以通过证书方式,使用curl测试下访问apiserver的版本资源

curl -k --cert/etc/kubernetes/ssl/apiserver-kubelet-client.crt --key /etc/kubernetes/ssl/apiserver-kubelet-client.keyhttps://10.30.0.127:6443/api/

{

  "kind":"APIVersions",

 "versions": [

    "v1"

  ],

 "serverAddressByClientCIDRs": [

    {

     "clientCIDR": "0.0.0.0/0",

     "serverAddress": "10.30.0.127:6443"

    }

  ]

}

服务账号也是用于pod访问apiserver的方式之一,

大部分POD都会挂载的一个存储卷/var/run/secrets/kubernetes.io/serviceaccount

bb19229b66723e9450e3fed4f31b54aa.png

这个存储对应的secret就是代表着服务账号default

7acd05e212abe4882b11d62d5488e47b.png

当与角色role绑定后,POD就可以执行相关操作,例如访问访问宿主机存储

另外apiserver目前在当前的K8S中,是以static pod方式启动的,kubelet会定期扫描/etc/kubernetes/manifest下的yaml文件,然后创建pod,即如果你放置一个yaml文件到此目录下,kubelet就会自动创建,并且不受K8S其他组件的制约,例如ReplicationController和DaemonSet 

二、启动令牌卷投射特性

由于服务账号存在提权的风险,K8S引入了一个令牌卷投射的功能,K8S默认不开启这个特性,我们在部署最新版kubeflow时,使用的istio1.3.1,需要使用这种功能,但是开启并不顺利

官方给出的方法是,/etc/kubernetes/manifests/kube-apiserver.yaml文件加入kube-apiserver的参数

--service-account-issuer=kubernetes.default.svc

--service-account-signing-key-file=/etc/kubernetes/pki/sa.key

1,修改后,配置立即生效,kubelet会重启apiserver,但未能成功重启

查看日志

/var/log/pods/kube-system_kube-apiserver-node1_249488fb95563c5e98715ecb8e3f7999/kube-apiserver/0.log(249488fb95563c5e98715ecb8e3f7999是配置文件的hash值,每次都不一样)中的日志发现报错:Error: --service-account-signing-key-file, --service-account-issuer, and--api-audiences should be specified together

说明少一个参数--api-audiences

2,继续增加后,再次报错

Error: failed to parse service-account-issuer-key-file:open /etc/kubernetes/pki/sa.key: no such file or directory

检查发现/etc/kubernetes/pki/sa.key不存在,但事实上,文件是存在的,不过是链接文件,发现配置文件中,其他参数,例如--client-ca-file=/etc/kubernetes/ssl/ca.crt,用的ssl,而不是pki,更改为ssl后,apiserver正常启动

3,当前测试集群是三个master,在其中一台测试成功后,其余两台也做同样的修改

sed -i '/service-account-key-file/a\ \ \ \ ---service-account-issuer=kubernetes.default.svc\n\ \ \ \ ---service-account-signing-key-file=/etc/kubernetes/ssl/sa.key\n\ \ \ \ - --api-audiences=kubernetes.default.svc'/etc/kubernetes/manifests/kube-apiserver.yaml

cat -n /etc/kubernetes/manifests/kube-apiserver.yaml |grep -A 6 service-account-key-file

4,确认令牌卷投射特性是否成功

查看api接口多了一个serviceaccounts/token表示,特性开启成功

curl -k --cert /etc/kubernetes/ssl/apiserver-kubelet-client.crt--key /etc/kubernetes/ssl/apiserver-kubelet-client.keyhttps://10.30.0.127:6443/api/v1/ | grep serviceaccount

     "name": "serviceaccounts",

     "name": "serviceaccounts/token",

由于serviceaccounts/token对应的类型TokenRequest没有list方法,所以不能通过kubectlget方式查看有多少的TokenRequest对象

c8f9c2d2a7a2f6b2e576d116780d9836.png

三、总结和参考

1,K8S的参数名是会变更的,要根据实际报错信息去确定

2,K8S的api资源类型并不都是可以kubectlget查看的

3,apiserver的pod仅被kubelet控制,不被K8S控制

四、参考链接

https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/?spm=a2c4g.11186623.2.17.3f2d7303yzdzjL#service-account-token-volume-projection

https://www.alibabacloud.com/help/zh/doc-detail/160384.htm

https://v1-17.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐