広告

kubernetes – ServiceAccount

Azure

ServiceAccount 周りの知識を整理しましたので、知識ポイント抜粋するような形で覚えておきたいポイントをできるだけ箇条書きで記載しました。
多少読みずらいところがありますが、メモとして後で思い出す時に使いやすいかと思います。

まず初めに、以前で紹介した記事の説明図を載せておきます。
詳細の仕組みを後続の内容で紹介するのですが、この図を見ながら、少しずつイメージを形成していただければと思います。

ServiceAccount仕組みの関係図

仕組みの理解をイメージしやすいよう、以下の図を作成しました。
簡単にイメージ作りに役に立ってればと思います。

Roleのイメージ図

Role

ClusterRoleのイメージ図

ClusterRole

ServiceAccount

では、ServcieAccount から紹介していきたいと思います。

ServcieAccount の特徴:

  • ServcieAccount は、Kubernetes のユーザー タイプの 1 つ

    • AKS のユーザー タイプ:UserAccount、ServcieAccount
  • ServiceAccount は Namespace 指定で作成する

    • Namespace 所属のリソース
    • 作成は他の K8s リソースと同様にマニフェストで作成可能
  • ServcieAccount は、K8s のリソースで、API サーバーにリクエストを出す時の認証/認可で使用される

    • 使用例:Pod で直接 K8s のリソースを操作する時とか
    • 設定:Pod などのマニフェストで、ServcieAccount を定義可能
  • K8s のリソースで、ServcieAccount を指定しない場合、デフォルトの ServcieAccount が使用される

    • デフォルト ServcieAccount 名:default
    • デフォルト ServcieAccount は Namespace ごとに既定で作成される
  • ServcieAccount はトークン ベースでの認証が行われる

    • ServcieAccount が作成されたら、自動的にトークン (secret) が作成される
    • ServcieAccount の資格情報 (トークン) は Kubernetes シークレットとして保管されている
    • 承認された Pod が API サーバーと通信する際に、トークンを使われる (トークンや証明書の場所をマウントして使う)
    • Pod などで、ServcieAccount を指定すると既定では自動的にトークンをマウントする
    • 自動マウントさせない設定も可能 (ServcieAccount 又は Pod で設定可能:automountServiceAccountToken: false ※ Pod の設定が優先)
    • トークンを変更したい場合、該当の secret を削除することで、自動再作成される
  • AKS のユーザー タイプ:

    • UserAccount:クラスタ レベル ユーザー (Azure AD などのサービスで管理)
    • ServcieAccount:Namespace レベル ユーザー (Kubernetes で管理)

ServcieAccount の作成と確認

ServcieAccount のマニフェスト例:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: sample-serviceaccount  # ServcieAccount 名
  namespace: default  # 所属の Namespace 指定
secrets:  # 含まれる権限トークンの secret を配列で指定 ※ secret は別途作成が必要
- name: xxx 
- name: yyy
# imagePullSecrets:  # イメージダウンロード用認証情報を取得
# - name: xxx

ServcieAccount 指定の Pod のマニフェスト例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment  # Deployment名
  labels:
    app: nginx
spec:  # ReplicaSetの設定
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:  # Podの設定
    metadata:
      labels:
        app: nginx
    spec:
      serviceAccountName: sample-serviceaccount  # ServcieAccount 指定
      containers:  # コンテナの設定
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

ServcieAccount の確認:
kubectl get pods <pod名> -o yaml コマンドで、ServcieAccount の設定を確認できます。
また、Pod にマウントした証明書やトークンのパスも確認できます。
※ 下記の例は default ServcieAccount を使う時の出力です。
※ pod にログインして、パスを確認することも可能です。

$ kubectl get pods nginx-deployment-585449566-kcl4n -o yaml
apiVersion: v1
kind: Pod
metadata:
  ...
spec:
  containers:
  - image: nginx:latest
    ...
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-dw55p
      readOnly: true
  ...
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  ...

Role と ClusterRole (RBAC)

ServiceAccount の権限設定では、Role という権限を定義するリソースを使って設定もできます。
Role は権限の影響範囲で、以下の2種類があります。

  • Role:Namespace範囲 (Namespace 指定して作成する)
  • ClusterRole:クラスタ全体 (Namespace指定不可)

また、ServiceAccount と Role を紐付けするために、以下の Binding 用のリソースも必要です。

  • RoleBinding:ServiceAccount と Role の紐付け
  • ClusterRoleBingding:ServiveAccount と ClusterRole の紐付け

