0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

secretsとserviceaccountを理解する

Posted at

目的

  • secretsとserviceaccountを理解する

手段

killercodaで手を動かす

環境

killercoda

secrets とは

secrets は k8s 上でパスワード・トークン・キーを保存するオブジェクトです。パスワード等を secrets に格納して、pod 等から参照して利用します。利用方法は pod の環境変数として代入する、または、pod 内の特定パスに対して volume マウントして利用します。

secret 作成

まず、secret を作成します。

controlplane:~$ k create secret generic holy --from-literal creditcard=1111222233334444 --dry-run=client -oyaml
apiVersion: v1
data:
  creditcard: MTExMTIyMjIzMzMzNDQ0NA==
kind: Secret
metadata:
  creationTimestamp: null
  name: holy
# 作成前に yaml フォーマットで確認します

controlplane:~$ k get secrets holy 
NAME   TYPE     DATA   AGE
holy   Opaque   1      8s
# 作成したオブジェクトを確認します

controlplane:~$ k get secrets holy -oyaml
apiVersion: v1
data:
  creditcard: MTExMTIyMjIzMzMzNDQ0NA==
kind: Secret
metadata:
  creationTimestamp: "2025-04-15T02:19:31Z"
  name: holy
  namespace: default
  resourceVersion: "6739"
  uid: 05b43f90-68c6-4454-926f-513a643bb671
# 作成した値は base64 でエンコード後の値で保持されます
# つまり、このオブジェクトを参照可能なユーザは チルダcreditcardチルダ の値をデコードして参照可能です

secrets 作成方法は literal と呼ばれる直接値を指定する方法やファイルから作成可能です。literal の作成方法は前述の作成方法です。次に、ファイルから secrets を作成します。

controlplane:~$ cat /opt/ks/secret-diver.yaml 
apiVersion: v1
data:
  hosts: MTI3LjAuMC4xCWxvY2FsaG9zdAoxMjcuMC4xLjEJaG9zdDAxCgojIFRoZSBmb2xsb3dpbmcgbGluZXMgYXJlIGRlc2lyYWJsZSBmb3IgSVB2NiBjYXBhYmxlIGhvc3RzCjo6MSAgICAgbG9jYWxob3N0IGlwNi1sb2NhbGhvc3QgaXA2LWxvb3BiYWNrCmZmMDI6OjEgaXA2LWFsbG5vZGVzCmZmMDI6OjIgaXA2LWFsbHJvdXRlcnMKMTI3LjAuMC4xIGhvc3QwMQoxMjcuMC4wLjEgaG9zdDAxCjEyNy4wLjAuMSBob3N0MDEKMTI3LjAuMC4xIGNvbnRyb2xwbGFuZQoxNzIuMTcuMC4zNSBub2RlMDEKMTcyLjE3LjAuMjMgY29udHJvbHBsYW5lCg== # hosts は key となり、エンコードされた文字列は value となります
kind: Secret 
metadata:
  name: diver # secret のオブジェクト名
# secret 作成元のファイルを確認します

controlplane:~$ k create -f /opt/ks/secret-diver.yaml 
secret/diver created
# creat コマンドで secret オブジェクトを作成します

controlplane:~$ k get secrets diver 
NAME    TYPE     DATA   AGE
diver   Opaque   1      11s
# get で参照します

controlplane:~$ k get secrets diver -o yaml
apiVersion: v1
data:
  hosts: MTI3LjAuMC4xCWxvY2FsaG9zdAoxMjcuMC4xLjEJaG9zdDAxCgojIFRoZSBmb2xsb3dpbmcgbGluZXMgYXJlIGRlc2lyYWJsZSBmb3IgSVB2NiBjYXBhYmxlIGhvc3RzCjo6MSAgICAgbG9jYWxob3N0IGlwNi1sb2NhbGhvc3QgaXA2LWxvb3BiYWNrCmZmMDI6OjEgaXA2LWFsbG5vZGVzCmZmMDI6OjIgaXA2LWFsbHJvdXRlcnMKMTI3LjAuMC4xIGhvc3QwMQoxMjcuMC4wLjEgaG9zdDAxCjEyNy4wLjAuMSBob3N0MDEKMTI3LjAuMC4xIGNvbnRyb2xwbGFuZQoxNzIuMTcuMC4zNSBub2RlMDEKMTcyLjE3LjAuMjMgY29udHJvbHBsYW5lCg==
