docker swarm v1.12 的内部负载平衡机制是什么

What's the mechanism of Inner Load Balancing along with docker swarm v1.12

Docker Swarm模式实现了Inner Load Balancing,据我所知,nginx是硬负载均衡,zookeeper是软负载均衡。

那么 Docker v1.12 的内部负载均衡机制是什么?

里面有没有嵌入nginx或者类似zookeeper的方法?

"Inner"负载均衡?不完全是。
Commit ea4fef2 documents it (docs/swarm/key-concepts.md) 作为

Swarm uses ingress load balancing to expose the services you want to make available externally to the Swarm.
Swarm can automatically assign the service a PublishedPort or you can configure a PublishedPort for the service in the 30000-32767 range.
External components, such as cloud load balancers, can access the service on the PublishedPort of any node in the cluster, even if the node is not currently running the service.

Swarm has an internal DNS component that automatically assigns each service in the Swarm DNS entry.
Swarm uses internal load balancing to distribute requests among services within the cluster based upon the services' DNS name.

现在(docker 2016 年 8 月 1.12 日),内部负载平衡无法始终如一地工作:issue 25325

➜  ~ time curl http://10.218.3.5:30000
I'm 272dd0310a95
curl http://10.218.3.5:30000  0.01s user 0.01s system 6% cpu 0.217 total
➜  ~ time curl http://10.218.3.5:30000
curl: (7) Failed to connect to 10.218.3.5 port 30000: Operation timed out

并且 swarmkit issue 1077 说明还没有计划

provide capabilities for session stickiness (cookie-based etc.) in this router mesh.
As awesome as it would be, not all apps are stateless, and we need to route users to the proper container in certain cases

因为:

since we do load balancing at L3/L4 it cannot be bases on things like session cookie.
The best that can be done is to have Source IP based stickiness.

源 IP 并不总是足够好:

That wouldn't work for our case.
We would have an upstream load balancer (F5) which would make traffic appear to come from a single IP, the "SNAT pool" IP on the F5 since it is a full proxy.
Effectively, Source IP based stickiness would cause all requests to go to one container since all the source IPs would come from the same address.

所以内部负载均衡器仍然相当"basic":

The main issue with adding "session stickyness" is that there are a hundred ways to do it.
It is also an L7 feature, whereas our load balancing operates at L3/4.

There are two high-level paths here:

  • Monitor events coming from the docker API to modify F5 state to route directly task slots.
  • Integrate with libnetwork and have the loadbalancer operate as an L7 LB would if it were running directly in the swarm.

目前的结论是:

If you want to handle all aspects of load balancing and not use IPVS, you can disable it by running services in DNSRR mode. You can run any load balancer inside of swarm to do load balancing, bypassing the service VIP and populate backends with the DNSRR entries.

这就是为什么最新版本 1.12 PR 827 添加了对 DNSRR 模式和禁用入口的支持。