docker swarm mode的服務發現和LB詳解
docker Swarm mode下會為每個節點的docker engine內置一個DNS server,各個節點間的DNS server通過control plane的gossip協議互相交互信息。註:此處DNS server用於容器間的服務發現。
swarm mode會為每個--net=自定義網路的service分配一個DNS entry。註:目前必須是自定義網路,比如overaly。而bridge和routing mesh的service,是不會分配DNS的。
下圖是dockercon 2016上關於swarm mode的服務發現的slide。
二、Load Balancingdocker swarm mode有兩種LB模式:1. Internal Load Balancing 2. Ingress Load Balancing。
要理解swarm的LB,需要具備1. iptables,2. LVS,3.CNM網路模型等知識。
1. Internal Load Balancing
顧名思義,此模式的LB用於同一個Swarm集群中容器和容器之前的互訪。
此模式下也分兩種情況:
1.1 當service的endpoint-mode為dnsrr時,service的DNS entry對應一組具體服務IP,通過round-robin輪詢各個IP來達到LB的效果。
此時的Traffic Flow如圖:1> 客戶端容器通過service域名訪問相應服務,節點docker的DNS server會round-robin各個後端容器的服務IP給Client container。
2> LB到各個服務的真實IP。
1.2 非dnsrr的自定義網路時,service的DNS entry對應一組服務的VIP,再由VIP+內核IPVS來做相應的LB。(當然也可以直接訪問VIP)
此時的Traffic Flow如圖:Internal LB通過在同一個網路中每個容器的networksandbox中配置相應的iptables和IPVS來達到負載均衡(LB)的效果。
同一個網路中每增加一個服務,每個容器的network sandbox中就會相應添加對應的iptables和ipvs規則,從而使得服務在整個網路內可訪問。1> 同處於網路my-net中的容器可以通過service域名或者VIP來訪問service;通過域名訪問時,容器會訪問docker engine中內置的DNS服務,從而獲取VIP。
進入client container:docker exec –it container_id/container_name sh
2> CNM網路模型中一個容器對應一個sandbox,也即容器的net namespace。容器的sandbox中設置iptables的mangle表,設置OUTPUT鏈,將destIP==VIP的包標記fwmark。
進入該容器的net namespace(即sandbox):
docker inspect container_id/container_name | grep -i sandboxnsenter --net=SandboxKey(/var/run/docker/netns/xxxxx)
Sandbox中iptablesmangle表內容:
serviceA的VIP為192.168.10.7,Fwmark設置為0x107,即2633> Sandbox中會設置kernel中的LVS模塊,將標記fwmark的包LB到各個實際IP中,默認round-robin演算法,VS/NAT方式。容器底層間通過overlay網路互連通信。
Sandbox中Ipvs規則:
FWM為263的包,LB到192.168.10.8和192.168.10.92. Ingress Load Balancing
註:此圖Task1,Task1,Task1應該為Task1,Task2,Task3
Ingress LB可以將容器網路中的服務暴露到宿主機網路中,從而被外部所訪問。
Swarm mode下,docker會創建一個默認的overlay網路—ingressnetwork。Docker也會為每個worker節點創建一個特殊的net namespace(sandbox)-- ingress_sbox。ingress_sbox有兩個endpoint,一個用於連接ingress network,另一個用於連接local bridge network -- docker_gwbridge。Ingressnetwork的IP空間為10.255.0.0/16,所有router mesh的service都共用此空間。
IngressLB分別在1)節點iptables,2)ingress_sbox的iptables和ipvs,3)service容器的iptables處設置相應規則,從而可以在宿主機網路上通過宿主機IP和published埠來訪問容器網路的服務。
整體flow圖:
1) 宿主機網路通過worker節點IP和service published port來訪問服務。比如:定義-p 8080:80,可以通過workerIP:8080 訪問服務。
2) Worker節點iptables中NAT表定義規則,對於匹配published的宿主機埠(8080)的數據,將其dstIP轉換成ingress_sbox中的ip:172.18.0.2。
3) Ingress_sbox是swarm為每個worker節點默認創建的netnamespace,用於連接ingress overlay network。此處會設置mangle表,將dst port為8080的數據做標記(fwmark)。
4) Ingress_sbox會設置kernel中的LVS模塊,將標記fwmark的包LB到各個實際IP中,默認round-robin演算法,forware為VS/NAT方式。容器底層間通過overlay網路互連通信。
5) Service的各個容器會將dstport為8080的數據的dst port轉換成80,從而訪問到真實的服務。
三、混合LB
非dnsrr的internal LB和ingress LB可以同時使用,但配置dnsrr時,不能使用ingress LB,即不能published port。
四、Reference:
l Docker Networking Deep Dive
https://www.youtube.com/watch?v=Gwdo3fo6pZg&list=PLkA60AVN3hh9gnrYwNO6zTb9U3i1Y9FMY&index=11l Ipvsadm
http://kb.linuxvirtualserver.org/wiki/Ipvsadml Service Discovery and Load balancing Internalsin Docker 1.12
Service Discovery and Load balancing Internals in Docker 1.12
l docker的網路-Container network interface(CNI)與Container network model(CNM)
https://xuxinkun.github.io/2016/07/22/cni-cnm/l What』s new in Docker 1.12.0 Load-Balancingfeature?
Dockercon 2017推薦閱讀:
※docker在web開發中得使用流程是怎樣的?
※學習docker要有什麼基礎?
※將JVM運行於DOCKER上,有什麼意義嗎?或者,什麼場景下,需要把JVM運行於DOCKER上?
※Docker 容器與鏡像的儲存
※1月6日@Kubernetes,2018容器熱點私享會
TAG:Docker |