k8s中的網路通訊總結

2022-02-23 21:15:13 字數 4409 閱讀 5789

同乙個pod中的容器,共用同乙個網路命名空間,直接使用localhost或127.0.0.1加上埠訪問就好了。可以看到這兩個容器的ip位址,路由表,以及暴露的埠號等都是一樣的,因為他們使用的是同乙個網路命名空間,同乙個網路棧。

【注意】:他們只是共用網路命名空間(network namespace),但是程序命名空間(pid namespace)、使用者名稱空間(user namespace)等其他的命名空間是相互隔離的。

每個pod都有唯一乙個ip(屬於docker0網橋上的網段),每個pod的網路基礎設施容器都是通過veth裝置對直接連在docker0網橋上的:

本機docker0網橋的位址的資料報都會通過容器內的eth0(veth裝置)直接轉給kernel,路由的範圍是link(與本裝置直接連線),因為veth裝置都是成對存在的,另一端連在docker0網橋上,所以會由kernel直接**給docker0網橋上的另乙個veth裝置。

宿主機將資料報通過docker0發給kernel,最終docker0網橋會將資料報**給目的pod。

要支援不同node節點上的pod通訊需要滿足的要求:

1)整個kubernetes集群中對每個pod分配乙個唯一的ip:在部署kubernetes時,對每個node節點的docker0網橋的網段重新劃分,使用者設定乙個大的網段(eg:10.20.0.0/16),存在etcd中,每個節點的flanneld會去etcd中查詢這個值,然後,flanneld隨機生成乙個屬於大網段的,且不衝突的子網(eg: 10.20.37.0/24; 10.20.92.0/24; 10.20.0.53/24)並將該值寫回etcd中,這樣就保證了每個pod的ip都會在10.20.0.0/16這個網段內;

2)node節點之間需要架設乙個overlay網路(一般通過flannel實現),保證pod可以互相訪問。

為了支援水平擴充套件和高可用,實際使用中並不會直接使用pod的ip來訪問pod中的服務,而是定義service來訪問一組pod中的服務。service是對一組pod的抽象,會根據訪問策略(負載均衡)來訪問這組pod。

kubernetes會在建立service時隨機分配乙個clusterip,這是乙個虛ip(vip),不能與docker0網橋的網段衝突,比如:10.10.0.0/16這個網段(在 kube-apiserver的--service-cluster-ip-range=10.10.0.0/16配置項中指定)。

訪問pod中服務是只需要訪問這個vip就好了,而service會將請求經過負載均衡之後**到後端pod中,這些工作都是執行在每個node節點的kube-proxy程序管理的,它的核心功能是:將對某個service的訪問經過負載均衡(round robin演算法)之後**到某乙個後端pod:

1、clusterip:預設型別,自動分配乙個僅cluster內部可以訪問的虛擬ip;

2、nodeport:在clusterip基礎上為service在每台機器上繫結乙個埠,這樣就可以通過:nodeport來訪問改服務;

3、loadbalancer:在nodeport的基礎上,借助cloud provider建立乙個外部的負載均衡器,並將請求**到:nodeport

無論是clusterip+targetport的方式,還是nodeip+nodeport的方式訪問服務,都會被節點的iptables規則重定向到kube-proxy監聽service的服務**埠,kube-proxy接受到service請求之後,會使用round-robin負載均衡演算法按照service維護的endpoint物件中選擇乙個endpoint(其實就是pod)。

任何資料報進入宿主機後,首先進入prerouting鏈:

-a prerouting -m comment --comment "

kubernetes service portals

" -j kube-services

-a prerouting -m addrtype --dst-type local -j docker

kube-proxy程序在啟動時或者監聽到service和endpoint發生變化之後,會為每個endpoint修改本機iptables的nat表中的4條規則鏈:

-a kube-sep-6xcc4vjackomsyvv -s 10.20.92.11/32 -m comment --comment "

hyjx--hyjx-group3/mysql-demo:mysqld-demo

" -j kube-mark-masq

-a kube-sep-6xcc4vjackomsyvv -p tcp -m comment --comment "

