让我先描述一下我最初的问题和解决方案:
我有几个 docker 撰写文件,它们描述了我的应用程序的不同部分。这些部件是独立开发和部署的,因此无法集成到单个撰写文件中。但是这些组件需要相互通信,我目前使用的解决方案是拥有一个所有服务都连接到的外部网络(网桥(。到目前为止一切顺利,只要我连接到自定义桥接网络,我确实可以连接到使用任何 docker 撰写文件启动的服务:
$ docker run --network=mynet --rm --name ping_test -it xenial-networking bash
root@0319469f7951:/# ping -c 1 proj_web_1
PING proj_web_1 (172.30.0.3) 56(84) bytes of data.
64 bytes from 172.30.0.3: icmp_seq=1 ttl=64 time=0.071 ms
--- proj_web_1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.071/0.071/0.071/0.000 ms
为什么要使用proj_web_1
?因为这是码头工人撰写的 DNS 条目正在创建。
这工作正常,没有人在乎域名中的下划线不是那么好。
没有人。。。除了看起来django
:
ERROR Invalid HTTP_HOST header: 'proj_web_1:8000'. The domain name provided is not valid according to RFC 1034/1035.
172.30.0.5 - admin [07/May/2018:05:41:53 +0000] "OPTIONS /api/v1/expansions/ HTTP/1.1" 400 58663 "-" "python-requests/2.18.4"
似乎 docker-compose 不支持使用连字符而不是下划线。
可能是我可以通过在我的 django 服务中启用DEBUG
来解决此问题。
有没有一种更干净的方法来启用它,而无需在 django 调试模式下运行? 有没有办法告诉 docker 撰写停止使用下划线?
交叉组合网络连接
运行撰写项目时,可以通过服务的全名(包括项目名称前缀,例如myproject_web_1
(和服务的服务名称(如 compose 文件中指定(访问服务,例如web
。短名称是网络范围的别名,这意味着连接到同一网络的任何容器都可以通过此名称访问容器。
默认情况下,docker-compose
为每个撰写项目(projectname_default
(创建一个网络,以便撰写项目中的所有服务都可以通信。由于该网络是为每个项目单独创建的,因此两个撰写项目不共享同一网络,并且其服务与其他撰写项目隔离。
但是,可以使撰写项目(或撰写项目中的各个服务(共享同一网络。
示例 1 - 对整个项目使用共享网络
以下撰写文件指定默认网络的自定义名称;两个合成文件都使用sharednet
网络作为默认网络,这意味着两个合成项目的服务将连接到同一网络:
撰写文件 1 (compose1.yml(:
version: '3.5'
services:
compose1service:
image: busybox
tty: true
networks:
default:
name: sharednet
撰写文件 2 (compose2.yml(:
version: '3.5'
services:
compose2service:
image: busybox
tty: true
networks:
default:
name: sharednet
为了说明这一点:
启动两个撰写文件:
docker-compose -f compose1.yml --project-name=compose1 up -d
docker-compose -f compose2.yml --project-name=compose2 up -d
使用短名称(compose2service
(从compose1service
容器中的服务内部pingcompose2service
;
docker exec compose1_compose1service_1 ping -c1 compose2service
PING compose2service (172.20.0.3): 56 data bytes
64 bytes from 172.20.0.3: seq=0 ttl=64 time=0.134 ms
--- compose2service ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.134/0.134/0.134 ms
反之亦然:
docker exec compose2_compose2service_1 ping -c1 compose1service
PING compose1service (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.151 ms
--- compose1service ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.151/0.151/0.151 ms
全名(包括项目前缀(也是如此;
docker exec compose2_compose2service_1 ping -c1 compose1_compose1service_1
PING compose1_compose1service_1 (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.151 ms
--- compose1_compose1service_1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.151/0.151/0.151 ms
示例 2 - 对项目中的某些服务使用共享网络
在此示例中,两个撰写项目都有自己的("默认"(网络,但除此之外,还添加了共享网络以允许某些服务连接到另一个撰写项目中的服务。
撰写文件 1 (compose3.yml(:
version: '3.5'
services:
compose3service:
image: busybox
tty: true
networks:
- default
- sharednet
compose3otherservice:
image: busybox
tty: true
networks:
sharednet:
name: mysharednetwork
注: 如果指定服务应连接到哪些网络,则会覆盖默认值,这意味着该服务不再自动连接到
default
网络。将default
网络包括在网络列表中,以允许服务与撰写项目中的其他服务进行通信。
撰写文件 2 (compose4.yml(:
version: '3.5'
services:
compose4service:
image: busybox
tty: true
networks:
- default
- sharednet
compose4otherservice:
image: busybox
tty: true
networks:
sharednet:
name: mysharednetwork
启动两个撰写文件:
docker-compose -f compose3.yml --project-name=compose3 up -d
docker-compose -f compose4.yml --project-name=compose4 up -d
同样,从compose3service
ping 到其他撰写项目中的compose4service
服务(通过短名或全名(;
docker exec compose3_compose3service_1 ping -c1 compose4service
PING compose4service (172.22.0.3): 56 data bytes
64 bytes from 172.22.0.3: seq=0 ttl=64 time=0.110 ms
--- compose4service ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.110/0.110/0.110 ms
docker exec compose3_compose3service_1 ping -c1 compose4_compose4service_1
PING compose4_compose4service_1 (172.22.0.3): 56 data bytes
64 bytes from 172.22.0.3: seq=0 ttl=64 time=0.093 ms
--- compose4_compose4service_1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.093/0.093/0.093 ms
但是,尝试以相同的方式连接到compose4otherservice
将失败,因为该服务未连接到mysharednetwork
网络:
docker exec compose3_compose3service_1 ping -c1 compose4otherservice
ping: bad address 'compose4otherservice'
docker exec compose3_compose3service_1 ping -c1 compose4_compose4otherservice_1
ping: bad address 'compose4_compose4otherservice_1'
注:
如果两个撰写项目具有同名的服务(例如,两个项目都具有名为web
的服务(,则应小心。在这种情况下,web
可能会从任一项目随机解析到web
服务。
我能够通过使用网络别名来解决问题,避免以下划线:
web:
restart: always
environment:
- DJANGO_SECRET_KEY=local
- DJANGO_CONFIGURATION=Develop
build:
context: ./
args:
- REGISTRY
image: web
command: ./run-gunicorn.sh
volumes:
- ./:/code
depends_on:
- postgres
networks:
spp:
aliases:
- projweb
现在我可以达到它:
root@a9c0fde612a1:/# ping -c 1 projweb
PING projweb (172.30.0.4) 56(84) bytes of data.
64 bytes from svc_web_1.spp (172.30.0.4): icmp_seq=1 ttl=64 time=0.082 ms
--- projweb ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.082/0.082/0.082/0.000 ms