K8s では、デフォルトで用意されているシステムのロールが存在します。
ただ、一般的によく知られているのは以下の幾つかのユーザー向け Role です。

  • cluster-admin:Super User、任意のリソースで任意のアクションを実行できます。
    • ClusterRoleBinding:クラスター内およびすべての Namespace 内のすべてのリソースを完全に制御可能
    • RoleBinding:Namespace 自体を含む、RoleBinding の Namespace 内のすべてのリソースを完全に制御可能
  • admin:Namespace 内の管理者アクセス権限
    • RoleBindingNamespace 内に Role と RoleBinding を作成する機能を含め、Namespace のほとんどのリソースへの読み取り/書き込みアクセスを許可
    • リソース クォータまたは Namespace 自体への書き込みアクセスは許可しない
  • editNamespace 内のほとんどのオブジェクトへの読み取り/書き込みアクセスを許可
    • RoleまたはRoleBindingの表示または変更を許可しない
  • viewNamespace 内のほとんどのオブジェクトを表示するための読み取り専用アクセスを許可

確認するには、以下のコマンドを使用できます。(AKSの結果)
Role

~$ kubectl get role -A
NAMESPACE     NAME                                             CREATED AT
kube-public   system:controller:bootstrap-signer               2022-05-02T03:08:19Z
kube-system   extension-apiserver-authentication-reader        2022-05-02T03:08:19Z
kube-system   system::leader-locking-kube-controller-manager   2022-05-02T03:08:19Z
kube-system   system::leader-locking-kube-scheduler            2022-05-02T03:08:19Z
kube-system   system:controller:bootstrap-signer               2022-05-02T03:08:19Z
kube-system   system:controller:cloud-provider                 2022-05-02T03:08:19Z
kube-system   system:controller:token-cleaner                  2022-05-02T03:08:19Z
kube-system   tunnelfront-secret                               2022-05-02T03:08:40Z

ClusterRole

