前面介绍过Kubernetes的结构组成,其中API Server用于与外界的交互,我们常用的命令行工具kubectl、UI工具lens、云服务商提供的WebUI,最终都是通过Restfule API的形式,走HTTP协议,到达API Server。此时就带来权限控制问题。
![image-20211203153658776](https://i-blog.csdnimg.cn/blog_migrate/af0fa90aab570288f85c8f98a63a1e5f.png)
如上图,对来自外部的请求,Api Server会经过三个组件
- Authentication:认证,验证用户的合法性,并从中提取出用户信息,如用户名、组等
- Authorization:鉴权,鉴定该用户是否有权限访问指定资源
- Admission:准入,它可以修改或拒绝请求
认证
与用户相关的概念,有用户、组、ServiceAccount,但只有ServiceAccount才在Kubernetes中以资源的形式存在,用户、组并不会以资源的形式存在,它们只是一个字符串,在使用的地方如RoleBinding时被引用,理解这一点很重要。
从集群内部,即pod中访问API Server时,需要ServiceAccount来标识身份;从集群外部访问API Server时,则需要走外部验证,包括:客户端证书、密码、普通令牌、引导令牌。
ServiceAccount
每个命名空间都会有一个默认的ServiceAccount。一个典型的ServiceAccount如下
gd % kubectl --kubeconfig ~/.kube/config-test get sa -o yaml
apiVersion: v1
items:
- apiVersion: v1
imagePullSecrets:
- name: acr-credential-560b66540f01e51c18524b09ad7f575f
- name: acr-credential-6731ef77d88edc24b279ebf20860f30f
- name: acr-credential-5dee66918cdf5d93de4aa5cd90247f73
- name: acr-credential-be55512166dd26eda658d0706de5a06a
- name: acr-credential-bab42ef118a2913b05cd8cdb95441d70
kind: ServiceAccount
metadata:
creationTimestamp: "2020-11-10T06:48:55Z"
name: default
namespace: default
resourceVersion: "100598603"
selfLink: /api/v1/namespaces/default/serviceaccounts/default
uid: 4ef6a2d3-19ad-47cf-a2de-135f2c9d86b5
secrets:
- name: default-token-vrqk9
kind: List
metadata:
resourceVersion: ""
selfLink: ""
可以看到它其实包含两部分:secrets、imagePullSecrets,其中,前者会被挂载到pod的容器内,用于在访问API Server时提供信息;后者则用于pod从私有仓库拉取镜像时使用的秘钥。也就是说,ServiceAccount的作用也就是这两部分了。本文重点关注secrets部分。
当一个pod创建时,它会默认拥有该ServiceAccount,这一点可以通过查看一个已经存在的pod得以验证
gd % kubectl --kubeconfig ~/.kube/config-test get pod app-bosslist-backend-67c59b8d94-k75kj -o yaml | grep service
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
serviceAccount: default
serviceAccountName: default
而该token包含两部分信息:服务端证书、token值的BASE64编码。
g % kubectl --kubeconfig ~/.kube/config-test get secret default-token-vrqk9 -o yaml
apiVersion: v1
data:
ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURHakNDQWdLZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREErTVNjd0ZBWURWUVFLRXcxaGJHbGkKWVdKaElHTnNiM1ZrTUE4R0ExVUVDaE1JYUdGdVozcG9iM1V4RXpBUkJnTlZCxxxxx
namespace: ZGVmYXVsdA==
token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklteEthMkpUUm1GbFVFZFlWRmhsUTBKcE1VTjJkbmd6TVZCRWVtSjNkSFZHUVVWU1RFWXhjak5DTlhjaWZRLmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFxxxxx
kind: Secret
metadata:
annotations:
kubernetes.io/service-account.name: default
kubernetes.io/service-account.uid: 4ef6a2d3-19ad-47cf-a2de-135f2c9d86b5
creationTimestamp: "2020-11-10T06:48:55Z"
name: default-token-vrqk9
namespace: default
resourceVersion: "38744013"
selfLink: /api/v1/namespaces/default/secrets/default-token-vrqk9
uid: 64ee0b11-9919-47b1-97e9-e055f47f3732
type: kubernetes.io/service-account-token
token值是JWT,解码结果如下
{