概要
Kubernetes ではポッドセキュリティポリシーにより、ポッドの作成と更新のきめ細かい承認が可能になります。また、Pod に直接設定するだけではなくRBAC を利用したデフォルトの設定を行うことができたり、OPAのgatekeepeを利用することで開発者は意識することなくセキュリティの設定を行うことができます。こちらにはreadOnlyRootFilesystem
というオプションがあり、このオプションを有効にするとコンテナ内がreadonlyになるためセキュリティの施策の1つとして有効にすべき場面が多いと思います。こちらは有用ですが yaml
を作成していざ、本番へというタイミングでしか分からないのは流石にしんどいです。そのため、デプロイの前にこれはテストをすることは無駄ではありません。
readOnlyRootFilesystem をやってみる
apiVersion: v1 kind: Pod metadata: name: read-onlyroot-filesystem spec: containers: - name: centos7 image: centos:7 command: [ "sh", "-c", "sleep 1h" ] securityContext: readOnlyRootFilesystem: true - name: centos8 image: centos:8 command: [ "sh", "-c", "sleep 1h" ]
Podの作成
kubectl apply -f readonly_pod.yaml pod/read-onlyroot-filesystem created kubectl get pod NAME READY STATUS RESTARTS AGE read-onlyroot-filesystem 2/2 Running 0 15m
ファイルのWrite 及び Read/Write を実施する
kubectl exec -it read-onlyroot-filesystem -c centos7 touch testfile kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead. touch: cannot touch 'testfile': Read-only file system command terminated with exit code 1 $ kubectl exec -it read-onlyroot-filesystem -c centos7 ls kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead. anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var $ kubectl exec -it read-onlyroot-filesystem -c centos7 pwd kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead. /
テストする
gatekeepe や ポッドセキュリティポリシー をユーザーやNamespace 単位で実施することにより開発者は意識することなくセキュリティの設定を行うことができますがyaml
を作成していざ、本番へというタイミングでしか分からないので流石にめんどくさいです。そのため、デプロイの前にこれはテストをすることは無駄ではありません。conftest は YAML や JSON などの構造化データに対してユニットテストを記述できるツールです。
install と実行
$ wget https://github.com/open-policy-agent/conftest/releases/download/v0.21.0/conftest_0.21.0_Linux_x86_64.tar.gz $ tar xzf conftest_0.21.0_Linux_x86_64.tar.gz $ sudo mv conftest /usr/local/bin
input.spec.containers.securityContext.readOnlyRootFilesystem
が正であればこれで通ります。
package main deny[msg] { input.kind == "Pod" input.spec.containers.securityContext.readOnlyRootFilesystem msg := "Containers must not write" }
Pass
しました
$ conftest test readonly_pod.yaml 1 test, 1 passed, 0 warnings, 0 failures, 0 exceptions
書き込みは許可したい場合はnot input.spec.containers.securityContext.readOnlyRootFilesystem
のような設定をぶちこんであげれば良いです。
package main deny[msg] { input.kind == "Pod" not input.spec.containers.securityContext.readOnlyRootFilesystem msg := "Containers must write" }
そして、実行すると、想定通りに失敗します。事前に分かるというメリットは以外に多くありますのでぜひ、皆さんの環境でも試してみてはいかがでしょうか?
conftest test readonly_pod.yaml FAIL - readonly_pod.yaml - Containers must write 1 test, 0 passed, 0 warnings, 1 failure, 0 exceptions