Service Account概念的引入是基于这样的使用场景:
运行在pod里的进程需要调用Kubernetes API以及非Kubernetes API的其它服务。Service Account它并不是给kubernetes集群的用户使用的,而是给pod里面的进程使用的,它为pod提供必要的身份认证。这样pod里的容器就可以访问api了。
kubectl get sa --all-namespaces NAMESPACE NAME SECRETS AGE default build-robot 1 1d default default 1 32d default kube-dns 1 31d kube-public default 1 32d kube-system dashboard 1 31d kube-system default 1 32d kube-system heapster 1 30d kube-system kube-dns 1 31d
如果kubernetes开启了ServiceAccount(–admission_control=…,ServiceAccount,… )那么会在每个namespace下面都会创建一个默认的default的ServiceAccount。
如下:每个sa都关联着一个secrets。
kubectl get sa default -o yaml apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: 2017-05-02T06:39:12Z name: default namespace: default resourceVersion: "175" selfLink: /api/v1/namespaces/default/serviceaccounts/default uid: 0de23575-2f02-11e7-98d0-5254c4628ad9 secrets: - name: default-token-rsf8r
当用户在该namespace下创建pod的时候都会默认使用这个sa,下面是get pod 截取的部分,可以看到kubernetes会把默认的sa挂载到容器内。
volumes: - name: default-token-rsf8r secret: defaultMode: 420 secretName: default-token-rsf8r
具体看一下secret
kubectl get secret default-token-rsf8r -o yaml apiVersion: v1 data: ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR2akNDQXFhZ0F3SUJBZ0lVZlpvZDJtSzNsa3JiMzR3NDhhUmtOc0pVVDJjd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1pURUxNQWtHQTFVRUJoTUN namespace: ZGVmYXVsdA== token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV0 metadata: annotations: kubernetes.io/service-account.name: default kubernetes.io/service-account.uid: 0de23575-2f02-11e7-98d0-5254c4628ad9 creationTimestamp: 2017-05-02T06:42:07Z name: default-token-rsf8r namespace: default resourceVersion: "12551" selfLink: /api/v1/namespaces/default/secrets/default-token-rsf8r uid: 75c0a236-2f02-11e7-98d0-5254c4628ad9 type: kubernetes.io/service-account-token
上面的内容是经过base64加密过后的,我们直接进入容器内:
~ # ls -l /var/run/secrets/kubernetes.io/serviceaccount/ total 0 lrwxrwxrwx 1 root root 13 May 4 23:57 ca.crt -> ..data/ca.crt lrwxrwxrwx 1 root root 16 May 4 23:57 namespace -> ..data/namespace lrwxrwxrwx 1 root root 12 May 4 23:57 token -> ..data/token
可以看到已将ca.crt 、namespace和token放到容器内了,那么这个容器就可以通过https的请求访问apiserver了。
Secret
Kubernetes提供了Secret来处理敏感信息,目前Secret的类型有3种:
Opaque(default): 任意字符串
kubernetes.io/service-account-token: 作用于ServiceAccount,就是上面说的。
kubernetes.io/dockerconfigjson: 作用于Docker registry,用户下载docker镜像认证使用。
imagePullSecrets
当在需要安全验证的环境中拉取镜像的时候,需要通过用户名和密码
apiVersion: v1 kind: Secret metadata: name: myregistrykey namespace: awesomeapps data: .dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== type: kubernetes.io/dockerconfigjson
接下来拉取镜像的时候,就可以使用了
apiVersion: v1 kind: Pod metadata: name: foo namespace: awesomeapps spec: containers: - name: foo image: janedoe/awesomeapp:v1 imagePullSecrets: - name: myregistrykey
其实本质上还是kubelet把这个认证放到了docker的目录下面,如下:
cat ~/.docker/config.json { "auths": { "10.39.0.118": { "auth": "Y2hlbm1vOmNtMTM4MTE2NjY3ODY=" }, "10.39.0.12:5000": { "auth": "dXNlcjAxOjEyMzQ1YQ==" }, "http://10.39.0.12:5000": { "auth": "dXNlcjAxOjEyMzQ1YQ==" } } }