~$ kubectl get clusterrole -A
NAME                                                                   CREATED AT
admin                                                                  2022-05-02T03:08:18Z
aks-service                                                            2022-05-02T03:08:36Z
cloud-node-manager                                                     2022-05-02T03:08:35Z
cluster-admin                                                          2022-05-02T03:08:18Z
container-health-log-reader                                            2022-05-02T03:08:39Z
csi-azurefile-node-secret-role                                         2022-05-02T03:08:39Z
edit                                                                   2022-05-02T03:08:18Z
node-viewer                                                            2022-05-02T03:08:40Z
omsagent-reader                                                        2022-05-02T03:08:36Z
system:aggregate-to-admin                                              2022-05-02T03:08:18Z
system:aggregate-to-edit                                               2022-05-02T03:08:18Z
system:aggregate-to-view                                               2022-05-02T03:08:18Z
system:auth-delegator                                                  2022-05-02T03:08:18Z
system:azure-cloud-provider                                            2022-05-02T03:08:39Z
system:azure-cloud-provider-secret-getter                              2022-05-02T03:08:39Z
system:basic-user                                                      2022-05-02T03:08:18Z
system:certificates.k8s.io:certificatesigningrequests:nodeclient       2022-05-02T03:08:18Z
system:certificates.k8s.io:certificatesigningrequests:selfnodeclient   2022-05-02T03:08:18Z
system:certificates.k8s.io:kube-apiserver-client-approver              2022-05-02T03:08:18Z
system:certificates.k8s.io:kube-apiserver-client-kubelet-approver      2022-05-02T03:08:18Z
system:certificates.k8s.io:kubelet-serving-approver                    2022-05-02T03:08:18Z
system:certificates.k8s.io:legacy-unknown-approver                     2022-05-02T03:08:18Z
system:controller:attachdetach-controller                              2022-05-02T03:08:18Z
system:controller:certificate-controller                               2022-05-02T03:08:18Z
system:controller:clusterrole-aggregation-controller                   2022-05-02T03:08:18Z
system:controller:cronjob-controller                                   2022-05-02T03:08:18Z
system:controller:daemon-set-controller                                2022-05-02T03:08:18Z
system:controller:deployment-controller                                2022-05-02T03:08:18Z
system:controller:disruption-controller                                2022-05-02T03:08:18Z
system:controller:endpoint-controller                                  2022-05-02T03:08:18Z
system:controller:endpointslice-controller                             2022-05-02T03:08:18Z
system:controller:endpointslicemirroring-controller                    2022-05-02T03:08:18Z
system:controller:ephemeral-volume-controller                          2022-05-02T03:08:18Z
system:controller:expand-controller                                    2022-05-02T03:08:18Z
system:controller:generic-garbage-collector                            2022-05-02T03:08:18Z
system:controller:horizontal-pod-autoscaler                            2022-05-02T03:08:18Z
system:controller:job-controller                                       2022-05-02T03:08:18Z
system:controller:namespace-controller                                 2022-05-02T03:08:18Z
system:controller:node-controller                                      2022-05-02T03:08:18Z
system:controller:persistent-volume-binder                             2022-05-02T03:08:18Z
system:controller:pod-garbage-collector                                2022-05-02T03:08:18Z
system:controller:pv-protection-controller                             2022-05-02T03:08:18Z
system:controller:pvc-protection-controller                            2022-05-02T03:08:18Z
system:controller:replicaset-controller                                2022-05-02T03:08:18Z
system:controller:replication-controller                               2022-05-02T03:08:18Z
system:controller:resourcequota-controller                             2022-05-02T03:08:18Z
system:controller:root-ca-cert-publisher                               2022-05-02T03:08:18Z
system:controller:route-controller                                     2022-05-02T03:08:18Z
system:controller:service-account-controller                           2022-05-02T03:08:18Z
system:controller:service-controller                                   2022-05-02T03:08:18Z
system:controller:statefulset-controller                               2022-05-02T03:08:18Z
system:controller:ttl-after-finished-controller                        2022-05-02T03:08:18Z
system:controller:ttl-controller                                       2022-05-02T03:08:18Z
system:coredns                                                         2022-05-02T03:08:39Z
system:coredns-autoscaler                                              2022-05-02T03:08:39Z
system:discovery                                                       2022-05-02T03:08:18Z
system:heapster                                                        2022-05-02T03:08:18Z
system:kube-aggregator                                                 2022-05-02T03:08:18Z
system:kube-controller-manager                                         2022-05-02T03:08:18Z
system:kube-dns                                                        2022-05-02T03:08:18Z
system:kube-scheduler                                                  2022-05-02T03:08:18Z
system:kubelet-api-admin                                               2022-05-02T03:08:18Z
system:metrics-server                                                  2022-05-02T03:08:36Z
system:monitoring                                                      2022-05-02T03:08:18Z
system:node                                                            2022-05-02T03:08:18Z
system:node-bootstrapper                                               2022-05-02T03:08:18Z
system:node-problem-detector                                           2022-05-02T03:08:18Z
system:node-proxier                                                    2022-05-02T03:08:18Z
system:persistent-volume-provisioner                                   2022-05-02T03:08:18Z
system:persistent-volume-secret-operator                               2022-05-02T03:08:36Z
system:prometheus                                                      2022-05-02T03:10:49Z
system:public-info-viewer                                              2022-05-02T03:08:18Z
system:service-account-issuer-discovery                                2022-05-02T03:08:18Z
system:volume-scheduler                                                2022-05-02T03:08:18Z
view                                                                   2022-05-02T03:08:18Z

Role の作成

Role の作成もほかの K8s リソースと同じく、マニフェストで定義できます。

Role マニフェスト例:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default  # Namespace 指定
  name: pod-reader  # Role の名前
rules:
- apiGroups: [""]  # "" はコアのAPIグループに属するリソース
  resources: ["pods"]  # 対象のリソース種類を指定
  verbs: ["get", "watch", "list"]  # 実行できる操作に指定 ※ 指定できる操作は後述あり

Role の特徴:

  • namespace の指定が必要
  • apiGroups 何を入れるべきか
    • kubectl api-resources コマンドで、リソース種類の apiGroups が表示されている
    • 複数 apiGroups のリソースも存在する:Deployment は appextensions に属している
    • 特定の apiGroups に属していない場合は Core API group を指定する:"" が Core API group です。
  • verbs で指定できる操作
    • *:すべての処理
    • create:作成
    • delete:削除
    • get:(情報)取得
    • list:一覧取得
    • patch:一部設定変更
    • update:更新
    • watch:変更の追跡

Deployment マニフェスト例:

# APIグループ" extensions "と " apps " の両方で、Deployments への読み取り/書き込みを許可
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: deployment-full-role
rules:
- apiGroups: ["extensions", "apps"]
  #
  # HTTPレベルでの、Deployment にアクセスするリソースの名前
  # オブジェクトは "deployments"
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

※ 上記マニフェスト例の配列を yaml 形式で書いても問題ない

ClusterRole の作成

ClusterRole マニフェスト例:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # 「namespace」は ClusterRoles が Namespace に属していないため、省略されています
  name: deployment-read-role
