container
docker-compose
AlibabaCloud
ContainerService

Alibaba Container Serviceを使ってDocker-Composeで構築したアプリケーションを動作させる(nginxで表示するHelloWorldアプリ編)

さて、今回はAlibaba Container Serviceを使って、簡単なアプリケーションのデプロイを試してみたいと思います。

早速ですが、Container Serviceの概要から確認していきましょう。


Alibaba Cloud Container Service って?

公式ページの説明を見てみましょう。

Alibaba Cloud Container Service はフルマネージドのクラウドコンテナー管理サービスです。

Alibaba Cloud ECS インスタンスの分散クラスター上にある Docker アプリケーションを効率的に実行、
管理できます。よって、従来のような個別でのコンテナークラスター基盤の導入や、運用、オートスケーリングなどの
拡張設計が不要になります。アプリケーション開発作業など、本来の作業に集中できます。

また、利点として


  • コンテナークラスターの作成は、数項目の入力のみ

  • Docker Compose テンプレートを使用してアプリケーションのオーケストレーションが可能

  • GUI と OpenAPI により、作業を簡便化

という点が挙げられており、Dockerアプリケーションの効率的な管理・実行というところにフォーカスしていることがわかります。

Container ServiceではSwarmクラスターを構築することで、docker-composeなどのツールを利用することができるようですので、今回はdocker-composeを利用したデプロイを試してみることにします。


Swarmクラスターの作成

00_ali_console.png

Alibaba Cloud Console から Container Serviceを選択します。

01_container_service_console.png

Container Service Console が表示されますので今回は、左側のメニュー上部で、初期状態で選択されているKubernatesではなく、Swarmを選択し、コンソール右上の クラスターの作成 を選択します。

02_create_cluster.png

クラスターの作成 画面が表示されます。この画面では、以下の項目の入力を行います。


  • クラスター名

  • リージョン

  • ゾーン

  • ネットワークタイプ

  • Container Serviceの初期CIDRブロック

  • 追加ノードの設定


    • 追加可否

    • ノードタイプ

    • オペレーティングシステム

    • インスタンスの世代

    • インスタンスのタイプ

    • I/O 最適化

    • インスタンスの種類

    • インスタンス数

    • システムディスクタイプ

    • データディスクタイプ

    • データディスクの接続

    • ログイン(キーペア/パスワード)

    • キーペア名



  • 上級


    • EIPの設定可否

    • ServerLoadBalancerの作成有無

    • 監視プラグインのインストール可否

    • RDSホワイトリスト

    • セキュリティグループ



かなり項目的には多いですね。ここでは、


  • リージョンをアジア東北1(東京)に

  • インスタンスタイプに ecs.xn4.small を指定

  • インスタンス数を1セット

として、ほかの項目は初期状態のままとし、クラスターの作成をクリックします。確認ダイアログが表示され、OKを選択することで作成が開始されます。

03_request_accepted.png

画面下部に 仕上げ というボタンが表示されますので、これをクリックすることでクラスターの一覧画面に戻ります。

04_clusters_processing.png

クラスターステータス初期化中になっていることがわかります。クラスターが作成されるまで少しの間待つ必要があります。

05_clusters_runnning.png

画面が小さいため見づらくてすみません。ステータスが ランニング になればクラスターが正常に作成されています。


docker-composeを利用してnginxとアプリケーションを動作させる

さあ、引き続き、docker-composeを利用してローカルからのクラスター構築を試してみます。

クラスターの一覧から、先程追加したクラスターの 管理 をクリックします。

06_manage_cluster.png

クラスターの基本情報が表示されています。

接続情報証明書のダウンロード というボタンがあるのでこれをクリックし、 CertFile.zip というファイルをダウンロードします。

これを、docker-composeを実行する端末の任意の場所に解凍し、基本情報画面に例示されているように、

export DOCKER_TLS_VERIFY="1"

