Skip to content

Commit 0e3bb4b

Browse files
everpeaceOkabe-Junyab1gb4by
committed
[ja] updated content/ja/docs/tasks/configure-pod-container/security-context.md
- 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 <[email protected]> Co-authored-by: Taisuke Okamoto <[email protected]>
1 parent 5bc26c7 commit 0e3bb4b

File tree

4 files changed

+285
-9
lines changed

4 files changed

+285
-9
lines changed

content/ja/docs/tasks/configure-pod-container/security-context.md

Lines changed: 253 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Podに設定したセキュリティ設定はPod内の全てのコンテナに
5252

5353
設定ファイルの中の`runAsUser`フィールドは、Pod内のコンテナに対して全てのプロセスをユーザーID 1000で実行するように指定します。
5454
`runAsGroup`フィールドはPod内のコンテナに対して全てのプロセスをプライマリーグループID 3000で実行するように指定します。このフィールドが省略されたときは、コンテナのプライマリーグループIDはroot(0)になります。`runAsGroup`が指定されている場合、作成されたファイルもユーザー1000とグループ3000の所有物になります。
55-
また`fsGroup`も指定されているため、全てのコンテナ内のプロセスは補助グループID 2000にも含まれます。`/data/demo`ボリュームとこのボリュームに作成されたファイルはグループID 2000になります。
55+
また`fsGroup`も指定されているため、全てのコンテナ内のプロセスは補助グループID 2000にも含まれます。`/data/demo`ボリュームとこのボリュームに作成されたファイルはグループID 2000になります。加えて、`supplementalGroups`フィールドが指定されている場合、全てのコンテナ内のプロセスは指定されている補助グループIDにも含まれます。もしこのフィールドが指定されていない場合、空を意味します。
5656

5757
Podを作成してみましょう。
5858

@@ -128,17 +128,176 @@ id
128128
出力はこのようになります。
129129

130130
```none
131-
uid=1000 gid=3000 groups=2000
131+
uid=1000 gid=3000 groups=2000,3000,4000
132132
```
133133

134-
出力から`runAsGroup`フィールドと同じく`gid`が3000になっていることが確認できるでしょう。`runAsGroup`が省略された場合、`gid`は0(root)になり、そのプロセスはグループroot(0)とグループroot(0)に必要なグループパーミッションを持つグループが所有しているファイルを操作することができるようになります。
134+
出力から`runAsGroup`フィールドと同じく`gid`が3000になっていることが確認できるでしょう。`runAsGroup`が省略された場合、`gid`は0(root)になり、そのプロセスはグループroot(0)とグループroot(0)に必要なグループパーミッションを持つグループが所有しているファイルを操作することができるようになります。また、`groups`の出力に、`gid`に加えて、`fsGroups``supplementalGroups`フィールドで指定したグループIDも含まれていることも確認できるでしょう。
135135

136136
shellから抜けましょう。
137137

138138
```shell
139139
exit
140140
```
141141

