目的
- securityContext を理解する
手段
killercodaで手を動かす
環境
killercoda
securityContext とは
KubernetesのsecurityContextは、Podやコンテナに適用されるセキュリティ設定を定義するオブジェクトです。これを使うことで、コンテナの特権レベルやアクセス権限を細かく制御し、セキュリティを強化できます。
つまり、securityContext は Pod や Conteiner 単位で指定可能です。Pod で設定が存在しても、Conteiner 側で設定を上書きできるパターンですね。マニュアル等でコンテナの実行権限(特権レベルを禁止)や実行ユーザを指定することができるイメージですね。
代表的な設定は?
runAsUser: Pod内のコンテナのプロセスが実行されるユーザーID。
runAsGroup: Pod内のコンテナのプロセスが実行されるグループID。
fsGroup: Podのボリュームに適用される所有グループID。これにより、コンテナは共有ボリュームのファイルにアクセスできるようになります。
seLinuxOptions: SELinux(Security-Enhanced Linux)のラベルを設定します。
コンテナ実行時のユーザID・グループID・所有グループIDを指定できます。続いて、特権レベルやファイルシステムへのアクセス制限を見ていきます。
capabilities: コンテナに付与する、または削除する**Linuxの機能(Capability)**を定義します。例えば、NET_ADMIN(ネットワーク設定変更)やCAP_KILL(任意のプロセスを停止)などの特権を付与できます。
privileged: trueに設定すると、コンテナはホストOSの全権限を持つことになり、特権モードで実行されます。これは極めて危険なため、慎重に利用すべきです。
readOnlyRootFilesystem: trueに設定すると、コンテナのルートファイルシステムが読み取り専用になります。これにより、コンテナ内での不正なファイルの書き込みを防げます。
allowPrivilegeEscalation: 親プロセスから子プロセスへの特権昇格を許可するかを制御します。falseに設定すると、execやsuのようなコマンドによる権限昇格を防ぐことができます。
capabilities は Linux の機能単位で権限を付与します。NET_ADMIN や CAP_KILL などです。明確な制限がある場合に細かく設定するイメージでしょうか。
priviledge: true はよく見るやつですね。コンテナを特権モードで実行可能などうか制御します。
readOnlyFilesystem: true もよく見るやつですね。コンテナのルートファイルシステムが読み取り専用になります。コンテナ自身でファイルシステムに書き込むためには、emptyDir などをボリュームマウントしてあげて、書き込み可能な領域を別途用意する必要があります。例えば、コンテナ起動時にファイルシステムへ書き込みを行う場合、エラーでコンテナが正しく起動しません。
allowPrivilegeEscalation は特権昇格の可否を制限します。こちらも false が推奨されますね。
controlplane:~$ k logs -n moon deployments/web4.0
Found 2 pods, using pod/web4.0-675c6bc9bd-58ktp
sh: can't create /etc/date.log: Read-only file system
# ファイルシステムへの書き込み失敗でコンテナの起動に失敗しています
続いて、emptyDir で書き込み可能な領域を用意します。
controlplane:~$ cat web4.0.yaml |grep -A10 volumeM
volumeMounts:
- mountPath: /etc
name: empty
volumes:
- name: empty
emptyDir: {}
controlplane:~$ k describe deployments.apps -n moon web4.0 |more
-- snip --
Mounts:
/etc from empty (rw)
Volumes:
empty:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
# /etc ディレクトリは emptyDir でマウントされています。
そもそもコンテナ自体を特権モードで動かすかどうかを指定可能です。
apiVersion: v1
kind: Pod
metadata:
labels:
run: prime
name: prime
spec:
containers:
- command:
- sh
- -c
- sleep 1d
image: nginx:alpine
name: prime
securityContext:
privileged: true
# privileged: true で特権モードで起動します
あとがき
Kubernetes は奥が深い...