↑↑↑↑接上一篇繼續部署↑↑↑↑
目錄
一、k8s集群的三種接口
二、k8s的三種網絡模式
1、pod內容器之間的通信
2、同一個node節點中pod之間通信
3、不同的node節點的pod之間通信
Overlay Network
VXLAN
三、flannel網絡插件
1、flannel插件模式之UDP模式(8285端口)
2、flannel插件模式之VXLAN模式
3、總結flannel插件的三大模式
4、拓展:關于vlan和vxlan的區別
四、calico網絡插件
1、calico插件模式之IPIP模式
2、calico插件模式之BGP模式
3、總結calico插件三大模式
五、對比flannel和calico的區別
六、在所有node節點部署cni網絡插件之flannel的vxlan模式
七、在所有node節點上部署coreDNS
八、最后拓展calico插件部署
一、k8s集群的三種接口
前言,k8s集群有三大接口:
CRI:容器進行時接口,連接容器引擎--docker、containerd、cri-o、podman
CNI:容器網絡接口,用于連接網絡插件如:flannel、calico、cilium
CSI:容器存儲接口,如nfs、ceph、gfs、oss、s3、minio
二、k8s的三種網絡模式
k8s集群中pod網絡通信分類
1、pod內容器之間的通信
在同一個 Pod 內的容器(Pod 內的容器是不會跨宿主機的)共享同一個網絡命令空間,相當于它們在同一臺機器上一樣,可以用 localhost 地址訪問彼此的端口。
2、同一個node節點中pod之間通信
每個 Pod 都有一個真實的全局 IP 地址,同一個 Node 內的不同 Pod 之間可以直接采用對方 Pod 的 IP 地址進行通信,Pod1 與 Pod2 都是通過 Veth 連接到同一個 docker0 網橋,網段相同,所以它們之間可以直接通信。
3、不同的node節點的pod之間通信
Pod 地址與 docker0 在同一網段,docker0 網段與宿主機網卡是兩個不同的網段,且不同 Node 之間的通信只能通過宿主機的物理網卡進行。
要想實現不同 Node 上 Pod 之間的通信,就必須想辦法通過主機的物理網卡 IP 地址進行尋址和通信。因此要滿足兩個條件:①Pod 的 IP 不能沖突;將 Pod 的 IP 和所在的 Node 的 IP 關聯起來,②通過這個關聯讓不同 Node 上 Pod 之間直接通過內網 IP 地址通信。
總結:因此引入了cni網絡插件的核心原因實際上就是為了解決不同node節點上的不同pod之間的通信,即pod跨主機通信
關于k8s的三種類型的網絡IP
節點網絡:nodeIP---node節點的物理網卡ip,實現node節點之間的通信
Pod網絡:PodIP---Pod與Pod之間通過PodIP進行通信
service網絡:clusterIP---k8s集群內部,service資源的clusterIP實現對Pod集群的網絡代理
Overlay Network
疊加網絡,在二層或者三層基礎網絡上疊加的一種虛擬網絡技術模式,該網絡中的主機通過虛擬鏈路隧道連接起來(類似于VPN)
個人理解為正常的數據包是一層 也就是【mac頭+ip頭+udp/tcp頭+真實數據】,這種疊加網絡就是說把【mac頭+ip頭+udp/tcp頭+真實數據】看做一個整體,作為真實數據 再次封裝,{【mac頭+ip頭+udp/tcp頭】+【mac頭+ip頭+udp/tcp頭+真實數據】} 這種看成一個整體
VXLAN
將源數據包封裝到UDP中,并使用基礎網絡的IP/MAC作為外層報文頭進行封裝,然后在以太網上傳輸,到達目的地后由隧道端點解封裝并將數據發送給目標地址。
三、flannel網絡插件
Flannel 的功能是讓集群中的不同節點主機創建的 Docker 容器都具有全集群唯一的虛擬 IP 地址。
Flannel 是 Overlay 網絡的一種,也是將 TCP 源數據包封裝在另一種網絡包里面進行路由轉發和通信,目前支持 udp、vxlan、 host-GW 3種數據轉發方式。
1、flannel插件模式之UDP模式(8285端口)
第一步:原始的數據包從pod容器發送給cni0網橋,cni0網橋將數據包發送給flannel0虛擬接口
第二步:flanneld服務進程會監聽flannel.0接口接收的數據,flanneld服務進程將數據包封裝到UDP的報文中(疊加封裝)
第三步:flanneld服務進程會通過etcd數據庫查詢路由表信息,找到關于目標pod所在的node節點的ip,然后在UDP報文外再次封裝nodeip頭部、mac頭部,并通過物理網卡發送給目標node節點
第四步:UDP報文通過8285端口送達到目標node節點的flanneld進程進行解封裝,在根據本地的路由表規則通過flannel0接口發送到cni0網橋,再由cni0發送給目標pod容器
總結:udp模式的工作核心是基于flanneld應用進行原始數據包封裝在udp報文中,屬于overlay網絡的一種
#ETCD 之 Flannel 提供說明:
①功能1:存儲管理Flannel可分配的IP地址段資源
②功能2:監控 ETCD 中每個 Pod 的實際地址,并在內存中建立維護 Pod 節點路由表
由于 udp 模式是在用戶態做轉發,會多一次報文隧道封裝,因此性能上會比在內核態做轉發的 vxlan 模式差。
2、flannel插件模式之VXLAN模式
第一步:原始數據幀從源主機的pod容器發出到cni0網橋,再由cni0轉發給flannel.1虛擬接口
第二步:flannel.1接口接收數據幀以后先添加vxlan頭部,然后在內核將原始數據幀封裝在UDP報文中
第三步:flanneld會查詢etcd中的路由表信息獲取目標pod的nodeip,然后再udp報文外封裝nodeip頭部和mac頭部,通過物理網卡發送給目標node節點
第四步:報文會通過8472端口到目標node節點的flannel.1接口,并在內核中解封裝,最后根據本地的路由規則轉發到cni0網橋,再發送到目標pod容器
3、總結flannel插件的三大模式
UDP——出現最早,性能最差。基于flanneld應用程序實現原始數據包的封裝和解封裝
VXLAN——是flannel的默認模式,也是推薦使用模式。(與udp模式比:)性能比udp好,基于內核實現原始數據幀的封裝和解封裝;(與HOST-GW模式比:)配置簡單使用方便。
HOST-GW——性能最好的模式,但是配置復雜,且不能跨網段(通過靜態路由實現)
4、拓展:關于vlan和vxlan的區別
(1)作用不同:
vlan是用于在交換機上實現邏輯劃分廣播域,還可以配合stp生成樹協議阻塞路徑接口,避免產生環路和廣播風暴
vxlan是將數據幀封裝在udp報文中,通過網絡層傳輸給其他網絡,實現虛擬大二層網絡通信
(2)數量不同:
vxlan支持更多的二層網絡,最多支持2^24個
vlan最多支持2^12個
(3)mac表中的記錄不同
vxlan采用的是隧道機制,mac物理地址不需要記錄在交換機中
vlan需要在mac表中記錄mac地址
四、calico網絡插件
●flannel方案
需要在每個節點上把發向容器的數據包進行封裝后,再用隧道將封裝后的數據包發送到運行著目標Pod的node節點上。目標node節點再負責去掉封裝,將去除封裝的數據包發送到目標Pod上。數據通信性能則大受影響。
●calico方案
Calico不使用隧道或NAT來實現轉發,而是把Host當作Internet中的路由器,使用BGP同步路由,并使用iptables來做安全訪問策略,完成跨Host轉發來。
#Calico 主要由三個部分組成:
Calico CNI插件:主要負責與kubernetes對接,供kubelet調用使用。
Felix:負責維護宿主機上的路由規則、FIB轉發信息庫等。
BIRD:負責分發路由規則,類似路由器。
Confd:配置管理組件。
1、calico插件模式之IPIP模式
第一步:原始數據包從源主機的pod發出,通過veth pair設備送達到tunl0接口,再被內核的ipip驅動封裝在node節點網絡的ip報文中
第二步:根據felix維護的路由規則通過物理網卡發送到目標的node節點
第三步:數據包到達目標node節點的tunl0接口后再通過內核的ipip驅動解封裝得到原始數據包,再根據本地的路由規則通過veth pair設備送達到目標pod容器
2、calico插件模式之BGP模式
calico的BGP模式工作原理(本質就是通過路由規則來實現Pod之間的通信)
每個Pod容器都有一個 veth pair 設備,一端接入容器,另一個接入宿主機網絡空間,并設置一條路由規則。
這些路由規則都是 Felix 維護配置的,由 BIRD 組件基于 BGP 動態路由協議分發路由信息給其它節點。
1)原始數據包從源主機的Pod容器發出,通過 veth pair 設備送達到宿主機網絡空間
2)根據Felix維護的路由規則通過物理網卡發送到目標node節點
3)目標node節點接收到數據包后,會根據本地路由規則通過 veth pair 設備送達到目標Pod容器
3、總結calico插件三大模式
五、對比flannel和calico的區別
(1)從模式來講
- flannel插件的模式有:udp、vxlan、host-gw
- calico插件的模式有:IPIP、BGP、CrossSubnet(混合模式)
(2)從默認網段來講
- flannel默認的網段是10.244.0.0/16
- calico默認的網段是192.168.0.0/16
(3)從模式的性能來講
flannel
- 通常會采用VXLAN模式,用的是疊加網絡、IP隧道方式傳輸數據,對性能有一定的影響。
- Flannel產品成熟,依賴性較少,易于安裝,功能簡單,配置方便,利于管理。但是不具備復雜的網絡策略配置能力。
calico
- 使用IPIP模式可以實現跨子網傳輸,但是傳輸過程中需要額外的封包和解包過程,對性能有一定的影響。
- 使用BGP模式會把每個node節點看作成路由器,通過Felix、BIRD組件來維護和分發路由規則,可實現直接通過BGP路由協議實現路由轉發,傳輸過程中不需要額外封包和解包過程,因此性能較好,但是只能在同一個網段里使用,無法跨子網傳輸。
- calico不使用cni0網橋,而使通過路由規則把數據包直接發送到目標主機,所以性能較高;而且還具有更豐富的網絡策略配置管理能力,功能更全面,但是維護起來較為復雜。
(4)從使用場景來講
- 對于較小規模且網絡要求簡單的K8S集群,可以采用flannel作為cni網絡插件;
- 對于K8S集群規模較大且要求更多的網絡策略配置時,可以考慮采用性能更好功能更全面的calico或cilium。
六、在所有node節點部署cni網絡插件之flannel的vxlan模式
上傳flannel-v0.21.5.zip
[root@node01 k8s#unzip flannel-v0.21.5.zip
##上傳 flannel-v0.21.5.zip 到 /opt/k8s 目錄中,并完成解壓[root@node01 k8s#ls
cni-plugins-linux-amd64-v1.3.0.tgz flannel-cni-plugin.tar flannel.tar flannel-v0.21.5.zip kube-flannel.yml kubelet.sh node.zip proxy.sh##導入鏡像
[root@node01 k8s#docker load -i flannel-cni-plugin.tar
[root@node01 k8s#docker load -i flannel.tar ##查看鏡像是否導入成功
[root@node01 k8s#docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
flannel/flannel v0.21.5 a6c0cb5dbd21 9 months ago 68.9MB
flannel/flannel-cni-plugin v1.1.2 7a2dcab94698 14 months ago 7.97MB##創建cni網絡插件的工作目錄
[root@node01 k8s#mkdir -p /opt/cni/bin#將flannel-v0.21.5.zip解壓后的cni-plugins-linux-amd64-v1.3.0.tgz解壓到cni網絡插件的工作目錄
[root@node01 k8s#tar xf cni-plugins-linux-amd64-v1.3.0.tgz -C /opt/cni/bin/
[root@node01 k8s#ls !$
ls /opt/cni/bin/
bandwidth bridge dhcp dummy firewall host-device host-local ipvlan loopback macvlan portmap ptp sbr static tap tuning vlan vrf##將2個鏡像和cni工作目錄傳輸給node02節點
[root@node01 k8s#scp flannel-cni-plugin.tar flannel.tar node02:/opt/k8s/
[root@node01 k8s#scp -r /opt/cni/ node02:/opt/
[root@node01 k8s#scp kube-flannel.yml master01:/opt/k8s/
//在 master01 節點上操作
#上傳 kube-flannel.yml 文件到 /opt/k8s 目錄中,部署 CNI 網絡
cd /opt/k8s
kubectl apply -f kube-flannel.yml kubectl get pods -n kube-flannel
NAME READY STATUS RESTARTS AGE
kube-flannel-ds-hjtc7 1/1 Running 0 7skubectl get nodes
NAME STATUS ROLES AGE VERSION
192.168.20.16 Ready <none> 81m v1.20.11
ip -d addr show flannel.1
?要知道網絡插件的目的是為了解決跨node節點的pod進行通信,那么驗證一下
1.在master01節點創建pod資源
##創建pod
[root@master01 k8s#kubectl create deployment test-v1 --image=soscscs/myapp:v1 --replicas=2#查看pod狀態
[root@master01 k8s#kubectl get pods -o wide
2.在node節點查看容器情況
3.進入容器中 查看是否可以完成跨主機pod通信?
注意:有幾個文件中的網段設置需要一致
kube-flannel.yml中的網段設置
與controller manager以及kube-proxy腳本中設置的網段需要保持一致
kube-flannel.yml?
?controller manager腳本
?kube-proxy腳本
七、在所有node節點上部署coreDNS
CoreDNS 是 K8S 默認的集群內部 DNS 功能實現,為 K8S 集群內的 Pod 提供 DNS 解析服務
- 根據 service 的資源名稱 解析出對應的 clusterIP
- 根據 statefulset 控制器創建的Pod資源名稱 解析出對應的 podIP
在所有node節點上上傳coredns.tar軟件包
//在所有 node 節點上操作
#上傳 coredns.tar 到 /opt 目錄中
cd /opt
docker load -i coredns.tar
?在master01節點上部署coredns
//在 master01 節點上操作
#上傳 coredns.yaml 文件到 /opt/k8s 目錄中,部署 CoreDNS
cd /opt/k8s
kubectl apply -f coredns.yamlkubectl get pods -n kube-system
驗證可以通過service的名稱進行通信
[root@master01 k8s#kubectl get pods --show-labels
##查看當前的pod資源 并展示其label標簽
NAME READY STATUS RESTARTS AGE LABELS
test-v1-56f56b4db5-ksplj 1/1 Running 0 25m app=test-v1,pod-template-hash=56f56b4db5
test-v1-56f56b4db5-z8p2p 1/1 Running 0 25m app=test-v1,pod-template-hash=56f56b4db5##查看當前的service資源有哪些
[root@master01 k8s#kubectl get service
[root@master01 k8s#kubectl expose deployment test-v1 --port=80 --target-port=80
##創建service資源
service/test-v1 exposed
?在node節點中進入容器,驗證可以通過service資源名稱通信 以及可以實現nslookup
?驗證service資源可以實現pod集群的四層網絡代理,實現負載均衡
八、最后拓展calico插件部署
//在 master01 節點上操作
#上傳 calico.yaml 文件到 /opt/k8s 目錄中,部署 CNI 網絡
cd /opt/k8s
vim calico.yaml
#修改里面定義Pod網絡(CALICO_IPV4POOL_CIDR),與前面kube-controller-manager配置文件指定的cluster-cidr網段一樣- name: CALICO_IPV4POOL_CIDRvalue: "192.168.0.0/16"kubectl apply -f calico.yamlkubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-659bd7879c-4h8vk 1/1 Running 0 58s
calico-node-nsm6b 1/1 Running 0 58s
calico-node-tdt8v 1/1 Running 0 58s#等 Calico Pod 都 Running,節點也會準備就緒
kubectl get nodes---------- node02 節點部署 ----------
//在 node01 節點上操作
cd /opt/
scp kubelet.sh proxy.sh root@192.168.20.17:/opt/
scp -r /opt/cni root@192.168.20.17:/opt///在 node02 節點上操作
#啟動kubelet服務
cd /opt/
chmod +x kubelet.sh
./kubelet.sh 192.168.20.17//在 master01 節點上操作
kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
node-csr-BbqEh6LvhD4R6YdDUeEPthkb6T_CJDcpVsmdvnh81y0 10s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending
node-csr-duiobEzQ0R93HsULoS9NT9JaQylMmid_nBF3Ei3NtFE 85m kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Approved,Issued#通過 CSR 請求
kubectl certificate approve node-csr-BbqEh6LvhD4R6YdDUeEPthkb6T_CJDcpVsmdvnh81y0kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
node-csr-BbqEh6LvhD4R6YdDUeEPthkb6T_CJDcpVsmdvnh81y0 23s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Approved,Issued
node-csr-duiobEzQ0R93HsULoS9NT9JaQylMmid_nBF3Ei3NtFE 85m kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Approved,Issued#加載 ipvs 模塊
for i in $(ls /usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs|grep -o "^[^.]*");do echo $i; /sbin/modinfo -F filename $i >/dev/null 2>&1 && /sbin/modprobe $i;done#使用proxy.sh腳本啟動proxy服務
cd /opt/
chmod +x proxy.sh
./proxy.sh 192.168.20.17#查看群集中的節點狀態
kubectl get nodes