11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Kubernetes]SecurityContextの動作を確認する

Last updated at Posted at 2020-06-26

はじめに

今回はSecurityContextの動作を確認したいと思います。SecurityContextは、個々のPodまたはコンテナに対して特権やアクセス制御などを定義するセキュリティ設定です。

Configure a Security Context for a Pod or Container

設定できる項目のうち、今回は代表的な項目として以下の動作を確認します。なお、PodSecurityContextとSecurityContext(コンテナ)で同じ項目が設定されている場合、SecurityContextの値が優先されます。

設定項目 概要 PodSecurityContext SecurityContext
runAsUser 実行ユーザ
runAsGroup 実行グループ
fsGroup マウントしたPVやVolumeのファイルシステムのグループ
runAsNonRoot rootで実行しない
readOnlyRootFilesystem rootファイルシステムをReadOnlyにする
capabilities Capabilitiesを追加/削除する

その他の設定項目は、以下をご確認ください。

PodSecurityContext v1 core
SecurityContext v1 core

PodSecurityContext

PodSecurityContextはPod内の全てのコンテナに対してセキュリティを設定します。

実行ユーザ、グループの設定

spec.securityContext配下に設定値を記載します。今回はCentOS 7と8のコンテナがありますので、それぞれで想定通りに設定されているかを確認します。

securityContext01.yaml
apiVersion: v1
kind: Pod
metadata:
  name: security-context01
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
  volumes:
  - name: sec-ctx-vol
    emptyDir: {}
  containers:
  - name: centos7
    image: centos:7
    command: [ "sh", "-c", "sleep 1h" ]
    volumeMounts:
    - name: sec-ctx-vol
      mountPath: /data/demo
  - name: centos8
    image: centos:8
    command: [ "sh", "-c", "sleep 1h" ]
    volumeMounts:
    - name: sec-ctx-vol
      mountPath: /data/demo
$ kubectl apply -f securityContext01.yaml
pod/security-context01 created

確認

まずはCentOS 7にログインして確認します。

$ kubectl exec -it security-context01 -c centos7 /bin/bash
bash-4.2$ id
uid=1000 gid=3000 groups=3000,2000                         #・・・1.
bash-4.2$ ps -ef                                           #・・・2.
UID        PID  PPID  C STIME TTY          TIME CMD
1000         1     0  0 13:15 ?        00:00:00 sleep 1h
1000         6     0  0 13:16 pts/0    00:00:00 /bin/bash
1000        12     6  0 13:16 pts/0    00:00:00 ps -ef
bash-4.2$ ls -l /data/
total 0
drwxrwsrwx. 2 root 2000 6 Jun 25 13:15 demo                #・・・3.
bash-4.2$ touch /data/demo/testfile                        #・・・4.
bash-4.2$ ls /data/demo/
testfile
bash-4.2$ exit
exit
  1. uidとgidがそれぞれrunAsUser/runAsGroupで設定したIDになっていますね。また、groupsにはfsGroupで設定したIDも含まれています。
  2. プロセスを実行しているユーザがrunAsUserで指定したIDになっていますね。
  3. VolumeをマウントしたファイルシステムのグループがfsGroupで指定したIDになっています。指定しない場合、グループも「root」になります。実行ユーザを変更した場合は、マウントしたボリュームに権限がない場合がありますので、その場合にfsGroupを指定します。
  4. 書き込みもできます。

次にCentOS 8にログインして同様に確認します。

$ kubectl exec -it security-context01 -c centos8 /bin/bash
bash-4.4$ id
uid=1000 gid=3000 groups=3000,2000
bash-4.4$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
1000         1     0  0 13:15 ?        00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1h
1000         6     0  0 13:18 pts/0    00:00:00 /bin/bash
1000        12     6  0 13:18 pts/0    00:00:00 ps -ef
bash-4.4$ ls -l /data/
total 0
drwxrwsrwx. 2 root 2000 22 Jun 25 13:18 demo
bash-4.4$ touch /data/demo/testfile2
bash-4.4$ ls /data/demo/
testfile  testfile2
bash-4.4$ exit
exit

CentOS 7と同様ですね。

rootユーザの実行制限

続いて、rootユーザで実行するのを制限するようにします。
securityContextの設定値を以下のマニフェストのように変更します。

securityContext02.yaml
apiVersion: v1
kind: Pod
metadata:
  name: security-context02
spec:
  securityContext:
#    runAsUser: 1000
#    runAsGroup: 3000
#    fsGroup: 2000
    runAsNonRoot: true
  volumes:
  - name: sec-ctx-vol
    emptyDir: {}
  containers:
  - name: centos7
    image: centos:7
    command: [ "sh", "-c", "sleep 1h" ]
    volumeMounts:
    - name: sec-ctx-vol
      mountPath: /data/demo

上記のマニフェストをapplyすると、エラーになります。
詳細を確認すると、CentOSはrootでの起動が必要になるようです。CentOSの他にも、NginxやRedisも同様のエラーで起動に失敗しました。

$ kubectl describe pod security-context02
Name:         security-context02
Namespace:    default

