これは、なにをしたくて書いたもの?
- OKD(OpenShift)を使って、Dockerイメージをデプロイする方法をまとめておこうかと思って
- 直接Dockerイメージをデプロイしたり、Dockerfileからビルドしてデプロイする方法もあるので、そちらも合わせて
Templateを使うパターンは、今回は置いておきます。
環境
今回の環境は、こちらです。
$ minishift version minishift v1.31.0+cfc599c $ oc version oc v3.11.0+0cbc58b kubernetes v1.11.0+d4cacc0 features: Basic-Auth GSSAPI Kerberos SPNEGO Server https://192.168.42.112:8443 kubernetes v1.11.0+d4cacc0
「oc new-app」
基本は、こちらです。
Creating New Applications - Application Life Cycle Management | Developer Guide | OKD 3.11
Dockerイメージをデプロイする
まずは、すでに存在するDockerイメージをデプロイする方法から。
Creating an Application From an Image
例えば、DockerHubにあるSonatype Nexus 3のDockerイメージをデプロイ。
$ oc new-app sonatype/nexus3:3.15.2
Routeを追加。
$ oc expose svc/nexus3
確認。
$ curl -I nexus3-myproject.192.168.42.112.nip.io HTTP/1.1 200 OK Date: Sat, 09 Feb 2019 06:24:23 GMT Server: Nexus/3.15.2-01 (OSS) X-Content-Type-Options: nosniff X-Frame-Options: DENY Content-Type: text/html Last-Modified: Sat, 09 Feb 2019 06:24:23 GMT Pragma: no-cache Cache-Control: post-check=0, pre-check=0 Expires: 0 Content-Length: 7085 Set-Cookie: 38db5894cd3f4d4cfad3c49452da8aee=8b9c65053c75611e79740b706923b345; path=/; HttpOnly
OKDにデプロイする場合は、なにも考えずにrootで起動するコンテナをデプロイすると、うまく起動できなかったりするので
注意しましょう。
ソースコードを含むGitリポジトリからデプロイする
続いて、アプリケーションのソースコードを含むGitリポジトリからDockerイメージを作って、デプロイする方法。
Creating an Application From Source Code
今回は、Node.js+Expressでサンプルアプリケーションを作ります。
$ npm i express
依存関係。
"dependencies": { "express": "^4.16.4" }
作成したコード。アクセスすると、実行中のNode.jsのバージョンを返却するようにしています。
server.js
const express = require("express"); const app = express(); app.get("/", (req, res) => { res.send(`Node.js version = ${process.version}`); }); console.log(`[${new Date()}] server startup`); app.listen(8080);
これを、「npm start」で実行できるようにしてGitリポジトリに登録します。
"scripts": { "start": "node server.js", "test": "echo \"Error: no test specified\" && exit 1" },
デプロイ。「--name」は省略すると、リポジトリ名から付与されますが、今回は明示。
$ oc new-app --name simple-nodejs-app http://〜[GitリポジトリへのURL]
イメージを作成する際に、どの言語としてビルドするのかはある程度自動判別してくれます。
言語の判定のルールは、こちら。
では、確認用にRouteを作成。
$ oc expose svc/simple-nodejs-app
確認。
$ curl simple-nodejs-app-myproject.192.168.42.112.nip.io Node.js version = v10.12.0
Node.js 10.12.0で動作していることが確認できました。
ソースコードを含むGitリポジトリからデプロイする(ビルド時に使用するイメージを指定する)
ところで、OKD 3.11で使えるNode.jsのバージョンはこれだけです。今回は、Node.jsの10が選ばれたことになります。
$ oc get is/nodejs -n openshift -o json | jq '.spec.tags[].name' "0.10" "10" "4" "6" "8" "8-RHOAR" "latest"
ビルド時に使うイメージを変えて、デプロイしてみましょう。Node.jsのバージョンは、8を使うことにします。
## 「-i」または「--image-stream」でNode.js 8を指定 $ oc new-app --name simple-nodejs-app -i nodejs:8 http://〜[GitリポジトリへのURL] ## または、GitリポジトリのURLの前に「使うイメージ~」を付ける $ oc new-app --name simple-nodejs-app nodejs:8~http://〜[GitリポジトリへのURL]
Route作成後、確認。どちらの方法でデプロイしても結果は同じなので、片方だけ。
$ oc expose svc/simple-nodejs-app $ curl simple-nodejs-app-myproject.192.168.42.112.nip.io Node.js version = v8.11.4
ソースコードを含むGitリポジトリからデプロイする(Dockerfileを使う)
また、GitリポジトリにDockerfileを入れておくと、Dockerfileからビルドしてイメージを作ってくれます。
今回は、このようなDockerfileを用意して、Gitリポジトリに追加しておきます。OKDに入っていない、Node.js 11のイメージを使います。
Dockerfile
FROM node:11.9.0 COPY . /opt/app RUN cd /opt/app && \ npm i && \ chgrp -R 0 /opt/app && \ chmod -R g=u /opt/app USER 1001 WORKDIR /opt/app EXPOSE 8080 ENTRYPOINT [ "npm", "start" ]
最初、EXPOSEを書くのを忘れて、Serviceが自動的に作られなくてハマりました…。
uidや権限の指定方法は、こちらを参考に。
では、デプロイ。
$ oc new-app --name simple-nodejs-app http://〜[GitリポジトリへのURL]
この時、Dockerfileで指定したイメージを使っていることがわかります。
--> Found Docker image 9ba05fb (3 days old) from Docker Hub for "node:11.9.0"
Routeを作成して、確認。
$ oc expose svc/simple-nodejs-app $ curl simple-nodejs-app-myproject.192.168.42.112.nip.io Node.js version = v11.9.0
Node.js 11上で動いていますね。
なお、Dockerfileが入った状態でもソースコードからイメージをビルドしたい場合は、「strategy」オプションで「source」を
指定すればOKです。
$ oc new-app --name simple-nodejs-app --strategy=source http://〜[GitリポジトリへのURL]
Dockerfileを使うことを明示する場合は、「docker」を指定します。
$ oc new-app --name simple-nodejs-app --strategy=docker http://〜[GitリポジトリへのURL]
strategyオプションについては、こちらを参照。
インラインDockerfileからビルド・デプロイする
最後は、インラインDockerfileからイメージをビルドして、デプロイするところまで。
この場合、「new-app」ではなく、「new-build」でイメージを作成してからデプロイすることになります。
こんなDockerfileを用意。
Dockerfile
FROM ubuntu:18.04 RUN apt-get update -y && apt-get install -y python3 && apt-get clean USER 1001 EXPOSE 8000 ENTRYPOINT [ "python3", "-m", "http.server" ]
Dockerイメージをビルド。「--dockerfile」オプションに「-」を指定することで、標準入力からDockerfileの定義を読み込むことが
できます。
$ cat Dockerfile | oc new-build --name simple-python-httpserver --dockerfile=-
アプリケーションとして、デプロイ。
$ oc new-app simple-python-httpserver
Routeを作成して、確認。
$ oc expose svc/simple-python-httpserver $ curl simple-python-httpserver-myproject.192.168.42.112.nip.io <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ascii"> <title>Directory listing for /</title> </head> <body> <h1>Directory listing for /</h1> <hr> <ul> <li><a href=".dockerenv">.dockerenv</a></li> <li><a href="bin/">bin/</a></li> <li><a href="boot/">boot/</a></li> <li><a href="dev/">dev/</a></li> <li><a href="etc/">etc/</a></li> <li><a href="home/">home/</a></li> <li><a href="lib/">lib/</a></li> <li><a href="lib64/">lib64/</a></li> <li><a href="media/">media/</a></li> <li><a href="mnt/">mnt/</a></li> <li><a href="opt/">opt/</a></li> <li><a href="proc/">proc/</a></li> <li><a href="root/">root/</a></li> <li><a href="run/">run/</a></li> <li><a href="sbin/">sbin/</a></li> <li><a href="srv/">srv/</a></li> <li><a href="sys/">sys/</a></li> <li><a href="tmp/">tmp/</a></li> <li><a href="usr/">usr/</a></li> <li><a href="var/">var/</a></li> </ul> <hr> </body> </html>
なお、DockerfileをBuildConfigを定義するYAMLに書いて、実行することもできます。
Binary Build
最後に、Binary Build。Dockerfileを使用します。
Binary Builds - Tutorials | Developer Guide | OKD 3.11
Binary Buildを使用することで、ローカルファイルをOKDに転送して、Gitリポジトリを使わずにビルドを行うことができます。
これを使うと、GitリポジトリにpushしたりしなくてもDockerイメージのビルドができるようになります。
ですが、Binary Buildを使うには各ビルド時にユーザーがファイルをアップロードしなければなりません。つまり、都度同じファイルを
アップロードしないと、ビルドに再現性がなくなります。また、ユーザーによるファイルのアップロードを伴うので、ビルドの自動起動も
できなくなります。
このあたりに注意して、使っていきましょう。
ファイルは、先ほど作成した、Node.jsのサンプルアプリケーションを使います。ファイルは、これだけ残しました。
$ ls -1 Dockerfile package-lock.json package.json server.js
あとは、こちらに従ってビルドし、アプリケーションをデプロイします。
Tutorial: Building private code
ビルドの定義。
$ oc new-build --strategy docker --binary --name simple-nodejs-app
カレントディレクトリ(「.」)の内容を転送して、ビルド開始。
$ oc start-build simple-nodejs-app --from-dir .
デプロイ、Route作成、確認。
$ oc new-app simple-nodejs-app $ oc expose svc/simple-nodejs-app $ curl simple-nodejs-app-myproject.192.168.42.112.nip.io Node.js version = v11.9.0
つまり、ビルドの度に毎回これをやることになる、というわけですね。
$ oc start-build simple-nodejs-app --from-dir .
今回はいろんな方法でOKD上でのDockerイメージのビルド、デプロイを試してみましたが、使ったことがないものも
あったので勉強になりました。