hyjx--hyjx-group3/mysql-demo:mysqld-demo

" -m tcp -j dnat --to-destination 10.20.92.11:3306

-a kube-services -d 10.10.147.26/32 -p tcp -m comment --comment "

hyjx--hyjx-group3/mysql-demo:mysqld-demo cluster ip

" -m tcp --dport 13306 -j kube-svc-dm5emdblordrgwll

-a kube-svc-dm5emdblordrgwll -m comment --comment "

hyjx--hyjx-group3/mysql-demo:mysqld-demo

" -j kube-sep-6xcc4vjackomsyvv

-a kube-nodeports -p tcp -m comment --comment "

hyjx--hyjx-group3/mysql-demo2:mysqld-demo2

" -m tcp --dport 30016 -j kube-mark-masq

-a kube-nodeports -p tcp -m comment --comment "

hyjx--hyjx-group3/mysql-demo2:mysqld-demo2

" -m tcp --dport 30016 -j kube-svc-nvngtmqmpftqa6ys

-a kube-sep-7mwhp37xxe3w6qi4 -s 10.20.92.11/32 -m comment --comment "

hyjx--hyjx-group3/mysql-demo2:mysqld-demo2

" -j kube-mark-masq

-a kube-sep-7mwhp37xxe3w6qi4 -p tcp -m comment --comment "

hyjx--hyjx-group3/mysql-demo2:mysqld-demo2

" -m tcp -j dnat --to-destination 10.20.92.11:3306

-a kube-services -d 10.10.95.1/32 -p tcp -m comment --comment "

hyjx--hyjx-group3/mysql-demo2:mysqld-demo2 cluster ip

" -m tcp --dport 23306 -j kube-svc-nvngtmqmpftqa6ys

-a kube-svc-nvngtmqmpftqa6ys -m comment --comment "

hyjx--hyjx-group3/mysql-demo2:mysqld-demo2

" -j kube-sep-7mwhp37xxe3w6qi4

nodeport型別的service比clusterip型別就多了兩條規則kube-nodeports,剩下的4條規則是用來處理使用clusterip的方式訪問服務的請求,因為nodeport型別的服務,同樣可以使用clusterip的方式訪問。

1)、第一條規則,實現了ip masquerade功能 ;

2)、第二條規則,如果是使用nodeip+nodeport的方式,目的埠為30016,處理方法和直接使用clusterip型別的服務訪問一樣。

使用服務的vip的方式還是不太友好,因為只有建立好service之後,系統才會隨機分配乙個vip,執行在容器中的應用無法提前知道這個vip,動態修改映象是不現實的。最終的解決方案是直接使用服務的名稱來訪問服務。而,服務的名稱到服務的vip的解析是由kube-dns來完成的。

kubelet在啟動容器的時候,會修改容器的/etc/resolv.conf,設定容器的dns伺服器為kube-dns(k8s-master節點ip),每個服務都有唯一乙個網域名稱。

在容器中無法ping通服務mysql-demo的vip,但是使用服務的名稱,kube-dns可以正確地返回服務對應的vip

設定service的型別為nodeport,並為服務指定乙個不衝突的埠(30000-32767)就行了,訪問時直接使用任意乙個node節點的ip加上這個nodeport

k8s網路基礎

為了保證網路方案的標準化 擴充套件性和靈活性,k8s 採用了 container networking inte ce cni 規範。cni 是由 coreos 提出的容器網路規範,它使用了外掛程式 plugin 模型建立容器的網路棧。它要求任何實現機制都必須滿足以下需求 因為k8s只約定了網路實現...

k8s 網路模式

1 clusterip kind service apiversion v1 metadata name my service spec selector ports protocol tcp port 80 targetport 80 root k8s master rc test kubectl...

K8S 操作總結

例如yaml中kind deployment 則應通過下面方法擴充套件 kubectl scale replicas 3 deployment foo 或者直接通過建立資源的yaml檔案擴充套件 kubectl scale replicas 3 f foo.yaml 將由 foo.yaml 配置檔案...