概要
マイクロサービスっぽいアプリをPython, MySQL, Dockerで作ってみて、Fargateにデプロイしてみる記事です。
AWSでいま最もアツいと(一部で)言われるFargateを使ってみたかったのと、マイクロサービスアーキテクチャへの興味でやってみました。とはいえ、マイクロサービスをちゃんと扱ったことも無いので、「こんな感じなんだろうな〜」という妄想のアーキテクチャです。もし誤りなどありましたら、ご意見いただけると嬉しいです。
なお、AWSならRDSもありますが、そもそもコンテナも初心者なので、勉強も兼ねてMySQLコンテナを使ってます。
そもそもマイクロサービスやFargateとは
いずれもネットに解説が多数ありますが、簡単に自分の理解を記載します。
マイクロサービス
- アプリケーションが複数の小さなサービスから成り立ち、それぞれが疎結合である。
- 疎結合ゆえ、改修が各サービス内で完結する。
- 各サービスを複数チームで開発できるため、各チームが得意な言語やフレームワークを利用できる。(逆にアプリ全体で統一する場合もあり)
- 小さなサービスを実現するための技術としてコンテナが使われる。
- コンテナを管理するツールとして、KubernetesやAWS ECSがある。
- サービス間のデータ通信では、RESTやgRPCが主に使われる。メッセージング技術(Kafkaとか)が使われることも。
Fargate
- 正確にはECSおよびEKSと合わせて使う。
- ECSなどのコンテナオーケストレーションツールを使えば、コンテナの管理は行えるが、コンテナをデプロイする先であるホスト(サーバ)は別で管理する必要がある。
- 例えば、 コンテナがスケーリングしてホストへの負荷が高まった場合、ホストもスケーリングする必要があり、こういった管理が使う側としては大変
- Fargateは、このホストの管理をAWS側が行うマネジメント型のサービス。例にあげたスケーリングも自動で行われるため、利用者はホストの管理を意識する必要がなくなる。
だいたいこんな理解です。つまり今回は、Dockerで構築したマイクロサービスをAWSのマネジメントサービスであるFargateにデプロイしてみる、ということをやります。
アプリのイメージ図
- マイクロサービスは、AplとBackEndの2つを用意します。
- サービス間の通信はHTTP(REST)
- クライアントからAplサービスのAPIにアクセス。AplサービスからBackEndサービスのAPIにアクセスすることで、クライアントからDBまでアクセスするイメージ
- Pythonを3.6と3.8で分けているのは、「Dockerならこんなこともできる」というのを体感したかっただけで、それ以上の理由はありません。両方3.6でも問題無いです。
記事の構成とゴール
まずはマイクロサービスをローカルをホストとしてデプロイして、その後Fargateに持っていきます。Fargateにデプロイが成功した後、外部から2つのマイクロサービスにHTTPで疎通できることをゴールとします。
環境
- 開発環境
- Python 3.6 / 3.8
- MySQL 5.7
- Docker
- Mac OS
- 前提知識
- Pythonのソースが読める
- SQLに関する基礎知識
- docker-composeを使ったことがある
- AWSのサービス名でどんなものかなんとなくわかる
1. まずはMacをホストにして起動
ローカルであるMac上にアプリをデプロイします。ソースなどは以下の通りです。
フォルダ構成
3つのコンテナ(apl-service, db-service, mysql)ごとにフォルダを作成してます。
.
├── apl-service
│ ├── Dockerfile
│ └── src
│ ├── results.py
│ └── server.py
├── db-service
│ ├── Dockerfile
│ └── src
│ ├── server.py
│ └── students.py
├── docker-compose.yml
└── mysql
├── Dockerfile
└── db
├── mysql_data
└── mysql_init
└── setup.sql
MySQL関連
FROM mysql/mysql-server:5.7
RUN chown -R mysql /var/lib/mysql && \
chgrp -R mysql /var/lib/mysql
create table students (id varchar(4), name varchar(20), score int);
insert into students values ('1001', 'Alice', 60);
insert into students values ('1002', 'Bob', 80);
commit;
mysql> select * from DB01.students;
+------+-------+-------+
| id | name | score |
+------+-------+-------+
| 1001 | Alice | 60 |
| 1002 | Bob | 80 |
+------+-------+-------+
db-service関連
FROM python:3.6
# コンテナ上のワークDIR
WORKDIR /usr/src/
# ライブラリのインストール
RUN pip install flask mysql-connector-python
CMD python ./server.py
from flask import Flask, request, abort, render_template, send_from_directory
from students import get_students
app = Flask(__name__)
@app.route('/students', methods=['GET'])
def local_endpoint():
return get_students()
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5001)
import json
import mysql.connector as mydb
def get_students():
conn = mydb.connect(user="user", passwd="password",
host="mysql", port="3306")
cur = conn.cursor()
sql_qry = 'select id, name, score from DB01.students;'
cur.execute(sql_qry)
rows = cur.fetchall()
results = [{"id": i[0], "name": i[1], "score": i[2]} for i in rows]
return_json = json.dumps({"students": results})
cur.close()
conn.close()
return return_json
- 簡単にソース解説
- Dockerコンテナ起動時に、server.pyを実行します。
- server.pyではFlaskを使ってサーバを立てています。
/students
というリソースにGETでアクセスしてきたら、students.pyからimportしたget_studentsを実行して、結果を返すAPIです。 - get_studentsでは、MySQLコンテナに接続して、DBからselectした結果をrowsに格納します。rowsから内包表記でdictにして、その後jsonに変換して値をリターンしています。
- ローカルへのデプロイなら
links
を使わなくてもコンテナ間で上手く繋がります。というか、links
は古い手法として、あまり最近は使われてないようですね...
apl-service関連
FROM python:3.8
# コンテナ上のワークDIR
WORKDIR /usr/src/
# ライブラリのインストール
RUN pip install requests flask
CMD python ./server.py
from flask import Flask, request, abort, render_template, send_from_directory
from results import get_results
API_URI = 'http://db-service:5001/students'
app = Flask(__name__)
@app.route('/results', methods=['GET'])
def local_endpoint():
return get_results(API_URI)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5002)
import json
import requests
def get_results(uri):
r = requests.get(uri)
students = r.json()["students"]
return_students = []
for student in students:
if student["score"] > 70:
student.setdefault("isPassed", True)
return_students.append(student)
else:
student.setdefault("isPassed", False)
return_students.append(student)
return_json = json.dumps({"addedStudents": return_students})
return return_json
- 簡単にソース解説
- server.pyあたりはdb-serviceとほぼ同じ。
/results
というリソースにGETでアクセスしてきたら、results.pyからimportしたget_resultsを実行して、結果を返すAPIです。 - 違いとしては、get_resultsからdb-serviceのAPIにアクセスするため、URIを設定しています。
- get_resultsでは、db-seriveから取得した値をstudentsに格納します。これをforで回して、各scoreの値が70より大きければ
"isPassed"
にTrue, それ以外はFalseを設定して、jsonの要素を追加します。
- server.pyあたりはdb-serviceとほぼ同じ。
docker-compose
version: '3'
services:
mysql:
container_name: mysql
build:
context: .
dockerfile: ./mysql/Dockerfile
hostname: mysql
ports:
- "3306:3306"
volumes:
- ./mysql/db/mysql_init:/docker-entrypoint-initdb.d
- ./mysql/db/mysql_data:/var/lib/mysql
environment:
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: DB01
command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci --skip-character-set-client-handshake
db-service:
build:
context: .
dockerfile: ./db-service/Dockerfile
container_name: db-service
ports:
- "5001:5001"
volumes:
- ./db-service/src/:/usr/src/
apl-service:
build:
context: .
dockerfile: ./apl-service/Dockerfile
container_name: apl-service
ports:
- "5002:5002"
volumes:
- ./apl-service/src/:/usr/src/
- 簡単にソース解説
- mysqlのvolumesでは、docker-entrypoint-initdb.dに先程のsetup.sqlが格納されるよう設定しています。MySQLでは、初回起動時に、docker-entrypoint-initdb.d配下にあるSQLが実行されます。要するに、初期データです。
デプロイして実行
結果は省略しますが、docker-composeコマンドでデプロイします。
$ docker-compose build
$ docker-compose up
デプロイが成功したら、疎通確認として各マイクロサービスにHTTPでアクセスしてみましょう。ソースの通り、db-serviceは5001, apl-serviceは5002のポートを使っています。
$ curl http://127.0.0.1:5001/students
{"students": [{"id": "1001", "name": "Alice", "score": 60}, {"id": "1002", "name": "Bob", "score": 80}]}
$ curl http://127.0.0.1:5002/results
{"addedStudents": [{"id": "1001", "name": "Alice", "score": 60, "isPassed": false}, {"id": "1002", "name": "Bob", "score": 80, "isPassed": true}]}
これで土台となる、(妄想の)マイクロサービスをローカルにデプロイできました。
apl-serviceのAPIの結果が返ってきているので、apl-serviceとdb-serviceのマイクロサービス間の疎通が取れていることも確認できます。
早速、これをFargateに持っていきます!が、ここからが長かった...
2. 改めて最終版のイメージ図
Fargateへデプロイすることを踏まえて最終版の構成図です。
ポイントとなるのは以下の点です。
- 1マイクロサービスを1つのFargateにデプロイすること。
- タスク内でコンテナ間通信(db-service⇔mysql)があること。
- タスク間通信(apl-service⇔db-service)があること。
これらを踏まえて、デプロイしていきます。
3. ECRへの登録
まずは、作成した3つのdockerイメージ(apl-service, db-service, mysql)をECRにpushします。ECRはUIがわかりやすいので、AWSのコンソールから「リポジトリを作成」と押してそのまま進めていけば、pushできると思います。
※ 1で作成した起動したコンテナは一度stopしてdocker rm
しておいてください。
4. Fargateへのデプロイ前に
ECSでは、docker-compose.ymlを使うことが可能です。ecs-cliを設定した後、以下のチュートリアルに沿って、Fargateにデプロイしていきますが、docker-compose.yml等を修正する必要があります。色々修正ポイントを上げていきますが、最終版のソースは記事の最後に掲載してますので、忙しい方はそちらを参照ください。
チュートリアル: Amazon ECS CLI を使用して Fargate タスクのクラスターを作成する
また、今回のアプリで言えば、5001, 5002のポートも使っているので、ステップ3のセキュリティグループの設定でこれらも許可する必要があります。
$ aws ec2 authorize-security-group-ingress --group-id <security-group-id> --protocol tcp --port 5001 --cidr 0.0.0.0/0 --region <region>
docker-compose.ymlの分割
- 今回、2つのマイクロサービスを2つのタスクとしてデプロイします。このため、docker-compose.ymlも2つに分割する必要があります。なお、デプロイのコマンド実行も2回必要となります。
- backend(db-service, mysql)と、apl(apl-service)で分割します。
- 同じ名前のdocker-compose.ymlファイルが2つできることになるので、適当にフォルダを分けておきましょう。
$ pwd
/Users/<省略>/aws_work
$ ls docker-compose.yml # db-service + mysqlのdocker-compose.yml
docker-compose.yml
$ ecs-cli compose --project-name backend service up ~
$ pwd
/Users/<省略>/aws_work2
$ ls docker-compose.yml # apl-serviceのdocker-compose.yml
docker-compose.yml
$ ecs-cli compose --project-name apl service up ~
※ この時点ではデプロイしても上手くいきません。
ECRにpushしたimageの指定
- さきほどpushしたimageをDockerfileの代わりに指定します。
build
,container_name
,hostname
は不要なので、代わりにimage
を指定します。 - 以下の例だと、mysqlコンテナのECRのリポジトリ名は
python-mysql/mysql
としています。 - db-service, apl-serviceも同様に
image
に置き換えます。
mysql:
image: <aws_account_id>.dkr.ecr.<region>.amazonaws.com/python-mysql/mysql
volumesを利用しないよう修正
- Fargateでは永続ストレージボリュームがサポートされません。難しく聞こえますが、docker-compose.ymlのvolumesが使えないということです。そのため、server.pyとかのソースがコンテナに反映されません。
- というわけで、docker-compose.ymlからvolumesをコメントアウト(もしくは物理削除)して、Dockerfile内にCOPYを記載するようそれぞれ修正します。
- db-service, apl-serviceも同様の修正を行います。
- Dockerfileを修正したので、再度ECRにpushする必要があります。
# volumes:
# - ./db-service/src/:/usr/src/
# コンテナにソースをコピー
COPY ./src/server.py /usr/src/server.py
COPY ./src/students.py /usr/src/students.py
コンテナログの設定
- 上記チュートリアルにも記載されていますが、Fargateタスクのベストプラクティスとして、コンテナログを設定します。ここではpython-dockerというロググループ名です。
- db-service, apl-serviceにも同様に設定します。
mysql:
logging:
driver: awslogs
options:
awslogs-group: python-docker
awslogs-region: <region>
awslogs-stream-prefix: mysql
また、今回は修正していませんが、Fargateではports
がホストとコンテナ側で同じ番号になる必要がある点も注意事項です。例えば、ローカルでは80:5001
という指定はできますが、Fargateでは5001:5001
と指定しないとエラーとなります。
4点ほど修正しましたが、これだけだとまだ上手くいきません。
5. 更に修正してFargateへデプロイ
5-1. コンテナ間通信とタスク間通信
ここからは、先述したタスク内でのコンテナ間通信や、タスク間通信を実現するために必要となる修正です。まずは、コンテナ間通信を実現するため、db-serviceとmysqlについて記載します。
デプロイしてHTTP通信してみる
さきほどまでの修正をデプロイした後、ecs-cli compose ~ service ps ~
のコマンドでステータスを確認すると、一応RUNNING
になっていると思います。
実際に、立ち上げ後psをした結果です。
$ ecs-cli compose --project-name backend service ps --cluster-config sample-config --ecs-profile sample-profile
Name State Ports TaskDefinition Health
<task-id>/db-service RUNNING XXX.XXX.XXX.XXX:5001->5001/tcp backend:12 UNKNOWN
<task-id>/mysql RUNNING XXX.XXX.XXX.XXX:3306->3306/tcp backend:12 UNKNOWN
グローバスのIPアドレスが表示されるため、Macからdb-serviceにGETで通信してみますが、先述の通りまだ上手くいきません。
$ curl http://XXX.XXXX.XXX.XXX:5001/students
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>
5-2. コンテナ間通信のための修正
ECSのコンソールにあるからLogsタブなどでログを確認すると、名前解決できていない旨のエラーが出てると思います。今回でいったら、db-serviceからmysqlのホスト名が見つからない、というエラーが出ます。要するに、コンテナ間で通信できてない、ということです。
なお、ローカルへのデプロイ時に書きましたが、今回はLinksを使っていません。また、FargateタイプではそもそもLinksがサポートされていません。
じゃあどうやって解決するのかというと、Fargateのコンテナ間通信は、同一タスク上であれば、ポート番号でアクセス可能となります。というわけで、students.pyのソースを以下の通り変更します。また、今更ですがホスト名をオンコーディングは微妙なので、docker-compose.ymlから環境変数で渡すよう合わせて修正します。
import json
import mysql.connector as mydb
import os # 追加
def get_students():
# 環境変数から取得するよう修正
conn = mydb.connect(user=os.environ['DB_USER'], passwd=os.environ['DB_PASS'],
host=os.environ['DB_HOST'], port=os.environ['DB_PORT'])
db-service:
- 省略 -
environment:
DB_HOST: 127.0.0.1
DB_USER: "user"
DB_PASS: "password"
DB_PORT: "3306"
再度、ECRにpushしてデプロイします。
なお、一度Fargateにデプロイしている場合、変更を反映するには、チュートリアルにもあるecs-cli compose ~ service down ~
のコマンドで一度落として、ecs-cli compose ~ service up ~
のコマンドで立ち上げ直します。
※ downのコマンド完了後も落ちきるまでは少し時間がかかるようです。
再度デプロイでdb-serviceは疎通!
無事、Macからdb-serviceにHTTP通信できていることが確認できます。
通信経路をおさらいすると、以下のとおりです。
1. Fargate上のdb-serviceというマイクロサービスに外部(Mac)からHTTP通信
2. db-serviceとMySQLがコンテナ間で通信して、データを取得
3. db-serviceを経由して、リクエスト元に値が返ってくる
$ curl http://XXX.XXX.XXX.XXX:5001/students
{"students": [{"id": "1001", "name": "Alice", "score": 60}, {"id": "1002", "name": "Bob", "score": 80}]}
※ バックエンドのサービスに直接通信できるのはセキュリティ的にちょっと...思われる方もいると思いますが、今回はわかりやすさを重視して通信可能としています。多分、本番運用ではセキュリティグループとかで設定するのかなあという妄想。
5-3. タスク間通信のための修正
続いて、apl-serviceを疎通させます。先述の通り、apl-serviceはdb-serviceのAPIを実行するため、別のタスクと通信させる必要があります。Fargateでこれを実現するには、サービス検出を有効にして起動を行います。
サービス検出の仕組みは、以下のClassmethodさんの記事が非常にわかりやすいので省略しますが、要するにRoute53のAレコードがマイクロサービス間に自動作成され、名前検出が可能となるということです。
ECSのサービスディスカバリーが東京にやってきて、コンテナ間通信の実装が簡単になりました!
今回は、ecs-cliを使っているので、AWS公式の以下チュートリアルを参考にコマンドでデプロイしていきます。
チュートリアル : Amazon ECS CLI を使用して サービス検出 を使用する Amazon ECS サービスを作成する
なお、サービス検出時のホスト名はservice_name.namespace
となります。今回、サービス名をbackend、名前空間をsampleとして作成するため、apl-serviceからdb-serviceにアクセスするためには、backend.sample
というホスト名を設定する必要があります。
というわけで、db-serviceの時と同様に、環境変数からホスト名を設定するよう修正します。
from flask import Flask, request, abort, render_template, send_from_directory
from results import get_results
import os # 追加
# 環境変数から取得するよう修正
API_URI = 'http://' + os.environ['BACKEND_HOST'] +':' + os.environ['BACKEND_PORT'] + '/students'
apl-service:
- 省略 -
environment:
BACKEND_HOST: "backend.sample"
BACKEND_PORT: "5001"
これで準備が整いました。再度apl-serviceのコンテナをECRにpushします。
既にdb-service, mysqlが起動している場合、同じ名前空間上を設定してデプロイする必要があるので、一度サービスを落とします。その後、それぞれのdocker-compose.ymlのファイルがあるフォルダで、名前空間のオプションを追加してデプロイします。
なお、サービス名はそれぞれbackend, aplとします。
$ ecs-cli compose --project-name backend service up --private-dns-namespace sample --vpc <vpc-id> --enable-service-discovery --ecs-profile sample-profile
$ ecs-cli compose --project-name apl service up --private-dns-namespace sample.com --vpc <vpc-id> --enable-service-discovery --ecs-profile sample-profile
注意事項として、チュートリアルのデプロイコマンドに、--ecs-profile
も付けてあげる必要があります。
apl-serviceも疎通!
$ curl http://XXX.XXX.XXX.XXX:5002/results
{"addedStudents": [{"id": "1001", "name": "Alice", "score": 60, "isPassed": false}, {"id": "1002", "name": "Bob", "score": 80, "isPassed": true}]}
これでようやく、apl-serviceも疎通確認ができました。通信経路をおさらいすると、以下のとおりです。
1. Fargate上のapl-serviceに外部(Mac)からHTTP通信
2. apl-serviceがdb-serviceのAPIを実行
3. db-serviceとMySQLがコンテナ間で通信して、データを取得
4. db-service, apl-serviceを経由して、リクエスト元に値が返ってくる
6. ソースとデプロイコマンドのまとめ
色々修正したので、変更があったソースとデプロイコマンドをまとめます。なお、regionはap-northeast-1でやりましたが、別を使われてる方は変更の必要があるのでご注意ください。
MySQL関連
FROM mysql/mysql-server:5.7
COPY ./db/mysql_init/setup.sql /docker-entrypoint-initdb.d/setup.sql
RUN chown -R mysql /var/lib/mysql && \
chgrp -R mysql /var/lib/mysql
setup.sqlは変更無いので省略
db-service関連
FROM python:3.6
# コンテナ上のワークDIR
WORKDIR /usr/src/
# ライブラリのインストール
RUN pip install flask mysql-connector-python
# コンテナにソースをコピー
COPY ./src/server.py /usr/src/server.py
COPY ./src/students.py /usr/src/students.py
CMD python ./server.py
db-service/src/server.py
は変更無いので省略
import json
import mysql.connector as mydb
import os
def get_students():
conn = mydb.connect(user=os.environ['DB_USER'], passwd=os.environ['DB_PASS'],
host=os.environ['DB_HOST'], port=os.environ['DB_PORT'])
cur = conn.cursor()
sql_qry = 'select id, name, score from DB01.students;'
cur.execute(sql_qry)
rows = cur.fetchall()
results = [{"id": i[0], "name": i[1], "score": i[2]} for i in rows]
return_json = json.dumps({"students": results})
cur.close()
conn.close()
return return_json
apl-service関連
FROM python:3.8
# コンテナ上のワークDIR
WORKDIR /usr/src/
# ライブラリのインストール
RUN pip install requests flask
# コンテナにソースをコピー
COPY ./src/server.py /usr/src/server.py
COPY ./src/results.py /usr/src/results.py
CMD python ./server.py
from flask import Flask, request, abort, render_template, send_from_directory
from results import get_results
API_URI = 'http://db-service:5001/students'
app = Flask(__name__)
@app.route('/results', methods=['GET'])
def local_endpoint():
return get_results(API_URI)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5002)
apl-service/src/results.py
は変更無いので省略
docker-compose (db-service, mysql)
# aws_account_id, regionは実態に合わせて修正必要
version: '3'
services:
mysql:
image: <aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/python-mysql/mysql
ports:
- "3306:3306"
environment:
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: DB01
command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci --skip-character-set-client-handshake
logging:
driver: awslogs
options:
awslogs-group: python-docker
awslogs-region: ap-northeast-1
awslogs-stream-prefix: mysql
db-service:
image: <aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/python-mysql/db-service
ports:
- "5001:5001"
environment:
DB_HOST: 127.0.0.1
DB_USER: "user"
DB_PASS: "password"
DB_PORT: "3306"
logging:
driver: awslogs
options:
awslogs-group: python-docker
awslogs-region: ap-northeast-1
awslogs-stream-prefix: db-service
docker-compose (apl-service)
# aws_account_id, regionは実態に合わせて修正必要
version: '3'
services:
apl-service:
image: <aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/python-mysql/apl-service
ports:
- "5002:5002"
environment:
BACKEND_HOST: "backend.sample"
BACKEND_PORT: "5001"
logging:
driver: awslogs
options:
awslogs-group: python-docker
awslogs-region: ap-northeast-1
awslogs-stream-prefix: apl-service
- ecs-params.ymlはチュートリアル通り作成すればOKなので省略
デプロイコマンド
チュートリアル(Amazon ECS CLI を使用して Fargate タスクのクラスターを作成する)のステップ3から主要な部分を載せていきますが、コメントが付いてる箇所が変更点です。括弧やregionは実際の値に置き換えてください。
$ ecs-cli up --cluster-config sample-config --ecs-profile sample-profile
$ aws ec2 describe-security-groups --filters Name=vpc-id,Values=<vpc-id> --region ap-northeast-1
$ aws ec2 authorize-security-group-ingress --group-id <security-group-id> --protocol tcp --port 80 --cidr 0.0.0.0/0 --region ap-northeast-1
# 5001, 5002も許可
$ aws ec2 authorize-security-group-ingress --group-id <security-group-id> --protocol tcp --port 5001 --cidr 0.0.0.0/0 --region ap-northeast-1
$ aws ec2 authorize-security-group-ingress --group-id <security-group-id> --protocol tcp --port 5002 --cidr 0.0.0.0/0 --region ap-northeast-1
# backendのデプロイ - サービス検出のため名前空間の作成オプションを追加
$ ecs-cli compose --project-name backend service up --create-log-groups --cluster-config sample-config --private-dns-namespace sample --vpc <vpc-id> --enable-service-discovery --ecs-profile sample-profile
# aplのデプロイ - backendと同様
$ ecs-cli compose --project-name apl service up --create-log-groups --cluster-config sample-config --private-dns-namespace sample --vpc <vpc-id> --enable-service-discovery --ecs-profile sample-profile
※ デプロイを2つ行うので、以降のコマンドも2つ実行
$ ecs-cli compose --project-name backend service up --private-dns-namespace sample --vpc <vpc-id> --enable-service-discovery --ecs-profile sample-profile
$ ecs-cli compose --project-name apl service up --private-dns-namespace sample.com --vpc <vpc-id> --enable-service-discovery --ecs-profile sample-profile
$ ecs-cli compose --project-name backend service down --cluster-config sample-config --ecs-profile sample-profile
$ ecs-cli compose --project-name apl service down --cluster-config sample-config --ecs-profile sample-profile
$ ecs-cli down --force --cluster-config sample-config --ecs-profile sample-profile
学んだこと(ハマったこと)
- Fargateでのマイクロサービスなアプリの利用イメージ
- ECSにおけるタスク内通信、タスク間通信の仕組みや方法
- Fargateでは永続ストレージボリュームがサポートされないなど、制約事項いろいろ
最後に
フルスクラッチでマイクロサービスとかも作った分、Fargateだけじゃなくマイクロサービス全般について理解が深まったような気がします。
自分がハマったこととかを色々書いたので、構成とかわかりにくい記事になったかもしれません。長くなってしまいましたが、読んでいただきありがとうございました。指摘や質問などもらえると、とてもありがたいです。