OpenShiftの基本的なソースからのビルドとデプロイでアプリケーションを動かす
OpenShift 全部俺 Advent Calendar 2017
minishiftで環境ができたので、アプリケーションをビルドして動作させてみましょう。使うのはソースからコンテナイメージをビルドするs2i (source to image)と呼ばれるビルド方式です。
初期状態ではdeveloperユーザ、myprojectというプロジェクトとなっています。この情報は~/.kube/configファイルに格納されています。
$ oc whoami developer $ oc status In project My Project (myproject) on server https://192.168.42.225:8443 You have no services, deployment configs, or build configs. Run 'oc new-app' to create an application.
myprojectみたいなデフォルトのものを使うのは後から使い分けしようとしたときに困ることが多く、あまり好きではないので、別ユーザ別プロジェクトを作成します。
nekopというユーザ、アプリケーションはRubyのものを使いますので、test-rubyというプロジェクトを作成します。minishiftではAllowAllという認証設定がされているので、ユーザ名は任意、パスワードに空文字以外で全て通るようになっています。
$ oc login -u nekop
Authentication required for https://192.168.42.225:8443 (openshift)
Username: nekop
Password:
Login successful.
You don't have any projects. You can try to create a new project, by running
oc new-project <projectname>
$ oc new-project test-ruby
Now using project "test-ruby" on server "https://192.168.42.225:8443".
You can add applications to this project with the 'new-app' command. For example, try:
oc new-app centos/ruby-22-centos7~https://github.com/openshift/ruby-ex.git
to build a new example application in Ruby.
アプリケーションのソースコードを指定してoc new-appを発行します。SinatraというRubyのWebフレームワークで書いたHello Worldのアプリ https://github.com/nekop/hello-sinatra を指定しています。
$ oc new-app https://github.com/nekop/hello-sinatra
--> Found image a6f8569 (10 days old) in image stream "openshift/ruby" under tag "2.4" for "ruby"
Ruby 2.4
--------
Ruby 2.4 available as docker container is a base platform for building and running various Ruby 2.4 applications and frameworks. Ruby is the interpreted scripting language for quick and easy object-oriented programming. It has many features to process text files and to do system management tasks (as in Perl). It is simple, straight-forward, and extensible.
Tags: builder, ruby, ruby24, rh-ruby24
* The source repository appears to match: ruby
* A source build using source code from https://github.com/nekop/hello-sinatra will be created
* The resulting image will be pushed to image stream "hello-sinatra:latest"
* Use 'start-build' to trigger a new build
* This image will be deployed in deployment config "hello-sinatra"
* Port 8080/tcp will be load balanced by service "hello-sinatra"
* Other containers can access this service through the hostname "hello-sinatra"
--> Creating resources ...
imagestream "hello-sinatra" created
buildconfig "hello-sinatra" created
deploymentconfig "hello-sinatra" created
service "hello-sinatra" created
--> Success
Build scheduled, use 'oc logs -f bc/hello-sinatra' to track its progress.
Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
'oc expose svc/hello-sinatra'
Run 'oc status' to view your app.
openshift/ruby:2.4というイメージを利用してアプリケーションがビルドされています。
状況を確認するコマンドはいろいろあります。oc status, oc get all, oc logs, oc get eventなどです。細かい説明は後日やります。たぶん。
$ oc status
In project test-ruby on server https://192.168.42.225:8443
svc/hello-sinatra - 172.30.168.102:8080
dc/hello-sinatra deploys istag/hello-sinatra:latest <-
bc/hello-sinatra source builds https://github.com/nekop/hello-sinatra on openshift/ruby:2.4
build #1 running for 22 seconds - cf28c79: Add index.html (Takayoshi Kimura <takayoshi@gmail.com>)
deployment #1 waiting on image or update
View details with 'oc describe <resource>/<name>' or list everything with 'oc get all'.
$ oc get all
NAME TYPE FROM LATEST
buildconfigs/hello-sinatra Source Git 1
NAME TYPE FROM STATUS STARTED DURATION
builds/hello-sinatra-1 Source Git@cf28c79 Running 48 seconds ago
NAME DOCKER REPO TAGS UPDATED
imagestreams/hello-sinatra 172.30.1.1:5000/test-ruby/hello-sinatra
NAME REVISION DESIRED CURRENT TRIGGERED BY
deploymentconfigs/hello-sinatra 0 1 0 config,image(hello-sinatra:latest)
NAME READY STATUS RESTARTS AGE
po/hello-sinatra-1-build 1/1 Running 0 48s
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/hello-sinatra 172.30.168.102 <none> 8080/TCP 48s
$ oc logs hello-sinatra-1-build -f
---> Installing application source ...
---> Building your Ruby application from source ...
---> Running 'bundle install --deployment --without development:test' ...
Fetching gem metadata from https://rubygems.org/.........
Fetching version metadata from https://rubygems.org/.
Installing rake 11.1.2
Installing power_assert 0.2.7
Installing rack 1.6.4
Installing tilt 2.0.2
Using bundler 1.13.7
Installing test-unit 3.1.8
Installing rack-protection 1.5.3
Installing rack-test 0.6.3
Installing sinatra 1.4.7
Bundle complete! 4 Gemfile dependencies, 9 gems now installed.
Gems in the groups development and test were not installed.
Bundled gems are installed into ./bundle.
---> Cleaning up unused ruby gems ...
Running `bundle clean --verbose` with bundler 1.13.7
Found no changes, using resolution from the lockfile
/opt/app-root/src/bundle/ruby/2.4.0/gems/rake-11.1.2/lib/rake/ext/fixnum.rb:4: warning: constant ::Fixnum is deprecated
Pushing image 172.30.1.1:5000/test-ruby/hello-sinatra:latest ...
Pushed 0/10 layers, 0% complete
Pushed 1/10 layers, 14% complete
Pushed 2/10 layers, 25% complete
Pushed 3/10 layers, 31% complete
Pushed 4/10 layers, 43% complete
Pushed 5/10 layers, 53% complete
Pushed 6/10 layers, 65% complete
Pushed 7/10 layers, 75% complete
Pushed 8/10 layers, 84% complete
Pushed 9/10 layers, 99% complete
Pushed 10/10 layers, 100% complete
Push successful
$ oc get event
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE
2m 2m 1 hello-sinatra-1-build Pod Normal Scheduled default-scheduler Successfully assigned hello-sinatra-1-build to localhost
2m 2m 1 hello-sinatra-1-build Pod Normal SuccessfulMountVolume kubelet, localhost MountVolume.SetUp succeeded for volume "crio-socket"
2m 2m 1 hello-sinatra-1-build Pod Normal SuccessfulMountVolume kubelet, localhost MountVolume.SetUp succeeded for volume "buildworkdir"
2m 2m 1 hello-sinatra-1-build Pod Normal SuccessfulMountVolume kubelet, localhost MountVolume.SetUp succeeded for volume "docker-socket"
2m 2m 1 hello-sinatra-1-build Pod Normal SuccessfulMountVolume kubelet, localhost MountVolume.SetUp succeeded for volume "builder-dockercfg-2g5jw-push"
2m 2m 1 hello-sinatra-1-build Pod Normal SuccessfulMountVolume kubelet, localhost MountVolume.SetUp succeeded for volume "builder-token-q8h4n"
2m 2m 1 hello-sinatra-1-build Pod spec.initContainers{git-clone} Normal Pulling kubelet, localhost pulling image "openshift/origin-sti-builder:v3.7.0"
2m 2m 1 hello-sinatra-1-build Pod spec.initContainers{git-clone} Normal Pulled kubelet, localhost Successfully pulled image "openshift/origin-sti-builder:v3.7.0"
2m 2m 1 hello-sinatra-1-build Pod spec.initContainers{git-clone} Normal Created kubelet, localhost Created container
2m 2m 1 hello-sinatra-1-build Pod spec.initContainers{git-clone} Normal Started kubelet, localhost Started container
2m 2m 1 hello-sinatra-1-build Pod spec.initContainers{manage-dockerfile} Normal Pulled kubelet, localhost Container image "openshift/origin-sti-builder:v3.7.0" already present on machine
2m 2m 1 hello-sinatra-1-build Pod spec.initContainers{manage-dockerfile} Normal Created kubelet, localhost Created container
2m 2m 1 hello-sinatra-1-build Pod spec.initContainers{manage-dockerfile} Normal Started kubelet, localhost Started container
2m 2m 1 hello-sinatra-1-build Pod spec.containers{sti-build} Normal Pulled kubelet, localhost Container image "openshift/origin-sti-builder:v3.7.0" already present on machine
2m 2m 1 hello-sinatra-1-build Pod spec.containers{sti-build} Normal Created kubelet, localhost Created container
2m 2m 1 hello-sinatra-1-build Pod spec.containers{sti-build} Normal Started kubelet, localhost Started container
1m 1m 1 hello-sinatra-1-deploy Pod Normal Scheduled default-scheduler Successfully assigned hello-sinatra-1-deploy to localhost
1m 1m 1 hello-sinatra-1-deploy Pod Normal SuccessfulMountVolume kubelet, localhost MountVolume.SetUp succeeded for volume "deployer-token-82bmt"
1m 1m 1 hello-sinatra-1-deploy Pod spec.containers{deployment} Normal Pulled kubelet, localhost Container image "openshift/origin-deployer:v3.7.0" already present on machine
1m 1m 1 hello-sinatra-1-deploy Pod spec.containers{deployment} Normal Created kubelet, localhost Created container
1m 1m 1 hello-sinatra-1-deploy Pod spec.containers{deployment} Normal Started kubelet, localhost Started container
1m 1m 1 hello-sinatra-1-deploy Pod spec.containers{deployment} Normal Killing kubelet, localhost Killing container with id docker://deployment:Need to kill Pod
1m 1m 1 hello-sinatra-1-jxqm5 Pod Normal Scheduled default-scheduler Successfully assigned hello-sinatra-1-jxqm5 to localhost
1m 1m 1 hello-sinatra-1-jxqm5 Pod Normal SuccessfulMountVolume kubelet, localhost MountVolume.SetUp succeeded for volume "default-token-fhb4l"
1m 1m 1 hello-sinatra-1-jxqm5 Pod spec.containers{hello-sinatra} Normal Pulling kubelet, localhost pulling image "172.30.1.1:5000/test-ruby/hello-sinatra@sha256:623df61eea9fb550df241a2cd8e909b44fd2fb69a4d82298f7221f5c92488167"
1m 1m 1 hello-sinatra-1-jxqm5 Pod spec.containers{hello-sinatra} Normal Pulled kubelet, localhost Successfully pulled image "172.30.1.1:5000/test-ruby/hello-sinatra@sha256:623df61eea9fb550df241a2cd8e909b44fd2fb69a4d82298f7221f5c92488167"
1m 1m 1 hello-sinatra-1-jxqm5 Pod spec.containers{hello-sinatra} Normal Created kubelet, localhost Created container
1m 1m 1 hello-sinatra-1-jxqm5 Pod spec.containers{hello-sinatra} Normal Started kubelet, localhost Started container
2m 2m 1 hello-sinatra-1 Build Normal BuildStarted build-controller Build test-ruby/hello-sinatra-1 is now running
1m 1m 1 hello-sinatra-1 Build Normal BuildCompleted build-controller Build test-ruby/hello-sinatra-1 completed successfully
1m 1m 1 hello-sinatra-1 ReplicationController Normal SuccessfulCreate replication-controller Created pod: hello-sinatra-1-jxqm5
2m 2m 1 hello-sinatra BuildConfig Warning BuildConfigTriggerFailed buildconfig-controller error triggering Build for BuildConfig test-ruby/hello-sinatra: Internal error occurred: build config test-ruby/hello-sinatra has already instantiated a build for imageid centos/ruby-24-centos7@sha256:905b51254a455c716892314ef3a029a4b9a4b1e832a9a1518783577f115956fd
1m 1m 1 hello-sinatra DeploymentConfig Normal DeploymentCreated deploymentconfig-controller Created new replication controller "hello-sinatra-1" for version 1
$ oc get pod
NAME READY STATUS RESTARTS AGE
hello-sinatra-1-build 0/1 Completed 0 1m
hello-sinatra-1-jxqm5 1/1 Running 0 25s
最後の出力を見るとアプリケーションのpodがRunningになっているので正常にデプロイされているようです。
oc new-appコマンドでは外部アクセス用のRouteは自動的に作成されないので、作成してアクセスしてみます。
$ oc expose svc hello-sinatra route "hello-sinatra" exposed $ oc get route NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD hello-sinatra hello-sinatra-test-ruby.192.168.42.225.nip.io hello-sinatra 8080-tcp None $ curl hello-sinatra-test-ruby.192.168.42.225.nip.io curl: (6) Could not resolve host: hello-sinatra-test-ruby.192.168.42.225.nip.io
あれれ、エラーになりましたね。どうやらminishiftがデフォルトで利用するDNSサービスの nip.io が落ちているようです。とりあえずは同種のサービスである xip.io に変更してみましょう。
$ oc delete route hello-sinatra route "hello-sinatra" deleted $ oc expose svc hello-sinatra --hostname hello-sinatra-test-ruby.192.168.42.225.xip.io route "hello-sinatra" exposed $ oc get route NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD hello-sinatra hello-sinatra-test-ruby.192.168.42.225.xip.io hello-sinatra 8080-tcp None $ curl hello-sinatra-test-ruby.192.168.42.225.xip.io hello
きちんとアプリケーションからhelloが返却されました。
一連の操作はWebコンソール上のGUIでも可能です。minishift consoleコマンドでブラウザ上でWebコンソールが開くようになっています。