Docker Swarm 访问容器到已发布端口上的容器?
Docker Swarm Access Container to Container on Published Port?
我已经看到至少 10 个这样的问题,但找不到答案。
我要从 Rancher 转移到 Docker Swarm。
我使用 docker-compose 来部署堆栈。
我正在使用 linux 主机。
➜ swarm git:(master) ✗ docker --version
Docker version 20.10.9, build c2ea9bc
➜ swarm git:(master) ✗ docker-compose --version
docker-compose version 1.29.2, build 5becea4c
我遇到的问题是我有一个容器(服务)smtp
在端口 2525
上侦听。在来自其他服务的 swarm 中,我需要将此服务引用为 smtp:25
而不是 2525
。当然,我只是做了一个端口映射。但是其他服务无法访问 25
端口上的服务,只能访问 2525
.
请注意,为了进行测试,我尝试映射为 2526->2525
以排除任何权限问题。
我的 docker-compose 条目如下所示:
smtp:
image: <my repository>
user: node
environment:
- NODE_ENV=production
privileged: true
ports:
- published: 2526
target: 2525
protocol: tcp
mode: ingress # I don't need this on the host, just on the swarm vip.
deploy:
replicas: 2
placement:
constraints:
- node.labels.scheme == task
restart_policy:
condition: on-failure
delay: 5s # how long to wait between retarts
window: 20s # How long to determine if startup has succeeded
healthcheck:
test: netstat -l | grep 2525
interval: 10s
timeout: 10s
retries: 10
start_period: 20s
从 busybox 容器中,我可以成功 telnet smtp 2525
但 telnet smtp 2526
给了我 connection refused
。另外,我也无法从 smtp 容器内远程登录到 smtp:2526。
Docker 检查服务显示
"Endpoint": {
"Spec": {
"Mode": "vip",
"Ports": [
{
"Protocol": "tcp",
"TargetPort": 2525,
"PublishedPort": 2526,
"PublishMode": "ingress"
}
]
},
"Ports": [
{
"Protocol": "tcp",
"TargetPort": 2525,
"PublishedPort": 2526,
"PublishMode": "ingress"
}
],
"VirtualIPs": [
{
"NetworkID": "wv8fe0yih5ql9ye09chcl6y1b",
"Addr": "10.0.0.41/24"
},
{
"NetworkID": "5a9tjqidsvphi9lphldit62tm",
"Addr": "10.0.2.145/24"
}
]
}
Netstat 揭示
~/app $ netstat -tulpn | grep LISTEN
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:2525 0.0.0.0:* LISTEN 13/node
tcp 0 0 127.0.0.11:42381 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:783 0.0.0.0:* LISTEN -
有什么想法吗?我不允许这样做吗?
编辑:
我必须让容器监听端口 25 才能让它工作。
首先,在 docker swarm 上,您使用 docker stack deploy
而不是 docker compose
来部署服务。
Docker swarm 管理与覆盖网络的服务连接:当您部署堆栈 (docker stack deploy
) 时,会隐式创建覆盖网络并将服务附加到它。连接到覆盖网络的所有服务都可以使用 docker 的网状网络 dns 发现相互发现。
因此,实际上,您可以使用修改后的堆栈文件来部署您的 smtp 服务,使其看起来更像这样:
version: "3.9"
networks:
public:
attachable: true
driver: overlay
name: smtp
services:
smtp:
image: ...
command: .... --listen :25
networks:
- public
ports:
- 2525:25
healthcheck:
test: netstat -l | grep 25
...
进一步注意:当服务使用 dockers 网桥或覆盖网络相互连接时,没有端口重新映射。 “ports”指令仅适用于入口,即从 swarm 外部到达 docker 节点的数据包,需要路由到服务。
因此,对于通过 :25 进行通信的服务到服务流量,需要将 smtp 容器配置为侦听 :25。
完成后,您可以通过指定目标网络从容器和服务连接到 smtp。
考虑到这一点,并假设可以将 smtp 服务配置为侦听 :25,我将该服务明确附加到撰写文件中名为“public”的网络。这个网络是用全局名称“smtp”创建的,它被标记为可附加的,所以临时容器可以附加到它。它明确声明为“覆盖”,因为 docker compose 将部署此 compose 并尝试将其创建为 bridge
网络。
然后,为了验证这是否有效,可以使用 netshoot 容器。只需将它连接到现在可用的网络并验证 dns 解析该网络上的“smtp”名称,并且端口 25 可以访问。
docker run --network smtp --rm -it nicolaka/netshoot
$ telnet smtp 25
...
其他需要使用 smtp 的服务将附加到 smtp public 网络:
version: "3.9"
networks:
smtp:
external: true
services:
some-other-service:
image: ...
command: ....
environment:
SMTP_URL: smtp://smtp:25
networks:
- default
- smtp
这里我明确地将此服务附加到隐式默认堆栈网络,以防除了 smtp 网络之外还有其他服务与之通信。
我已经看到至少 10 个这样的问题,但找不到答案。
我要从 Rancher 转移到 Docker Swarm。
我使用 docker-compose 来部署堆栈。
我正在使用 linux 主机。
➜ swarm git:(master) ✗ docker --version
Docker version 20.10.9, build c2ea9bc
➜ swarm git:(master) ✗ docker-compose --version
docker-compose version 1.29.2, build 5becea4c
我遇到的问题是我有一个容器(服务)smtp
在端口 2525
上侦听。在来自其他服务的 swarm 中,我需要将此服务引用为 smtp:25
而不是 2525
。当然,我只是做了一个端口映射。但是其他服务无法访问 25
端口上的服务,只能访问 2525
.
请注意,为了进行测试,我尝试映射为 2526->2525
以排除任何权限问题。
我的 docker-compose 条目如下所示:
smtp:
image: <my repository>
user: node
environment:
- NODE_ENV=production
privileged: true
ports:
- published: 2526
target: 2525
protocol: tcp
mode: ingress # I don't need this on the host, just on the swarm vip.
deploy:
replicas: 2
placement:
constraints:
- node.labels.scheme == task
restart_policy:
condition: on-failure
delay: 5s # how long to wait between retarts
window: 20s # How long to determine if startup has succeeded
healthcheck:
test: netstat -l | grep 2525
interval: 10s
timeout: 10s
retries: 10
start_period: 20s
从 busybox 容器中,我可以成功 telnet smtp 2525
但 telnet smtp 2526
给了我 connection refused
。另外,我也无法从 smtp 容器内远程登录到 smtp:2526。
Docker 检查服务显示
"Endpoint": {
"Spec": {
"Mode": "vip",
"Ports": [
{
"Protocol": "tcp",
"TargetPort": 2525,
"PublishedPort": 2526,
"PublishMode": "ingress"
}
]
},
"Ports": [
{
"Protocol": "tcp",
"TargetPort": 2525,
"PublishedPort": 2526,
"PublishMode": "ingress"
}
],
"VirtualIPs": [
{
"NetworkID": "wv8fe0yih5ql9ye09chcl6y1b",
"Addr": "10.0.0.41/24"
},
{
"NetworkID": "5a9tjqidsvphi9lphldit62tm",
"Addr": "10.0.2.145/24"
}
]
}
Netstat 揭示
~/app $ netstat -tulpn | grep LISTEN
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:2525 0.0.0.0:* LISTEN 13/node
tcp 0 0 127.0.0.11:42381 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:783 0.0.0.0:* LISTEN -
有什么想法吗?我不允许这样做吗?
编辑:
我必须让容器监听端口 25 才能让它工作。
首先,在 docker swarm 上,您使用 docker stack deploy
而不是 docker compose
来部署服务。
Docker swarm 管理与覆盖网络的服务连接:当您部署堆栈 (docker stack deploy
) 时,会隐式创建覆盖网络并将服务附加到它。连接到覆盖网络的所有服务都可以使用 docker 的网状网络 dns 发现相互发现。
因此,实际上,您可以使用修改后的堆栈文件来部署您的 smtp 服务,使其看起来更像这样:
version: "3.9"
networks:
public:
attachable: true
driver: overlay
name: smtp
services:
smtp:
image: ...
command: .... --listen :25
networks:
- public
ports:
- 2525:25
healthcheck:
test: netstat -l | grep 25
...
进一步注意:当服务使用 dockers 网桥或覆盖网络相互连接时,没有端口重新映射。 “ports”指令仅适用于入口,即从 swarm 外部到达 docker 节点的数据包,需要路由到服务。 因此,对于通过 :25 进行通信的服务到服务流量,需要将 smtp 容器配置为侦听 :25。
完成后,您可以通过指定目标网络从容器和服务连接到 smtp。
考虑到这一点,并假设可以将 smtp 服务配置为侦听 :25,我将该服务明确附加到撰写文件中名为“public”的网络。这个网络是用全局名称“smtp”创建的,它被标记为可附加的,所以临时容器可以附加到它。它明确声明为“覆盖”,因为 docker compose 将部署此 compose 并尝试将其创建为 bridge
网络。
然后,为了验证这是否有效,可以使用 netshoot 容器。只需将它连接到现在可用的网络并验证 dns 解析该网络上的“smtp”名称,并且端口 25 可以访问。
docker run --network smtp --rm -it nicolaka/netshoot
$ telnet smtp 25
...
其他需要使用 smtp 的服务将附加到 smtp public 网络:
version: "3.9"
networks:
smtp:
external: true
services:
some-other-service:
image: ...
command: ....
environment:
SMTP_URL: smtp://smtp:25
networks:
- default
- smtp
这里我明确地将此服务附加到隐式默认堆栈网络,以防除了 smtp 网络之外还有其他服务与之通信。