環境
- minikube version: v1.16.0
検証1:「busybox」での検証
手順
busypodをapplyする為のyamlを作る。
kubectl run busybox --image=busybox --restart=Never --dry-run=client -o=yaml -- sleep 3600 > pod_busybox3600.yaml
出来上がったyamlファイルをテキストエディタで修正する。
apiVersion: v1kind: Pod
metadata:
creationTimestamp: null
labels:
run: busybox
name: busybox
spec:
containers:
- args:
- sleep
- "3600"
image: busybox
name: busybox
resources: {}
securityContext: ←ここを追記
runAsUser: 1000 ←ここを追記
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
作ったyamlが正しくかを確認する。
kubectl apply -f pod_busybox3600.yaml --dry-run=client -o=yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
{記載省略}
creationTimestamp: null
labels:
run: busybox
name: busybox
namespace: default
spec:
containers:
- args:
- sleep
- "3600"
image: busybox
name: busybox
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Never
securityContext: ←ここをチェック
runAsUser: 1000 ←ここをチェック
status: {}
作ったyamlでbusyboxをapplyする。
kubectl apply -f pod_busybox3600.yaml
Podの状態を確認
>kubectl get pod
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 7s
起動までに問題がなかったかを確認
>kubectl describe pod busybox
Name: busybox
Namespace: default
Priority: 0
{記載省略}
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 47s default-scheduler Successfully assigned default/busybox to minikube
Normal Pulling 46s kubelet Pulling image "busybox"
Normal Pulled 43s kubelet Successfully pulled image "busybox" in 3.178333781s
Normal Created 43s kubelet Created container busybox
Normal Started 43s kubelet Started container busybox
実行ユーザーを確認
>kubectl exec -it busybox -- sh
/ $ whoami
whoami: unknown uid 1000 ← 意図したユーザーで実行されている事を確認
各プロセスの実行ユーザーを確認
/ $ ps
PID USER TIME COMMAND
1 1000 0:00 sleep 3600
9 1000 0:00 sh
17 1000 0:00 ps
/ $
busyboxのユーザー一覧を確認
/ $ cat etc/passwd
root:x:0:0:root:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/false
bin:x:2:2:bin:/bin:/bin/false
sys:x:3:3:sys:/dev:/bin/false
sync:x:4:100:sync:/bin:/bin/sync
mail:x:8:8:mail:/var/spool/mail:/bin/false
www-data:x:33:33:www-data:/var/www:/bin/false
operator:x:37:37:Operator:/var:/bin/false
nobody:x:65534:65534:nobody:/home:/bin/false
/ $
ここまでの検証結果まとめ。
busyboxの場合は、存在しないユーザー(UID)を設定してもコンテナは正常に起動し、且つ、そのUIDで動作出来た。
検証2:「nginx」での検証
手順
nginxをapplyする為のyamlを作る。
kubectl run nginx --image=nginx --restart=Never --dry-run=client -o=yaml > pod_nginx.yaml
出来上がったyamlファイルをテキストエディタで修正する。
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
securityContext: ←ここを追記
runAsUser: 1000 ←ここを追記
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
作ったyamlが正しくかを確認する。
kubectl apply -f pod_nginx.yaml --dry-run=client -o=yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
{記載省略}
creationTimestamp: null
labels:
run: nginx
name: nginx
namespace: default
spec:
containers:
- image: nginx
name: nginx
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Never
securityContext: ←ここをチェック
runAsUser: 1000 ←ここをチェック
status: {}
作ったyamlでbusyboxをapplyする。
>kubectl apply -f pod_nginx.yaml
pod/nginx created
Podの状態を確認 。。。Errorになっている。
>kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 0/1 Error 0 29s
起動までに問題がなかったかを確認
>kubectl describe pod nginx
Name: nginx
Namespace: default
Priority: 0
{記載省略}
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m5s default-scheduler Successfully assigned default/nginx to minikube
Normal Pulling 2m4s kubelet Pulling image "nginx"
Normal Pulled 2m1s kubelet Successfully pulled image "nginx" in 3.162750793s
Normal Created 2m1s kubelet Created container nginx
Normal Started 2m1s kubelet Started container nginx
実行ユーザーを確認。エラーなのでコンテナに入れず。
>kubectl exec -it nginx -- sh
error: cannot exec into a container in a completed pod; current phase is Failed
ログを確認
>kubectl logs nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: can not modify /etc/nginx/conf.d/default.conf (read-only file system?)
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/01/08 14:33:02 [warn] 1#1: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
nginx: [warn] the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
2021/01/08 14:33:02 [emerg] 1#1: mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)
nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)
最初の警告メッセージを見てみる。
the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
↓
「user」ディレクティブは、マスタープロセスがスーパーユーザー権限で実行されている場合にのみ意味があり、/ etc / nginx / nginx.conf:2では無視されます。
うーん。
root実行に戻して、/etc/nginx/nginx.confの2行目を見てみる。
>kubectl delete -f pod_nginx.yaml
pod "nginx" deleted
>kubectl run nginx --image=nginx --restart=Never
pod/nginx created
>kubectl exec -it nginx -- sh
# cat /etc/nginx/nginx.conf
←ここが1行目
user nginx; ←ここが2行目
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
{以下、記載省略}
nginxっていうユーザーでないとダメ?なのかもしれない。
nginxというユーザーがあるのか調べる。
# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
{記載省略}
nginx:x:101:101:nginx user,,,:/nonexistent:/bin/false ←いた!
いったんnginxのpodを削除して、pod_nginx.yamlのrunAsUserを101に変えて再トライ。
# exit
command terminated with exit code 127
>kubectl delete pod nginx
pod "nginx" deleted
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
securityContext:
runAsUser: 101 ← ここを1000から101に変更。
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
>kubectl apply -f pod_nginx.yaml
pod/nginx created
>kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 0/1 Error 0 10s
>kubectl logs nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: can not modify /etc/nginx/conf.d/default.conf (read-only file system?)
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/01/08 15:05:53 [warn] 1#1: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
nginx: [warn] the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
2021/01/08 15:05:53 [emerg] 1#1: mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)
nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)
やはり、Errorになってしまった。結局最後のログで ディレクトリ作りたいけれど権限足らないってことみたい。
つまりは元のコンテナで適切に仕事が出来るユーザーを作っておいた上で、runAsUserに指定しないとダメって事かなー。
検証3:「node」での検証
最初にDockerHubの公式イメージからnodejsのコンテナイメージを取得し、kubernetesのPod内のコンテナとして起動する。
DockerHubのnodejs公式イメージ(https://hub.docker.com/_/node)
>kubectl run mynodejs --image=node -- /bin/sh -c "sleep 3600"
pod/mynodejs created
>kubectl get pod mynodejs
NAME READY STATUS RESTARTS AGE
mynodejs 1/1 Running 0 15s
起動したコンテナにログインして以下の事を確認する。
- ログイン時のユーザーは何になるか?
- 各プロセスは、どのユーザーで起動しているか?
- 登録されているユーザーにはどんなものがあるか?
>kubectl exec -it mynodejs -- /bin/sh
# whoami
root
# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 4280 696 ? Ss 03:13 0:00 /bin/sh -c sleep 3600
root 8 0.0 0.0 4188 640 ? S 03:13 0:00 sleep 3600
root 9 0.0 0.0 4280 736 pts/0 Ss 03:14 0:00 /bin/sh
root 17 0.0 0.1 36636 2732 pts/0 R+ 03:14 0:00 ps -aux
# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
{中略}
_apt:x:100:65534::/nonexistent:/bin/false
node:x:1000:1000::/home/node:/bin/bash ← node というユーザーが存在。UID:GIDともに1000
#
起動ユーザーを指定するyamlを作ってnodejsコンテナを、kubernetesのPod内のコンテナとして起動する。
- yamlファイルを生成。
>kubectl run mynodejs --image=node --dry-run=client -o=yaml -- /bin/sh -c "node; sleep 3600" > mynodejs.yaml
- securityContextで、ユーザーとグループを指定。またrootでの起動を抑止。
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: mynodejs
name: mynodejs
spec:
securityContext: ←ここを追加
runAsUser: 1000 ←ここを追加
runAsGroup: 1000 ←ここを追加
runAsNonRoot: True ←ここを追加
containers:
- args:
- /bin/sh
- -c
- node; sleep 3600
image: node
name: mynodejs
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
- kubernetesのPod内のコンテナとして起動する。
>kubectl apply -f mynodejs.yaml
pod/mynodejs created
起動したコンテナにログインして以下の事を確認する。
- ログイン時のユーザーは何になるか?
- nodeコマンドが動くか?
- 各プロセスは、どのユーザーで起動しているか?
>kubectl apply -f mynodejs.yaml
pod/mynodejs created
>kubectl exec -it mynodejs -- sh
$ whoami
node
$ ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
node 1 0.0 0.0 4280 696 ? Ss 03:31 0:00 /bin/sh -c node; sleep 3600
node 19 0.0 0.0 4188 668 ? S 03:31 0:00 sleep 3600
node 20 0.0 0.0 4280 700 pts/0 Ss 03:32 0:00 sh
node 27 0.0 0.1 36636 2856 pts/0 R+ 03:33 0:00 ps -aux
$ node
Welcome to Node.js v15.5.1.
Type ".help" for more information.
>
結果。
まずコンテナ自体がrootユーザー以外で動作できるアプリケーションのかたまりである事が必要。
今回のようにnodeユーザーで動作する前提のコンテナなら、Podでユーザーを指定して動作させる事が可能。
nginxのように実行するユーザーに制限があるままだと、適用なユーザーIDを指定してもうまくはいかない。