この記事は 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 さんに質問してみたところあっさり教えてもらいました。
同じタスク定義内のコンテナはlocalhostを共有しているので、localhost+ポート番号でアクセスさせると良いです。
— riywo (@riywo) 2017年12月7日
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してます。
ブラウザでアクセスしてみます。
データベースがないってエラーにはなってますが、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
ブラウザでアクセスすると、
正常に動きました。
まとめ
Fargateでコンテナ間で通信させたい場合は、Link機能は使えないけど、localhost:ポート番号でアクセスできる!
1. Dockerのlink機能は非推奨になってるみたいです。
https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/ ↩
2. Fargateではボリュームマウントもできないので、データ永続化させるようなMySQLコンテナを動かすってことはあまりないかと思いますが・・・↩