kubestronautへの道 ~CKS編 その26 killer coda「ServiceAccount Token Mounting」~

tech article

今日覚えて帰ること

ServiceAccount

  • podのマニフェストファイルにspec.serviceAccountNameというフィールドが存在し、ここにSAを指定することでpodにSAをアタッチできる
  • 上記のフィールドを設定しない場合、各nsに存在するdefaultというSAが自動的にアタッチされる。
  • デフォルトの動作でpodにServiceAccountToken用のボリュームがマウントされる

ServiceAccount Token Mounting

Don’t mount ServiceAccount token in a Pod

  1. Modify the the config file /opt/ks/pod-one.yaml to disable the mounting of the ServiceAccount token into that Pod.
  2. Apply the modified file /opt/ks/pod-one.yaml to Namespace one .
  3. Verify that the ServiceAccount token hasn’t been mounted into the Pod.

podにServiceAccount tokenをマウントしないようにしろ、と言っています。

ServiceAccountTokenが何なのかよくわからないので調査します。

Managing Service Accounts
A ServiceAccount provides an identity for processes that run in a Pod. A process inside a Pod can use the identity of its associated service account to authenti...

ServiceAccountTokenどころか、ServiceAccount(以後SA)がよくわかっていませんでした。

SAは、podなどのkubernetesリソースに付与されるアイデンティティのことです。
各リソースにアタッチされたSAに対してRBAC(Role-Based Access Control)で権限の制御を行います。
SAが認証の仕組み、RBACが認可の仕組みって感じですかね(曖昧です。)

で、SAの認証を行う際に使用されるのがServiceAccountTokenって感じっぽいですね。

それでは、実際に進めていきましょう。
まずpodのマニフェストファイルを確認します。

controlplane $ cat /opt/ks/pod-one.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-one
  namespace: one
spec:
  serviceAccountName: custom
  containers:
  - name: webserver
    image: nginx:1.19.6-alpine
    ports:
    - containerPort: 80controlplane $ 

serviceAccountNameというフィールドにcustomというSAが存在しています。
ということで、この記載を削除してapplyすればいいのでは?と思いましたが、失敗しました。

If the pod does not have a .spec.serviceAccountName set, the admission controller sets the name of the ServiceAccount for this incoming Pod to default.

https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/#serviceaccount-admission-controller

上記にあるように、serviceAccountNameフィールドがマニフェストファイルに存在しない場合は、defaultという各nsにデフォルトで存在するSAがアタッチされてしまいます。

指定の通りの挙動にするには、automountServiceAccountToken を false にする必要があります。

controlplane $ cat /opt/ks/pod-one.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-one
  namespace: one
spec:
  serviceAccountName: custom
  automountServiceAccountToken: false
  containers:
  - name: webserver
    image: nginx:1.19.6-alpine
    ports:
    - containerPort: 80controlplane $ 

これを指定されているnsである one にapplyすれば完了です。

以下のコマンドでpodにSAがマウントされないことを確認できます。
トークンはpod内の/var/run/secrets/kubernetes.io/serviceaccount配下に配置されるらしいです。

controlplane $ kubectl -n one exec -it pod-one -- mount | grep serviceaccount
controlplane $ 
controlplane $ kubectl -n one exec -it pod-one -- cat /var/run/secrets/kubernetes.io/serviceaccount/token
cat: can't open '/var/run/secrets/kubernetes.io/serviceaccount/token': No such file or directory
command terminated with exit code 1
controlplane $ 

Don’t mount ServiceAccount token for ServiceAccount

  1. Modify the default ServiceAccount in Namespace two to prevent any Pod that uses it from mounting its token by default.
  2. Apply the Pod configuration file /opt/ks/pod-two.yaml to Namespace two .
  3. Verify that the ServiceAccount token hasn’t been mounted into the Pod.

デフォルトのSAを修正して、デフォルトの動作としてpodがそのSAのトークンをマウントしないようにせよ、と言っています。

SAにもautomountServiceAccountTokenが設定できるみたいなので、twoという名前空間のdefaultというSAを修正します。

podの時と違って、spec配下のフィールドではなく、最上位のフィールドとして存在しているみたいです。

controlplane $ k edit -n two sa

apiVersion: v1
automountServiceAccountToken: false
kind: ServiceAccount
metadata:
  creationTimestamp: "2024-09-16T03:41:25Z"
  name: default
  namespace: two
  resourceVersion: "4011"
  uid: 6abb71d7-0d14-4e3d-b54e-1ddd680e66b8

上記のように修正できれば完了です。

公式ページから情報を探すことができなかったので解答を確認してから記事を作成したのですが、各マニフェストファイルに記載できる内容は下記にまとまっているみたいです。

Kubernetes API Reference Docs

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