Edited at

AWS Fargateでコンテナ間通信させたいとき

More than 1 year has passed since last update.

この記事は AWS Fargate Advent Calendar 2017 の19日目の記事です。

cloudpack大阪の佐々木です。

Fargateでコンテナ間通信させるときの話です。


概要

Docker環境で、コンテナ間で通信させるためにLinkという機能があります。1

ECS上でLink機能を使用しているタスク定義を、Fargateで実行しようとしてもエラーになって動きません。


実行結果

まず簡単な例として、Wordpress + MySQLという構成があるとします。2

WordpressコンテナとMySQLコンテナがあって、Wordpressの方にLinkを指定することで、mysqlという名前で通信できるようになります。


docker-compose.yml

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.


http://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html

Fargateのネットワークモードは awsvpc になるので、この機能はサポートされてないと。


解決方法

色々見てみたんですが、Link機能の代替となるようなものを見つけられなかったので、@riywo さんに質問してみたところあっさり教えてもらいました。

https://qiita.com/sawanoboly/items/2766c8b0760ad9f9be99

なるほど・・・

ん? 別のコンテナの起動しているポートもlocalhostとして見えるのか?

確認してみました。


確認

同じタスク定義内に、もう一つ別にssh接続用のコンテナを起動して、そのコンテナからどう見えるのかを確認してみました。

ssh接続用コンテナの作り方はこのへんを参考にしました。

https://qiita.com/sawanoboly/items/2766c8b0760ad9f9be99


docker-compose.yml

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してます。

ブラウザでアクセスしてみます。

image.png

image.png

データベースがないってエラーにはなってますが、MySQLへの接続は問題なくてきているようです。

ちなみに データベースのホスト名 のところは localhost ではなく、 127.0.0.1 と入力しないとエラーになります。

理由はこちら

https://qiita.com/TanukiTam/items/f6a08740d0fcda0db7be


完成形

最終的に作成した docker-compose.yml は下記のようになります。


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

ブラウザでアクセスすると、

image.png

正常に動きました。


まとめ

Fargateでコンテナ間で通信させたい場合は、Link機能は使えないけど、localhost:ポート番号でアクセスできる!






  1. Dockerのlink機能は非推奨になってるみたいです。https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/ 



  2. Fargateではボリュームマウントもできないので、データ永続化させるようなMySQLコンテナを動かすってことはあまりないかと思いますが・・・