LoginSignup
5
2

More than 3 years have passed since last update.

GoのカスタムS2Iイメージを作ってS2Iビルドしてみる

Posted at

OpenShiftのSource to Imageの理解のため、GoのカスタムS2Iイメージを作成し、Minishiftで動かしてみたメモ。

Minishiftを動かすまでは以下を参考。

コンポーネント バージョン
Minishift v1.34.1+c2ff9cb
OpenShift v3.11.0
s2i v1.1.14-dirty

準備

Minishiftを起動しておく。

minishift start

s2iコマンドをインストールしておく。

brew install source-to-image

S2Iビルダーイメージの作成

s2iコマンドで雛形を作成する。

s2i create custom-go-s2i custom-go-s2i

作成されたファイルを確認。

$ tree -a custom-go-s2i
custom-go-s2i
├── Dockerfile
├── Makefile
├── README.md
├── s2i
│   └── bin
│       ├── assemble
│       ├── run
│       ├── save-artifacts
│       └── usage
└── test
    ├── run
    └── test-app
        └── index.html

4 directories, 9 files
$

assemblerunを編集する。usageはそのまま使う。save-artifactsは今回は使わないので削除する。

ファイル 説明
assemble ソースからアプリをビルドして適切な場所に配置する。
run DockerfileのCMDとして実行される。
save-artifacts キャッシュを使ってビルドを早くしたいときに使う。
usage イメージの使い方の説明を書く。
assemble
#!/bin/bash -e

# If the 'custom-go-s2i' assemble script is executed with the '-h' flag, print the usage.
if [[ "$1" == "-h" ]]; then
    exec /usr/libexec/s2i/usage
fi

echo "---> Installing application source..."
cp -Rf /tmp/src/. /opt/app-root/

echo "---> Building application from source..."
XDG_CACHE_HOME=/tmp/.cache go build app.go
run
#!/bin/bash -e

exec /opt/app-root/app
usage
#!/bin/bash -e
cat <<EOF
This is the custom-go-s2i S2I image:
To use it, install S2I: https://github.com/openshift/source-to-image

Sample invocation:

s2i build <source code path/URL> custom-go-s2i <application image>

You can then run the resulting image via:
docker run <application image>
EOF

Dockerfileを編集する。ベースイメージはRed Hat Container Catalogから取得するのが望ましいと思われるが、今回はDockerHubのものを使う。

Dockerfile
FROM golang:1.12

LABEL maintainer="Your Name <your@email.com>"

LABEL io.k8s.description="A Go S2I builder image" \
      io.k8s.display-name="Go S2I builder image" \
      io.openshift.expose-services="8080:http" \
      io.openshift.s2i.scripts-ulr="image:///usr/libexec/s2i" \
      io.openshift.tags="builder, go, golang"

ENV APP_ROOT /opt/app-root

COPY ./s2i/bin/ /usr/libexec/s2i

RUN mkdir -p ${APP_ROOT} && \
    chown -R 1001:1001 ${APP_ROOT} && \
    chgrp -R 0 ${APP_ROOT} && \
    chmod -R g=u ${APP_ROOT}

USER 1001

EXPOSE 8080

WORKDIR ${APP_ROOT}}

CMD ["/usr/libexec/s2i/usage"]

ビルドする。

cd custom-go-s2i
docker build -t custom-go-s2i:1.12 .
$ docker build -t custom-go-s2i:1.12 .
Sending build context to Docker daemon  22.53kB
Step 1/10 : FROM golang:1.12
 ---> 80bb9c6de3f2
Step 2/10 : LABEL maintainer="Your Name <your@email.com>"
 ---> Using cache
 ---> 613e6931e678
Step 3/10 : LABEL io.k8s.description="A Go S2I builder image"       io.k8s.display-name="Go S2I builder image"       io.openshift.expose-services="8080:http"       io.openshift.s2i.scripts-url="image:///usr/libexec/s2i"       io.openshift.tags="builder, go, golang"
 ---> Using cache
 ---> 5abe1287a367
Step 4/10 : ENV APP_ROOT /opt/app-root
 ---> Using cache
 ---> 03d0dac2e9d6
Step 5/10 : COPY ./s2i/bin/ /usr/libexec/s2i
 ---> Using cache
 ---> 4d0267aa8319
Step 6/10 : RUN mkdir -p ${APP_ROOT} &&     chown -R 1001:1001 ${APP_ROOT} &&     chgrp -R 0 ${APP_ROOT} &&     chmod -R g=u ${APP_ROOT}
 ---> Using cache
 ---> 21c9c19cb0ad
Step 7/10 : USER 1001
 ---> Using cache
 ---> 3364c5ab36b3
Step 8/10 : EXPOSE 8080
 ---> Using cache
 ---> c07ab7cf6395
Step 9/10 : WORKDIR ${APP_ROOT}
 ---> Using cache
 ---> 8fe5f15618e5