Events:
  Type     Reason     Age              From                   Message
  ----     ------     ----             ----                   -------
  Normal   Scheduled  10s              default-scheduler      Successfully assigned default/security-context02 to k8s-worker02
  Normal   Pulled     7s (x3 over 9s)  kubelet, k8s-worker02  Container image "centos:7" already present on machine
  Warning  Failed     7s (x3 over 9s)  kubelet, k8s-worker02  Error: container has runAsNonRoot and image will run as root

SecurityContext

続いてSecurityContextでコンテナに対して個別にセキュリティを設定します。

実行ユーザ、グループの設定

spec.containers.securityContext配下に設定値を記載します。2つのコンテナがありますが、CentOS 7のみに設定して、CentOS 8は設定せずにデフォルトのままとします。

securityContext03.yaml
apiVersion: v1
kind: Pod
metadata:
  name: security-context03
spec:
  containers:
  - name: centos7
    image: centos:7
    command: [ "sh", "-c", "sleep 1h" ]
    securityContext:
      runAsUser: 1000
      runAsGroup: 3000
  - name: centos8
    image: centos:8
    command: [ "sh", "-c", "sleep 1h" ]
$ kubectl apply -f securityContext03.yaml
pod/security-context03 created

CentOS 7にログインして、各値を確認します。

$ kubectl exec -it security-context03 -c centos7 /bin/bash
bash-4.2$ id
uid=1000 gid=3000 groups=3000
bash-4.2$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
1000         1     0  0 14:15 ?        00:00:00 sleep 1h
1000         6     0  0 14:16 pts/0    00:00:00 /bin/bash
1000        12     6  0 14:16 pts/0    00:00:00 ps -ef
bash-4.2$
bash-4.2$ exit
exit

PodSecurityContextと同様にユーザとグループが指定したIDになっていて、プロセスを実行しているユーザも設定したユーザとなっています。

次にCentOS 8にログインして確認します。

$ kubectl exec -it security-context03 -c centos8 /bin/bash
[root@security-context03 /]# id
uid=0(root) gid=0(root) groups=0(root)
[root@security-context03 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 14:15 ?        00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1h
root         6     0  0 14:16 pts/0    00:00:00 /bin/bash
root        20     6  0 14:16 pts/0    00:00:00 ps -ef

こちらはデフォルトのrootでログインし、プロセスを実行しています。

ReadOnlyのrootファイルシステム

readOnlyRootFilesystemパラメータをtrueに設定して、Podをデプロイします。

securityContext04.yaml
apiVersion: v1
kind: Pod
metadata:
  name: security-context04
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" ]
$ kubectl apply -f securityContext04.yaml
pod/security-context04 created

デプロイしたら、コンテナにログインし書き込みができないことを確認します。

$ kubectl exec -it security-context04 -c centos7 touch /testfile
touch: cannot touch '/testfile': Read-only file system
command terminated with exit code 1
$ kubectl exec -it security-context04 -c centos8 touch /testfile
$ kubectl exec -it security-context04 -c centos8 ls /
bin  etc   lib    lost+found  mnt  proc  run   srv  testfile  usr
dev  home  lib64  media       opt  root  sbin  sys  tmp       var

ReadOnlyに設定したCentOS 7には書き込みができませんが、設定していないCentOS 8には書き込めることがわかります。

Capabilitiesの設定

Capabilitiesによってコンテナに対してLinux capabilities個別に追加/削除ができます。
ここでは、CentOS 7に対して「NET_ADMIN」と「SYS_TIME」を追加します。

securityContext05.yaml
apiVersion: v1
kind: Pod
metadata:
  name: security-context05
spec:
  containers:
  - name: centos7
    image: centos:7
    command: [ "sh", "-c", "sleep 1h" ]
    securityContext:
      capabilities:
        add: ["NET_ADMIN", "SYS_TIME"]
  - name: centos8
    image: centos:8
    command: [ "sh", "-c", "sleep 1h" ]
$ kubectl apply -f securityContext05.yaml
pod/security-context05 created

CentOS 7にログインして確認します。

$ kubectl exec -it security-context05 -c centos7 /bin/bash
[root@security-context05 /]#  capsh --print | grep net_admin
Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_admin,cap_net_raw,cap_sys_chroot,cap_sys_time,cap_mknod,cap_audit_write,cap_setfcap+eip
Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_admin,cap_net_raw,cap_sys_chroot,cap_sys_time,cap_mknod,cap_audit_write,cap_setfcap
[root@security-context05 /]#  capsh --print | grep sys_time
Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_admin,cap_net_raw,cap_sys_chroot,cap_sys_time,cap_mknod,cap_audit_write,cap_setfcap+eip
Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_admin,cap_net_raw,cap_sys_chroot,cap_sys_time,cap_mknod,cap_audit_write,cap_setfcap
[root@security-context05 /]# exit
exit

個別に追加した「NET_ADMIN」と「SYS_TIME」が設定されていることがわかります。

次にCentOS 8を確認します。

$ kubectl exec -it security-context05 -c centos8 /bin/bash
[root@security-context05 /]# capsh --print | grep net_admin
[root@security-context05 /]# capsh --print | grep sys_time
[root@security-context05 /]# exit
exit

こちらには設定されていませんね。

まとめ

今回確認した以外にもSecurityContextには設定できる項目があります。設定すればそれだけセキュリティ的には強固になりますが、場合によってはコンテナが起動しないこともありますので、慎重に設計、設定する必要がありますね。

11
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?