Libertyコンテナでumaskを変える

Dockerコンテナとして稼働するWebSphere Libertyプロセスの`umask`を変える方法を確認。

`Dockerfile`で`RUN umask 0002`としたり`.bashrc`等を設定しても、最終的に`ENTRYPOINT`や`CMD`でプロセスを起動する際にはログインシェルを介さないので、意味がないことに注意。

## ENTRYPOINTとCMDの確認

ググると以下のような情報がある。

- [How to set umask for Docker container](https://codeyarns.com/2017/07/21/how-to-set-umask-for-docker-container/)
- [Change umask in docker containers](http://widerin.net/blog/change-umask-in-docker-containers/)

コンテナ内に以下の様なスクリプトを`COPY`して`ENTRYPOINT`に指定している。

```bash
#!/bin/bash
umask 0002
/bin/bash
```

ベースとするイメージの`ENTRYPOINT`と`CMD`がどうなっているかにより、好ましい対応方法は異なると思われる。また、上記の記事の方法では親となる`bash`プロセスが余計に起動することになると思われる。

[websphere-liberty:18.0.0.3-kernelのDockerfile](https://github.com/WASdev/ci.docker/blob/051f60c8158806ddaf3a1a1e1f4fd75fa826ab8a/ga/18.0.0.3/kernel/Dockerfile)を確認すると、`ENTRYPOINT`と`CMD`は以下となっている。

```
ENTRYPOINT ["/opt/ibm/docker/docker-server"]
CMD ["/opt/ibm/wlp/bin/server", "run", "defaultServer"]
```

`ENTRYPOINT`に指定されている`/opt/ibm/docker/docker-server`は`LICENSE`と`KEYSTORE_REQUIRED`環境変数がある場合に何か処理をしたのち、最後は以下のように引数で与えられた内容を`exec`している。

```
# Pass on to the real server run
exec "$@"
```

すなわち`CMD`で指定された内容が実行され、`/opt/ibm/docker/docker-server`のプロセスは終了する。

## WLP_SKIP_UMASK

Libertyは環境変数`WLP_SKIP_UMASK=true`を設定していない場合は、起動時にOtherのアクセス権を拒否するようにumaskを設定する挙動をすることに注意。

[サーバー・コマンド・オプション](https://www.ibm.com/support/knowledgecenter/ja/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/rwlp_command_server.html)

## Dockerfileでの設定例

`umask`を変更し、もともと`CMD`に設定されていた内容を実行するスクリプトを作成する。

```bash:start.sh
#!/bin/bash
umask 0002
exec /opt/ibm/wlp/bin/server run defaultServer
```

実行権限を付与する。

```
chmod +x start.sh
```

`Dockerfile`は以下のようにする。

```dockerfile:Dockerfile
FROM websphere-liberty:latest
COPY start.sh /
CMD ["/start.sh"]
```

ビルドする。

```
docker build -t umask .
```

コンテナを起動し、ログファイルの権限が変わっていることと余計なプロセスがないことを確認。

```shell-session
$ docker run --rm -d --name liberty-umask umask
64c21c20f112c2b6b1d03bd4b571f80d7decf0577402b9beb3dd6fa8133f830a
$ docker exec -it liberty-umask ls -l /logs
total 12
-rw-rw---- 1 default root 11345 Nov 14 07:59 messages.log
$ docker exec -it liberty-umask ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
default      1     0 28 07:58 ?        00:00:15 /opt/ibm/java/jre/bin/java -java
default    292     0  0 07:59 pts/0    00:00:00 ps -ef
$
```

（umaskを変えない場合）

```shell-session
$ docker run --rm -d --name liberty websphere-liberty
78902882c748f7674ccfb02447d07f13caa10a0a95689fa62d9cc38c7f30da48
$ docker exec -it liberty ls -l /logs
total 12
-rw-r----- 1 default root 11345 Nov 14 07:59 messages.log
$ docker exec -it liberty ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
default      1     0 40 07:59 ?        00:00:14 /opt/ibm/java/jre/bin/java -java
default    221     0  1 07:59 pts/0    00:00:00 ps -ef
$
```

## 別の設定例

以下のように`CMD`ではなく`ENTRYPOINT`のほうを変えてもよい。

```bash:custom-entrypoint.sh
#!/bin/bash
umask 0002
exec /opt/ibm/docker/docker-server "${@}"
```

```dockerfile:Dockerfile
FROM websphere-liberty:latest
COPY custom-entrypoint.sh /
ENTRYPOINT ["/custom-entrypoint.sh"]
CMD ["/opt/ibm/wlp/bin/server", "run", "defaultServer"]
```

## Kuberenetesのマニフェストでの設定例

Kubernetes上で稼働させる場合で、Dokcerイメージ内にわざわざスクリプトを入れ込みたくない場合は、マニフェストで定義する事も可能。Dockerfileの`ENTRYPOINT`が`command`に、`CMD`が`args`に相当する。

```yaml:liberty.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: liberty
spec:
  selector:
    matchLabels:
      app: liberty
  replicas: 1
  template:
    metadata:
      labels:
        app: liberty
    spec:
      containers:
      - name: liberty
        image: websphere-liberty:kernel
        imagePullPolicy: Always
        ports:
        - containerPort: 9080
        args:
        - bash
        - -c
        - |
          umask 0002
          exec /opt/ibm/wlp/bin/server run defaultServer
```

マニフェストをデプロイ。

```
kubectl apply -f liberty.yaml
```

確認する。

```shell-session
$ kubectl exec -it liberty-666b7c759c-hq8ss -- ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
default      1     0  8 09:19 ?        00:00:04 /opt/ibm/java/jre/bin/java -java
default     76     0  0 09:20 pts/0    00:00:00 ps -ef
$ kubectl exec -it liberty-666b7c759c-hq8ss -- ls -l /logs
total 4
-rw-rw---- 1 default root 2070 Nov 29 09:19 messages.log
$
```

## 参考リンク

[[docker] CMD とENTRYPOINT の違いを試してみた](https://qiita.com/hihihiroro/items/d7ceaadc9340a4dbeb8f)