(第四章)容器化思維

1.容器化思維

  • 容器的本質是一個進程以及運行該進程所需要的各種依賴,我們不需要去備份一個容器,而是應該把需要備份的數據放在容器外掛的volume裏或者數據庫裏。
  • 若要進入容器,進行程序調試的話:
docker exec -it <containerName> bash
  • Docker的日誌管理方法
    (1)在容器內收集
    (2)在容器外收集
    (3)在專用容器只能收集

  • 通過veth pair連接兩個network namespace
    缺點:如果有更多的network namespace需要連接,那就要引入虛擬網橋
    在這裏插入圖片描述

如閃圖4-1進行配置,過程如下:
都是在主機上輸入:
(1)創建兩個network namespace ns1,ns2
ip nets add ns1
ip nets add ns2

(2)創建veth pair設備veth-a,veth-b
ip link add veth-a type veth peer name veth-b

(3)將網卡分別放置到兩個namespace中
ip link set veth-a nets ns1
ip link set veth-b nets ns2

(4)啓動2張網卡
ip nets exec ns1 ip link set veth-a up
ip nets exec ns2 ip link set veth-b up

(5)分配IP
ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth-a
ip netns exec ns2 ip addr add 10.0.0.2/24 dev veth-b

(6)驗證
ip nets exec ns1 ping 10.0.0.2

2.如何將容器連接到本機?

  • (1)要使容器和容器主機處於同一個網絡,那麼容器和主機應該處在一個二層網絡中。即:把兩臺機器連接到同一個交換機或者連在不同的級聯的交換機上
  • (2)在虛擬網橋中,可以將容器連在一個二層網絡中,只要將主機的網卡橋接到虛擬網絡中,就能將容器和主機的網絡連接起來
    在這裏插入圖片描述
目標:test1容器可以與本地主機相互訪問,並且容器可以通過本地網絡的網關
10.10.103.254訪問外部網絡。
如上圖所示:本地網絡爲10.10.103.0/24,網關是:10.10.103.254
主機ip:10.10.103.91/24,網卡爲eth0
容器test1:需要配置的ip:10.10.103.95/24

(1)啓動一個名爲test1的Docker容器
docker run -itd --name test1 --net-none ubuntu /bin/bash

(2)創建一個供容器連接的網絡br0
brctl addr br0
ip link et br0 up

(3)將主機的eth0橋接到br0,並把eth0的ip配置在br0上,由於是遠程操作,
會導致網絡斷開,因此放在一條命令中執行
 ip addr add 10.10.103.91/24 dev br0;\
 	ip addr del 10.10.103.91/24 dev eth0;\
 	brctl addif br0 eth0;\
 	ip route del default;\
 	ip route add default via 10.10.103.254 dev br0

(3)找到test1的PID,保存到pid中
pid=$(docker inspect --format '{{ .State.Pid }}' test1)
將容器的network namespace添加到/var/run/nets目錄下
mkdir -p /var/run/netns
ln -s /proc/$pid/ns/net /var/run/netns/$pid

(4)創建用於連接網橋和Docker容器的網卡設備
將veth-a連接到br0網橋中
ip link veth-a type veth peer name veth-b
brctl addif br0 veth-a
ip link set veth-a up

(5)將veth-b放到test1的network namespace中,命名爲eth0,併爲
其配置IP和默認路由
ip link set set veth-b netns $pid
ip netns exec $pid  ip link set dev veth-b name eth0
ip netns exec $pid ip link set eth0 up
ip netns exec $pid ip addr add 10.10.103.95/25 dev eth0
ip netns exec $pid ip route add default via 10.10.103.254

  • pipework:容器的SDN解決方案,可以在複雜場景下將容器連接起來 ,功能主要有:
    (1)支持Linux網橋連接容器並配置容器IP地址
    (2)支持使用macvlan設備將容器連接到本地網絡
    (3)支持DHCP獲取容器的IP
    (4)支持Open vSwitch
    (5)支持設置網卡MAC地址以及配置容器VLAN

