• Service Account
    • 使用默认的 Service Account 访问 API server
    • 使用多个Service Account
    • 手动创建 service account 的 API token
    • 为 service account 添加 ImagePullSecret
    • 参考

    Service Account

    Service Account为Pod中的进程提供身份信息。

    注意本文是关于 Service Account 的用户指南,管理指南另见 Service Account 的集群管理指南 。

    本文档描述的关于 Service Account 的行为只有当您按照 Kubernetes 项目建议的方式搭建起集群的情况下才有效。您的集群管理员可能在您的集群中有自定义配置,这种情况下该文档可能并不适用。

    当您(真人用户)访问集群(例如使用kubectl命令)时,apiserver 会将您认证为一个特定的 User Account(目前通常是admin,除非您的系统管理员自定义了集群配置)。Pod 容器中的进程也可以与 apiserver 联系。 当它们在联系 apiserver 的时候,它们会被认证为一个特定的 Service Account(例如default)。

    使用默认的 Service Account 访问 API server

    当您创建 pod 的时候,如果您没有指定一个 service account,系统会自动得在与该pod 相同的 namespace 下为其指派一个default service account。如果您获取刚创建的 pod 的原始 json 或 yaml 信息(例如使用kubectl get pods/podename -o yaml命令),您将看到spec.serviceAccountName字段已经被设置为 default

    您可以在 pod 中使用自动挂载的 service account 凭证来访问 API,如 Accessing the Cluster 中所描述。

    Service account 是否能够取得访问 API 的许可取决于您使用的 授权插件和策略。

    在 1.6 以上版本中,您可以选择取消为 service account 自动挂载 API 凭证,只需在 service account 中设置 automountServiceAccountToken: false

    1. apiVersion: v1
    2. kind: ServiceAccount
    3. metadata:
    4. name: build-robot
    5. automountServiceAccountToken: false
    6. ...

    在 1.6 以上版本中,您也可以选择只取消单个 pod 的 API 凭证自动挂载:

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: my-pod
    5. spec:
    6. serviceAccountName: build-robot
    7. automountServiceAccountToken: false
    8. ...

    如果在 pod 和 service account 中同时设置了 automountServiceAccountToken , pod 设置中的优先级更高。

    使用多个Service Account

    每个 namespace 中都有一个默认的叫做 default 的 service account 资源。

    您可以使用以下命令列出 namespace 下的所有 serviceAccount 资源。

    1. $ kubectl get serviceAccounts
    2. NAME SECRETS AGE
    3. default 1 1d

    您可以像这样创建一个 ServiceAccount 对象:

    1. $ cat > /tmp/serviceaccount.yaml <<EOF
    2. apiVersion: v1
    3. kind: ServiceAccount
    4. metadata:
    5. name: build-robot
    6. EOF
    7. $ kubectl create -f /tmp/serviceaccount.yaml
    8. serviceaccount "build-robot" created

    如果您看到如下的 service account 对象的完整输出信息:

    1. $ kubectl get serviceaccounts/build-robot -o yaml
    2. apiVersion: v1
    3. kind: ServiceAccount
    4. metadata:
    5. creationTimestamp: 2015-06-16T00:12:59Z
    6. name: build-robot
    7. namespace: default
    8. resourceVersion: "272500"
    9. selfLink: /api/v1/namespaces/default/serviceaccounts/build-robot
    10. uid: 721ab723-13bc-11e5-aec2-42010af0021e
    11. secrets:
    12. - name: build-robot-token-bvbk5

    然后您将看到有一个 token 已经被自动创建,并被 service account 引用。

    您可以使用授权插件来 设置 service account 的权限 。

    设置非默认的 service account,只需要在 pod 的spec.serviceAccountName 字段中将name设置为您想要用的 service account 名字即可。

    在 pod 创建之初 service account 就必须已经存在,否则创建将被拒绝。

    您不能更新已创建的 pod 的 service account。

    您可以清理 service account,如下所示:

    1. $ kubectl delete serviceaccount/build-robot

    手动创建 service account 的 API token

    假设我们已经有了一个如上文提到的名为 ”build-robot“ 的 service account,我们手动创建一个新的 secret。

    1. $ cat > /tmp/build-robot-secret.yaml <<EOF
    2. apiVersion: v1
    3. kind: Secret
    4. metadata:
    5. name: build-robot-secret
    6. annotations:
    7. kubernetes.io/service-account.name: build-robot
    8. type: kubernetes.io/service-account-token
    9. EOF
    10. $ kubectl create -f /tmp/build-robot-secret.yaml
    11. secret "build-robot-secret" created

    现在您可以确认下新创建的 secret 取代了 “build-robot” 这个 service account 原来的 API token。

    所有已不存在的 service account 的 token 将被 token controller 清理掉。

    1. $ kubectl describe secrets/build-robot-secret
    2. Name: build-robot-secret
    3. Namespace: default
    4. Labels: <none>
    5. Annotations: kubernetes.io/service-account.name=build-robot,kubernetes.io/service-account.uid=870ef2a5-35cf-11e5-8d06-005056b45392
    6. Type: kubernetes.io/service-account-token
    7. Data
    8. ====
    9. ca.crt: 1220 bytes
    10. token: ...
    11. namespace: 7 bytes

    注意:该内容中的token被省略了。

    为 service account 添加 ImagePullSecret

    首先,创建一个 imagePullSecret,详见这里。

    然后,确认已创建。如:

    1. $ kubectl get secrets myregistrykey
    2. NAME TYPE DATA AGE
    3. myregistrykey kubernetes.io/.dockerconfigjson 1 1d

    然后,修改 namespace 中的默认 service account 使用该 secret 作为 imagePullSecret。

    1. kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'

    Vi 交互过程中需要手动编辑:

    1. $ kubectl get serviceaccounts default -o yaml > ./sa.yaml
    2. $ cat sa.yaml
    3. apiVersion: v1
    4. kind: ServiceAccount
    5. metadata:
    6. creationTimestamp: 2015-08-07T22:02:39Z
    7. name: default
    8. namespace: default
    9. resourceVersion: "243024"
    10. selfLink: /api/v1/namespaces/default/serviceaccounts/default
    11. uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
    12. secrets:
    13. - name: default-token-uudge
    14. $ vi sa.yaml
    15. [editor session not shown]
    16. [delete line with key "resourceVersion"]
    17. [add lines with "imagePullSecret:"]
    18. $ cat sa.yaml
    19. apiVersion: v1
    20. kind: ServiceAccount
    21. metadata:
    22. creationTimestamp: 2015-08-07T22:02:39Z
    23. name: default
    24. namespace: default
    25. selfLink: /api/v1/namespaces/default/serviceaccounts/default
    26. uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
    27. secrets:
    28. - name: default-token-uudge
    29. imagePullSecrets:
    30. - name: myregistrykey
    31. $ kubectl replace serviceaccount default -f ./sa.yaml
    32. serviceaccounts/default

    现在,所有当前 namespace 中新创建的 pod 的 spec 中都会增加如下内容:

    1. spec:
    2. imagePullSecrets:
    3. - name: myregistrykey

    参考

    • Configure Service Accounts for Pods