はじめに
上記の記事では、GitHubで公開したDockerfileとその他の関連ファイルを用いてDockerイメージを作成しました。一方、Dockerfile単体でビルドできるイメージの場合、DockerfileだけをGitHubにアップロードするのは少し大げさです。このような際は、ビルド設定(BuildConfig)にDockerfileの内容をインラインで記述してしまうことも可能です。
また、OpenShiftでは、Dockerfileを使用にせずに、独自に用意したスクリプトを用いてイメージの作成を自動化する「Source to Image(S2I)」という機能も利用できます。ここでは、これらの手法でイメージを作成する例を紹介します。
はじめに準備として、例によって、プロジェクトを作成して、CentOS7のベースイメージをイメージストリームに登録しておきます。
# oc login -u enakai # oc delete project project01 # oc new-project project01 --description="Project to learn S2I image build" --display-name="Learning S2I Image Development" # docker pull centos:7 # docker login -u enakai -e enakai@example.com -p $(oc whoami -t) registry.oso.example.com # docker tag docker.io/centos:7 registry.oso.example.com/project01/centos7:latest # docker push registry.oso.example.com/project01/centos7:latest
Dcokerfileをインラインで記述する例
この後で、node.jsを用いたアプリケーションイメージをビルドするので、その準備として、CentOS7にnodejs関連のパッケージを追加したイメージを作成して、イメージストリーム「nodejs-base」に登録します。次の設定ファイルで、イメージストリームとビルド設定をまとめて登録します。
apiVersion: v1 kind: List items: - apiVersion: v1 kind: ImageStream metadata: name: nodejs-base - apiVersion: v1 kind: BuildConfig metadata: name: nodejs-base spec: output: to: kind: ImageStreamTag name: nodejs-base:latest source: dockerfile: | FROM centos:7 MAINTAINER E.Nakai RUN yum -y install epel-release; yum -y install nodejs npm RUN useradd node -u 9999 USER 9999 type: Dockerfile strategy: dockerStrategy: from: kind: ImageStreamTag name: centos7:latest type: Docker triggers: - imageChange: {} type: ImageChange
ビルド設定「nodejs-base」を見ると、「source.type」に「Dockerfile」が指定されています。これは、「source.dockerfile」にインラインで記載されたDockerfileを使用することを意味します。その他の設定は、これまでの説明と同様です。実際に設定を登録すると、次のようになります。
# oc create -f nodejs-base_bc.yml imagestream "nodejs-base" created buildconfig "nodejs-base" created # oc get is NAME DOCKER REPO TAGS UPDATED centos7 172.30.84.64:5000/project01/centos7 latest 5 minutes ago nodejs-base 172.30.84.64:5000/project01/nodejs-base # oc describe bc nodejs-base Name: nodejs-base Created: About a minute ago Labels: <none> Latest Version: Never built Strategy: Docker Source Type: Dockerfile Dockerfile: FROM centos:7 MAINTAINER E.Nakai RUN yum -y install epel-release; yum -y install nodejs npm RUN useradd node -u 9999 USER 9999 From Image: ImageStreamTag centos7:latest Output to: ImageStreamTag nodejs-base:latest Triggered by: ImageChange
ビルド設定の中にDockerfileの内容が含まれていることが分かります。ここでは、ユーザー「node」を作成して、「USER」をUIDで指定している点に注意してください。これは、S2Iのベースイメージとして必要な設定となります。S2Iのビルドプロセスは、このようにUIDで指定された一般ユーザーによって実行することが前提となるためです。
このまましばらく待つと、「triggers:」で指定したトリガーによって、ビルドが開始されます。もしくは、次のコマンドで明示的にビルドを開始します。
# oc start-build nodejs-base nodejs-base-1 # oc get build NAME TYPE FROM STATUS STARTED DURATION nodejs-base-1 Docker Dockerfile Running 6 seconds ago 6s # oc logs -f build/nodejs-base-1 Step 0 : FROM 172.30.84.64:5000/project01/centos7@sha256:b04ac745db2b0c65049667b26df41226b9875a139719ac0f3b41fed57b00c3c9 ---> 60e65a8e4030 ... Successfully built 63142468eb03 I0103 02:12:06.393278 1 docker.go:86] Pushing image 172.30.84.64:5000/project01/nodejs-base:latest ... I0103 02:12:52.004238 1 docker.go:90] Push successful # oc describe is nodejs-base Name: nodejs-base Created: 3 minutes ago Labels: <none> Annotations: openshift.io/image.dockerRepositoryCheck=2016-01-03T08:09:22Z Docker Pull Spec: 172.30.84.64:5000/project01/nodejs-base Tag Spec Created PullSpec Image latest <pushed> About a minute ago 172.30.84.64:5000/project01/nodejs-base@sha256:ed8a1c57bee0ea10a4be3fc84bc4cd11fc87b28b3caa949e6af1bc76b5f02132
S2Iによるイメージ作成の例
S2Iを使用する際は、アプリケーションのビルドに必要なソースファイル一式をGitHubで公開しておきます。この時、「.sti/bin」以下に、「asssemble」、および、「run」というスクリプトを含めます。これらは、それぞれ、アプリケーションのビルド、および、実行に用いられます。ここでは、例として、下記で公開しているEtherpad-Liteのソースを利用します。
assemble、および、runの内容は下記の通りで、「OpenShift OriginによるDockerイメージ管理(3)〜Dockerfileからイメージを作成する際のお作法」で説明したお作法に従って、アプリケーションの導入・実行を行ないます。本来はバックエンドのMySQLを必要としますが、ここでは簡単のためにテスト用の組み込みDB(dirtydb)を使用する設定としています。(MySQLのコンテナと連携する方法は、次回に解説します。)なお、GitHubから取得したコンテンツは、デフォルトで「/tmp/src」に配置されるので、assembleでは、その前提でのビルド処理を行っています。
.sti/bin/assemble
#!/bin/bash APP_ROOT=/home/node SRC=/tmp/src cp -a $SRC/* $APP_ROOT/ cd $APP_ROOT sh bin/installDeps.sh cp -f settings.json.template settings.json chmod og+rwx $APP_ROOT chmod -R og+w $APP_ROOT
.sti/bin/run
#!/bin/bash APP_ROOT=/home/node cd $APP_ROOT /usr/bin/node node_modules/ep_etherpad-lite/node/server.js
そして、これを用いて、S2Iを実行するビルド設定は、次のとおりです。先ほどと同様に、作成したイメージを出力するイメージストリームもあわせて定義しています。
etherpad-lite_bc.yml
apiVersion: v1 kind: List items: - apiVersion: v1 kind: ImageStream metadata: name: etherpad-lite - apiVersion: v1 kind: BuildConfig metadata: name: etherpad-lite spec: output: to: kind: ImageStreamTag name: etherpad-lite:latest source: git: uri: https://github.com/enakai00/etherpad-lite.git ref: openshift_1.5.7 type: Git strategy: sourceStrategy: from: kind: ImageStreamTag name: nodejs-base:latest type: Source triggers: - imageChange: {} type: ImageChange
「spec.strategy.type」の「Source」が、S2Iによるビルドの指定になります。また、「spec.source.git」に、GitHubのURLと使用するブランチ(この例では「openshift_1.5.7」)を指定しています。
# oc create -f etherpad-lite_bc.yml imagestream "etherpad-lite" created buildconfig "etherpad-lite" created # oc get is NAME DOCKER REPO TAGS UPDATED centos7 172.30.84.64:5000/project01/centos7 latest 28 minutes ago etherpad-lite 172.30.84.64:5000/project01/etherpad-lite nodejs-base 172.30.84.64:5000/project01/nodejs-base latest 21 minutes ago # oc describe bc etherpad-lite Name: etherpad-lite Created: 27 seconds ago Labels: <none> Latest Version: Never built Strategy: Source Source Type: Git URL: https://github.com/enakai00/etherpad-lite.git Ref: openshift_1.5.7 From Image: ImageStreamTag nodejs-base:latest Output to: ImageStreamTag etherpad-lite:latest Triggered by: ImageChange
ビルドを開始します。ログを見ると、ベースイメージからコンテナを起動した後、GitHubからソースを取得して、「assemble」スクリプトを実行していることが分かります。
# oc start-build etherpad-lite etherpad-lite-1 # oc get build NAME TYPE FROM STATUS STARTED DURATION etherpad-lite-1 Source Git@openshift_1.5.7 Running 1 seconds ago 1s nodejs-base-1 Docker Dockerfile Complete 26 minutes ago 40s # oc logs -f build/etherpad-lite-1 I0103 08:37:00.110401 1 sti.go:163] The value of ALLOWED_UIDS is [1-] I0103 08:37:00.116206 1 docker.go:230] Pulling image 172.30.84.64:5000/project01/nodejs-base@sha256:ed8a1c57bee0ea10a4be3fc84bc4cd11fc87b28b3caa949e6af1bc76b5f02132 ... I0103 08:39:45.620174 1 sti.go:217] Pushing 172.30.84.64:5000/project01/etherpad-lite:latest image ... I0103 08:40:29.900013 1 sti.go:233] Successfully pushed 172.30.84.64:5000/project01/etherpad-lite:latest # oc describe is etherpad-lite Name: etherpad-lite Created: 5 minutes ago Labels: <none> Annotations: openshift.io/image.dockerRepositoryCheck=2016-01-03T08:35:50Z Docker Pull Spec: 172.30.84.64:5000/project01/etherpad-lite Tag Spec Created PullSpec Image latest <pushed> About a minute ago 172.30.84.64:5000/project01/etherpad-lite@sha256:05c4600b8abec75a85c32baed153c0023cc0cbc7ab0250a3f14ce5d66962ed46
アプリケーションの実行
それでは、完成したアプリケーションイメージを実行してみましょう。デプロイ設定(DeploymentConfig)、サービス(Service)、ルーティング(Route)をまとめて一気に設定してしまいます。
etherpad-lite_deploy.yml
apiVersion: v1 kind: List items: - apiVersion: v1 kind: DeploymentConfig metadata: name: etherpad-lite spec: template: metadata: labels: name: etherpad-lite spec: containers: - name: etherpad-lite-latest image: etherpad-lite:latest ports: - containerPort: 9001 protocol: TCP replicas: 1 selector: name: etherpad-lite triggers: - type: ImageChange imageChangeParams: automatic: true containerNames: - etherpad-lite-latest from: kind: ImageStreamTag name: etherpad-lite:latest - type: ConfigChange - apiVersion: v1 kind: Service metadata: name: etherpad-lite spec: ports: - name: 9001-tcp protocol: TCP port: 9001 targetPort: 9001 selector: deploymentconfig: etherpad-lite - apiVersion: v1 kind: Route metadata: name: etherpad-lite-route spec: host: eplite.project01.oso.example.com to: kind: Service name: etherpad-lite
# oc create -f etherpad-lite_deploy.yml deploymentconfig "etherpad-lite" created service "etherpad-lite" created route "etherpad-lite-route" created # oc describe dc etherpad-lite Name: etherpad-lite Created: About a minute ago Labels: <none> Latest Version: 1 Triggers: Image(etherpad-lite@latest, auto=true), Config Strategy: Rolling Template: Selector: name=etherpad-lite Replicas: 1 Containers: NAME IMAGE ENV etherpad-lite-latest 172.30.84.64:5000/project01/etherpad-lite@sha256:05c4600b8abec75a85c32baed153c0023cc0cbc7ab0250a3f14ce5d66962ed46 Deployment #1 (latest): Name: etherpad-lite-1 Created: about a minute ago Status: Complete Replicas: 1 current / 1 desired Selector: deployment=etherpad-lite-1,deploymentconfig=etherpad-lite,name=etherpad-lite Labels: openshift.io/deployment-config.name=etherpad-lite Pods Status: 1 Running / 0 Waiting / 0 Succeeded / 0 Failed # oc get pod NAME READY STATUS RESTARTS AGE etherpad-lite-1-build 0/1 Completed 0 8m etherpad-lite-1-x3elu 1/1 Running 0 31s nodejs-base-1-build 0/1 Completed 0 34m # oc get service NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE etherpad-lite 172.30.14.201 <none> 9001/TCP deploymentconfig=etherpad-lite 45s # oc get route NAME HOST/PORT PATH SERVICE LABELS INSECURE POLICY TLS TERMINATION etherpad-lite-route eplite.project01.oso.example.com etherpad-lite
これで、「http://eplite.project01.oso.example.com」にアクセスすると、Etherpadが利用できるようになっています。