3. pipework跨主機通信:橋接方式

  • (1)爲了隔離Docker容器間的網絡和主機網絡,需要額外使用一塊網卡橋接Docker容器。
    思路:在所有主機上用虛擬網橋將本機的Docker容器連接起來,然後將一塊一塊網卡加入到虛擬網絡中,使所有主機上的虛擬網橋級聯在一起,這樣,不同主機上的Docker容器也就如同連在了一個大的邏輯交換機上。
  • (2)爲解決不同機器上的Docker容器可能獲得相同的IP地址,解決辦法是:爲每一臺主機上的Docker daemon指定不同的–fixed-cidr參數,將不同主機上的Docker容器的地址限定在不同的網段中。
  • (3)eg如下,如圖4-3
    在這裏插入圖片描述
兩臺Ubuntu的主機host1和host2,每臺主機上有兩塊網卡eth0和eth1.
兩個主機的主網卡eth0連在主機的局域網環境中,IP分別爲:
10.10.103.91/2410.10.103.92/24.
兩個主機的網卡eth1用來橋接不同主機上的Docker容器,因此eth1不需要配置IP。

host1主機上的docker0的IP爲172.17.42.1/16,其IP範圍限制在172.17.1.0/24
host2主機上的docker0網橋地址修改爲172.17.42.2/16,其IP範圍限制在172.17.2.0/24網段,然後將eth1橋接到
docker0中。

具體配置:
(1)在host1上的操作(暫時):
echo ‘DOCKER_OPTS="--fixed-cidr=172.17.1.1/24"' >> /etc/default/docker
service docker stop 
service docker start
將eth1網卡接入到docker0網橋
brctl addif docker0 eth1

(2)在host2上的操作(暫時)
echo ‘DOCKER_OPTS="--fixed-cidr=172.17.2.1/24"' >> /etc/default/docker
爲了避免和host1上的docker0的IP衝突,修改docker0的ip
ifconfig docker0 172.17.42.2/16
service docker stop 
service docker start
將eth1網卡接入到docker0網橋
brctl addif docker0 eth1

or:
在host2上的操作(永久):寫入/etc/network/interfaces目錄下
auto docker0
iface docker0 inet static
	address 172.17.42.2
	netmask 255.255.0.0
	bridge_ports eth1
	bridge_stp off
	bridge_fd 0

(3)兩個主機上分別創建容器,並用nc測試
host1操作:
docker run -it --rm --name con1 ubuntu /bin/bash
進入容器操作:
ifconfig eth0
route -n
在主機操作:nc -l 172.17.1.1 9000

host2操作:
docker run -it --rm --name con2 ubuntu /bin/bash
進入容器操作:
ifconfig eth0
nc -w 1 -v 172.17.1.1 9000


總結:
(1)橋接方式:是將所有主機上的Docker容器放在一個二層網絡中,他們之間的
通信是由交換機直接轉發,不通過路由器。
(2)數據從容器從con1:172.17.1.1——>容器con2:172.17.2.1
查看本身的路由表發現目的地址和自己處於同一網段,那麼就不需要發往網關,
con1通過ARP廣播獲取到con2的MAC地址;
構造以太網幀發往con2即可;
docker0網橋充當普通的交換機轉發數據幀,數據流經的路徑如圖4-3中兩個容器
的eth0網卡所連接的路徑
(3)該例子不同主機的容器在同一子網,但是主機在同一個子網

4.pipework跨主機通信:直接路由

  • (1)爲了避免不同主機上的Docker容器使用相同的IP,所以應該爲不同的主機分配不同的IP子網。
  • (2)eg:如圖4-4
    在這裏插入圖片描述
命令如下:
兩臺主機host1,host2,每臺主機有1塊網卡。
host1的IP地址爲:10.10.103.91/24,Docker容器在172.17.1.0/24子網中
host2的IP地址爲:10.10.103.92/24,Docker容器在172.17.2.0/24子網中
路由規則:所有目的地址爲172.17.1.0/24的包都被轉發至host1,
目的地址爲172.17.2.0/24的包都被轉發至host2

