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

posted @ 2019-06-09 16:17  漂泊的蒲公英  阅读(805)  评论(0编辑  收藏  举报