zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Kubernetes ServiceAccount 解决 pod 在集群里面的身份认证问题

Kubernetes认证集群 解决 里面 Pod 身份 问题
2023-09-14 09:15:17 时间

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 。