nekop's blog

OpenShift / JBoss / WildFly / Infinispanの中の人 http://twitter.com/nekop

OpenShiftでコンテナの詳細を調べる

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 istagoc 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-imageoc runしてしまえばImageStreamとDeploymentConfigが出来るのでOpenShift上でイメージの調査ができるようになります。