Step 10/10 : CMD ["/usr/libexec/s2i/usage"]
 ---> Using cache
 ---> e41359221ed9
Successfully built e41359221ed9
Successfully tagged custom-go-s2i:1.12
$
$ docker images custom-go-s2i
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
custom-go-s2i       1.12                e41359221ed9        4 minutes ago       814MB
$

ビルダーイメージの動作確認

GoのWebサーバーのコードを書く。

app.go
package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Hello World")
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

ローカルでビルダーイメージとコードを統合してイメージを作成してみる。

s2i build test/test-app/ custom-go-s2i:1.12 custom-go-app
$ s2i build test/test-app/ custom-go-s2i:1.12 custom-go-app
---> Installing application source...
---> Building application from source...
Build completed successfully
$

作成されたイメージを確認。

$ docker images custom-go-app
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
custom-go-app       latest              ef6d1ee144fd        9 seconds ago       821MB
$

ローカルで実行してアクセス確認。OpenShiftでは適当なUIDが割り振られて実行されるため、適当なUIDで実行する。

$ docker run --rm -it -d --name go-test -u 1234 -p 8080:8080 custom-go-app
4370e075cdd1b448f0b23afb6b2436e5ca396db521aa59d9fcbb9904d6481cce
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
4370e075cdd1        custom-go-app       "/usr/libexec/s2i/run"   8 seconds ago       Up 7 seconds        0.0.0.0:8080->8080/tcp   go-test
$ curl http://localhost:8080
Hello World
$

Minishiftへの登録

Minishiftのocコマンドへパスを通す。

eval $(minishift oc-env)

developerでログインしていることを確認。ログインしていなければログイン。

oc whoami
oc login -u developer

プロジェクトを作成。

oc new-project custom-go

Minishiftでは内部レジストリーが公開されていないが、その場合にイメージを登録する方法は以下の記事が分かりやすい。Minishift内部のDockerエンジンからなら内部レジストリーに接続できる。

一旦イメージをファイルに保存する。

docker save custom-go-s2i:1.12 -o custom-go-s2i.tar

dockerコマンドの向き先をMinishift内のDockerエンジンに向ける。

eval $(minishift docker-env)

ファイルに保存しておいたイメージをロード。

docker load -i custom-go-s2i.tar

タグ付けしてMinishiftの内部レジストリーにプッシュ。

docker tag custom-go-s2i:1.12 $(minishift openshift registry)/custom-go/custom-go-s2i:1.12
docker login -u $(oc whoami) -p $(oc whoami -t) $(minishift openshift registry)
docker push $(minishift openshift registry)/custom-go/custom-go-s2i:1.12

ImageStreamが登録されたことを確認する。

$ oc get is
NAME            DOCKER REPO                               TAGS      UPDATED
custom-go-s2i   172.30.1.1:5000/custom-go/custom-go-s2i   1.12      18 seconds ago
$

dockerコマンドの向き先を戻しておく。

unset DOCKER_TLS_VERIFY
unset DOCKER_HOST
unset DOCKER_CERT_PATH

S2Iでのアプリのデプロイ

GoのWebアプリのソースコードのGitHubリポジトリーを作成する。

アプリをデプロイ。

コマンド
oc new-app --name=hello custom-go-s2i:1.12~https://github.com/sotoiwa/go-sample
実行ログ
$ oc new-app --name=hello custom-go-s2i:1.12~https://github.com/sotoiwa/go-sample
--> Found image e413592 (About an hour old) in image stream "custom-go/custom-go-s2i" under tag "1.12" for "custom-go-s2i:1.12"

    Go S2I builder image
    --------------------
    A Go S2I builder image

    Tags: builder,  go,  golang

    * A source build using source code from https://github.com/sotoiwa/go-sample will be created
      * The resulting image will be pushed to image stream tag "hello:latest"
      * Use 'start-build' to trigger a new build
    * This image will be deployed in deployment config "hello"
    * Port 8080/tcp will be load balanced by service "hello"
      * Other containers can access this service through the hostname "hello"

--> Creating resources ...
    imagestream.image.openshift.io "hello" created
    buildconfig.build.openshift.io "hello" created
    deploymentconfig.apps.openshift.io "hello" created
    service "hello" created
--> Success
    Build scheduled, use 'oc logs -f bc/hello' 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'
    Run 'oc status' to view your app.
$

アプリが動き出したことを確認。

$ oc get po
NAME            READY     STATUS      RESTARTS   AGE
hello-1-build   0/1       Completed   0          1m
hello-1-xfkzb   1/1       Running     0          56s
$

アプリを外部公開。

oc expose svc hello --hostname hello.example.com

アクセス確認。

curl -H "Host: hello.example.com" http://$(minishift ip)
$ curl -H "Host: hello.example.com" http://$(minishift ip)
Hello World!!
$
5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2