我正在尝试设置一个具有以下服务的群:
这导致docker-compose文件类似于:
version: '3'
services:
proxy:
image: nginx:1.13.5-alpine
ports:
- "80:80"
deploy:
placement:
constraints: [node.role == manager]
depends_on:
- api
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
networks:
- webnet
api:
image: user/webapp:latest
deploy:
replicas: 4
ports:
- "8000:8000"
depends_on:
- postgres
- redis
networks:
- webnet
postgres:
image: postgres:9.6.5-alpine
ports:
- "5432:5432"
deploy:
placement:
constraints: [node.role == manager]
networks:
- webnet
redis:
image: redis:4.0.2-alpine
ports:
- "6379:6379"
deploy:
placement:
constraints: [node.role == manager]
command: redis-server --appendonly yes
networks:
- webnet
networks:
webnet:
我使用的nginx配置文件是:
upstream api {
server api:8000;
}
server {
listen 80;
location / {
proxy_pass http://api;
}
}
这一切都有效。我可以使用curl和nginx服务代理从另一台机器连接到相应的webapp服务。
问题是,我还可以从外部机器连接到redis,api和postgres服务。
我想要的是只从外部接口访问代理服务。
我想确保redis,api和postgres服务只能通过swarm访问。 (或者,只能在主机节点的本地网络上访问。在这种情况下,主机是CentOS 7设置为群集管理器。)
我尝试创建一个名为后端的覆盖网络,而不是使用网络,将internal
设置为true
。像这样:
docker network create -d overlay --internal backend
然后在docker-compose.yml文件中使用backend
网络而不是用于redis,postgres和api服务的webnet。这似乎不起作用。所有服务仍可在外部IP上使用。
我可以通过以下方式解决此问题:
虽然上述方法确实有效,但我真的更喜欢所有这些逻辑都在docker-compose级别强制执行,而不是依赖防火墙或外部进程。
答案 0 :(得分:2)
如果您不希望外部访问端口,则无需发布这些端口。容器总是可以通过公共docker网络将容器与容器通信,而不会发布端口。
version: '3'
services:
proxy:
image: nginx:1.13.5-alpine
ports:
- "80:80"
deploy:
placement:
constraints: [node.role == manager]
depends_on:
- api
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
networks:
- webnet
api:
image: user/webapp:latest
deploy:
replicas: 4
depends_on:
- postgres
- redis
networks:
- webnet
postgres:
image: postgres:9.6.5-alpine
deploy:
placement:
constraints: [node.role == manager]
networks:
- webnet
redis:
image: redis:4.0.2-alpine
deploy:
placement:
constraints: [node.role == manager]
command: redis-server --appendonly yes
networks:
- webnet
networks:
webnet: