这是我已经部署的一个相当简单的docker堆栈:
version: "3"
services:
mysql:
environment:
- MYSQL_ROOT_PASSWORD=welcome
- MYSQL_DATABASE=db1
- MYSQL_USER=dbuser
- MYSQL_PASSWORD=welcome
- MYSQL_ROOT_HOST=*
- MYSQL_LOG_CONSOLE=true
image: mysql/mysql-server:latest
deploy:
replicas: 1
restart_policy:
condition: on-failure
ports:
- "3306:3306"
networks:
- test_net
repository:
environment:
- DB_USER=dbuser
- DB_PASSWORD=welcome
- DB_HOST=mysql
- DB_PORT=3306
image: private_repo/repository-service:0.1.3
deploy:
replicas: 1
restart_policy:
condition: on-failure
ports:
- "9091:80"
networks:
- test_net
deployment:
environment:
- DB_USER=dbuser
- DB_PASSWORD=welcome
- DB_HOST=mysql
- DB_PORT=3306
image: private_repo/deployment-service:0.1.3
deploy:
replicas: 1
restart_policy:
condition: on-failure
ports:
- "9092:80"
networks:
- test_net
networks:
test_net:
部署docker stack之后,我可以看到所有服务正在运行。但是,当我尝试通过主机系统上的程序(例如Postman)访问存储库或部署服务的REST API时,此操作不起作用(连接只是挂起)。所以我做了一些调试:
1)容器可以使用服务名称在覆盖网络上相互ping通。例如
docker exec -i edb7432cdb64 ping mysql
PING mysql (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2 (10.0.0.2): icmp_seq=1 ttl=64 time=0.050 ms
64 bytes from 10.0.0.2 (10.0.0.2): icmp_seq=2 ttl=64 time=0.065 ms
64 bytes from 10.0.0.2 (10.0.0.2): icmp_seq=3 ttl=64 time=0.058 ms
64 bytes from 10.0.0.2 (10.0.0.2): icmp_seq=4 ttl=64 time=0.083 ms
64 bytes from 10.0.0.2 (10.0.0.2): icmp_seq=5 ttl=64 time=0.062 ms
2)从一个容器中,我可以使用curl来访问另一个容器,但只能在内部端口上。
例如,这可行:
docker exec -i edb7432cdb64 curl http://models:80/services/v1/models
但这会返回错误:
docker exec -i edb7432cdb64 curl http://models:9091/services/v1/models
curl: (7) Failed connect to models:9091; Connection refused
3)覆盖网络似乎缺少信息:
docker inspect tf0z2ht7tfhe
[
{
"Name": "repository2_test_net",
"Id": "tf0z2ht7tfhefrcqvh4g0a2zq",
"Created": "0001-01-01T00:00:00Z",
"Scope": "swarm",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "",
"Options": null,
"Config": null
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": null,
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": "4097"
},
"Labels": {
"com.docker.stack.namespace": "repository2"
}
}
]
当我尝试在Mac上部署此确切的堆栈时,它可以工作!覆盖网络的相同检查将提供更多信息。一方面,它显示了一个容器列表,还给了我一个子网和网关。
以某种方式在我的Linux机器上,用于覆盖的网络设置不正确。我不确定我可能会错过什么配置。 Mac的docker stack / swarm与Linux的docker stack / swarm之间似乎并没有太大区别。任何关于看什么或下一步尝试的指针将不胜感激。
docker -v
Docker version 17.06.2-ol, build d02b7ab
答案 0 :(得分:0)
所以看来,尽管我无法使用例如localhost:9091访问服务,但可以使用群体管理器地址访问它们。
swarm init
Swarm initialized: current node (a5aiio3xh1qfpnw6gf8keam4y) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-2e1yxt76ui6syrk2p4970hns25n57tquvprxn1l160vnrk0bog-bi10m0b0jcz54cv17pd469a26 10.*.*.*:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
我可以通过10. 。。*:9091访问我的服务。不知道为什么只在Linux上发生这种情况,或者不确定是否可以在此配置中使用localhost。但是目前这行得通。
答案 1 :(得分:0)
端口映射仅影响主机(或者,对于您而言,我想是群管理器)。在用户定义的网络中,容器只能看到彼此的实际端口。如果要通过映射到主机的端口访问某个容器,则需要使用主机的IP:docker exec -i edb7432cdb64 curl http://<Swarm manager IP>:9091/services/v1/models
。但这将很尴尬,而且毫无用处。