標籤:

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 Balancing

docker 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,即263

3> Sandbox中會設置kernel中的LVS模塊,將標記fwmark的包LB到各個實際IP中,默認round-robin演算法,VS/NAT方式。容器底層間通過overlay網路互連通信。

Sandbox中Ipvs規則:

FWM為263的包,LB到192.168.10.8和192.168.10.9

2. 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

youtube.com/watch?

l Ipvsadm

kb.linuxvirtualserver.org

l 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)

xuxinkun.github.io/2016

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 |