kind: Secret
metadata:
  creationTimestamp: "2025-04-15T02:25:18Z"
  name: diver
  namespace: default
  resourceVersion: "7189"
  uid: 3418e296-7ea8-4390-8f81-c60c8feba0c5
type: Opaque
# -oyaml で secret オブジェクトの中身を確認します
secret を pod にマウント

ここからは作成した secret を pod で利用する方法を確認します。まずは、volume として pod 内の特定パスにマウントします。

controlplane:~$ k run pod1 --image=nginx --dry-run=client -oyaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod1
  name: pod1
spec:
  containers:
  - image: nginx
    name: pod1
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
# ベースのyamlを作成する
controlplane:~$ cat pod1.yaml 
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod1
  name: pod1
spec:
  volumes:
    - name: diver
      secret:
        secretName: diver # 事前に作成した secret を指定する
  containers:
  - image: nginx
    name: pod1
    volumeMounts:
      - name: diver
        readOnly: true # readOnlyであれば指定する
        mountPath: "/etc/diver/" # secret をマウントするパスを指定する
    resources: {}                # マウントするhostsはテキストファイルなので上位のディレクトリまでを指定する
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

次に正しくマウントできているかを確認する。

controlplane:~$ k exec pod1 -- cat /etc/diver/hosts
127.0.0.1       localhost
127.0.1.1       host01

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
127.0.0.1 host01
127.0.0.1 host01
127.0.0.1 host01
127.0.0.1 controlplane
172.17.0.35 node01
172.17.0.23 controlplane
# マウントしたファイルを確認できます

続いて、secret を環境変数として代入します。

controlplane:~$ cat pod1.yaml 
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod1
  name: pod1
spec:
  volumes:
    - name: diver
      secret:
        secretName: diver # 事前に作成した secret を指定する
  containers:
  - image: nginx
    name: pod1
    volumeMounts:
      - name: diver
        readOnly: true # readOnlyであれば指定する
        mountPath: "/etc/diver/" # secret をマウントするパスを指定する
    env:
    - name: HOLY # 環境変数名を指定
      valueFrom:
        secretKeyRef:
          name: holy # 参照先の secret 名を指定
          key: creditcard # secret 内の key を指定
    resources: {}                # マウントするhostsはテキストファイルなので上位のディレクトリまでを指定する
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
# yaml 内容を確認します

controlplane:~$ k exec pod1 -- env |grep HOLY
HOLY=1111222233334444
# 正しく環境変数に設定されているか確認します

controlplane:~$ k get secrets holy -oyaml
apiVersion: v1
data:
  creditcard: MTExMTIyMjIzMzMzNDQ0NA==
kind: Secret
metadata:
  creationTimestamp: "2025-04-15T10:56:40Z"
  name: holy
  namespace: default
  resourceVersion: "2475"
  uid: b88654b7-b22e-403c-9740-5b4eec44c641
type: Opaque
# secret 内容を確認します

secret をデコード

デコードした secret の中身を確認します。

kubectl -n one get secret s1 -ojsonpath="{.data.data}" | base64 -d
kubectl -n one get secret s2 -ojsonpath="{.data.data}" | base64 -d
# スマートに jsonpath 指定で取得できます

controlplane:~$ k get -n one secrets s1 -oyaml |grep "data: " |awk '{ print $2 }' | base64 --decode >> /opt/ks/one
controlplane:~$ k get -n one secrets s2 -oyaml |grep "data: " |awk '{ print $2 }' | base64 --decode >> /opt/ks/one
# 実際に手を動かすとこんな感じです...

serviceaccount とは

