OpenShift Origin(OKD)に、Node.jsアプリケーションをデプロイしていろいろ試すというエントリで「コンテナに引数を設定してみる」でargsを利用しているところで「ですがまあ、これは不正解な気がします。」と書いていてソース方面を見にいくという方法を取っていますが、それをOpenShift上できちんと裏付け調査する方法について書いておきます。
アプリケーションは以下のサンプルを利用しています。手元の環境ではOCP 3.9を利用していますがokd 3.10でも一緒です。
oc new-app https://github.com/sclorg/nodejs-ex
現在のコンテナで何が実行されるかはコンテナイメージメタデータのEntrypointとCmdを見る必要があります。コンテナイメージメタデータはImageStreamに入っていてImageStreamTagというvirtual objectを通して参照できるようになっています。
$ oc get istag
NAME DOCKER REF UPDATED IMAGENAME
nodejs-ex:latest docker-registry.default.svc:5000/test-nodejs/nodejs-ex@sha256:7222ec78ef8e9f84a119fece9eeb49053718e4bd7fba6d203c23ea7fe30f99f5 36 minutes ago sha256:7222ec78ef8e9f84a119fece9eeb49053718e4bd7fba6d203c23ea7fe30f99f5
$ oc export istag nodejs-ex:latest
apiVersion: v1
generation: 1
image:
dockerImageLayers:
- (省略)
dockerImageMetadata:
Config:
Cmd:
- /usr/libexec/s2i/run
Entrypoint:
- container-entrypoint
Env:
(以下省略)
ちなみにistagはvirtual objectであるせいか、oc export istagやoc get istag -o yamlというようにオブジェクト名の指定を省略した場合はコンテナメタデータなどの詳細を表示しないという挙動となるようです。上のようにoc export istag nodejs-ex:latestと指定する必要があります。ちょっとはまりました。
OpenShiftではクライアントサイドにocコマンドさえあれば、dockerなどがインストールされていなくてもこういったコンテナの詳細が調査できるのが便利です。
次にcontainer-entrypointと/usr/libexec/s2i/runは何か、という話になりますが、これはコンテナイメージ内を調査する必要があります。コンテナイメージ内の調査は場合によって以下の3種類のどれかを利用します。
- 既存のPodに
oc rsh(Entrypint, Cmdが既に実行されている状態の調査)- 例:
oc rsh dc/node-ex
- 例:
- 既存のDeploymentConfigに
oc debug(Entrypint, Cmd実行前の状態の調査)- 例:
oc debug dc/node-ex
- 例:
oc run(s2iイメージなどDeploymentConfigなどが存在しないイメージの調査)- 例:
oc run foo --image=docker-registry.default.svc:5000/test-nodejs/nodejs-ex@sha256:7222ec78ef8e9f84a119fece9eeb49053718e4bd7fba6d203c23ea7fe30f99f5 --command -- tail -f /dev/null
- 例:
今回は直接rshで問題ありません。
oc rsh dc/nodejs-ex
コンテナに入ったら必要なファイルなどを調査します。
sh-4.2$ which container-entrypoint
/usr/bin/container-entrypoint
sh-4.2$ cat $(which container-entrypoint)
#!/bin/bash
exec "$@"
$ cat /usr/libexec/s2i/run
#!/bin/bash
# S2I run script for the 'nodejs' image.
# The run script executes the server that runs your application.
#
# For more information see the documentation:
# https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md
#
set -e
if [ -e "/opt/app-root/etc/generate_container_user" ]; then
source /opt/app-root/etc/generate_container_user
fi
# Runs the nodejs application server. If the container is run in development mode,
# hot deploy and debugging are enabled.
run_node() {
echo -e "Environment: \n\tDEV_MODE=${DEV_MODE}\n\tNODE_ENV=${NODE_ENV}\n\tDEBUG_PORT=${DEBUG_PORT}"
if [ "$DEV_MODE" == true ]; then
echo "Launching via nodemon..."
exec nodemon --inspect="$DEBUG_PORT"
else
echo "Launching via npm..."
exec npm run -d $NPM_RUN
fi
}
#Set the debug port to 5858 by default.
if [ -z "$DEBUG_PORT" ]; then
export DEBUG_PORT=5858
fi
# Set the environment to development by default.
if [ -z "$DEV_MODE" ]; then
export DEV_MODE=false
fi
# If NODE_ENV is not set by the user, then NODE_ENV is determined by whether
# the container is run in development mode.
if [ -z "$NODE_ENV" ]; then
if [ "$DEV_MODE" == true ]; then
export NODE_ENV=development
else
export NODE_ENV=production
fi
fi
# If the official dockerhub node image is used, skip the SCL setup below
# and just run the nodejs server
if [ -d "/usr/src/app" ]; then
run_node
fi
# Allow users to inspect/debug the builder image itself, by using:
# $ docker run -i -t openshift/centos-nodejs-builder --debug
#
[ "$1" == "--debug" ] && exec /bin/bash
run_node
起動はNPM_RUN環境変数を引数にしているようなので、これを調整するのが正解だとわかります。デフォルトの定義を調べます。
$ oc export istag nodejs-ex:latest | grep NPM_RUN
- NPM_RUN=start
というわけで、 NPM_RUN='start arg1'と設定するのがこのイメージのお作法である、で正解です。
s2iに限らず、どのようなイメージでもoc import-imageとoc runしてしまえばImageStreamとDeploymentConfigが出来るのでOpenShift上でイメージの調査ができるようになります。