(1)在host1主機上操作
ifconfig docker0 172.17.1.254/24
service docker restart
添加路由規則:目的地址爲172.17.2.0/24的包都被轉發至host2
route add -net 172.17.2.0 netmask 255.255.255.0 gw 10.10.103.92
配置iptables
iptables -t nat -F POSTROUTING
iptables -t nat -A POSTROUTING -s 172.17.1.0/24 ! -d 172.17.0.0/16 -j MASQUEREAD
docker run -it --name con1 ubuntu /bin/bash
在con1容器中:
nc -l 90002)在host2上操作
ifconfig docker0 172.17.2.254/24
service docker restart
添加路由規則:目的地址爲172.17.1.0/24的包都被轉發至host1
route add -net 172.17.1.0 netmask 255.255.255.0 gw 10.10.103.91
配置iptables
iptables -t nat -F POSTROUTING
iptables -t nat -A POSTROUTING -s 172.17.2.0/24 ! -d 172.17.0.0/16 -j MASQUEREAD
docker run -it --name con2 ubuntu /bin/bash
在con2容器中:
nc -w 1 -v 172.17.1.1 9000



總結:
(1)該例子不同主機的容器在不在一子網,但是主機在同一個子網
(2)從con1發往con2的包,首先發往con1的網關docker0:172.17.1.254,
然後通過查看主機的路由的路由得知,要將包發給host2:10.10.103.92,包
到達host2後,再轉發給host2的docker0:172.17.2.254,最後達到容器con2中
(3)與橋接網絡的區別:
橋接網絡中,所有主機上的容器都在172.17.0.0/16這個大網中,這從docker0的
IP:172.17.42.1/16可以看出。
在直接路由的方法中,不同主機上的Docker容器不在同一個網絡中,他們有不同的
網絡號。
host1的docker0的ip是從host1的docker0上獲取的;
橋接網絡是二層通信,通過MAC地址轉發;
直接路由爲三層通信,通過IP地址進行路由轉發。

(4)(瞭解即可)啓動Docker daemon時會創建下面的iptables規則:用於容器與外界通信
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUEREAD
從con1發往con2的包,在主機eth0轉發出去時,這條規則會將包的源地址改爲
eth0地址:10.10.103.91,so,con2看到包是從10.10.103.91發過來的

5.單主機Docker容器的VLAN劃分

  • 在交換機中劃分子網,,隔離廣播域的思路形成了VLAN
  • VLAN(Virtual Local Area Network)即:虛擬局域網,把一個大型交換網絡劃分爲許多個獨立的廣播域
  • 在多租戶的雲環境中,VLAN是一個最基本的隔離手段。
  • 多交換機VLAN劃分的eg:如下圖4-5
    在這裏插入圖片描述
1)PC1和PC3屬於VLAN100,PC2和PC4屬於VLAN200,所以PC1和PC3處於同一個二層網絡,PC2和PC4處於同一個二層網絡
Por1,25678屬於access端口,經過access端口的數據包會被打上tag標籤;
當數據幀從交換機內部通過access端口發送時,數據幀的VLAN ID和access端口的VLAN ID一致,access端口才接收此幀

(2)PORT3,4爲trunk端口,trunk端口是交換機和交換機之間的多個VLAN通道,表明只允許帶有這些VLAN ID的數據幀可以通過
  • 單主機Docler容器的VLAN劃分如下:
    Docker默認網絡下,所有的容器都連在docker0網橋上,docker0網橋是普通的Linux網橋,不支持VLAN功能
    eg如下:
    在這裏插入圖片描述
爲了方便操作,使用Open vSwitch代替docker0進行VLAN劃分
上述的四個容器都在同一個IP網段中,但是實際上它們是二層隔離的兩個網絡,屬於不同的廣播域

(1)在主機A上操作
在主機A上創建四個容器
docker run -itd --name con1 ubuntu /bin/bash
docker run -itd --name con2 ubuntu /bin/bash
docker run -itd --name con3 ubuntu /bin/bash
docker run -itd --name con4 ubuntu /bin/bash

用pipework將con1,con2劃分到一個VLAN中
pipwork ovs0 con1 192.168.0.1/24 @100
pipwork ovs0 con2 192.168.0.2/24 @100

用pipework將con3,con4劃分到一個VLAN中
pipwork ovs0 con3 192.168.0.3/24 @100
pipwork ovs0 con4 192.168.0.4/24 @100

