LoginSignup
0
2

More than 5 years have passed since last update.

IBM Cloud を利用した Go言語のアプリ開発入門(その4)

Last updated at Posted at 2018-01-18

Go言語の初心者として今回は、Go言語のアプリを IBM Cloud コンテナサービス すなわち Kubernetes(以下 k8s) のクラスタにデプロイするまでを考えます。順番としては、DockerコンテナをビルドするためのDockerファイルの開発、そして、ローカルのDocker環境でのテスト、それから、k8sへデプロイするためコンテナレジストリへの登録、そして、k8sへのデプロイの流れになります。

Cloud Foundry の手軽さからすると、k8s へのデプロイは面倒な感じがしますね。 Dockerコンテナをそのままデプロイできる処は素晴らしいですが、もっと、自動化したいものですが、今期は手作業で進めます。

Go言語アプリは、以下の3つのリポジトリから構成されるもので、一番目のリポジトリから、2番目を依存パッケージとして、3番目は2番目の依存パッケージとして構成しています。

  1. ウェブコンテンツ、各種定義ファイル https://github.com/takara9/go_webpages
  2. Go言語で書いたシンプルなWebサーバー https://github.com/takara9/go_webserver2
  3. Go言語の共通モジュール https://github.com/takara9/go_util

上記の1番目のリポジトリの内容は、参考資料の3を参照してください。

手打ちでDockerコンテナをビルドして、Dockerfileに必要な材料を確認

その3で作成した リポジトリ https://github.com/takara9/go_webpages から、Go言語で書いたウェブサーバーのコンテナをビルドして、動作させるまでの、作業手順を試行錯誤で作ったものが、以下になります。 パッケージ・マネージャーのgodep restoreで前提パッケージを集めて、go installでビルドして、実行という流れです。

$ docker run -it golang bash
root@5d68e424048f:/go# echo $GOPATH
/go
rm -fr go
cd /
git clone https://github.com/takara9/go_webpages --recursive go
cd /go
go get github.com/tools/godep
godep restore
go install github.com/takara9/go_webserver2
bin/go_webserver2 

コンテナ内でサーバーgo_webserver2を起動

手打ちで実行した go_webserver2が正しく動作しているか確認します。 ビルドでは、対話モードでコンテナに入って作業していたので、上記の稼働中のコンテナに別のターミナルから入って、curlコマンドでアクセスしてテストします。

以下は、上記と同じコンテナに入った処です。 go_webserver2が動作しているのが確認できます。

$ docker exec -it 4707e89a7800 bash
root@4707e89a7800:/go# ps -ax
  PID TTY      STAT   TIME COMMAND
    1 pts/0    Ss     0:00 bash
  509 pts/0    Sl+    0:00 bin/go_webserver2
  512 pts/1    Ss     0:00 bash
  516 pts/1    R+     0:00 ps -ax

同じコンテナに入ってcurlのアクセス・テスト

curlの実行結果です。 確かにHTMLコンテンツを送出している事が確認したできました。

root@4707e89a7800:/go# curl http://localhost:4040/
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Go言語で作ったウェブサーバー</title>
<meta charset="utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<H1>質問#1</H1>
<p>歌詞などで表現される「時計仕掛けの夜」とはなんだろう?</p>
<br>
<img src="gopher.png">
<br>
<a href="test_doc_1.html">答えページへ進む</a>


</body>
</html>

コンテナをビルドして、ローカルでテスト

Dockerfileの作成

上記の手打ちの結果をもとに、Dockerfileを作成したのが、以下のファイルです。

FROM golang:1.9.2

RUN rm -fr $GOPATH
RUN git clone https://github.com/takara9/go_webpages --recursive $GOPATH
WORKDIR $GOPATH
RUN go get github.com/tools/godep
RUN godep restore
RUN go install github.com/takara9/go_webserver2

EXPOSE 4040
ENTRYPOINT ["bin/go_webserver2"]

ビルドの実行

上記のDockerfileを利用してローカルのMacの環境で、コンテナをビルドして、テストします。

vagrant@vagrant-ubuntu-trusty-64:~/go/go_webpages$ docker build -t go_webserver .
Sending build context to Docker daemon  423.9kB
Step 1/9 : FROM golang:1.9.2
 ---> 138bd936fa29
