root(UID:0)を含む、任意のUIDでpod(の中で動作するプロセス)を動かすには。
基本的にid:nekopさんの記事の通りです。
環境
CRCを使用。あとsccの操作はcluster-admin権限が必要(のはず)。
$ oc version Client Version: v4.3.0 Server Version: 4.2.13 Kubernetes Version: v1.14.6+a8d983c
あと、OCP v4でoc get scc
で各権限のサマリが見れなくなったのは、この辺のcustom-columns
とかで工夫するしかない?
前置き
OpenShiftではセキュリティのため、任意のUID(非0)でpodが実行されることが求められる。 通常はネームスペース毎にランダムなUIDのレンジが割り当てられ、その設定によって実行時のUIDが決定される。
$ oc describe project scc-sample Name: scc-sample Created: 12 seconds ago Labels: <none> Annotations: openshift.io/description= openshift.io/display-name= openshift.io/requester=kube:admin openshift.io/sa.scc.mcs=s0:c23,c22 openshift.io/sa.scc.supplemental-groups=1000550000/10000 openshift.io/sa.scc.uid-range=1000550000/10000 : :
この出力例でいうと、sa.scc.uid-range=1000550000/10000
の部分によって、UIDは1000550000
が基準になる。
といっても、何らかの理由で特定のUIDでプロセスを動かしたいという要件もあるかもしれない。
- コンテナ化するアプリが特定のUIDで実行される前提になっている
- ウェルノウンポートを使用しており変更できない
- その他root権限必須
などなど。。
そこで出番なのがSecurity Context Constraints(scc)で、設定を行うことで特定のUIDで動作できるようになる。
基本のコマンド
$ oc run sample-app --image=rhel:7.7 -- tail -f /dev/null $ oc rsh sample-app-1-txzmq bash bash-4.2$ id uid=1000550000(1000550000) gid=0(root) groups=0(root),1000550000 bash-4.2$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND 1000550+ 1 0.0 0.0 4412 672 ? Ss 12:51 0:00 tail -f /dev/null 1000550+ 15 0.2 0.0 11836 2920 pts/0 Ss 12:51 0:00 bash 1000550+ 23 0.0 0.0 51764 3560 pts/0 R+ 12:51 0:00 ps aux
nonrootを使って指定のUID(非0)で動作させる
特定のUID(非0)でpodを実行するには、デフォルトのsccのnonroot
を使うことで可能。
作業用プロジェクト作成
$ oc new-project scc-sample-nonroot
デフォルトで使用されるUIDを確認する
$ oc describe projects scc-sample-nonroot Name: scc-sample-nonroot Created: 21 seconds ago Labels: <none> Annotations: openshift.io/description= openshift.io/display-name= openshift.io/requester=kube:admin openshift.io/sa.scc.mcs=s0:c24,c14 openshift.io/sa.scc.supplemental-groups=1000580000/10000 openshift.io/sa.scc.uid-range=1000580000/10000 Display Name: <none> : :
ServiceAccount/defaultにnonroot権限を付与
$ oc adm policy add-scc-to-user nonroot -z default securitycontextconstraints.security.openshift.io/nonroot added to: ["system:serviceaccount:scc-sample-nonroot:default"]
設定内容を確認する
$ oc describe scc nonroot Name: nonroot Priority: <none> Access: Users: system:serviceaccount:scc-sample-nonroot:default Groups: <none> : :
デプロイ用のマニフェスト作成
手っ取り早く、前述「基本のコマンド」に対して--dry-run -o yaml
を付けて実行した結果をファイルにリダイレクトする:)
(status
部分は要らないので削除)
apiVersion: apps.openshift.io/v1 kind: DeploymentConfig metadata: creationTimestamp: null labels: run: sample-app name: sample-app spec: replicas: 1 selector: run: sample-app strategy: resources: {} template: metadata: creationTimestamp: null labels: run: sample-app spec: containers: - args: - tail - -f - /dev/null image: rhel:7.7 name: sample-app resources: {} test: false triggers: null
このマニフェストの.spec.template
以下に、securityContext.runAsUser
記述を追記する。
89
のとこは実行に使用したいUIDを指定。
securityContext: runAsUser: 89
spec
部分を一部抜粋するとこんな感じ
spec: {...} template: {...} spec: containers: - args: - tail - -f - /dev/null image: rhel:7.7 name: sample-app resources: {} securityContext: runAsUser: 89
デプロイ
$ oc apply -f nonroot-deploy.yml deploymentconfig.apps.openshift.io/sample-app created $ oc get all NAME READY STATUS RESTARTS AGE pod/sample-app-1-deploy 0/1 ContainerCreating 0 2s NAME DESIRED CURRENT READY AGE replicationcontroller/sample-app-1 0 0 0 2s NAME REVISION DESIRED CURRENT TRIGGERED BY deploymentconfig.apps.openshift.io/sample-app 1 1 0 config
Running
になるまで待つ
$ oc get pod NAME READY STATUS RESTARTS AGE sample-app-1-deploy 0/1 Completed 0 21s sample-app-1-xfnkt 1/1 Running 0 11s
$ oc rsh sample-app-1-xfnkt bash bash-4.2$ bash-4.2$ id uid=89(89) gid=0(root) groups=0(root) bash-4.2$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND 89 1 0.0 0.0 4412 696 ? Ss 13:05 0:00 tail -f /dev/null 89 25 0.0 0.0 11836 3008 pts/0 Ss 13:05 0:00 bash 89 34 0.0 0.0 51764 3500 pts/0 R+ 13:05 0:00 ps aux bash-4.2$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin 89:x:89:0:89 user:/:/sbin/nologin
runAsUser
で指定したUID=89で動作しているのが確認できる。
なお、99(nobody)
のように、既に存在するUIDでも動く。
$ oc edit dc sample-app (runAsUserの値を変更) $ oc rsh sample-app-2-6pk9t bash bash-4.2$ id uid=99(nobody) gid=99(nobody) groups=99(nobody)
ただし、0(root)
は指定してもデプロイに失敗する。
$ oc get event : : 3s Warning FailedCreate replicationcontroller/sample-app-3 Error creating: pods "sample-app-3-" is forbidden: unable to validate against any security context constraint: [spec.containers[0].securityContext.securityContext.runAsUser: Invalid value: 0: must be in the ranges: [1000580000, 1000589999] spec.containers[0].securityContext.securityContext.runAsUser: Invalid value: 0: running with the root UID is forbidden]
anyuidを使ってroot(UID:0)を指定して動作
nonroot
でなくanyuid
を使えば、runAsUser
に0
を指定できる。
手順はnonroot
の場合と全く一緒。
準備
$ oc new-project scc-sample-anyuid
ServiceAccount/defaultにanyuidを付与
$ oc adm policy add-scc-to-user anyuid -z default
マニフェスト作成
apiVersion: apps.openshift.io/v1 kind: DeploymentConfig metadata: creationTimestamp: null labels: run: sample-app name: sample-app spec: replicas: 1 selector: run: sample-app strategy: resources: {} template: metadata: creationTimestamp: null labels: run: sample-app spec: containers: - args: - tail - -f - /dev/null image: rhel:7.7 name: sample-app resources: {} securityContext: runAsUser: 0 test: false triggers: null
デプロイ
$ oc apply -f anyuid-deploy.yml
podが起動して確認してみると
$ oc rsh sample-app-1-jvc9p bash [root@sample-app-1-jvc9p /]# id uid=0(root) gid=0(root) groups=0(root) [root@sample-app-1-jvc9p /]# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.3 0.0 4412 684 ? Ss 13:18 0:00 tail -f /dev/null root 7 0.3 0.0 11840 3060 pts/0 Ss 13:19 0:00 bash root 23 0.0 0.0 51764 3436 pts/0 R+ 13:19 0:00 ps aux
rootで動いてプロンプトも#
になっている。
コンテナごとにID指定
前述の2つの例は、spec.template.spec
直下にsecurityContext
を定義したので、全コンテナで共通設定になる。
コンテナごとにUIDを指定する場合(あるいは特定のコンテナ以外は指定が不要な場合)は、containers[*]
配下に設定すればOK
spec: containers: - args: - tail - -f - /dev/null image: rhel:7.7 name: rhel7 securityContext: runAsUser: 0 - args: - tail - -f - /dev/null image: rhscl/perl-526-rhel7:latest name: perl resources: {} - args: - tail - -f - /dev/null image: rhscl/python-36-rhel7:latest name: python resources: {} securityContext: runAsUser: 5000
確認
[zaki@codeready scc]$ oc rsh -c rhel7 sample-app-2-9lssg bash [root@sample-app-2-9lssg /]# id uid=0(root) gid=0(root) groups=0(root) [root@sample-app-2-9lssg /]# exit [zaki@codeready scc]$ oc rsh -c perl sample-app-2-9lssg bash bash-4.2$ id uid=1001(default) gid=0(root) groups=0(root) bash-4.2$ exit [zaki@codeready scc]$ oc rsh -c python sample-app-2-9lssg bash (app-root) bash-4.2$ id uid=5000(5000) gid=0(root) groups=0(root) (app-root) bash-4.2$ exit
perl
コンテナのUIDが、プロジェクトのuid-range
に設定されている桁数のやたら長いランダムなUIDでなく1001
になっているのは、ビルドに使われたDockerfileにUSER 1001
の指定があるため。たぶん。
privileged(参考)
ちなみにanyuid
でもroot権限で動作させることができるが、更に強い権限にprivileged
がある。
これはコンテナ内のプロセスの権限だけでなく、ホストに対するVOLUME設定などあらゆる制限がかかってない状態でpodが動作するので、変な野良コンテナなどで試さないように。
ということで、基本的にはデフォルトのrestricted
で動作するように設計しましょう。
余談:
1年くらい前にrsyslogをpodで動かしたい要件があり、無邪気にrhelコンテナにrsyslog突っ込んだイメージを作ろうとしたら、こいつ/var/runにpidファイルを作ろうするのに、このディレクトリがrootじゃないと書き込めなかったのがそもそもの経緯。
ただしこのときは、特権動作させるのではなく、rsyslogの起動オプション-i
でpidファイルの作成先を指定できることが分かったので、/var/tmp辺りに作成して回避して、ずっとpodで特権動作の調査をほったらかしてましたとさ。。。