Kubernetes ServiceAccount 解决 pod 在集群里面的身份认证问题
ServiceAccount 介绍
接下来,我们讲一下 ServiceAccount。ServiceAccount 首先是用于解决 pod 在集群里面的身份认证问题,身份认证信息是存在于 Secret 里面。
[root@k8s-master ~]# kubectl get secret
NAME TYPE DATA AGE
default-token-j9294 kubernetes.io/service-account-token 3 148d
[root@k8s-master ~]# kubectl get sa
NAME SECRETS AGE
default 1 148d
[root@k8s-master ~]# kubectl describe sa default
Name: default
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: default-token-j9294
Tokens: default-token-j9294
Events: <none>
[root@k8s-master ~]# kubectl get sa default -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2020-11-15T06:57:19Z"
name: default
namespace: default
resourceVersion: "406"
selfLink: /api/v1/namespaces/default/serviceaccounts/default
uid: 3b6f6ac8-fb89-42e0-9a45-d14680ee6157
secrets:
- name: default-token-j9294
[root@k8s-master ~]# kubectl get secret default-token-j9294 -o yaml
apiVersion: v1
data:
ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJd01URXhOVEEyTlRZeU5sb1hEVE13TVRFeE16QTJOVFl5Tmxvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSmZsCmtaVVhUcVJ3ZjJVeDdqS1pjQURvaHV1aHNXcHAvK2NIOEF1MVpmR3JqN0lTb3VoelVISkZ5cGR5ekdoTDFBRHgKMTkxVlVCN1ZCWlk4cXBDRHYyRnZvWkRFbFVYR1JrTFFDT0lxc1hOVUt3ZU0xdnJqZnpZVW5ZNGN6NDhKNDdpTgpnUjJHRGtsWUlrZFpGZEU1ekN2eitldEtEVVUzdE5GV0djL00yZFE0NUIxNGZlTldpTUR3T0l3dTBSSWRvYmpnCndmSnhoVlJHMmgzdEplL0RpUjQ2cXI1NEdMVUU2VXNDUGJvZ0JxNTVBakt2c2NiOWUzeGdzMVJhZW1BdFZhd08KSFNjRkRDYWhBZDVPUlgzMlIzSGNoRnY2QmFwczgyb0dqUDBLOEY1RXNQWkFYQXFoK3c0UTFMRWQ2aHRuQWhyWAoxcmJ5cTF4eUNESnhhbENaSHBjQ0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZPZXFad29TeUxrVDVKWXlRNURMamUzRFRHUjJNQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFCemtMRXMzUGhIN08wYWs5VWlTbFhDVTljK1RoYlZaTmZVUStKS1JpQU5KQys5Qm8vZApLdUlLYWhxQlE5UkprSk53TmVwT0NJOWxzcGJ4TGtHK3ArYktHV29Yb25CME5RdnZoZTRQd0p0dmdUcGlhVmVYCmNLejhUMDBRT1YyRzR0WEtmaTViK0dvZDA3NktlZm4zbm00U0l1VDh6bmNDclUxeHRpQTRSU3RQRVZZZTRQalAKY2p6MHJVS3BnTmhJL0lYc2JPVDNYV0hFNE4vU0VLcmtIYkRJNFpEUGRYa2gxd3piM1FZODFuZTh1enBNQVJ5VwpLbkx6R1NRaGJ0WTlWRUZkdlhGK0wreWFrQjcrR29xa1lJa1BNdURveFRoeTBuMFJjZStSTUhtZkFQSEh2RDFyCjdSNC9xdlpBLzA4Q0hxb3ZDcCsxUzNXbFE5WE5MRzE3TWExTAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
namespace: ZGVmYXVsdA==
token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNkluUjBjVFJITkROUVVHRk1lVVo1Um5wMWF6Wm5TVUV5UlZVMFdFWTFkV2RFTUVZd2QwNTZabk5rV1djaWZRLmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUprWldaaGRXeDBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpXTnlaWFF1Ym1GdFpTSTZJbVJsWm1GMWJIUXRkRzlyWlc0dGFqa3lPVFFpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxjblpwWTJVdFlXTmpiM1Z1ZEM1dVlXMWxJam9pWkdWbVlYVnNkQ0lzSW10MVltVnlibVYwWlhNdWFXOHZjMlZ5ZG1salpXRmpZMjkxYm5RdmMyVnlkbWxqWlMxaFkyTnZkVzUwTG5WcFpDSTZJak5pTm1ZMllXTTRMV1ppT0RrdE5ESmxNQzA1WVRRMUxXUXhORFk0TUdWbE5qRTFOeUlzSW5OMVlpSTZJbk41YzNSbGJUcHpaWEoyYVdObFlXTmpiM1Z1ZERwa1pXWmhkV3gwT21SbFptRjFiSFFpZlEuY2JIVE14YWhnVmdJbXQybGwtY040cEpJYnROX2dNa3M5V2ctQXFjM2h2bnRrdHBtUEZOMFRSazllVDM2MkhvWUZwZjZSQjVwSnZINFhnLWVBQ29aOUlmT2NJcURLOGt5MTRqazF6NVRvbGdYckx2MU9xYWN4SThQbFJKQkR2bWpJRVg4aUxJeGNGRTYzZ0pRcEJvRHNjQ09ITU1zLWkxY3V5Z2RScjJ2RXE0N1hYX3lreFBnNDlwdzFoUmFHNERTTGpmQ1RBN2tBRzNSLTlObmhHQ3BleHJ1cnlEZDRmdHFhS0tmMTJCVG1UOHhneWRjdk5XenprZ25ZTW5vRi1vOGNmYUxxZDljXy1UT3IzaDFWR3lvb3A5MjVDQ3JUWHFIeEJVNlZQRW5TUm96ZWdJZkRiTHdieWhwNFdxM0NURHlCQWM0WVNtOFdicVJQeWlrTlJhLW93
kind: Secret
metadata:
annotations:
kubernetes.io/service-account.name: default
kubernetes.io/service-account.uid: 3b6f6ac8-fb89-42e0-9a45-d14680ee6157
creationTimestamp: "2020-11-15T06:57:20Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:ca.crt: {}
f:namespace: {}
f:token: {}
f:metadata:
f:annotations:
.: {}
f:kubernetes.io/service-account.name: {}
f:kubernetes.io/service-account.uid: {}
f:type: {}
manager: kube-controller-manager
operation: Update
time: "2020-11-15T06:57:20Z"
name: default-token-j9294
namespace: default
resourceVersion: "401"
selfLink: /api/v1/namespaces/default/secrets/default-token-j9294
uid: 70848700-78a5-437a-9409-d5431deacbae
type: kubernetes.io/service-account-token
先看一下上面的左侧截图,可以看到最下面的红框里,有一个 Secret 字段,它指定 ServiceAccount 用哪一个 Secret,这个是 K8s 自动为 ServiceAccount 加上的。
然后再来看一下上图中的右侧截图,它对应的 Secret 的 data 里有两块数据,一个是 ca.crt,一个是 token。ca.crt 用于对服务端的校验,token 用于 Pod 的身份认证,它们都是用 base64 编码过的。然后可以看到 metadata 即元信息里,其实是有关联 ServiceAccount 信息的(这个 secret 被哪个 ServiceAccount 使用)。最后我们注意一下 type,这个就是 service-account-token 这种类型。
举例:Pod 里的应用访问它所属的 K8s 集群
介绍完 ServiceAccount 以及它对应的 secret 后,我们来看一下,pod 是怎么利用 ServiceAccount 或者说它是怎么利用 secret 来访问所属 K8s 集群的。
其实 pod 创建的时候,首先它会把这个 secret 挂载到容器固定的目录下,这是 K8s 功能上实现的。它要把这个 ca.crt 和 token 这两个文件挂载到固定目录下面。
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-6799fc88d8-drb2s 1/1 Running 3 148d
[root@k8s-master ~]# kubectl exec -it nginx-6799fc88d8-drb2s -- bash
root@nginx-6799fc88d8-drb2s:/var/run/secrets/kubernetes.io/serviceaccount# ls
ca.crt namespace token
pod 要访问集群的时候,它是怎么来利用这个文件的呢?我们看一下下面的代码截图:
我们在 Go 里面实现 Pod 访问 K8s 集群时,一般直接会调一个 InClusterConfig 方法,来生成这个访问服务 Client 的一些信息。然后可以看一下,最后这个 Config 里面有两部分信息:
- 一个是 tlsClientConfig,这个主要是用于 ca.crt 校验服务端;
- 第二个是 Bearer Token,这个就是 pod 的身份认证。在服务端,会利用 token 对 pod 进行一个身份认证。
再次回到上图左侧。认证完之后 pod 的身份信息会有两部分:一个是 Group,一个是 User。身份认证是就是认证这两部分信息。接着可以使用 RBAC 功能,对 pod 进行一个授权管理。
假如 RBAC 没有配置的话,默认的 pod 具有资源 GET 权限,就是可以从所属的 K8s 集群里 get 数据。如果是需要更多的权限,那么就需要 自行配置 RBAC 。
目录 返回
首页