pipework配置完成後,每個容器都多了一塊eth1網卡,eth1連在ovs0網橋上,並且進行了VLAN的隔離
con1和con2可以通信,但無法與con3或者con4通信
pipework就是將veth pair的一端加入到ovs0網橋,但不需要trunk端口

6.多主機Docker容器的VLAN劃分

  • 多主機VLAN劃分的前提是跨主機通信
  • eg:如下圖4-7
    在這裏插入圖片描述
1)大致方法:
用橋接的方式將所有容器連接在一個邏輯交換機上,再根據具體的情況進行VLAN的劃分;
橋接需要將主機的一塊網卡橋接到容器所連接的Open vSwitch網橋上,即需要一塊額外的網卡eth1
這裏,將不同VLAN的容器設在同一個子網中,僅僅是爲了演示隔離的效果
con1和con3屬於VLAN100;
con2和con4屬於VLAN200;
物理交換機上連接host1和host2的端口應設置爲trunk端口;
兩個主機的eth1沒有設置VLAN限制

(2)具體如下:
在host1上:
socker run -itd --name con1 ubuntu /bin/bash
docker run -itd --name con2 ubuntu /bin/bash
pipework ovs0 con1 192.168.0.1/24 @100
pipework ovs0 con2 192.168.0.2/24 @200
ovs-vsctl add-port ovs0 eth1;

在host2上:
socker run -itd --name con3 ubuntu /bin/bash
docker run -itd --name con4 ubuntu /bin/bash
pipework ovs0 con1 192.168.0.3/24 @100
pipework ovs0 con2 192.168.0.4/24 @200
ovs-vsctl add-port ovs0 eth1;

說明:主機在同一個子網

7.多租戶下的Overlay網絡簡介

  • (1)pipework跨主機通信,橋接和直接路由的方式必須保證主機在同一個子網中。 eg:若兩個數據中心的Docker容器需要通信時,這種方法就會失效
  • (2)Overlay網絡就是隧道技術,就是將一種網絡協議包裝在另一種協議中傳輸的技術。 eg:如果有兩個使用IPv6的站點之間需要通信,而它們之間的網絡使用IPv4協議,此時,就需將IPv6的數據包裝在IPv4中傳輸。
  • (3)當前的Overlay技術由:VXLAN和NVGRE
  • (4)在普通的網絡傳輸中,源IP地址和目的IP地址是不變的,而二層的幀頭在每個路由器節點上都會改變,這是TCP/IP協議的規定。
  • (5)用於封裝傳輸數據的協議有一個類似VLAN ID的標識,以區分不同的隧道。如圖4-8
    在這裏插入圖片描述

8.GRE實現Docker容器跨網絡通信(容器在同一個子網)

  • 如何才能使兩個辦公地點相互通信?
    由於兩個地點的主機都處在NAT轉化之下,so,兩地的主機並不能直接進行ping或者ssh操作。通過在雙方路由器上配置GRE隧道就可以實現。
  • 要求:路由器要配置一個GRE隧道的網卡設備。eg:GRE協議封裝的是IP包,實現了一個VPN的功能。
  • GRE實現Docker容器跨網絡通信eg,如圖4-12
    在這裏插入圖片描述
目前普遍的方法是結合Open vSwitch虛擬交換機;
兩臺主機處在不同的網絡中;
host1的IP爲10.10.103.91/24,host2的IP爲10.10.105.235/24
爲了解決兩臺主機上IP地址衝突問題,使用--fixedicidr參數對容器的IP進行限制;
ovs0爲Open VSwitch網橋,用來創建GRE隧道,並於docker0網橋相連;

(1)在host1操作:
echo 'DOCKER_OPTS="--fixed-cidr=172.17.1.1/24"'>>/etc/default/docker
service docker restart

創建ovs0,並與docker0相連
ovs-vsctl add-br ovs0
brctl addif docker0 ovs0

在ovs0上創建GRE隧道
ovs-vsctl add-port ovs0 gre0 -- set interface gre0 type=gre options:remote_ip=10.10.105.2352)在host2上操作:
echo 'DOCKER_OPTS="--fixed-cidr=172.17.2.1/24"'>>/etc/default/docker
避免與host1的docker0的ip衝突,修改
ifconfig docker0 172.17.42.2/16
service docker restart

