kubestronautへの道 ~CKS編 その17 killer coda「Immutability Readonly Filesystem」~

tech article

今日覚えて帰ること

readOnlyRootFilesystem

  • SecurityContext 配下に設定する
    • (podのマニフェストファイルにおいて) spec 配下と、 spec.containers 配下に SecurityContextフィールドが存在するが、readOnlyRootFilesystem は spec.containers 配下の SecurityContext に設定する。
  • コンテナ内で書き込みしたいディレクトリがある場合は、別のボリュームをアタッチする

Immutability Readonly Filesystem

Create a Pod with read-only filesystem

Create a Pod named pod-ro in Namespace sun of image busybox:1.32.0 .

Make sure the container keeps running, like using sleep 1d .

The container root filesystem should be read-only.

コンテナ内におけるルートファイルシステムを readonly にせよ、と言っています。

以下を参考にして進めます。

Podとコンテナにセキュリティコンテキストを設定する
セキュリティコンテキストはPod・コンテナの特権やアクセスコントロールの設定を定義します。 セキュリティコンテキストの設定には以下のものが含まれますが、これらに限定はされません。 任意アクセス制御: user ID (UID) と group ID (GID)に基づいて、ファイルなどのオブジェクトに対する許可を行います...

まずは pod のマニフェストファイルを作成します。
pod は deployment と違って稼働中に編集できるフィールドがほとんどないので、dry-run で yaml 形式で出力し、そのファイルを修正して apply します。

controlplane $ k run -n sun pod-ro --image=busybox:1.32.0 --dry-run -o yaml >  pod.yaml  
W0819 06:13:58.619653    7155 helpers.go:703] --dry-run is deprecated and can be replaced with --dry-run=client.

controlplane $ cp -p pod.yaml pod.yaml.org
controlplane $ vi pod.yaml
controlplane $ diff -u pod.yaml.org pod.yaml
--- pod.yaml.org        2024-08-19 06:13:58.618310839 +0000
+++ pod.yaml    2024-08-19 06:15:30.659059970 +0000
@@ -11,6 +11,8 @@
   - image: busybox:1.32.0
     name: pod-ro
     resources: {}
+    securityContext:
+      readOnlyRootFilesystem: true
   dnsPolicy: ClusterFirst
   restartPolicy: Always
 status: {}

controlplane $ k apply -f pod.yaml 
pod/pod-ro created

これでOKです

Fix existing Nginx Deployment to work with read-only filesystem

The Deployment web4.0 in Namespace moon doesn’t seem to work with readOnlyRootFilesystem .

Add an emptyDir volume to fix this.

deployment でエラー出てるから直してね、と言っています。

まずは pod がどのようなエラーを吐いているのか確認します。

controlplane $ k get po -n moon 
NAME                      READY   STATUS             RESTARTS      AGE
web4.0-65fd646799-q9sc5   0/1     CrashLoopBackOff   6 (76s ago)   6m55s
web4.0-65fd646799-z7hbl   0/1     CrashLoopBackOff   6 (64s ago)   6m55s
controlplane $ k logs -n moon web4.0-65fd646799-q9sc5 
sh: can't create /etc/date.log: Read-only file system
controlplane $ 

問題文にもある通り、 readonly で動いている pod ですが、/etc/date.log を作成しようとしてエラーが吐かれています。
deployment の中身を確認してみましょう。

controlplane $ k edit deployments.apps -n moon web4.0 

///

  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web4.0
    spec:
      containers:
      - command:
        - sh
        - -c
        - date > /etc/date.log && sleep 1d
        image: busybox:1.32.0
        imagePullPolicy: IfNotPresent
        name: container
        resources: {}
        securityContext:
          readOnlyRootFilesystem: true
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst

command で /etc/date.log を作成しようとしています。
が、securityContext で readOnlyRootFilesystem: true と設定されているため、ファイルの作成ができない状態になっています。

そのため、ルートファイルシステムとは別のボリュームをアタッチして、そこに書き込むように設定することにします。
今回は emptyDir を設定するように指示があるので、emptyDir をマウントするように設定します。

  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web4.0
    spec:
      containers:
      - command:
        - sh
        - -c
        - date > /etc/date.log && sleep 1d
        image: busybox:1.32.0
        imagePullPolicy: IfNotPresent
        name: container
        resources: {}
        securityContext:
          readOnlyRootFilesystem: true
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /etc
          name: temp
      volumes:
      - name: temp
        emptyDir: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

このように設定することで、この deployment から生成される pod における /etc 配下は書き込みが可能になります。

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