当使用AWS Fargate时,如何实现容器之间的通信
本文是2017年AWS Fargate系列日历活动的第19篇文章。
我是Cloudpack大阪的佐々木。
我要谈的是在Fargate上实现容器间通信的问题。
简而言之
Docker環境で、コンテナ間で通信させるためにLinkという機能があります。1
ECS上でLink機能を使用しているタスク定義を、Fargateで実行しようとしてもエラーになって動きません。
执行结果
假设有一个简单的示例,包括WordPress + MySQL。有一个WordPress容器和一个MySQL容器,通过在WordPress容器中指定链接,可以通过“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のドキュメントには下記のように記載されてました。
只有在任务定义的网络模式设置为桥接时才支持。
由于Fargate的网络模式是awsvpc,因此不支持该功能。
问题的解决方案
我尝试找到替代Link功能的选项,但没能找到。于是我向@riywo问了一下,她很快就告诉了我。
在相同的任务定义中,容器共享本地主机,所以通过 localhost+端口号来访问是一个好办法。
我懂了。。。 (Wǒ le…)
哦?其他容器的正在运行的端口也能在本地主机上显示出来吗?
我查证了一下。
确认
我在同一任务定义中启动了一个额外的用于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端口被监听着。
我会尝试使用浏览器进行访问。
数据库报了没有的错误,但是连接到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的链接功能似乎已经过时了。https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/
由于Fargate无法进行卷挂载,因此我认为很少会运行用于保持数据持久性的MySQL容器。