創建ovs0,並與docker0相連
ovs-vsctl add-br ovs0
brctl addif docker0 ovs0

在ovs0上創建GRE隧道
ovs-vsctl add-port ovs0 gre0 -- set interface gre0 type=gre options:remote_ip=10.10.103.913)驗證
在host1上操作:
docker run -it --rm --name con1 ubuntu /bin/bash
在容器中操作:
nc -l 172.17.1.1 9000

在host2上操作:
docker run -it --rm --name con1 ubuntu /bin/bash
在容器中操作:
nc 172.17.1.1 90004)說明:
儘管不同主機上的容器IP有不同的範圍,但是它們還是屬於同一個子網(172.17.0.0/16)

9.GRE實現Docker容器跨網絡通信(容器在不同的子網)

  • eg:如圖4-13
    在這裏插入圖片描述
使用Open vSwitch的隧道模式;
host1:10.10.103.91/24,con1:172.17.1.0/24
host2:10.10.105.235/24,con2:172.17.2.0/24;
由於兩臺主機不再同一個子網中,容器間通信不能再使用直接路由的方式,而需依賴Open vSwitch建立的GRE隧道

(1)host1設置
使得Docker容器的IP在172.17.1.0/24網絡中
ifconfig docker0 172.17.1.254
service docker restart

將ovs0連在docker0上
ovs-vsctl add-br ovs0
brctl addif docker0 ovs0

在ovs0上創建一個internal類型的端口rou0,並分配一個私有IP
ovs-vsctl add-port ovs0 rou0 -- set interface rou0 type=internal
ifconfig rou0 192.168.1.1/24

將Docker容器的流量路由到rou0
rout add-net 172.17.0.0/16 dev rou0

創建GRE隧道
ovs-vsctl add-port ovs0 gre0 -- set interface gre0 type=gre options:remote_ip=10.10.103.91

刪除Docker創建的iptables規則
iptables -t nat -D POSTROUTING -s 172.17.1.0/24 ! -o docker0 -j MASQUEREAD
創建自己的規則
iptables -t nat -A POETROUTING -A 172.17.0.0/16 -o eth0 -j MASQUEREAD

(2)host2設置
使得Docker容器的IP在172.17.2.0/24網絡中
ifconfig docker0 172.17.2.254
service docker restart

將ovs0連在docker0上
ovs-vsctl add-br ovs0
brctl addif docker0 ovs0

在ovs0上創建一個internal類型的端口rou0,並分配一個私有IP
ovs-vsctl add-port ovs0 rou0 -- set interface rou0 type=internal
ifconfig rou0 192.168.1.1/24

將Docker容器的流量路由到rou0
rout add-net 172.17.0.0/16 dev rou0

創建GRE隧道
ovs-vsctl add-port ovs0 gre0 -- set interface gre0 type=gre options:remote_ip=10.10.105.235

刪除Docker創建的iptables規則
iptables -t nat -D POSTROUTING -s 172.17.2.0/24 ! -o docker0 -j MASQUEREAD
創建自己的規則
iptables -t nat -A POETROUTING -A 172.17.0.0/16 -o eth0 -j MASQUEREAD

(3)驗證:
在host1上:
docker run -it --name con1 ubuntu /bin/bash
在容器中
nc -l 9000

在host2上:
docker run -it --name con2 ubuntu /bin/bash
在容器中
nc -w 1 -v 172.17.1.1 9000

  • 該網絡模型與K8S類似,此處將一個容器視作爲一個pod
    在這裏插入圖片描述

10.OpenStack的GRE網絡模型介紹

  • Overlay網絡在虛擬化場景下除了實現虛擬機之間的跨網絡通信外,還可以填補VLAN的不足,滿足多用戶的隔離的需求
  • eg:如圖4-15
    在這裏插入圖片描述
如圖是OpenStack集羣中的兩臺計算節點的網絡連接圖
每臺主機有兩臺虛擬機,vm1和vm3屬於租戶A,處在一個子網;
vm2和vm4屬於租戶B,處在一個子網中。
4個vm都連在br-int網橋上,且有vlan標識,vm1和vm3的vlan id=1,vm2和vm4的vlan id=4
br-int是Open vSwitch交換機,它依據MAC地址和VLAN ID轉發數據;
br-tun是隧道網橋,它依據流表來轉發數據

