17.User Account和Service Account

Kubernetes明确的区分了UserAccount(我没有看到一个叫做UserAccount的资源)和ServiceAccount的概念,原因如下:

  1. UserAccount的使用者是用户,ServiceAccount的使用者是运行在Pod中的进程。

  2. UserAccount应该是全局的,用户名在集群范围内(跨名称空间)必须唯一。ServiceAccount的名称在名称空间内唯一即可

  3. 通常,集群的UserAccount可能是从企业的数据库同步过来(如何操作?想尝试去找一款UserAccount管理工具),在那里,创建新的UserAccount需要特殊的权限,并且受复杂的业务流程管控。ServiceAccount的创建则更加轻量级,允许集群的用户为特定的任务创建ServiceAccount(最小权限的原则)。

  4. 对用户和ServiceAccount的审计过程可能会不一样(这儿指的是准入控制么)

  5. 一个复杂系统中,可能为不同的组件配置不同的ServiceAccount。由于ServiceAccount可以临时创建,并且在名称空间内唯一,这种配置信息是可以移植的

Service Account Admission Controller

Admission Controller是ApiServer的一部分,它在Pod创建或者更新时,对Pod执行一些修改。此控制器激活时(默认处于激活状态),当Pod被创建或修改时,该控制器将执行如下动作:

  1. 如果Pod未设置ServiceAccount,将ServiceAccount设置为default
  2. 如果Pod设置了ServiceAccount,确保Pod引用的ServiceAccount存在,否则拒绝创建或者修改Pod
  3. 如果Pod不包含任何ImagePullSecrets,则ServiceAccount中的ImagePullSecrets将被添加到Pod上(不是很熟悉)
  4. 为Pod添加一个Volume(其中包含了访问APIServer的token)(由TokenController自动创建的)
  5. 为Pod中的每一个容器添加一个VolumeSource,并挂载到路径/var/run/secrets/kubernetes.io/serviceaccount(不是很熟悉)

Token Controller

TokenController作为controller-manager的一部分运行。以异步的方式执行如下动作:

  1. 监听ServiceAccount的创建,并创建一个对应的Secret以允许访问APIServer

  2. 监听ServiceAccount的删除,并删除所有对应的ServiceAccountToken Secrets

  3. 监听Secret的添加,确保其引用的ServiceAccount以存在,并在需要时向Secret添加Token(两者的关系我还不太熟悉呀)

  4. 监听Secret的删除,并在需要的情况下将对应ServiceAccount中对Secret的引用也删除掉

启动controller-manager时,必须通过--service-account-private-key-file参数,向TokenController传递一个ServiceAccount Privatekey文件。该PrivateKey将用来为生成的ServiceAccount Token签名。类似的,也必须为通过--service-account-key-file将其对应的PublicKey传递给kube-apiserver。该PublicKey将被用来在认证时验证Token。(这个道理很好理解)

Service Account Controller

Service Account Controller管理了名称空间中的ServiceAccount,并确保每一个当前有效的名称空间中都存在一个名为default的ServiceAccount。

其他知识:创建额外的API Token

目前这部分知识还没有系统化,所以我只是先记录一下,然后等相关知识形成知识面。

控制器确保每个ServiceAccount都有一个包含ApiToken的Secret。如需为ServiceAccount创建额外的ApiToken,可以创建一个类型为ServiceAccountToken的Secret,并在注解中引用对应的ServiceAccount,此时,控制器将为其创建一个新的Token:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

{
    "kind": "Secret",
    "apiVersion": "v1",
    "metadata": {
        "name": "mysecretname",
        "annotations": {
            "kubernetes.io/service-account.name": "myserviceaccount"
        }
    },
    "type": "kubernetes.io/service-account-token"
}

相关指令如下:

1
2
3
4
5
6
7

kubectl create -f ./secret.json
kubectl delete -f ./secret.json
kubectl delete secret mysecretname

kubectl describe secret mysecretname

研究一下创建命名空间时自动创建的ServiceAccount及Secret。创建命名空间时会自动创建一个名为default的ServiceAccount,按照前面所说的,控制器还会确保每个ServiceAccount都包含一个ApiToken的Secret。可以使用如下指令查看这些资源:


kubectl get sa -n nfs
kubectl get secrets -n nfs