Docker routing mesh
routing mesh:无论访问哪个节点,即使该节点上没有运行 service 的副本,最终都能访问到 service。
在swarm中使用ingress network,需要防火墙允许以下端口通过
- Port 7946
- Port 4789
发布服务的端口
docker service create \
--name <SERVICE-NAME> \
--publish published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \
<IMAGE>
- target: 指定容器内的端口(必须)
- published: 为service提供外部访问的端口
如果不指定published,将绑定一个随机的端口(可选)
下面的命令将nginx容器80端口发布到集群中所有节点的8080端口
[root@node1 ~]# docker service create --name my-web --publish published=8080,target=80 --replicas 2 nginx
1n4wovg4797wt8oqhmrxle34w
访问任意节点的8080端口,docker可以把请求转到容器中
给已经存再的service绑定外部访问端口
$ docker service update \
--publish-add published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \
<SERVICE>
查看服务的发布端口
[root@node1 ~]# docker service inspect --format="{{json .Endpoint.Spec.Ports}}" my-web
[{"Protocol":"tcp","TargetPort":80,"PublishedPort":8080,"PublishMode":"ingress"}]
[root@node1 ~]#
只发布TCP或UDP端口
默认情况下,发布的是一个TCP端口。可以手动指定是TCP端口,还是UDP端口
只发布TCP端口
docker service create --name dns-cache \
--publish published=53,target=53 \
dns-cache
发布TCP和UDP端口
$ docker service create --name dns-cache \
--publish published=53,target=53 \
--publish published=53,target=53,protocol=udp \
dns-cache
只发布UDP端口
$ docker service create --name dns-cache \
--publish published=53,target=53,protocol=udp \
dns-cache
Bypass the routing mesh
You can bypass the routing mesh, so that when you access the bound port on a given node, you are always accessing the instance of the service running on that node. This is referred to as host mode. There are a few things to keep in mind.
- If you access a node which is not running a service task, the service does not listen on that port. It is possible that nothing is listening, or that a completely different application is listening.
- If you expect to run multiple service tasks on each node (such as when you have 5 nodes but run 10 replicas), you cannot specify a static target port. Either allow Docker to assign a random high-numbered port (by leaving off the published), or ensure that only a single instance of the service runs on a given node, by using a global service rather than a replicated one, or by using placement constraints.
To bypass the routing mesh, you must use the long --publish service and set mode to host. If you omit the mode key or set it to ingress, the routing mesh is used. The following command creates a global service using host mode and bypassing the routing mesh.
$ docker service create --name dns-cache \
--publish published=53,target=53,protocol=udp,mode=host \
--mode global \
dns-cache
配置外部负载均衡器
可以为配置外部负载均衡器来将请求路由到集群内部。外部负载均衡器与routing mesh结合使用,或者单独使用
使用routing mesh
配置haproxy来平衡对发布到8080端口的nginx请求
编辑 /etc/haproxy/haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
...snip...
# Configure HAProxy to listen on port 80
frontend http_front
bind *:80
stats uri /haproxy?stats
default_backend http_back
# Configure HAProxy to route requests to swarm nodes on port 8080
backend http_back
balance roundrobin
server node1 192.168.99.100:8080 check
server node2 192.168.99.101:8080 check
server node3 192.168.99.102:8080 check
Without the routing mesh
To use an external load balancer without the routing mesh, set --endpoint-mode to dnsrr instead of the default value of vip. In this case, there is not a single virtual IP. Instead, Docker sets up DNS entries for the service such that a DNS query for the service name returns a list of IP addresses, and the client connects directly to one of these. You are responsible for providing the list of IP addresses and ports to your load balancer. See Configure service discovery.
参考
https://docs.docker.com/engine/swarm/ingress/
https://www.cnblogs.com/CloudMan6/p/7930321.html