Projectとアプリケーションデプロイ
本稿では下記の筋立てでOpenShiftを使った開発者向けのトピックを提供します。
- Projectとは
- ビルド済みのイメージを使う:CaaSとしての利用
- Docker Hubのイメージの利用
- セキュリティを緩める回避策
- Docker Hubのイメージの利用2
- Podのスケールアウト
- どんなリソースができたか
- oc runコマンドの別の使い方
- ローカルのイメージの利用
- Minishiftでの内部レジストリへのプッシュ
- イメージのインポートとImageStream
- OpenShiftでのDockerビルド
- OpenShiftが提供するイメージの利用
- Docker Hubのイメージの利用
- イメージを自分で作成する:PaaSとしての利用
- S2Iビルドとは
- プログラムのソースコードの用意
- JavaのS2Iビルド
- インクリメンタルビルドの有効化
- S2Iビルドのカスタマイズ
- チェーンビルド
- ビルドのトリガーについて
CDK(Minishift)を含むOpenShiftクラスタへログインが可能で、ocコマンドをインストール済みであることを想定しています。お使いのシェルにあわせて、下記のコマンドを実行してコマンドの補完機能を有効にしておくことをお勧めします。
$ source <(oc completion bash)
Projectとは
Project(混乱がない限り、カタカナ表記も用います)とは、OpenShiftクラスタにおける作業の単位です。ちょうど自分のマシンで何か作業をするときにまずディレクトリを作るように、OpenShiftでもまずProjectを作成し、そこですべての作業を行います。
ocコマンドでクラスタにログインした直後は、自分のProjectが何もない状態か、もしくはクラスタの管理者により作成された何らかのProject内にいる状態になっています。ログイン後に表示されたメッセージをよく見てみるか、oc statusまたはoc projectコマンドを実行して、現在のProjectが何かを確認してみて下さい。
Projectは気軽に新規作成できます。本稿の説明を何もない空のProjectから始めるためにも、「my-testproject」という名前で作ってみましょう。
$ oc new-project my-testproject
Projectの名前は、そのOpenShiftクラスタ内で一意である必要があります。これは、Projectの実体がKubernetesのNamespaceであるための制約です。Minishiftのような一人で独占できるOpenShiftクラスタ環境であれば問題ありませんが、共用の環境を使っている場合は「my-」の部分にユーザ名を適用するなどして、一意性を確保して下さい。
OpenShiftでは、さまざまな場面でこのProject名の一意性を利用しています。
例えば、Dockerのイメージ名が下記のルールで決められているのは、皆さんご存知のはずです。
<registry>/<owner>/<repository>:<tag>
具体的には、Docker Hubにある公式のNginxの最新イメージは下記の名前で取得できます。
docker.io/library/nginx:latest
実は、すべてのOpenShiftクラスタは統合されたDockerレジストリを内部に持っており、それが「<registry>」の部分になり、「<owner>」の部分にはProject名が使われるのです。
OpenShiftでは既存のイメージを使用するだけでなく、自分で作成することもできます。その作成されたイメージはOpenShift内のレジストリ(本稿では「内部レジストリ」と呼ぶことにします)に保存され、その名前の一意性を確保するために、Project名が一意であることを利用しています。
Projectにはこのように、他のユーザと作業空間を分けたり、作成されるイメージ名の一部になったりと、名前空間としての役割を持ちます。他にもユーザが使用可能なメモリやCPUなどのリソースをProject単位で制限したり、他のユーザに自分のProjectを見せたり編集させたりする権利を明示的に与える等、様々な役割があります。
ビルド済みのイメージを使う:CaaSとしての利用
Docker Hubには様々なイメージが公開されており、dockerコマンドが使える環境であれば手軽にそれらを試すことができます。例えば先にも触れたNginxのイメージをDockerで使うには、下記のように実行します。なお、イメージ名には「nginx」とだけ指定する短縮形を用いています。
$ docker run -d -p 8080:80 nginx 5828ea67fc7ca11a3c1e454e56f9f12550c84b3e7fe00f4acbdb3b20e0d63437 $ curl http://localhost:8080/ (...) <h1>Welcome to nginx!</h1> (...)
そして不要になったら「docker rm -f 5828ea」で消すだけです。
OpenShiftでも、Dockerと同じくらい簡単に既存のイメージを利用でき、CaaS(Container as a Service)としての側面を持っています。ただし注意点もありますので、具体例に沿って見ていきましょう。
Docker Hubのイメージの利用
OpenShiftで既存のDockerイメージを指定してコンテナを起動するには、oc runコマンドを用います。これはKubernetesにあるkubectl runコマンドと同じです。
$ oc run nginx --port=80 --expose --image=nginx
何が起きたかを確認するために、Project内のすべてのリソースを表示させるoc get allを実行してみましょう。
$ oc get all NAME READY STATUS RESTARTS AGE pod/nginx-1-6mdql 0/1 CrashLoopBackOff 3 1m NAME DESIRED CURRENT READY AGE replicationcontroller/nginx-1 1 1 0 1m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/nginx ClusterIP 172.30.131.239 <none> 80/TCP 1m NAME REVISION DESIRED CURRENT TRIGGERED BY deploymentconfig.apps.openshift.io/nginx 1 1 1 config
oc runを実行しただけなのに、何やら多くのリソースができています。そして、「pod/nginx-1-6mdql」が肝心のコンテナを含むリソースですが、「CrashLoopBackOff」というおかしな状態になっています。
実際、Nginxのコンテナの起動に失敗しているのです。oc logsコマンドを対象のPodに対して実行してログを見れば、何が起きているのか分ります。
$ oc logs pod/nginx-1-6mdql 2018/12/16 04:36:59 [warn] 1#1: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2 nginx: [warn] the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2 2018/12/16 04:36:59 [emerg] 1#1: mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied) nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)
「実行ユーザの変更ができない」という警告([warn])の他、「Permission denied」でディレクトリの作成に失敗しています。これは、OpenShiftが通常ユーザでコンテナを起動しようとしている一方で、Nginxのイメージがroot権限を持つスーパーユーザでの実行を想定して作られているために起きているエラーです。
このように、Docker公式イメージのように広く使われているものですら、root権限を要求するものがあります。言うまでもなく、スーパーユーザでのプロセスの実行は好ましくありません。サーバのように長期間動作するものであれば、なおさらです。このセキュリティの問題をよく認識したうえで、その回避策をまず紹介します。
セキュリティを緩める回避策
回避策として、OpenShiftクラスタの管理者にお願いして、Podを実行するアカウントである「default」に、rootを含む任意のユーザを使う許可「anyuid」を与えてもらうというのがあります。
次に示すコマンドは、クラスタの管理権限を持つユーザでログインし直して実行するが必要あります。
# oc adm policy add-scc-to-user anyuid -z default
もしくは、自分がクラスタ管理者でもあるなら、--asオプションを用いてこのコマンドに限って別のユーザで実行することも可能です。
$ oc adm policy add-scc-to-user anyuid -z default --as=system:admin
OpenShiftでは、コンテナに適当なUIDを割り当てて実行しようとします。上記のNginxの例では、実際の実行ユーザはDockerfileで指定されたrootユーザ(UID=0)ではなく、「1000500000」のような適当に採番されたUIDの一般ユーザになっています。そのため実行時にエラーとなっていました。
「anyuid」はSCC(Security Context Constraint)の一種で、コンテナの実行ユーザを実行しようとしているイメージのDockerfileのUSERインストラクションで指定されているUIDにするものです。特にUSERインストラクションの指定がない場合はrootが使われますが、「anyuid」を指定することで、それも許可されます。
そして「default」はSA(Service Account)の一つで、Projectごとに自動で設けられ、そのProject内で動作するPodがデフォルトで使用するアカウントになります。正式名称はプロジェクト名を含んだ「system:serviceaccount:my-testproject:default」ですが、同じプロジェクト内で上記のコマンドを実行する分には「-z default」のように省略した記述が使えます。
実は、Minishiftの環境では、このanyuidがすべてのログイン済みユーザにデフォルトで与えられるようになっています(oc adm policy add-scc-to-user anyuid system:authenticatedと同等のコマンドが実行済みの状態で起動する)。これはMinishiftでOpenShiftに入門する人向けの特別な措置で、既存のroot権限を必要とする多くのイメージを、とりあえず使えるようにするためのものです。
このようにanyuidを許可することは、極めて大きなセキュリティ上のリスクにもなり得ます。どうしても必要な場合は、Minishiftのように広範なユーザ(system:authenticate)に対して許可するのではなく、「-z default」のようにプロジェクトごとに制限されたService Accountに対して許可するようにしましょう。
理想的には、root権限を必要としないような、適切に設計されたイメージのみを使うべきです。Red Hat Container Catalogでは、RHELをベースにした安全なイメージが多数用意されており、製品版のOpenShiftやCDKからはデフォルトで利用可能になっています。
Docker Hubのイメージの利用2
さて、回避策としてのanyuid権限を与えた上で、改めてDocker HubのNginxイメージをOpenShiftで使ってみましょう。
まず前の実行でできたものを削除します。oc runコマンドでできたリソースには「run=<runコマンドに与えた名前>」のラベルが付きますので、ラベルを指定して削除を実行します。
$ oc delete all -l run=nginx
そして改めてoc runコマンドを実行します。
$ oc run nginx --port=80 --expose --image=nginx $ oc get all NAME READY STATUS RESTARTS AGE pod/nginx-1-xrd78 1/1 Running 0 5m NAME DESIRED CURRENT READY AGE replicationcontroller/nginx-1 1 1 1 5m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/nginx ClusterIP 172.30.150.229 <none> 80/TCP 5m NAME REVISION DESIRED CURRENT TRIGGERED BY deploymentconfig.apps.openshift.io/nginx 1 1 1 config
今度はPodのステータスが「Running」になっているはずです。
しかし、このままではOpenShift内で動作するPodからしかアクセスできません。Podの外部からアクセスするには、Routeを作成します。これはロードバランサやリバースプロキシのような役割を持つリソースです。
$ oc expose svc nginx
できたRouteがどういうURLを公開したかをoc get routeコマンドで確認し、実際にアクセスしてみます。
$ oc get route NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD nginx nginx-my-testproject.192.168.42.254.nip.io nginx 80 None $ curl http://nginx-my-testproject.192.168.42.254.nip.io/ (...) <h1>Welcome to nginx!</h1> (...)
正しくHTMLページが返されているのが分ります。
Podのスケールアウト
OpenShiftおよびそれが内部で使用しているKubernetesが、コンテナのオーケストレーションシステムと呼ばれる所以の一端を見てみましょう。まずはoc scaleコマンドでPodの数を3つに増やしてみます。
$ oc scale dc nginx --replicas=3 $ oc get pod -w (Podの変化をモニタする。Ctrl-Cで終了)
Podがすべて出そろったら、ターミナルを3つ開き、それぞれで「oc logs -f <Pod名>」を実行します。このNginxイメージは、アクセスログを標準出力に表示するようになっています。ブラウザやcurlコマンドでアクセスするたびに、いずれかのPodにアクセスログが出力され、リクエストがロードバランスされるのが分かるはずです。このように複数のPodをまとめ上げて動作させることが簡単にできます。
どんなリソースができたか
oc get allコマンドで出てきたリソースの種類に何があるかを簡単に説明します。
リソース | 短縮名 | 説明 |
---|---|---|
DeploymentConfig | dc | ReplicationControllerを通じて使用するイメージのバージョンを管理する |
ReplicationController | rc | Podが指定された台数(レプリカ数)だけ動くように管理する |
Pod | po | コンテナを動かす。一つのPodに複数のコンテナを配置することも可能 |
Service | svc | 複数のPodを代表するクラスタ内でのみ有効なIPアドレスを提供する |
Route | - | Serviceに対してクラスタ外部からアクセス可能なURLを提供する |
初めのうちは、「DeploymentConfig、ReplicationController、Podの3階層のリソース群でコンテナオーケストレーションを実現している」と理解しておけば十分です。
なお歴史的理由により、OpenShiftではKubernetesとは少し異なるリソースを使っています。お互いにほとんど同じ役割を持つため、違いを気にせねばならないケースは多くはありませんが、対応表を載せておきます。
OpenShift | Kubernetes |
---|---|
DeploymentConfig | Deployment |
ReplicationController | ReplicaSet |
Route | Ingress |
DeploymentなどKubernetesのリソースも通常どおり使用できますので、Kubernetesで使っていたマニフェストファイルをそのまま移行することも可能です。
oc runコマンドの別の使い方
docker runコマンドではコンテナが一つできるだけなのに、oc runコマンドではPodだけでなくDeploymentConfigなどもできて、大掛かりな仕掛けになってしまいました。指定したイメージを使ったPodを一つだけ実行させるといったシンプルな使い方はできないのでしょうか?
実は、--restart=Neverオプションを付けることでそれも可能です。Docker HubのFedoraイメージを対話的に使ってみることで確認してみましょう。
$ oc run fedora -it --image=fedora --restart=Never --command -- bash If you don't see a command prompt, try pressing enter. [root@fedora /]# curl http://nginx/ (...) <h1>Welcome to nginx!</h1> (...) [root@fedora /]# exit
起動したbashの中では特に、「curl http://nginx/」としてサービス名「nginx」を使ってPodにアクセスしています。Routeを使わずにPodにアクセスするには、このように同じOpenShiftのネットワーク環境で動くPodが必要です。
--restartオプションは省略すると「Always」が指定されたとみなされ、その場合はPodを常に起動しておこうと試みるため、DeploymentConfigによる管理が行われるのです。これはNginxのようなサーバプログラムには適切ですが、単にコマンドを実行したいといった場合には大げさです。そこで「Never」を指定してやることで、一回きりのPodが必要であることを伝え、余計なリソースを作成しないようにできます。ちなみに、--restartに指定可能なオプションには他に「OnFailure」がありますが、これを指定した場合はJobというリソースがPodを管理するようになります。
ローカルのイメージの利用
ここまでの例では、Docker Hubでインターネットに公開されているイメージを使ってきました。ここからは、まだどこのレジストリにもプッシュされておらず、自分のローカルマシンにしかないイメージをOpenShiftの内部レジストリにプッシュして、それを使ってみます。
あらかじめ、適当なHTMLファイルをコピーしてある「mynginx」というイメージが、ローカルのDockerにあるとして、これを内部レジストリにプッシュします。
まずは正しい内部レジストリ名とProject名を使って、タグを付けておきます。
$ docker tag mynginx docker-registry-default.example.com/my-testproject/mynginx:latest
上記の例では内部レジストリ名は「docker-registry-default.example.com」になっています。お使いの環境でどうなっているかは、クラスタ管理者にお問い合わせ下さい。内部レジストリは「docker-registry」という名前で「default」プロジェクトに存在しますので、「default」プロジェクトのview権限があるアカウントで下記のコマンドを実行して確認することもできます。
$ oc get route -n default --as=system:admin
正しい名前でタグを付け終わったら、内部レジストリにログインし、docker pushコマンドを実行します。内部レジストリはOpenShiftと統合されているため、認証情報にocコマンドの結果を用いることができます。
$ docker login -u $(oc whoami) -p $(oc whoami -t) docker-registry-default.example.com $ docker push docker-registry-default.example.com/my-testproject/mynginx:latest
これで、指定したイメージ名がOpenShiftのプロジェクトからも使えるようになりました。これまでの例と同様に、oc runコマンドでそのイメージが使えます。加えて、my-testproject内には「mynginx」という名前のImageStream(短縮名はis)もできているはずです。ImageStreamは、より多機能であるoc new-appというコマンドで使うことができます。詳細は後ほど説明しますが、ここでは簡単に使い方だけ見てみます。
$ oc get is NAME DOCKER REPO TAGS UPDATED mynginx docker-registry-default.example.com/my-testproject/mynginx latest 13 minutes ago $ oc new-app mynginx $ oc expose svc mynginx $ oc get route mynginx NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD mynginx mynginx-my-testproject.192.168.42.254.nip.io mynginx 80-tcp None $ curl http://mynginx-my-testproject.192.168.42.254.nip.io/
上記のように、oc new-appに続いてoc expose svcでRouteを作成し、oc get routeでできたRouteを確認してcurlでアクセスするというパターンはこれからも頻出しますので、覚えておくとよいでしょう。
Minishiftでの内部レジストリへのプッシュ
Minishiftの環境では内部レジストリは公開されておらず、そのままではアクセスする手段がありません。しかし、Minishiftの仮想マシン内で動くDockerデーモンと直接通信するための裏技が用意されていますので、それを使います。
まず、プッシュしたいイメージをローカルファイルとして保存しておきます。次にdockerコマンドのための環境変数を定義するMinishiftの裏技を実行して、dockerコマンドの接続先をMinishift内部のものに変更します。このコマンド以降は、ローカルのDockerデーモンにはアクセスできません。あらかじめdocker saveコマンドを実行するのはそのためです。その後docker loadコマンドで新しいDockerデーモンにイメージをロードします。
$ docker save mynginx > mynginx.tar $ source <(minishift docker-env) $ docker load -i mynginx.tar
Dockerデーモンの切り替えを先に行っておき、その後「mynginx」イメージのビルドを行うという方法でも同じ効果を達成できます。
後は通常の場合と同じです。Minishiftの内部レジストリ名は、デフォルトでは「172.30.1.1:5000」となりますが、minishift openshift registryコマンドでプログマラブルに取得することもできます。
$ docker tag mynginx $(minishift openshift registry)/my-testproject/mynginx:latest $ docker login -u $(oc whoami) -p $(oc whoami -t) $(minishift openshift registry) $ docker push $(minishift openshift registry)/my-testproject/mynginx:latest
正しくImageStreamができているか確認してみましょう。
$ oc get is NAME DOCKER REPO TAGS UPDATED mynginx 172.30.1.1:5000/my-testproject/mynginx latest 54 seconds ago
イメージのインポートとImageStream
先の例では、Docker HubのNginxイメージを、Kubernetesと同様のoc runコマンドによって実行してみました。一方、ローカルにあったmynginxイメージを内部リポジトリにプッシュしてから使う例では、できたImageStreamをoc new-appコマンドで利用しました。
実はoc new-appコマンドに直接Dockerイメージを指定して実行することも可能です。ただしImageStreamの名前と誤解されないように、レジストリ名を含んだフルネームを指定する必要があります。
$ oc new-app docker.io/library/nginx
oc runコマンドを使った場合との違いは、ImageStreamも追加で作られる点です。
$ oc get is NAME DOCKER REPO TAGS UPDATED nginx 172.30.1.1:5000/my-testproject/nginx latest About a minute ago
ImageStreamはOpenShiftに固有のリソースで、複数のImageStreamTag(短縮名istag)を内部に持っています。そしてImageStreamTagは、ある特定のDockerイメージに対する間接参照を提供します。タグ名はデフォルトで「latest」になりますので、できたImageStreamTagの詳細を見るには次のように実行します。
$ oc describe istag nginx:latest
DeploymentConfigなどのOpenShiftの他のリソースからイメージを指定する場合は、実際にはこのImageStreamTagが用いられていることが多いです。Gitなどのバージョン管理システムにおけるブランチ名のように、普段は固定の名前を用いて、それが指す具体的なイメージの方を変えていくといった使い方ができます。また、ImageStreamTagが指すDockerイメージの変更をOpenShiftが検知して、それをトリガーに自動でデプロイを開始するといった機能も担っています。
あるDockerイメージを指すImageStreamを、自分の好きな名前で作ることも可能です。今度はDocker HubのApache httpdのイメージを例に使ってみましょう。
$ oc import-image myhttpd --from=docker.io/library/httpd --confirm (インポートしたイメージに関する説明) $ oc get is NAME DOCKER REPO TAGS UPDATED myhttpd 172.30.1.1:5000/my-testproject/myhttpd latest About a minute ago
実行後にインポートしたイメージに関する説明が表示されますが、これはoc describe istag myhttpd:latestで表示されるものと同じです。上記の例ではインポート時にタグ名を省略したので、デフォルトの「latest」が使われました。インポートできたら、以降の流れは前と同じです。
$ oc new-app myhttpd $ oc expose svc myhttpd $ oc get route myhttpd NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD myhttpd myhttpd-my-testproject.192.168.42.254.nip.io myhttpd 80-tcp None $ curl http://myhttpd-my-testproject.192.168.42.254.nip.io/ <html><body><h1>It works!</h1></body></html>
OpenShiftでのDockerビルド
これまでにインターネットに公開されているイメージを使う方法と、ローカルにある既存のイメージを使う方法を見てきました。次はDockerを(直接的には)使わず、OpenShiftだけでDockerイメージのビルドを行ってみます。
適当な作業用のディレクトリに、下記の内容でDockerfileとindex.htmlの2つのファイルがあるとします。
$ ls -l total 8 -rw-r--r--. 1 onagano onagano 49 Dec 11 11:45 Dockerfile -rw-r--r--. 1 onagano onagano 82 Dec 11 11:47 index.html $ cat Dockerfile FROM nginx COPY index.html /usr/share/nginx/html $ cat index.html <head> <title>Test Page</title> </head> <body> <h1>Test Page</h1> </body>
ローカルにあるファイルをCOPYインストラクションで利用しています。OpenShiftでこうしたDockerビルドを行うには、「バイナリービルド」と呼ばれる手順を実行します。具体的にはまずoc new-buildコマンドでBuildConfigを作成し、次にoc start-buildコマンドでビルドを開始するという、2段階の操作が必要です。
$ oc new-build --name=mynginx --strategy=docker --binary $ oc start-build mynginx --from-dir=. --follow (...) Push successful
上記のコマンドのオプションについて説明しておきましょう。oc new-buildコマンドの--strategyオプションで、Dockerビルドであることを明示しています。そして--binaryオプションで、これがローカルファイルを使用するバイナリービルドであることを指示しています。そしてそのローカルファイルがOpenShiftクラスタからも見えるように、oc start-buildコマンドの--from-dirオプションで場所を指定しています。
ビルドの成果物として「mynginx」という名前のImageStreamができますので、あとはそれをoc new-app mynginxのように実行するだけです。
OpenShiftが提供するイメージの利用
Nginxイメージを例に、Docker Hubにあるイメージでもroot権限を要求する危険なものも含まれていること、およびそれを回避するanyuidのSCC付与も望ましくないことを先に説明しました。ではどのようなイメージを使えばいいのでしょうか?
答えは「セキュリティを考慮して作られたイメージ(およびそれを参照するImageStream)」です。そのようなイメージは「openshift」プロジェクト内に用意されていますので、そこから目ぼしいものを選んで使えばよいのです。「openshift」プロジェクトは、デフォルトですべてのユーザにview権限が与えられていますので、-nオプションで名前空間を指定してoc getコマンドやoc describeコマンドで詳しく調べることができます。
$ oc get is -n openshift # ImageStreamの一覧を表示させる $ oc describe is nginx -n openshift # ImageStream "nginx"の詳細を表示させる
上記のコマンドでは、「nginx」と名付けられたImageStreamの詳細も表示させています。その詳細をよく見てみると、「1.12」や「1.10」のように複数のImageStreamTagがあるのが分ります。個別のImageStreamについて調べたければ、「nginx:1.12」のようにコロンの後にタグ名を付けて、詳細を確認できます。ImageStreamTagの詳細の出力量はかなり多いですが、ここでは「Docker Labels」のセクションに表示されている下記の2つのラベルに注目してみます。
io.openshift.tags=builder,nginx,rh-nginx112<br/> io.openshift.s2i.scripts-url=image:///usr/libexec/s2i
これらのラベルは、このイメージが普通とは異なるS2I(Source to Image)のビルダーイメージであることを表明しています。そしてこうしたビルダーイメージは、oc runコマンドでの利用は想定されておらず、代わりにoc new-appコマンドでのS2Iビルドを想定して作られているのです。
S2Iビルドの説明はのちのセクションに譲るとして、ここでは使い方を見てみましょう。oc new-appコマンドの主なオプションとして、「~」を挟んだ下記の書式が用いられます。
<S2Iのビルダーイメージ名>~<ソースコードの場所>
今回の例では 「<S2Iのビルダーイメージ名>」が「nginx」、「<ソースコードの場所>」が「https://github.com/sclorg/nginx-container」です。NginxはWebサーバですので、この場合ソースコードはHTMLファイル群を意味します。このURLで示されたGitリポジトリを見てみると、ディレクトリ「examples/1.12/test-app」内にテストにちょうど良いHTMLファイル群が見つかります。--context-dirオプションでそのディレクトリを指定して、このS2Iビルドのソースとして使うよう指示しています。
まとめると下記のような実行例になります。
$ oc new-app --name=mysite nginx~https://github.com/sclorg/nginx-container --context-dir=examples/1.12/test-app $ oc expose svc mysite $ oc get route mysite NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD mysite mysite-my-testproject.192.168.42.254.nip.io mysite 8080-tcp None $ curl http://mysite-my-testproject.192.168.42.254.nip.io/ <html> <head> <title>Test NGINX passed</title> </head> <body> <h1>NGINX is working</h1> </body> </html>
以上の操作だけでNginxに指定したHTMLファイル群が入ったDockerイメージができ、それを参照するImageStreamもできるのです。
GitHubで別のHTMLファイル群を見つけたなら、それをソースにしてS2Iビルドを行ってみるのもいいでしょう。しかしS2Iビルドの本領は、プログラミング言語のビルダーイメージを使った際に発揮されます。次のセクションでは本格的なプログラミング言語のS2Iビルドの例としてJavaのビルダーイメージを使ってみます。
本稿では詳しく触れることはできませんが、openshiftプロジェクトにはImageStreamだけでなく多数のTemplateも登録されています。Templateは、複数のリソースの定義をパラメタ化して、あるソフトウェアスタックを一気に作り出すことができるリソースです。「oc get template -n openshift」を実行し、興味のあるリソースについて「oc describe template」コマンド実行して詳細を確認してみて下さい。openshiftプロジェクトにある多数のImageStreamやTemplateは、「oc new-app -S」コマンドで検索をかけることも可能です。
なお、これまでの作業で作成されたリソースは、下記のコマンドでプロジェクトごと消してかまいません。
$ oc delete project my-testproject