11.Dockerfile最佳實踐

  • Dockerfile是Docker用來構建鏡像的文本,包含自定義的指令和格式。
  • docker build命令從Dockerfile中構建鏡像,這個過程與傳統分佈式集羣的編排配置過程很相似,且提供了一系列統一的資源配置語法。用戶可以用統一的語法命令,通過統一的配置文件,可以在不同的平臺上分發,使用時,還可以根據配置文件進行自動化構建。
  • Dockerfile與鏡像配合使用,使Docker在構建時,可以充分利用鏡像的功能進行緩存
  • Dockerfile實踐心得
    (1)給鏡像打上標籤,docker build -t =“ruby:2.0-on build”
    (2)謹慎選擇基礎鏡像
    (3)儘量將Dockerfile文件中相同的都放在前面,而將不同的部門放在後面
    (4)使用RUN curl來獲取遠程URL中的壓縮包,這樣可以刪除解壓後不再需要的文件,並且不需要在鏡像中再添加一層;
    儘量使用docker volume共享文件,而不是使用ADD或者COPY指令添加文件到鏡像中;
    (6)爲了避免緩存問題,RUN apt-get update && apt-get install -y package-bar package-foo package-baz;
    如果需要更新一個包eg:foo,直接使用指令:RUN apt-get install -y foo
    在Docker中,鏡像之間有層級關係,像一棵樹。我們可以在任一層建立一個容器。so,不要將所有的命令寫在一個RUN指令中(很像源碼控制)。
    (7)不要在Dockerfile中做端口映射
    因爲Docker的核心概念是:可重複性和可移植性。端口映射應在docker run命令中用-p參數指定。
    (8)使用Dockerfile共享Docker鏡像,Dockerfile文件可以加入版本控制

12.Docker容器的監控手段

1)
查看當前的運行的容器信息
docker ps

-a參數可以列出已停止的所有容器的信息
docker ps -a

(2)
列出所有頂層鏡像的信息
docker images

查看所有中間層的鏡像的信息
docker images -a

(3)docker stats只有在選用libcontainer作爲執行驅動時,纔可以使用
容器狀態信息統計:包括CPU,內存,塊設備IO,網絡IO
docker stats redis-master 

開發者可以使用stats API將容器的運行狀態信息傳遞到自己構建的應用中,以實現容器的系統監控
stats API(GET/containers/(id)/stats)
echo -e "GET /containers/redis-slave1/stats HTTP/1.0\r\n\" | nc -U /var/ryn/docker.sock

(4)查看鏡像或容器的底層詳細信息
瞭解鏡像或容器的完整構建信息,包括:基礎配置,主機配置,網絡設置,狀態信息等
-f參數:設定輸出格式
docker inspect -f {{.NetworkSettings.IPAddress}} 9bec172.17.0.25)查看正在運行的容器中的進程的運行情況
docker top 9bec6)
查看容器與主鍵之間的端口映射關係
docker port bc0a
  • 常用的容器監控工具
1)Google cAdvisor:監控應用
在啓動cAdvisor後,它會在後臺運行,並暴露8080端口,用戶可以訪問:http://localhost:8080來查看cAdvisor
還支持輸出狀態信息到InfluxDB數據庫進行存儲和讀取;
支持將容器的統計信息以Prometheus標準指標形式輸出,並存儲在指定的/metrics HTTP服務端點,以便通過Prometheus應用
來查看cAdvisor;還提供了豐富的API接口服務cAdvisor Remote RESET API

(2)Datadog:監測雲端應用
利用Docker所使用的內核結構cgroups獲取Docker的性能指標

(3)Prometheus
是一個開源服務監控系統和時間序列數據庫;
使用Prometheus時,一般結合container-exporter使用,其可以收集以libcontainer爲執行驅動的容器的各類性能指標,並將
數據提供給Prometheus使用;

