两个Docker容器在macOS上的通信10.12
我正在使用MacOS 10.12上的Docker 1.12.5,并且正在使用一个应用程序映像和一个共享的redis映像来设置一个开发环境,这个映像有一些预先填充的configurationvariables。
即使遵循几个教程(并阅读关于docker0
在Mac上不可用),我正在努力连接两个容器。
我开始使用我的redis
映像:
docker run -d -p 6379:6379 (IMAGE ID)
在我的redis
映像中,我有:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES dffb89854618 d59 "docker-entrypoint.sh" 20 seconds ago Up 19 seconds 0.0.0.0:6379->6379/tcp drunk_williams
从我的Mac,我可以通过redis-cli
命令成功连接,没有问题。
但是,当我启动一个简单的ubuntu
映像,我似乎无法连接到这个单独的redis
映像:
root@2d4eda315f4f:/# ifconfig eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:03 inet addr:172.17.0.3 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:20707 errors:0 dropped:0 overruns:0 frame:0 TX packets:11515 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:28252929 (28.2 MB) TX bytes:635848 (635.8 KB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:12 errors:0 dropped:0 overruns:0 frame:0 TX packets:12 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:680 (680.0 B) TX bytes:680 (680.0 B) root@2d4eda315f4f:/# telnet localhost 6379 Trying ::1... Trying 127.0.0.1... telnet: Unable to connect to remote host: Connection refused root@2d4eda315f4f:/# telnet 172.17.0.3 6379 Trying 172.17.0.3... telnet: Unable to connect to remote host: Connection refused
这是主机中没有docker0
接口的结果吗? 是否有一些简单的解决方法允许这些容器在开发环境中进行通信(当在同一主机上运行时)?
更新:试图使用命名容器,我仍然无法连接。
docker run -d --name redis_server redis
结果是:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5d05820aa985 redis "docker-entrypoint.sh" 43 hours ago Up 1 seconds 6379/tcp redis_server
但是,如果我启动一个新的Ubuntu容器:
root@e92b47419bc4:/# redis-cli -h redis_server Could not connect to Redis at redis_server:6379: Name or service not known
我不知道如何find/连接到第一个redis_server
容器。
每个容器都有自己的本地主机
每个服务都在自己的容器中运行。 从Ubuntu容器的angular度来看,redis不在本地主机上监听。
使用Dockernetworking
为了让你的容器进行通信,他们应该在同一个Dockernetworking上。 这包括三个步骤:
- 创build一个Dockernetworking
- 给你的容器名称
- 将您的容器连接到您创build的networking
通过这样做,容器可以使用它们的名字相互交谈,就好像它们是主机名一样。
有不止一种方式来剥皮这只猫…我会在这个答案中看两个,但是可能还有其他一些方法来做到这一点,我不熟悉(比如使用Kubernetes或Swarm)。
手工操作
您可以使用docker network
命令为此应用程序创build一个networking。
# Show the current list of networks docker network ls # Create a network for your app docker network create my_redis_app
当你运行redis容器时,确保它有一个名字,并且在这个networking上。 如果你想(使用-p
),你可以在外部暴露端口(到macOS),但是这对于其他容器来说是不必要的。
docker run -d -p 6379:6379 --name redis_server --network my_redis_app <IMAGE ID>
现在运行你的Ubuntu容器。 如果你喜欢,你可以把它命名,但是我不会在这个例子中打扰,因为这个没有运行任何服务。
docker run -it --network my_redis_app ubuntu bash
现在从Ubuntu容器中,您应该能够使用名称redis_server
访问redis,就好像它是DNS名称一样。
使用Compose进行
我倾向于使用Compose构build像这样的设置,因为将它写入YAML文件(IMO)更容易。 以上是一个以docker-compose.yml格式重写的例子:
version: '2' services: redis: image: <IMAGE ID> networks: - my_redis_app ports: 6379:6379 ubuntu: image: ubuntu:latest networks: - my_redis_app networks: my_redis_app: driver: bridge
有了这个,您可以运行docker-compose up -d redis
并使用特定的Dockernetworking在线提供redis服务。 撰写将为您创buildnetworking,如果它不存在。
以这种方式运行Ubuntu容器是没有意义的……当然,它是交互式的。 但是我认为一旦你有了redis,你将会添加一些应用程序容器,或者像nginx这样的web代理,只要把其他的services
也放到services
中,你就可以一起pipe理它们。
由于ubuntu
是交互式的,你可以交互地运行它:
# without -d, container is run interactively docker-compose run ubuntu bash
现在在Ubuntu中,你应该能够使用它的名字来连接到redis,在这个例子中, redis
是简单的。