この記事は AWS Fargate Advent Calendar 2017 の19日目の記事です。
cloudpack大阪の佐々木です。
Fargateでコンテナ間通信させるときの話です。
概要
Docker環境で、コンテナ間で通信させるためにLinkという機能があります。1
ECS上でLink機能を使用しているタスク定義を、Fargateで実行しようとしてもエラーになって動きません。
実行結果
まず簡単な例として、Wordpress + MySQLという構成があるとします。2
WordpressコンテナとMySQLコンテナがあって、Wordpressの方にLinkを指定することで、mysqlという名前で通信できるようになります。
version: '2'
services:
wordpress:
image: wordpress
ports:
- "80:80"
links:
- mysql
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: password
ECSであれば、この構成で問題なく動くんですが、Fargateで起動させると下のようなエラーになります。
$ ecs-cli compose service up --launch-type FARGATE
WARN[0000] Skipping unsupported YAML option... option name=networks
WARN[0000] Skipping unsupported YAML option for service... option name=networks service name=mysql
WARN[0000] Skipping unsupported YAML option for service... option name=networks service name=wordpress
ERRO[0001] Error registering task definition error="ClientException: Links are not supported when networkMode=awsvpc.\n\tstatus code: 400, request id: axxxxx-e39c-11e7-a22a-xxxxxxxxx" family=wordpress
ERRO[0001] Create task definition failed error="ClientException: Links are not supported when networkMode=awsvpc.\n\tstatus code: 400, request id: axxxxx-e39c-11e7-a22a-xxxxxxxxx"
FATA[0001] ClientException: Links are not supported when networkMode=awsvpc.
status code: 400, request id: axxxxx-e39c-11e7-a22a-xxxxxxxxx
つまりFargateではLink機能はサポートされていないということです。
AWSのドキュメントには下記のように記載されてました。
Only supported if the network mode of a task definition is set to bridge.
Fargateのネットワークモードは awsvpc
になるので、この機能はサポートされてないと。
解決方法
色々見てみたんですが、Link機能の代替となるようなものを見つけられなかったので、@riywo さんに質問してみたところあっさり教えてもらいました。
同じタスク定義内のコンテナはlocalhostを共有しているので、localhost+ポート番号でアクセスさせると良いです。
— riywo (@riywo) 2017年12月7日
なるほど・・・
ん? 別のコンテナの起動しているポートもlocalhostとして見えるのか?
確認してみました。
確認
同じタスク定義内に、もう一つ別にssh接続用のコンテナを起動して、そのコンテナからどう見えるのかを確認してみました。
ssh接続用コンテナの作り方はこのへんを参考にしました。
version: '2'
services:
sshd:
image: taishin/amazonlinux-sshd
ports:
- "22:22"
wordpress:
image: wordpress
ports:
- "80:80"
# links:
# - mysql
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: password
起動して、sshログインし、確認してみます。
-bash-4.2# netstat -nl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:3128 0.0.0.0:* LISTEN
tcp 0 0 :::3306 :::* LISTEN
tcp 0 0 :::3128 :::* LISTEN
udp 0 0 0.0.0.0:68 0.0.0.0:*
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ACC ] STREAM LISTENING 17520 /var/run/mysqld/mysqld.sock
おー 確かに別コンテナが使用しているTCP/80、TCP/3306もローカルでLISTENしてます。
ブラウザでアクセスしてみます。
データベースがないってエラーにはなってますが、MySQLへの接続は問題なくてきているようです。
ちなみに データベースのホスト名
のところは localhost
ではなく、 127.0.0.1
と入力しないとエラーになります。
理由はこちら
https://qiita.com/TanukiTam/items/f6a08740d0fcda0db7be
完成形
最終的に作成した docker-compose.yml
は下記のようになります。
version: '2'
services:
wordpress:
image: wordpress
ports:
- "80:80"
environment:
WORDPRESS_DB_HOST: 127.0.0.1
WORDPRESS_DB_PASSWORD: password
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: password
Wordpressコンテナの環境変数はこちらを参照
https://hub.docker.com/_/wordpress/
ecs-cli compose service up --launch-type FARGATE [15:20:08]
WARN[0000] Skipping unsupported YAML option... option name=networks
WARN[0000] Skipping unsupported YAML option for service... option name=networks service name=wordpress
WARN[0000] Skipping unsupported YAML option for service... option name=networks service name=mysql
WARN[0000] Skipping unsupported YAML option for service... option name=networks service name=sshd
INFO[0001] Using ECS task definition TaskDefinition="wordpress:11"
INFO[0002] Created an ECS service service=ecscompose-service-wordpress taskDefinition="wordpress:11"
INFO[0002] Updated ECS service successfully desiredCount=1 serviceName=ecscompose-service-wordpress
INFO[0018] (service ecscompose-service-wordpress) has started 1 tasks: (task xxxxxxx-46f4-4b29-b09f-5484982bd294). timestamp=2017-12-18 06:22:45 +0000 UTC
INFO[0124] Service status desiredCount=1 runningCount=1 serviceName=ecscompose-service-wordpress
INFO[0124] (service ecscompose-service-wordpress) has reached a steady state. timestamp=2017-12-18 06:24:31 +0000 UTC
INFO[0124] ECS Service has reached a stable state desiredCount=1 runningCount=1 serviceName=ecscompose-service-wordpress
ブラウザでアクセスすると、
正常に動きました。
まとめ
Fargateでコンテナ間で通信させたい場合は、Link機能は使えないけど、localhost:ポート番号でアクセスできる!
-
Dockerのlink機能は非推奨になってるみたいです。https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/ ↩
-
Fargateではボリュームマウントもできないので、データ永続化させるようなMySQLコンテナを動かすってことはあまりないかと思いますが・・・ ↩