13.實現服務發現、服務發佈與訂閱的關鍵技術:高可用配置中心etcd

  • etcd
    (1)是鍵值存儲倉庫,用於配置共享和服務發現
    (2)特點:基於HTTP+JSON的API,用curl命令就可以輕鬆使用;可選SSL客戶認證機制;每個實例每秒支持1千次寫操作;使用Raft算法充分實現了分佈式
    (3)etcd主要解決的是分佈式系統中的數據一致性的問題,而分佈式系統中的數據分爲控制數據(數據量小但更新訪問頻繁)和應用數據

  • etcd場景1:服務發現
    (1)在同一個分佈式集羣中的進程或服務,互相感知並建立連接,這就是服務發現。eg:瞭解集羣中是否有進程在監聽UDP或TCP端口,並通過對應的字符串信息就可以進行查找和連接
    (2)解決服務發現問題的三大支柱:
    一個強一致性,高可用的額服務存儲目錄;
    一種註冊服務和監控服務健康狀態的機制;
    一種查找和連接服務的機制;
    eg1:服務提供者在服務發現倉庫註冊,服務請求者在倉庫中查找,最後通過查找的細節進行連接。
    在這裏插入圖片描述
    eg2:在etcd中註冊某個服務名字的目錄,在該目錄下存儲可用的服務節點的IP。
    eg以Docker爲承載的前端在服務發現目錄中查找可用的中間件,中間件再找到服務後端,以此快速構建起一個動態和高可用的架構
    在這裏插入圖片描述
    eg3:應用中的某個實例隨時都有可能故障重啓,此時,通過etcd的服務發現功能可以解決動態配置問題:動態地配置域名解析(路由)中的信息
    在這裏插入圖片描述

  • etcd場景2:消息發佈與訂閱
    (1)在分佈式系統中,最合適的組件間通信方式是消息發佈與訂閱機制
    (2)構建一個配置共享中心,需要什麼?
    數據提供者:在這個配置中心發佈消息;
    消息使用者: 訂閱 他們關心的主題,一旦相關主題有消息發佈,就會實時通知訂閱者

  • etcd場景3:負載均衡
    (1)在分佈式系統中, 爲了保證服務的高可用以及數據的一致性,通常會部署多份數據和服務,以此來達到對等服務
    (2)實現數據訪問時的負載均衡,可將用戶的訪問流量分流到不同的機器上

  • etcd場景4:分佈式通知與協調
    (1)與消息發佈與訂閱類似
    (2)不同系統都在etcd上對同一個目錄進行註冊,同時設置Watcher監控該目錄的變化,當某個系統更新了etcd的目錄,那麼設置了Watcher的系統就會收到通知(異步通知),並作出相應的處理

  • etcd場景5:分佈式鎖與競選
    (1)etcd使用Raft算法保持了數據的全局強一致性,因此要實現分佈式鎖。
    (2)分佈式的鎖服務有兩種實現方式:
    保持獨佔:所有試圖獲取鎖的用戶最終只有一個可以得到,etcd實現了一套分佈式鎖原子操作CAS(CompareAndSwap)的API。在多個節點同時創建某個目錄時,只有一個能成功,該用戶即可認爲是獲得了鎖
    控制時序:即所有視圖獲取鎖的用戶都會進入等待隊列,獲取鎖的順序是全局唯一的,同時決定了隊列的執行順序。
    (3)分佈式鎖完成Leader競選: 對於長時間的CPU計算或者I/O操作,只需要由競選出的Leader計算處理一次,再把結果複製給其它的Follower即可,節省計算資源。

  • etcd場景6:分佈式隊列
    (1)與分佈式鎖的控制時序用法類似,即創建一個先進先出的隊列,保證順序
    (2)其他方式:在保證隊列到達某個條件時,再統一按順序執行

  • etc場景7:集羣監控
    (1)Watcher機制:當某個節點消失或者有變動時,Watcher機制會第一時間發現並告知用戶
    (2)設置TTL key,心跳來判斷該節點是否存活

  • etcd vs ZooKeeper
    (1)etcd:go語言,簡單,使用HTTP作爲接口;使用raft算法;數據一更新就會進行持久化;
    (2)ZooKeeper:Java語言實現,部署複雜;Paxos強一致性算法難;只提供Java和C兩種語言的接口;

發佈了569 篇原創文章 · 獲贊 140 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章