rules:
- apiGroups: ["extensions", "apps"]
  #
  # HTTPレベルでの、Secretにアクセスするリソースの名前
  # オブジェクトは"secrets"
  resources: ["deployments"]
  verbs: ["get", "watch", "list"]  # deployment に対する権限
- nonResourceURLs: ["/healthz", "/healthz/*"] # nonResourceURLの「*」はサフィックスグロブマッチです
  verbs: ["get", "post"]  # nonResourceURLs に対する権限

ClusterRole の特徴:

  • namespace の指定は不要
  • apiGroups:※ Role と同じ
  • verbs:※ Role と同じ
  • nonResourceURLs の指定が可能
    • nonResourceURLs:ヘルスチェックのエンドポイントやバージョン情報の表示用エンドポイントなどの URL
    • K8s に関する API ではない
    • 例えば、Deployment に関して、Read ができる権限と nonResourceURLs の Get 権限の ClusterRole で死活監視するとか

ClusterRole の Aggregation (集約)

複数の ClusterRole を1つの ClusterRole に集約 (関連付け) して、新しい ClusterRole を作成することもできます。
元の ClusterRole が変更された場合、集約の ClusterRole もその変更が反映されるようになっています。
※ 集約の ClusterRole に権限を設定しても、効果はないので、ご注意ください。
※ Role には集約できません

集約例:

# 元 ClusterRole 1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  namespace: default
  name: deployment-read-role
  labels:  # 集約するために設定した labels
    app: sample-rbac
rules:
- apiGroups: ["extensions", "apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch"]
---
# 元 ClusterRole 2
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  namespace: default
  name: services-read-role
  labels:  # 集約するために設定した labels
    app: sample-rbac
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: sample-aggregated-clusterrole
aggregationRule:
  clusterRoleSelectors:  # Labels で集約する
  - matchLabels:
      app: sample-rbac
rules: [] # コントロールプレーンは自動的にルールを入力するので、記載しても上書きされる

RoleBinding と ClusterRoleBinding

RoleBinding と ClusterRoleBinding の構成はほぼ同じです。
roleRef で指定した Role を subjects で指定した User や ServcieAccount に binding (紐付け)します。

特徴:

  • 1 RoleBinding に、1 Role だけですが、subjects には複数の User や ServcieAccount を指定可能
    • 1 Role ⇔ 多 User

RoleBinding 例

# サンプル ServcieAccount 作成
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sample-serviceaccount-1  # ServcieAccount 名
  namespace: default  # 所属の Namespace 指定
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sample-serviceaccount-2  # ServcieAccount 名
  namespace: default  # 所属の Namespace 指定
---
# RoleBinding 作成
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: role-grantor-binding
  namespace: default  # RoleBinding は Namespace 指定必須
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: deployment-full-role  # 上記の例で作った role
subjects:
- kind: ServiceAccount
  name: sample-serviceaccount-1
  namespace: default  # ServcieAccount は Namespace 指定必須
- kind: ServiceAccount
  name: sample-serviceaccount-2
  namespace: default

結果確認:

~$ kubectl get rolebindings -o wide

NAME                   ROLE                        AGE   USERS   GROUPS   SERVICEACCOUNTS
role-grantor-binding   Role/deployment-full-role   98s                    default/sample-serviceaccount-1, default/sample-serviceaccount-2

ClusterRoleBinding 例

# サンプル ServcieAccount 作成
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sample-serviceaccount-3  # ServcieAccount 名
  namespace: default  # 所属の Namespace 指定
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sample-serviceaccount-4  # ServcieAccount 名
  namespace: default  # 所属の Namespace 指定
---
# ClusterRoleBinding 作成
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-role-grantor-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: deployment-read-role  # 上記の例で作った ClusterRole
subjects:
- kind: ServiceAccount
  name: sample-serviceaccount-3
  namespace: default  # ServcieAccount は Namespace 指定必須
- kind: ServiceAccount
  name: sample-serviceaccount-4
  namespace: default

結果確認:

~$ kubectl get clusterrolebindings cluster-role-grantor-binding -o wide

NAME                           ROLE                               AGE     USERS   GROUPS   SERVICEACCOUNTS
cluster-role-grantor-binding   ClusterRole/deployment-read-role   4m25s                    default/sample-serviceaccount-3, default/sample-serviceaccount-4                                                  

最後に

今回は K8s の世界の話のみを紹介してますが、Azure の AKS において、Azure の RBAC との連携も可能なので、次回はそこら辺を纏めようと思います。

参考資料

コメント

タイトルとURLをコピーしました