nekop's blog

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

OpenShiftでDockerfileやバイナリビルド利用してコンテナをビルドする

OpenShift 全部俺 Advent Calendar 2017

昨日はギョウザパーティでした。基本のs2iビルドではソースコードからビルドしましたが、今回はDockerfileを利用します。

ソースコードと同じようにDockerfileが置いてあるGit URLを指定すると同じようにビルドできるのですが、それでは面白くないのでちょっとアドホックなビルドをしてみましょう。

tail -f /dev/nullを実行するコンテナイメージを作成するDockerfileをGitを利用せずにOpenShiftに食べさせてみます。oc new-buildでビルドしてからoc new-appでImageStreamを指定してアプリケーションを作成という流れになります。

oc new-project test-dockerbuild
cat <<EOF > Dockerfile 
FROM registry.access.redhat.com/rhel
CMD tail -f /dev/null
EOF
cat Dockerfile | oc new-build --dockerfile=- --to=sleep
oc logs sleep-1-build -f
oc new-app sleep

できました。デプロイされたコンテナを見ると実行されていますね。

$ oc rsh dc/sleep ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
1000080+     1  0.0  0.0   4352   352 ?        Ss   06:34   0:00 tail -f /dev/nu
1000080+    16  0.0  0.0  47448  1612 ?        Rs+  06:35   0:00 ps aux

この方式だとDockerfileはBuildConfigに埋め込まれているので、以降内容を編集する場合はoc edit bcで直接編集できます。

$ oc export bc sleep
kind: BuildConfig
spec:
  source:
    dockerfile: |
      FROM registry.access.redhat.com/rhel
      CMD tail -f /dev/null
    type: Dockerfile

ただし、上記のDockerfile埋め込みだとビルドコンテキストが渡せないので、ファイルをイメージ内にコピーしたりしたいときに困ります。そのような場合はバイナリビルドにしてoc start-build時にディレクトリをまるごと転送する、というのもできます。

oc new-build --strategy=docker --binary=true --name=$APP_NAME
oc start-build $APP_NAME --from-dir=.
oc new-app $APP_NAME

バイナリビルドはDockerfileに限らず、s2iのソースツリーでも同じようにGitを経由しないビルドができます。

ちなみにDockerfileを利用したビルドは現状docker daemon内、つまりrootで実行されているためセキュリティレベルとしては最低です。このため、OpenShift OnlineではDockerビルドは無効化されています。そのうちbuildahなどを利用してdocker daemonとは無関係の通常権限でのDockerfileビルドもできるようになるとは思いますが、そこまでしてDockerfile形式を利用しなければならない理由もあまり無いので、より扱いやすいコンテナイメージの記述およびビルド方式が先にサポートされる気もします。