142+
### コンテナイメージ内の`/etc/group`から暗黙的にマージされるグループ情報
143+
144+
Kubernetesは、デフォルトでは、Podで定義された情報に加えて、コンテナイメージ内の`/etc/group`のグループ情報をマージします。
145+
146+
{{% code_sample file="pods/security/security-context-5.yaml" %}}
147+
148+
このPodはsecurity contextで`runAsUser``runAsGroup``supplementalGroups`フィールドが指定されています。しかし、コンテナ内のプロセスには、コンテナイメージ内の`/etc/group`に定義されたグループIDが、補助グループとして付与されていることが確認できるでしょう。
149+
150+
Podを作成してみましょう。
151+
152+
```shell
153+
kubectl apply -f https://k8s.io/examples/pods/security/security-context-5.yaml
154+
```
155+
156+
Podのコンテナが実行されていることを確認します。
157+
158+
```shell
159+
kubectl get pod security-context-demo
160+
```
161+
162+
実行中のコンテナでshellを取ります。
163+
164+
```shell
165+
kubectl exec -it security-context-demo -- sh
166+
```
167+
168+
プロセスのユーザー、グループ情報を確認します。
169+
170+
```shell
171+
$ id
172+
```
173+
174+
出力はこのようになります。
175+
176+
```none
177+
uid=1000 gid=3000 groups=3000,4000,50000
178+
```
179+
180+
`groups`にグループID`50000`が含まれていることが確認できるでしょう。これは、ユーザー(`uid=1000`)がコンテナイメージで定義されており、コンテナイメージ内の`/etc/group`でグループ(`gid=50000`)に所属しているためです。
181+
182+
コンテナイメージの`/etc/group`の内容を確認してみましょう。
183+
184+
```shell
185+
$ cat /etc/group
186+
```
187+
188+
ユーザー`1000`がグループ`50000`に所属していることが確認できるでしょう。
189+
190+
```none
191+
...
192+
user-defined-in-image:x:1000:
193+
group-defined-in-image:x:50000:user-defined-in-image
194+
```
195+
196+
shellから抜けましょう。
197+
198+
```shell
199+
exit
200+
```
201+
202+
{{<note>}}
203+
_暗黙的にマージされる_ 補助グループはボリュームアクセスを行う際にセキュリティ上の懸念を引き起こすことがあります(詳細は[kubernetes/kubernetes#112879](https://issue.k8s.io/112879)を参照してください)。回避したい場合、次節を参照してください。
204+
{{note>}}
205+
206+
## Podにfine-grained(きめ細かい) SupplementalGroups controlを設定する {#supplementalgroupspolicy}
207+
208+
{{< feature-state feature_gate_name="SupplementalGroupsPolicy" >}}
209+
210+
この機能はkubeletとkube-apiseverに`SupplementalGroupsPolicy`
211+
[フィーチャーゲート](/docs/reference/command-line-tools-reference/feature-gates/)を設定し、Podの`.spec.securityContext.supplementalGroupsPolicy`フィールドを指定することで利用できます。
212+
213+
`supplementalGroupsPolicy`フィールドは、Pod内のコンテナプロセスに付与される補助グループを、どのように決定するかを定義します。有効な値は次の2つです。
214+
215+
* `Merge`: `/etc/group`で定義されている、コンテナのプライマリユーザーが所属するグループをマージします。指定されていない場合、このポリシーがデフォルトです。
216+
217+
* `Strict`: `fsGroup``supplementalGroups``runAsGroup`フィールドで指定されたグループのみ補助グループに指定されます。つまり、`/etc/group`で定義された、コンテナのプライマリユーザーのグループ情報はマージされません。
218+
219+
この機能が有効な場合、`.status.containerStatuses[].user.linux`フィールドで、コンテナの最初のプロセスに付与されたユーザー、グループ情報が確認出来ます。暗黙的なグループIDが付与されているかどうかを確認するのに便利でしょう。
220+
221+
{{% code_sample file="pods/security/security-context-6.yaml" %}}
222+
223+
このPodマニフェストは`supplementalGroupsPolicy=Strict`を指定しています。`/etc/group`に定義されているグループ情報が、コンテナ内のプロセスの補助グループにマージされないことが確認できるでしょう。
224+
225+
Podを作成してみましょう。
226+
227+
```shell
228+
kubectl apply -f https://k8s.io/examples/pods/security/security-context-6.yaml
229+
```
230+
231+
Podのコンテナが実行されていることを確認します。
232+
233+
```shell
234+
kubectl get pod security-context-demo
235+
```
236+
237+
プロセスのユーザー、グループ情報を確認します。
238+
239+
```shell
240+
kubectl exec -it security-context-demo -- id
241+
```
242+
243+
出力はこのようになります。
244+
245+
```none
246+
uid=1000 gid=3000 groups=3000,4000
247+
```
248+
249+
Podのステータスを確認します。
250+
251+
```shell
252+
kubectl get pod security-context-demo -o yaml
253+
```
254+
255+
`status.containerStatuses[].user.linux`フィールドでコンテナの最初のプロセスに付与されたユーザー、グループ情報が確認出来ます。
256+
257+
```none
258+
...
259+
status:
260+
containerStatuses:
261+
- name: sec-ctx-demo
262+
user:
263+
linux:
264+
gid: 3000
265+
supplementalGroups:
266+
- 3000
267+
- 4000
268+
uid: 1000
269+
...
270+
```
271+
272+
{{<note>}}
273+
`status.containerStatuses[].user.linux`フィールドで公開されているユーザー、グループ情報は、コンテナの最初のプロセスに、_最初に付与された_ 情報であることに注意してください。
274+
もしそのプロセスが、自身のユーザー、グループ情報を変更できるシステムコール(例えば [`setuid(2)`](https://man7.org/linux/man-pages/man2/setuid.2.html),
275+
[`setgid(2)`](https://man7.org/linux/man-pages/man2/setgid.2.html),
276+
[`setgroups(2)`](https://man7.org/linux/man-pages/man2/setgroups.2.html)等)を実行する権限を持っている場合、プロセス自身で動的に変更が可能なためです。
277+
つまり、実際にプロセスに付与されているユーザー、グループ情報は動的に変化します。
278+
{{note>}}
279+
280+
### 利用可能な実装 {#implementations-supplementalgroupspolicy}
281+
282+
{{% thirdparty-content %}}
283+
284+
下記のコンテナランタイムがfine-grained(きめ細かい) SupplementalGroups controlを実装しています。
285+
286+
CRI実装:
287+
- [containerd](https://containerd.io/) v2.0以降
288+
- [CRI-O](https://cri-o.io/) v1.31以降
289+
290+
ノードのステータスでこの機能が利用可能かどうか確認出来ます。
291+
292+
```yaml
293+
apiVersion: v1
294+
kind: Node
295+
...
296+
status:
297+
features:
298+
supplementalGroupsPolicy: true
299+
```
300+
142301
## Podのボリュームパーミッションと所有権変更ポリシーを設定する
143302
144303
{{< feature-state for_k8s_version="v1.23" state="stable" >}}
@@ -367,6 +526,41 @@ securityContext:
367526
localhostProfile: my-profiles/profile-allow.json
368527
```
369528

529+
## コンテナにAppArmorプロフィールを設定する
530+
531+
コンテナにAppArmorプロフィールを設定するには、`securityContext`セクションに`appAormorProfile`フィールドを含めてください。
532+
`appAormerProfile`フィールドには、`type`フィールドと`localhostProfile`フィールドから構成される[AppArmorProfile](/docs/reference/generated/kubernetes-api/{{< param "version"
533+
>}}/#apparmorprofile-v1-core)オブジェクトが入ります。`type`フィールドの有効なオプションは`RuntimeDefault`(デフォルト)、`Unconfined`、`Localhost`です。
534+
`localhostProfile`は`type`が`Localhost`のときには必ず設定しなければなりません。この値はノードで事前に設定されたプロフィール名を示します。Podは事前にどのノードにスケジュールされるかわからないため、指定されたプロフィールはPodがスケジュールされ得る全てのノードにロードされている必要があります。カスタムプロフィールをセットアップする方法は[Setting up nodes with profiles](/docs/tutorials/security/apparmor/#setting-up-nodes-with-profiles)を参照してください。
535+
536+
注意: `containers[*].securityContext.appArmorProfile.type`が明示的に`RuntimeDefault`に設定されている場合は、もしノードでAppArmorが有効化されていなければ、Podの作成は許可されません。
537+
しかし、`containers[*].securityContext.appArmorProfile.type`が設定されていない場合、AppArmorが有効化されていれば、デフォルト(`RuntimeDefault`)が適用されます。もし、AppArmorが無効化されている場合は、Podの作成は許可されますが、コンテナには`RuntimeDefault`プロフィールの制限は適用されません。
538+
539+
これは、AppArmorプロフィールとして、ノードのコンテナランタイムのデフォルトプロフィールを設定する例です。
540+
541+
```yaml
542+
...
543+
containers:
544+
- name: container-1
545+
securityContext:
546+
appArmorProfile:
547+
type: RuntimeDefault
548+
```
549+
550+
これは、AppArmorプロフィールとして、`k8s-apparmor-example-deny-write`という名前で事前に設定されたプロフィールを設定する例です。
551+
552+
```yaml
553+
...
554+
containers:
555+
- name: container-1
556+
securityContext:
557+
appArmorProfile:
558+
type: Localhost
559+
localhostProfile: k8s-apparmor-example-deny-write
560+
```
561+
562+
より詳細な内容については[Restrict a Container's Access to Resources with AppArmor](/docs/tutorials/security/apparmor/)を参照してください。
563+
370564
## コンテナにSELinuxラベルをつける
371565

372566
コンテナにSELinuxラベルをつけるには、Pod・コンテナマニフェストの`securityContext`セクションに`seLinuxOptions`フィールドを追加してください。
@@ -386,24 +580,72 @@ SELinuxラベルを適用するには、ホストOSにSELinuxセキュリティ
386580

387581
### 効率的なSELinuxのボリューム再ラベル付け
388582

389-
{{< feature-state for_k8s_version="v1.25" state="alpha" >}}
583+
{{< feature-state feature_gate_name="SELinuxMountReadWriteOncePod" >}}
584+
585+
{{< note >}}
586+
Kubernetes v1.27で、`ReadWriteOncePod` アクセスモードを使用するボリューム(およびPersistentVolumeClaim)にのみ、この機能の限定的な機能が早期提供されています。
587+
588+
Alphaフィーチャーとして、`SELinuxMount`[フィーチャーゲート](/docs/reference/command-line-tools-reference/feature-gates/)を有効にすることで、以下で説明するように、他の種類のPersistentVolumeClaimにもパフォーマンス改善の範囲を広げる事ができます。
589+
{{< /note >}}
390590

391591
デフォルトでは、コンテナランタイムは全てのPodのボリュームの全てのファイルに再帰的にSELinuxラベルを付与します。処理速度を上げるために、Kubernetesはマウントオプションで`-o context=
392592

393593
この高速化の恩恵を受けるには、以下の全ての条件を満たす必要があります。
394594

395595
* Alphaフィーチャーゲートの`ReadWriteOncePod`と`SELinuxMountReadWriteOncePod`を有効にすること
396-
* Podが`accessModes: ["ReadWriteOncePod"]`でPersistentVolumeClaimを使うこと
596+
* Podが適用可能な`accessModes`でPersistentVolumeClaimを使うこと
597+
* ボリュームが`accessModes: ["ReadWriteOncePod"]`を持ち、フィーチャーゲート`SELinuxMountReadWriteOncePod`が有効であること
598+
* または、ボリュームが他のアクセスモードを使用し、フィーチャーゲート`SELinuxMountReadWriteOncePod`と`SELinuxMount`の両方が有効であること
397599
* Pod(またはPersistentVolumeClaimを使っている全てのコンテナ)に`seLinuxOptions`が設定されていること
398-
* 対応するPersistentVolumeが{{< glossary_tooltip text="CSI" term_id="csi" >}}ドライバーを利用するボリュームか、レガシー`iscsi`ボリュームタイプを利用するボリュームであること
399-
* CSIドライバーを利用するボリュームを利用している場合、そのCSIドライバーがCSIドライバーインスタンスで`spec.seLinuxMount: true`を指定したときに`-o context`でマウントを行うとアナウンスしていること
600+
* 対応するPersistentVolumeが以下のいずれかであること
601+
* レガシーのin-treeボリュームの場合、`iscs`、`rbd`、`fc`ボリュームタイプであること
602+
* または、{{< glossary_tooltip text="CSI" term_id="csi" >}}ドライバーを使用するボリュームで、そのCSIドライバーがCSIドライバーインスタンスで`spec.seLinuxMount: true`を指定したときに`-o context`でマウントを行うとアナウンスしていること
400603

401604
それ以外のボリュームタイプでは、コンテナランタイムはボリュームに含まれる全てのinode(ファイルやディレクトリ)に対してSELinuxラベルを再帰的に変更します。
402605
ボリューム内のファイルやディレクトリが増えるほど、ラベリングにかかる時間は増加します。
403606

607+
## `/proc`ファイルシステムへのアクセスを管理する {#proc-access}
608+
609+
{{< feature-state feature_gate_name="ProcMountType" >}}
610+
611+
OCI runtime specificationに準拠するランタイムでは、コンテナはデフォルトで、いくつかの複数のパスはマスクされ、かつ、読み取り専用のモードで実行されます。
612+
その結果、コンテナのマウントネームスペース内にはこれらのパスが存在し、あたかもコンテナが隔離されたホストであるかのように機能しますが、コンテナプロセスはそれらのパスに書き込むことはできません。
613+
マスクされるパスおよび読み取り専用のパスのリストは次のとおりです。
614+
615+
- マスクされるパス:
616+
- `/proc/asound`
617+
- `/proc/acpi`
618+
- `/proc/kcore`
619+
- `/proc/keys`
620+
- `/proc/latency_stats`
621+
- `/proc/timer_list`
622+
- `/proc/timer_stats`
623+
- `/proc/sched_debug`
624+
- `/proc/scsi`
625+
- `/sys/firmware`
626+
- `/sys/devices/virtual/powercap`
627+
628+
- 読み取り専用のパス:
629+
- `/proc/bus`
630+
- `/proc/fs`
631+
- `/proc/irq`
632+
- `/proc/sys`
633+
- `/proc/sysrq-trigger`
634+
635+
一部のPodでは、デフォルトでパスがマスクされるのを回避したい場合があります。このようなケースで最も一般的なのは、Kubernetesコンテナ(Pod内のコンテナ)内でコンテナを実行しようとする場合です。
636+
637+
`securityContext`の`procMount`フィールドを使用すると、コンテナの`/proc`を`Unmasked`にしたり、コンテナプロセスによって読み書き可能な状態でマウントすることができます。この設定は、`/proc`以外の`/sys/firmware`にも適用されます。
638+
639+
```yaml
640+
...
641+
securityContext:
642+
procMount: Unmasked
643+
```
644+
404645
{{< note >}}
405-
Kubernetes 1.25では、kubeletは再起動後にボリュームラベルを追跡できなくなります。言い換えると、kubeletはPodの中のラベルのコンフリクトが解消されるまで"conflicting
406-
SELinux labels of volume"というようなエラーでPodの起動を拒否する可能性があるということです。Kubeletを再起動する前に必ずノードを[完全にdrain](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/)された状態にしてください。
646+
`procMount`をUnmaskedに設定するには、Podの`spec.hostUsers`の値が`false`である必要があります。
647+
つまり、Unmaskedな`/proc`やUnmaskedな`/sys`を使用したいコンテナは、[user namespace](/docs/concepts/workloads/pods/user-namespaces/)内で動作している必要があります。
648+
Kubernetes v1.12からv1.29までは、この要件は強制されません。
407649
{{< /note >}}
408650

409651
## 議論
@@ -442,3 +684,5 @@ kubectl delete pod security-context-demo-4
442684
* [PodSecurity Admission](/docs/concepts/security/pod-security-admission/)
443685
* [AllowPrivilegeEscalation design document](https://git.k8s.io/design-proposals-archive/auth/no-new-privs.md)
444686
* Linuxのセキュリティについてさらに知りたい場合は、[Overview of Linux Kernel Security Features](https://www.linux.com/learn/overview-linux-kernel-security-features)を確認してください(注: 一部の情報は古くなっています)。
687+
* Linux pods向けの[User Namespaces](/docs/concepts/workloads/pods/user-namespaces/)について確認してください。
688+
* [Masked Paths in the OCI Runtime Specification](https://github.com/opencontainers/runtime-spec/blob/f66aad47309/config-linux.md#masked-paths)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: security-context-demo
5+
spec:
6+
securityContext:
7+
runAsUser: 1000
8+
runAsGroup: 3000
9+
supplementalGroups: [4000]
10+
containers:
11+
- name: sec-ctx-demo
12+
image: registry.k8s.io/e2e-test-images/agnhost:2.45
13+
command: [ "sh", "-c", "sleep 1h" ]
14+
securityContext:
15+
allowPrivilegeEscalation: false
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: security-context-demo
5+
spec:
6+
securityContext:
7+
runAsUser: 1000
8+
runAsGroup: 3000
9+
supplementalGroups: [4000]
10+
supplementalGroupsPolicy: Strict
11+
containers:
12+
- name: sec-ctx-demo
13+
image: registry.k8s.io/e2e-test-images/agnhost:2.45
14+
command: [ "sh", "-c", "sleep 1h" ]
15+
securityContext:
16+
allowPrivilegeEscalation: false

content/ja/examples/pods/security/security-context.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ spec:
77
runAsUser: 1000
88
runAsGroup: 3000
99
fsGroup: 2000
10+
supplementalGroups: [4000]
1011
volumes:
1112
- name: sec-ctx-vol
1213
emptyDir: {}

0 commit comments

Comments
 (0)