Step 2/9 : RUN rm -fr $GOPATH
 ---> Running in 68a725444541
 ---> fb59c95a1e5f
Removing intermediate container 68a725444541
Step 3/9 : RUN git clone https://github.com/takara9/go_webpages --recursive $GOPATH
 ---> Running in 2b5f79923ce9
Cloning into '/go'...
Submodule 'vendor/github.com/takara9/go_util' (https://github.com/takara9/go_util.git) registered for path 'vendor/github.com/takara9/go_util'
Submodule 'vendor/github.com/takara9/go_webserver2' (https://github.com/takara9/go_webserver2.git) registered for path 'vendor/github.com/takara9/go_webserver2'
Cloning into '/go/vendor/github.com/takara9/go_util'...
Cloning into '/go/vendor/github.com/takara9/go_webserver2'...
Submodule path 'vendor/github.com/takara9/go_util': checked out '38ff0221e206b57cd7ea242e4f1238fb8f613b8a'
Submodule path 'vendor/github.com/takara9/go_webserver2': checked out '25d39c2700995e71dbb9a3b9c80891cec437ffd5'
 ---> 756ad9a01728
Removing intermediate container 2b5f79923ce9
Step 4/9 : WORKDIR $GOPATH
 ---> eccea02c8da2
Removing intermediate container f1d8e8634a95
Step 5/9 : RUN go get github.com/tools/godep
 ---> Running in 0dc09366ed94
 ---> b1d4f2e4c65d
Removing intermediate container 0dc09366ed94
Step 6/9 : RUN godep restore
 ---> Running in 4f048faa37a3
godep: [WARNING]: godep should only be used inside a valid go package directory and
godep: [WARNING]: may not function correctly. You are probably outside of your $GOPATH.
godep: [WARNING]:   Current Directory: /go
godep: [WARNING]:   $GOPATH: /go
 ---> 29ee74bb965b
Removing intermediate container 4f048faa37a3
Step 7/9 : RUN go install github.com/takara9/go_webserver2
 ---> Running in dd5fbd7202ef
 ---> 4ad3472126d3
Removing intermediate container dd5fbd7202ef
Step 8/9 : EXPOSE 4040
 ---> Running in d556fe610c0c
 ---> 4cf9d6904ea9
Removing intermediate container d556fe610c0c
Step 9/9 : ENTRYPOINT bin/go_webserver2
 ---> Running in 48123c88fc70
 ---> a9b6339a9a56
Removing intermediate container 48123c88fc70
Successfully built a9b6339a9a56
Successfully tagged go_webserver:latest

コンテナ・イメージができていることを確認

vagrant@vagrant-ubuntu-trusty-64:~/go/go_webpages$ docker images
REPOSITORY     TAG     IMAGE ID            CREATED             SIZE
go_webserver   latest  a9b6339a9a56        7 seconds ago       751MB

コンテナのテスト

コンテナをデーモンとして起動

vagrant@vagrant-ubuntu-trusty-64:~/go/go_webpages$ docker run -d -p 8080:4040 go_webserver
568cdb58537aa9947821ab2ca2faa3ea4cb76101481f44a2d259644bf456c7cc

curlでのアクセステストで、HTMLコンテンツの応答がきたので、テスト完了です。

vagrant@vagrant-ubuntu-trusty-64:~/go/go_webpages$ curl http://localhost:8080/
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Go言語で作ったウェブサーバー</title>
<meta charset="utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<H1>質問#1</H1>
<p>歌詞などで表現される「時計仕掛けの夜」とはなんだろう?</p>
<br>
<img src="gopher.png">
<br>
<a href="test_doc_1.html">答えページへ進む</a>

k8sのコンテナ・レジストリへ登録

コンテナをK8sクラスタへデプロイするために、IBM Cloud レジストリサービスへコンテナを登録します。
東京DCのk8sクラスタを利用するために、ap-southのレジストリを利用します。 ネームスペースは既に作成しておいた takara を利用します。
ローカルのコンテナ・レジストリにタグを付けて、リモート・レジストリへプッシュする流れです。

$ bx cr region-set ap-south
$ bx cr login
$ bx cr namespace-list
<中略>
Namespace   
takara   

$ docker tag go_webserver:latest registry.au-syd.bluemix.net/takara/go_webserver:v1
$ docker push registry.au-syd.bluemix.net/takara/go_webserver:v1

リモート・レジストリ、すなわち、IBM Cloudのレジストリ・サービスに登録された事がわかります。 このレジストリは、プライベートなので、失敗した場合は、bx cr login を確認してください。

$ bx cr images
<中略>
NAMESPACE   TAG   DIGEST         CREATED         SIZE     VULNERABILITY STATUS   
registry.au-syd.bluemix.net/takara/go_webserver   takara      v1    ecfd885a3874   24 minutes ago   279 MB   Vulnerable   

これで 東京DC の k8s へデプロイする準備が整いました。

Kubernetesへのデプロイと公開

k8sへデプロイして、サービスとして内部公開、さらにIngressサービスで外部へ公開するために、3つのYAMLファイルを準備します。

次は、コンテナをポッドとして、デプロイするためのYAMLです。 imageのフィールドに、先に登録したリポジトリ名をセットします。

k8s_deploy.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: go-web-deploy
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: go-web
    spec:
      containers:
      - name: go-web
        image: registry.au-syd.bluemix.net/takara/go_webserver:v1
        ports:
        - containerPort: 4040

次は、デプロイしたポッドが、k8sクラスタの他からアクセスできる様にするサービスを定義するものです。
これにより、ポッドのクラスタの代表アドレスが取得され、k8sのDNSサービスに登録されます。 これによって、Ingressから接続できる様になります。

k8s_svc.yml
apiVersion: v1
kind: Service
metadata:
  name: go-web-svc
spec:
  type: ClusterIP
  selector:
    app: go-web
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 4040

次は、パブリック・ネットワークであるインターネットから HTTPでアクセスするために、設定する Igressサービスの定義です。
go-web-svcの8080ポートをプロキシーして、外部へ公開します。

k8s_ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: go-web-ingress
spec:
  tls:
  - hosts:
    - mycluster3.jp-tok.containers.mybluemix.net
    secretName: mycluster3
  rules:
  - host: mycluster3.jp-tok.containers.mybluemix.net
    http:
      paths:
      - path: /
        backend:
          serviceName: go-web-svc
          servicePort: 8080

次のコマンドで、k8sクラスタへのデプロイを実行します。 このコマンドが実行できる様になるまでに、bx login、k8sクラスタのセットアップなどの作業がありますが、ここでは省略しています。ごめんなさい。

kubectl apply -f k8s_deploy.yml
kubectl apply -f k8s_svc.yml
kubectl apply -f k8s_ingress.yml

デプロイが成功したら、ブラウザからアクセスできる様になります。

スクリーンショット 2018-01-17 20.27.52.png

まとめ

Go言語で開発したアプリをk8sクラスタで公開するまでの作業内容を確認してみました。 流れをまとめると、以下の様になると思います。

  • Go言語で開発したサービスをコンテナ化
  • Dockerfileを開発して、ビルドとローカルでのテスト
  • k8sクラスタ環境のセットアップ(今回は省略)
  • コンテナのレジストリサービスへ登録
  • k8sのクラスタへデプロイするためのYAMLファイル作成
  • kubectrlでデプロイ

Go言語だからといって、特別な事は無いのですが、GitHubとgodepの使い方が、重要な事が良く判りました。

参考資料

  1. IBM Cloud を利用して Go言語のアプリ開発入門(その1) https://qiita.com/MahoTakara/items/70572f3f214f24ee452d
  2. IBM Cloud を利用した Go言語のアプリ開発入門(その2) https://qiita.com/MahoTakara/items/76d5d7905d07c9452d06
  3. IBM Cloud を利用した Go言語のアプリ開発入門(その3) https://qiita.com/MahoTakara/items/20dcb775f97eaf4a73dd
  4. 今さらだけど、Go言語に入門するための情報源 https://qiita.com/MahoTakara/items/10fede35c03db1e3b849
  5. Ingress のアノテーション IBM Cloud Docs https://console.bluemix.net/docs/containers/cs_annotations.html#service-rate-limit
  6. Docker-docs-ja http://docs.docker.jp/engine/toc.html
0
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
0
2