export DOCKER_HOST="tcp://master1g1.cs-ap-northeast-1.aliyun.com:20007"
export DOCKER_CERT_PATH="$PWD"

と実行し、ContainerServiceで構築したクラスタへdocker-composeを実行するための、環境変数を整えます。


docker-compose.yml等、構築に必要なファイルについて

さて、これからdocker-composeを実行するわけですが、実行するdocker-compose.ymlとdockerfileなどを以下に例示します。

とりあえずではありますが、nginxとGoのアプリケーションを用意するため以下のようにしています。


docker-compose.yml

version: '3'

services:
nginx:
build: docker/nginx
ports:
- "80:80"
links:
- go
restart: always
network_mode: bridge
go:
build: docker/go
working_dir: "/go/src/github.com/deadcheat/containexercise"
expose:
- "3000"
command: "go run main.go"
restart: always
network_mode: bridge



docker/go/Dockerfile

FROM golang:latest

RUN go get github.com/deadcheat/containexercise

EXPOSE 3000



docker/nginx/Dockerfile

FROM nginx:latest

COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80



docker/nginx/nginx.conf

user  nginx;

worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;

upstream go-app {
server go:3000;
}

server {
listen 80;

location / {
proxy_pass http://go-app;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}


また、この時点で動作させるアプリケーションのコードは、以下のようにHelloWorldを返却するだけのシンプルなアプリケーションコードとなっています。


main.go

package main

import (
"fmt"
"net/http"
)

func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World")
})
http.ListenAndServe(":3000", nil)
}



docker-compose実行、確認

さて、それでは実行してみます。

先程の手順で環境変数が整えられていれば、ローカル環境でdocker-composeを実行するのと全く変わりません。

docker-compose build

docker-compose up

なお、上記コマンドでは、確認のため docker-compose up を実行して、コンソール出力を確認しています。実際にアプリケーションをデプロイする際には、 通常ローカルで利用するのと同様に、docker-compose up -d とすることで、コンソールを停止しても動作させることができます。

さて、docker-composeがエラーなく実行できたら、Container Service Consoleに戻りましょう。

07_return_to_console.png

左側のメニューから、 サービス を選択します。

08_services.png

ここに、docker-composeでデプロイしたサービスが一覧化されているはずですので、 nginx の行の 更新 をクリックします。

09_update_service.png

サービスの更新 画面が表示されますので、ネットワークWebルーティング の項目の をクリックします。

10_add_web_routing.png


  • コンテナポート

  • ドメイン

を入力する入力欄が表示されますので、


  • コンテナポート: 80

  • ドメイン: nginx

と入力し、画面右側の 更新 ボタンをクリックします。

11_returned_to_services.png

サービスリストの画面に戻りますので、 サービス名、この場合は nginx をクリックします。

12_access_endpoint.png

サービスの詳細画面が表示されます。

画面上部に、 アクセスエンドポイント が表示されていますので、これをクリックしてみましょう。

13_hello_world.png

ブラウザに、アプリケーションが出力する「Hello, World」が表示されています。アプリケーションのデプロイを非常に簡単に実現することができました。

さて、ここからDBやキャッシュ機構を使ったアプリケーションを構築していきたいところですが、今回はここまでにしておきます。


今回のまとめ

いかがでしたでしょうか?今回は、アプリケーションとnginxの組み合わせをデプロイするところまででしたのでアプリケーションの内容も非常にシンプルなものでしたが、


  • 開発時に利用しているdocker-compose.ymlを利用して、アプリケーションのデプロイが簡単に行える

  • サービスごとに公開設定などを行えるため、非常に柔軟にアプリケーションの構築を行うことができる

といった部分について、少しでもお伝えすることができたら幸いです。

なお、今回使用しているアプリケーションやdocker-compose.ymlなどのファイルについては、こちらにご用意していますので、気になる方は参考にしていただければと思います。

今回も、ここまでお読みいただきありがとうございました!