サービスアカウントは人間以外のアカウントの一種で、KubernetesではKubernetesクラスタ内で個別のIDを提供しますAPIサーバーへの認証などのさまざまな場面で役立ちます。

serviceaccount 作成

create コマンドで作成します。

controlplane:~$ k create serviceaccount secret-manager
serviceaccount/secret-manager created
# 作成コマンドです

controlplane:~$ k get serviceaccounts -oyaml
apiVersion: v1
items:
- apiVersion: v1
  kind: ServiceAccount
  metadata:
    creationTimestamp: "2025-03-22T19:51:55Z"
    name: default # デフォルトの Serviceaccount です
    namespace: default
    resourceVersion: "426"
    uid: 72c16a73-bb3a-4ddf-b484-8cd235d8a21a
- apiVersion: v1
  kind: ServiceAccount
  metadata:
    creationTimestamp: "2025-04-15T11:15:56Z"
    name: secret-manager # 作成した ServiceAccount です
    namespace: default
    resourceVersion: "2664"
    uid: 6466b9af-d85e-48dd-a914-13a7db94c724
kind: List
metadata:
  resourceVersion: ""

次に pod に作成した serviceaccount を設定します。

controlplane:~$ cat secret-manager.yaml 
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: secret-manager
  name: secret-manager
  namespace: ns-secure
spec:
  serviceAccountName: secret-manager # 作成した serviceaccount を指定します
  volumes:
    - name: secret-volume
      secret:
        secretName: sec-a2
  containers:
  - image: httpd:alpine
    name: secret-manager
    resources: {}
    volumeMounts:
      - name: secret-volume
        readOnly: true
        mountPath: "/etc/sec-a2"
    env:
    - name: SEC_A1
      valueFrom:
        secretKeyRef:
          name: sec-a1
          key: aaa
  dnsPolicy: ClusterFirst
  restartPolicy: Always

controlplane:~$ k apply -f secret-manager.yaml 
pod/secret-manager created
serviceaccounttoken の自動マウントを制御

次に serviceaccouttoken の自動マウント動作を確認します。

controlplane:~$ cat /opt/ks/pod-one.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-one
  namespace: one
spec:
  serviceAccountName: custom
  automountServiceAccountToken: false # serviceaccouttoken の自動マウント有無を指定します
  containers:
  - name: webserver
    image: nginx:1.19.6-alpine
    ports:
    - containerPort: 80

controlplane:~$ k apply -f /opt/ks/pod-one.yaml 
pod/pod-one created
# yaml を適用します
serviceaccounttoken のマウント状態を確認

serviceaccouttoken のマウント状態を確認します。

controlplane:~$ k exec -n one pod-one -- mount | grep serviceaccout
controlplane:~$ k exec -n one pod-one -- mount | cat /var/run/secrets/kubernetes.io/serviceaccount/token
cat: /var/run/secrets/kubernetes.io/serviceaccount/token: No such file or directory
# マウントを無効化しているため、マウントされていません

次に automoutServiceAccoutToken を true にして pod を作成します。

controlplane:~$ cat /opt/ks/pod-one.yaml |grep auto 
  automountServiceAccountToken: true

controlplane:~$ k replace -f /opt/ks/pod-one.yaml --force
pod "pod-one" deleted
pod/pod-one replaced

マウント状況を確認します

controlplane:~$ k exec -n one pod-one -- mount | grep serviceaccount
tmpfs on /run/secrets/kubernetes.io/serviceaccount type tmpfs (ro,relatime,size=1912956k,inode64,noswap)

controlplane:~$ kubectl -n one exec -it pod-one -- cat /var/run/secrets/kubernetes.io/serviceaccount/token
eyJhbGciOiJSUzI1NiIsImtpZCI6InRaVDhLaEdBeGVWTHRXTkJJRUNDT1BGRmxkYmNzOFVCd2doYWpuSlNrODgifQ.--snip---
controlplane:~$ 
# マウントされていることを確認できます。

あとがき

アウトプットは良いですね!

ソース

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?