From 0e3bb4b8e6b0df57a9b9fecc33ed1ca559fdac49 Mon Sep 17 00:00:00 2001 From: Shingo Omura Date: Wed, 14 Aug 2024 20:10:33 +0900 Subject: [PATCH] [ja] updated content/ja/docs/tasks/configure-pod-container/security-context.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - updated "Efficient SELinux volume relabeling" section - added "Managing access to the `/proc` filesystem" section - added "fine-grained SupplementalGroups control" section - added "Set the AppArmor Profile for a Container" section - s|ユーザ|ユーザー|g - s|ユーザー/グループ|ユーザー、グループ| - removed unnecessary space - applied suggestions from code review Co-authored-by: Junya Okabe <86868255+Okabe-Junya@users.noreply.github.com> Co-authored-by: Taisuke Okamoto <34154552+b1gb4by@users.noreply.github.com> --- .../security-context.md | 262 +++++++++++++++++- .../pods/security/security-context-5.yaml | 15 + .../pods/security/security-context-6.yaml | 16 ++ .../pods/security/security-context.yaml | 1 + 4 files changed, 285 insertions(+), 9 deletions(-) create mode 100644 content/ja/examples/pods/security/security-context-5.yaml create mode 100644 content/ja/examples/pods/security/security-context-6.yaml diff --git a/content/ja/docs/tasks/configure-pod-container/security-context.md b/content/ja/docs/tasks/configure-pod-container/security-context.md index 4f41c65ec0..6b21918aef 100644 --- a/content/ja/docs/tasks/configure-pod-container/security-context.md +++ b/content/ja/docs/tasks/configure-pod-container/security-context.md @@ -52,7 +52,7 @@ Podに設定したセキュリティ設定はPod内の全てのコンテナに 設定ファイルの中の`runAsUser`フィールドは、Pod内のコンテナに対して全てのプロセスをユーザーID 1000で実行するように指定します。 `runAsGroup`フィールドはPod内のコンテナに対して全てのプロセスをプライマリーグループID 3000で実行するように指定します。このフィールドが省略されたときは、コンテナのプライマリーグループIDはroot(0)になります。`runAsGroup`が指定されている場合、作成されたファイルもユーザー1000とグループ3000の所有物になります。 -また`fsGroup`も指定されているため、全てのコンテナ内のプロセスは補助グループID 2000にも含まれます。`/data/demo`ボリュームとこのボリュームに作成されたファイルはグループID 2000になります。 +また`fsGroup`も指定されているため、全てのコンテナ内のプロセスは補助グループID 2000にも含まれます。`/data/demo`ボリュームとこのボリュームに作成されたファイルはグループID 2000になります。加えて、`supplementalGroups`フィールドが指定されている場合、全てのコンテナ内のプロセスは指定されている補助グループIDにも含まれます。もしこのフィールドが指定されていない場合、空を意味します。 Podを作成してみましょう。 @@ -128,10 +128,10 @@ id 出力はこのようになります。 ```none -uid=1000 gid=3000 groups=2000 +uid=1000 gid=3000 groups=2000,3000,4000 ``` -出力から`runAsGroup`フィールドと同じく`gid`が3000になっていることが確認できるでしょう。`runAsGroup`が省略された場合、`gid`は0(root)になり、そのプロセスはグループroot(0)とグループroot(0)に必要なグループパーミッションを持つグループが所有しているファイルを操作することができるようになります。 +出力から`runAsGroup`フィールドと同じく`gid`が3000になっていることが確認できるでしょう。`runAsGroup`が省略された場合、`gid`は0(root)になり、そのプロセスはグループroot(0)とグループroot(0)に必要なグループパーミッションを持つグループが所有しているファイルを操作することができるようになります。また、`groups`の出力に、`gid`に加えて、`fsGroups`、`supplementalGroups`フィールドで指定したグループIDも含まれていることも確認できるでしょう。 shellから抜けましょう。 @@ -139,6 +139,165 @@ shellから抜けましょう。 exit ``` +### コンテナイメージ内の`/etc/group`から暗黙的にマージされるグループ情報 + +Kubernetesは、デフォルトでは、Podで定義された情報に加えて、コンテナイメージ内の`/etc/group`のグループ情報をマージします。 + +{{% code_sample file="pods/security/security-context-5.yaml" %}} + +このPodはsecurity contextで`runAsUser`、`runAsGroup`、`supplementalGroups`フィールドが指定されています。しかし、コンテナ内のプロセスには、コンテナイメージ内の`/etc/group`に定義されたグループIDが、補助グループとして付与されていることが確認できるでしょう。 + +Podを作成してみましょう。 + +```shell +kubectl apply -f https://k8s.io/examples/pods/security/security-context-5.yaml +``` + +Podのコンテナが実行されていることを確認します。 + +```shell +kubectl get pod security-context-demo +``` + +実行中のコンテナでshellを取ります。 + +```shell +kubectl exec -it security-context-demo -- sh +``` + +プロセスのユーザー、グループ情報を確認します。 + +```shell +$ id +``` + +出力はこのようになります。 + +```none +uid=1000 gid=3000 groups=3000,4000,50000 +``` + +`groups`にグループID`50000`が含まれていることが確認できるでしょう。これは、ユーザー(`uid=1000`)がコンテナイメージで定義されており、コンテナイメージ内の`/etc/group`でグループ(`gid=50000`)に所属しているためです。 + +コンテナイメージの`/etc/group`の内容を確認してみましょう。 + +```shell +$ cat /etc/group +``` + +ユーザー`1000`がグループ`50000`に所属していることが確認できるでしょう。 + +```none +... +user-defined-in-image:x:1000: +group-defined-in-image:x:50000:user-defined-in-image +``` + +shellから抜けましょう。 + +```shell +exit +``` + +{{}} +_暗黙的にマージされる_ 補助グループはボリュームアクセスを行う際にセキュリティ上の懸念を引き起こすことがあります(詳細は[kubernetes/kubernetes#112879](https://issue.k8s.io/112879)を参照してください)。回避したい場合、次節を参照してください。 +{{}} + +## Podにfine-grained(きめ細かい) SupplementalGroups controlを設定する {#supplementalgroupspolicy} + +{{< feature-state feature_gate_name="SupplementalGroupsPolicy" >}} + +この機能はkubeletとkube-apiseverに`SupplementalGroupsPolicy` +[フィーチャーゲート](/docs/reference/command-line-tools-reference/feature-gates/)を設定し、Podの`.spec.securityContext.supplementalGroupsPolicy`フィールドを指定することで利用できます。 + +`supplementalGroupsPolicy`フィールドは、Pod内のコンテナプロセスに付与される補助グループを、どのように決定するかを定義します。有効な値は次の2つです。 + +* `Merge`: `/etc/group`で定義されている、コンテナのプライマリユーザーが所属するグループをマージします。指定されていない場合、このポリシーがデフォルトです。 + +* `Strict`: `fsGroup`、`supplementalGroups`、`runAsGroup`フィールドで指定されたグループのみ補助グループに指定されます。つまり、`/etc/group`で定義された、コンテナのプライマリユーザーのグループ情報はマージされません。 + +この機能が有効な場合、`.status.containerStatuses[].user.linux`フィールドで、コンテナの最初のプロセスに付与されたユーザー、グループ情報が確認出来ます。暗黙的なグループIDが付与されているかどうかを確認するのに便利でしょう。 + +{{% code_sample file="pods/security/security-context-6.yaml" %}} + +このPodマニフェストは`supplementalGroupsPolicy=Strict`を指定しています。`/etc/group`に定義されているグループ情報が、コンテナ内のプロセスの補助グループにマージされないことが確認できるでしょう。 + +Podを作成してみましょう。 + +```shell +kubectl apply -f https://k8s.io/examples/pods/security/security-context-6.yaml +``` + +Podのコンテナが実行されていることを確認します。 + +```shell +kubectl get pod security-context-demo +``` + +プロセスのユーザー、グループ情報を確認します。 + +```shell +kubectl exec -it security-context-demo -- id +``` + +出力はこのようになります。 + +```none +uid=1000 gid=3000 groups=3000,4000 +``` + +Podのステータスを確認します。 + +```shell +kubectl get pod security-context-demo -o yaml +``` + +`status.containerStatuses[].user.linux`フィールドでコンテナの最初のプロセスに付与されたユーザー、グループ情報が確認出来ます。 + +```none +... +status: + containerStatuses: + - name: sec-ctx-demo + user: + linux: + gid: 3000 + supplementalGroups: + - 3000 + - 4000 + uid: 1000 +... +``` + +{{}} +`status.containerStatuses[].user.linux`フィールドで公開されているユーザー、グループ情報は、コンテナの最初のプロセスに、_最初に付与された_ 情報であることに注意してください。 +もしそのプロセスが、自身のユーザー、グループ情報を変更できるシステムコール(例えば [`setuid(2)`](https://man7.org/linux/man-pages/man2/setuid.2.html), +[`setgid(2)`](https://man7.org/linux/man-pages/man2/setgid.2.html), +[`setgroups(2)`](https://man7.org/linux/man-pages/man2/setgroups.2.html)等)を実行する権限を持っている場合、プロセス自身で動的に変更が可能なためです。 +つまり、実際にプロセスに付与されているユーザー、グループ情報は動的に変化します。 +{{}} + +### 利用可能な実装 {#implementations-supplementalgroupspolicy} + +{{% thirdparty-content %}} + +下記のコンテナランタイムがfine-grained(きめ細かい) SupplementalGroups controlを実装しています。 + +CRI実装: +- [containerd](https://containerd.io/) v2.0以降 +- [CRI-O](https://cri-o.io/) v1.31以降 + +ノードのステータスでこの機能が利用可能かどうか確認出来ます。 + +```yaml +apiVersion: v1 +kind: Node +... +status: + features: + supplementalGroupsPolicy: true +``` + ## Podのボリュームパーミッションと所有権変更ポリシーを設定する {{< feature-state for_k8s_version="v1.23" state="stable" >}} @@ -367,6 +526,41 @@ securityContext: localhostProfile: my-profiles/profile-allow.json ``` +## コンテナにAppArmorプロフィールを設定する + +コンテナにAppArmorプロフィールを設定するには、`securityContext`セクションに`appAormorProfile`フィールドを含めてください。 +`appAormerProfile`フィールドには、`type`フィールドと`localhostProfile`フィールドから構成される[AppArmorProfile](/docs/reference/generated/kubernetes-api/{{< param "version" +>}}/#apparmorprofile-v1-core)オブジェクトが入ります。`type`フィールドの有効なオプションは`RuntimeDefault`(デフォルト)、`Unconfined`、`Localhost`です。 +`localhostProfile`は`type`が`Localhost`のときには必ず設定しなければなりません。この値はノードで事前に設定されたプロフィール名を示します。Podは事前にどのノードにスケジュールされるかわからないため、指定されたプロフィールはPodがスケジュールされ得る全てのノードにロードされている必要があります。カスタムプロフィールをセットアップする方法は[Setting up nodes with profiles](/docs/tutorials/security/apparmor/#setting-up-nodes-with-profiles)を参照してください。 + +注意: `containers[*].securityContext.appArmorProfile.type`が明示的に`RuntimeDefault`に設定されている場合は、もしノードでAppArmorが有効化されていなければ、Podの作成は許可されません。 +しかし、`containers[*].securityContext.appArmorProfile.type`が設定されていない場合、AppArmorが有効化されていれば、デフォルト(`RuntimeDefault`)が適用されます。もし、AppArmorが無効化されている場合は、Podの作成は許可されますが、コンテナには`RuntimeDefault`プロフィールの制限は適用されません。 + +これは、AppArmorプロフィールとして、ノードのコンテナランタイムのデフォルトプロフィールを設定する例です。 + +```yaml +... +containers: +- name: container-1 + securityContext: + appArmorProfile: + type: RuntimeDefault +``` + +これは、AppArmorプロフィールとして、`k8s-apparmor-example-deny-write`という名前で事前に設定されたプロフィールを設定する例です。 + +```yaml +... +containers: +- name: container-1 + securityContext: + appArmorProfile: + type: Localhost + localhostProfile: k8s-apparmor-example-deny-write +``` + +より詳細な内容については[Restrict a Container's Access to Resources with AppArmor](/docs/tutorials/security/apparmor/)を参照してください。 + ## コンテナにSELinuxラベルをつける コンテナにSELinuxラベルをつけるには、Pod・コンテナマニフェストの`securityContext`セクションに`seLinuxOptions`フィールドを追加してください。 @@ -386,24 +580,72 @@ SELinuxラベルを適用するには、ホストOSにSELinuxセキュリティ ### 効率的なSELinuxのボリューム再ラベル付け -{{< feature-state for_k8s_version="v1.25" state="alpha" >}} +{{< feature-state feature_gate_name="SELinuxMountReadWriteOncePod" >}} + +{{< note >}} +Kubernetes v1.27で、`ReadWriteOncePod` アクセスモードを使用するボリューム(およびPersistentVolumeClaim)にのみ、この機能の限定的な機能が早期提供されています。 + +Alphaフィーチャーとして、`SELinuxMount`[フィーチャーゲート](/docs/reference/command-line-tools-reference/feature-gates/)を有効にすることで、以下で説明するように、他の種類のPersistentVolumeClaimにもパフォーマンス改善の範囲を広げる事ができます。 +{{< /note >}} デフォルトでは、コンテナランタイムは全てのPodのボリュームの全てのファイルに再帰的にSELinuxラベルを付与します。処理速度を上げるために、Kubernetesはマウントオプションで`-o context=