K8s之網絡通信


網絡通信機制

k8s的網絡基於第三方插件實現,但是定義了一些插件兼容規范,該規范有CoreOS和Google聯合定制,叫做 CNI(Container Network Interface)。

calicoz支持更多的網絡層的安全策略,flannel不支持
公有雲大多使用flannel,使用vxlan+Directrouting模式
自建IDC使用哪種模型都可以,flannel配置比較簡單,calico功能較多
性能差別不大,calico性能會略高於flannel
私有雲推薦使用calico
公有雲推擠使用flannel

flannel

官網:https://coreos.com/flannel/docs/latest/
文檔:https://coreos.com/flannel/docs/latest/kubernetes.html

Flannel 網絡模型 (后端),Flannel目前有三種方式實現 UDP/VXLAN/host-gw

UDP:早期版本的Flannel使用UDP封裝完成報文的跨越主機轉發,其安全性及性能略有不足。 
VXLAN:Linux 內核在在2012年底的v3.7.0之后加入了VXLAN協議支持,因此新版本的Flannel也有UDP轉換為 VXLAN,VXLAN本質上是一種tunnel(隧道)協議,用來基於3層網絡實現虛擬的2層網絡,目前flannel 的網絡模型已 經是基於VXLAN的疊加(覆蓋)網絡。 
Host-gw:也就是Host GateWay,通過在node節點上創建到達各目標容器地址的路由表而完成報文的轉發,因此這種 方式要求各node節點本身必須處於同一個局域網(二層網絡)中,因此不適用於網絡變動頻繁或比較大型的網絡環境,但是 其性能較好。

Flannel 組件的解釋

  • Cni0:網橋設備,每創建一個pod都會創建一對 veth pair,其中一端是pod中的eth0,另一端是Cni0網橋中的端口 (網卡),Pod中從網卡eth0發出的流量都會發送到Cni0網橋設備的端口(網卡)上,Cni0 設備獲得的ip地址是該節 點分配到的網段的第一個地址。
  • Flannel.1: overlay網絡的設備,用來進行vxlan報文的處理(封包和解包),不同node之間的pod數據流量都從 overlay設備以隧道的形式發送到對端。

Flannel的系統文件及目錄

  • root@node2:~# find / -name flannel
    /run/flannel
    /usr/bin/flannel
    /var/lib/cni/flannel

flannel pod狀態

root@master1:~#  kubectl get pods -n kube-system
NAME                          READY   STATUS    RESTARTS   AGE
coredns-85bd4f9784-95qcb      1/1     Running   0          6h15m
kube-flannel-ds-amd64-4dvn9   1/1     Running   0          23h
kube-flannel-ds-amd64-6zk8z   1/1     Running   0          23h
kube-flannel-ds-amd64-d54j4   1/1     Running   0          23h
kube-flannel-ds-amd64-hmnsj   1/1     Running   0          22h
kube-flannel-ds-amd64-k52kz   1/1     Running   0          23h
kube-flannel-ds-amd64-q42lh   1/1     Running   0          23h

當前node主機IP地址范圍

root@node1:~#  cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.20.0.0/16
FLANNEL_SUBNET=10.20.3.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true

當前node主機cni信息

root@node1:~# cat /var/lib/cni/flannel/0929d39656c75c9518ac16a785c12ebc301a254d03e58387d27ff365e04562a0 
{"cniVersion":"0.3.1","hairpinMode":true,"ipMasq":false,"ipam":{"routes":[{"dst":"10.20.0.0/16"}],"subnet":"10.20.3.0/24","type":"host-local"},"isDefaultGateway":true,"isGateway":true,"mtu":1450,"name":"cbr0","type":"bridge"}

UDP網絡模型(不可用)

重新執行網絡並重啟master與node服務器

  • 設置flannel 后端
    • FLANNEL_BACKEND: "host-gw"
    • FLANNEL_BACKEND: "vxlan"
    • FLANNEL_BACKEND: "UDP
修改backend為UDP

Type有變量FLANNEL_BACKEND定義

root@master1:~# vim /etc/ansible/roles/flannel/templates/kube-flannel.yaml.j2
net-conf.json: |
{
  "Network": "{{ CLUSTER_CIDR }}",
  "Backend": {
{% if FLANNEL_BACKEND == "vxlan" and DIRECT_ROUTING %}
        "DirectRouting": true,
{% endif %}
        "Type": "{{ FLANNEL_BACKEND }}"
      }
    }

查找定義FLANNEL_BACKEND變量的文件

 root@master1:~# grep FLANNEL_BACKEND /etc/ansible/roles/flannel/ -R
/etc/ansible/roles/flannel/defaults/main.yml:#FLANNEL_BACKEND: "host-gw"
/etc/ansible/roles/flannel/defaults/main.yml:FLANNEL_BACKEND: "vxlan"
/etc/ansible/roles/flannel/templates/kube-flannel.yaml.j2:{% if FLANNEL_BACKEND == "vxlan" and DIRECT_ROUTING %}
/etc/ansible/roles/flannel/templates/kube-flannel.yaml.j2:        "Type": "{{ FLANNEL_BACKEND }}"   

將FLANNEL_BACKEND設置為UDP

root@master1:~# cat /etc/ansible/roles/flannel/defaults/main.yml
# 部分flannel配置,參考 docs/setup/network-plugin/flannel.md
# 設置flannel 后端
#FLANNEL_BACKEND: "host-gw"
#FLANNEL_BACKEND: "vxlan"
FLANNEL_BACKEND: "udp"
DIRECT_ROUTING: false

#flanneld_image: "quay.io/coreos/flannel:v0.10.0-amd64"
flanneld_image: "easzlab/flannel:v0.11.0-amd64"

# 離線鏡像tar包
flannel_offline: "flannel_v0.11.0-amd64.tar"

k8s需要重新安裝生效

VxLAN Directrouting

Directrouting 為在同一個二層網絡中的node節點啟用直接路由機制,類似於host-gw模式。

修改flannel支持Directrouting

需要讓配置文件在node節點重新生效

修改DIRECT_ROUTING:為true
root@master1:~# vim /etc/ansible/roles/flannel/defaults/main.yml 
# 部分flannel配置,參考 docs/setup/network-plugin/flannel.md

# 設置flannel 后端
#FLANNEL_BACKEND: "host-gw"
FLANNEL_BACKEND: "vxlan"
DIRECT_ROUTING: true

#flanneld_image: "quay.io/coreos/flannel:v0.10.0-amd64"
flanneld_image: "easzlab/flannel:v0.11.0-amd64"

# 離線鏡像tar包
flannel_offline: "flannel_v0.11.0-amd64.tar"

重新配置network

root@master1:/etc/ansible# ansible-playbook 06.network.yml

master和node節點重啟或重裝k8s生效

root@node1:~# reboot
修改前的路由表
root@node1:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.203.104.254  0.0.0.0         UG    0      0        0 ens160
10.20.0.0       10.20.0.0       255.255.255.0   UG    0      0        0 flannel.1
10.20.1.0       10.20.1.0       255.255.255.0   UG    0      0        0 flannel.1
10.20.2.0       10.20.2.0       255.255.255.0   UG    0      0        0 flannel.1
10.20.3.0       0.0.0.0         255.255.255.0   U     0      0        0 cni0
10.20.4.0       10.20.4.0       255.255.255.0   UG    0      0        0 flannel.1
10.20.5.0       10.20.5.0       255.255.255.0   UG    0      0        0 flannel.1
10.203.104.0    0.0.0.0         255.255.255.0   U     0      0        0 ens160
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
修改后的路由表
root@node1:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.203.104.254  0.0.0.0         UG    0      0        0 ens160
10.20.0.0       10.203.104.21   255.255.255.0   UG    0      0        0 ens160
10.20.1.0       10.203.104.20   255.255.255.0   UG    0      0        0 ens160
10.20.2.0       10.203.104.27   255.255.255.0   UG    0      0        0 ens160
10.20.3.0       0.0.0.0         255.255.255.0   U     0      0        0 cni0
10.20.4.0       10.203.104.28   255.255.255.0   UG    0      0        0 ens160
10.20.5.0       10.203.104.22   255.255.255.0   UG    0      0        0 ens160
10.203.104.0    0.0.0.0         255.255.255.0   U     0      0        0 ens160
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0

host-gw網絡模型

修改FLANNEL_BACKEND為host-gw模型

root@master1:~# vim /etc/ansible/roles/flannel/defaults/main.yml 
# 部分flannel配置,參考 docs/setup/network-plugin/flannel.md

# 設置flannel 后端
FLANNEL_BACKEND: "host-gw"
#FLANNEL_BACKEND: "vxlan"
DIRECT_ROUTING: false

#flanneld_image: "quay.io/coreos/flannel:v0.10.0-amd64"
flanneld_image: "easzlab/flannel:v0.11.0-amd64"

# 離線鏡像tar包
flannel_offline: "flannel_v0.11.0-amd64.tar"

重新配置network

root@master1:/etc/ansible# ansible-playbook 06.network.yml

master和node節點重啟或重裝k8s生效

root@node1:~# reboot

Flannel不同node上的pod的通信流程

Flannel.1 是一個overlay網絡的設備,用來進行 vxlan 報文的處理(封包和解包),不同node之間的pod數據流量 都從overlay設備以隧道的形式發送到對端。

->: pod中產生數據,根據pod的路由信息,將數據發送到Cni0 
->: Cni0 根據節點的路由表,將數據發送到隧道設備flannel.1 
->: Flannel.1查看數據包的目的ip,從flanneld獲得對端隧道設備的必要信息,封裝數據包。 
->: Flannel.1將數據包發送到對端設備,對端節點的網卡接收到數據包 
->: 對端節點發現數據包為overlay數據包,解開外層封裝,並發送到到本機flannel.1設備。 
->: Flannel.1設備查看數據包,根據路由表匹配,將數據發送給Cni0設備。 
->: Cni0匹配路由表,發送數據給網橋上對應的端口(pod)。

Calico

官網:https://www.projectcalico.org/
github: https://github.com/projectcalico/calico

Calico是一個純三層的網絡解決方案,為容器提供多node間的訪問通信,calico將每一個node節點都當做為一個路 由器(router),各節點通過BGP(Border Gateway Protocol) 邊界網關協議學習並在node節點生成路由規則,從而 將不同node節點上的pod連接起來進行通信。

BGP是一個去中心化的協議,它通過自動學習和維護路由表實現網絡的可用性,但是並不是所有的網絡都支持 BGP,另外為了跨網絡實現更大規模的網絡管理,calico 還支持IP-in-IP的疊加模型,簡稱IPIP,IPIP可以實現跨不 同網段建立路由通信,但是會存在安全性問題,其在內核內置,可以通過Calico的配置文件設置是否啟用IPIP,在 公司內部如果k8s的node節點沒有跨越網段建議關閉IPIP。

IPIP是一種將各Node的路由之間做一個tunnel,再把兩個網絡連接起來的模式。啟用IPIP模式時,Calico將在各 Node上創建一個名為"tunl0"的虛擬網絡接口。 
BGP模式則直接使用物理機作為虛擬路由路(vRouter),不再創建額外的tunnel。

calico 核心組件

Felix:calico的agent,運行在每一台node節點上,其主要是維護路由規則、匯報當前節點狀態以確保pod的誇主機 通信。 
BGP Client:每台node都運行,其主要負責監聽node節點上由felix生成的路由信息,然后通過BGP協議廣播至其他剩 余的node節點,從而相互學習路由實現pod通信。 
Route Reflector:集中式的路由反射器,calico v3.3開始支持,當Calico BGP客戶端將路由從其FIB(Forward Information dataBase,轉發信息庫)通告到Route Reflector時,Route Reflector會將這些路由通告給部署 集群中的其他節點,Route Reflector專門用於管理BGP網絡路由規則,不會產生pod數據通信。 

注:calico默認工作模式是BGP的node-to-node mesh,如果要使用Route Reflector需要進行相關配置。 https://docs.projectcalico.org/v3.4/usage/routereflector https://docs.projectcalico.org/v3.2/usage/routereflector/calico-routereflector

部署過程

修改ansible的hosts文件中的CLUSTER_NETWORK為calico

root@master1:~# grep CLUSTER_NETWORK /etc/ansible/hosts 
CLUSTER_NETWORK="calico"

下載鏡像並上傳到harbor

root@master1:~# docker images | grep calico
calico/node                                                                       v3.4.4              a8dbf15bbd6f        14 months ago       79.6MB
calico/cni                                                                        v3.4.4              f5e5bae3eb87        14 months ago       75.4MB
calico/kube-controllers                                                           v3.4.4              0030ff291350        14 months ago       56.5MB

root@master1:~# docker tag calico/node:v3.4.4 harbor.linux.com/calico/node:v3.4.4
root@master1:~# docker push harbor.linux.com/calico/node:v3.4.4


root@master1:~# docker tag calico/cni:v3.4.4 harbor.linux.com/calico/cni:v3.4.4
root@master1:~# docker push harbor.linux.com/calico/cni:v3.4.4

root@master1:~# docker tag calico/kube-controllers:v3.4.4 harbor.linux.com/calico/kube-controllers:v3.4.4
root@master1:~# docker push harbor.linux.com/calico/kube-controllers:v3.4.4

calico-v3.4.yaml.j2配置文件

將image修改為harbor的地址,其他字段不需要修改
root@master1:/etc/ansible/roles/calico/templates# vim calico-v3.4.yaml.j2

開啟和關閉IPIP

root@master1:/etc/ansible# cat roles/calico/defaults/main.yml 
# 部分calico相關配置,更全配置可以去roles/calico/templates/calico.yaml.j2自定義

# 如果 node 節點有多塊網卡,請設置 true
# 另外發現設置為 true 時能夠解決v1.10使用ipvs偶爾出現pod內‘dial tcp 10.68.0.1:443: i/o timeout’的 bug
NODE_WITH_MULTIPLE_NETWORKS: "true"

# etcd 集群服務地址列表, 根據etcd組成員自動生成
TMP_ENDPOINTS: "{% for h in groups['etcd'] %}https://{{ h }}:2379,{% endfor %}"
ETCD_ENDPOINTS: "{{ TMP_ENDPOINTS.rstrip(',') }}"

# 設置 CALICO_IPV4POOL_IPIP=“off”,可以提高網絡性能,條件限制詳見 docs/setup/calico.md
CALICO_IPV4POOL_IPIP: "Always"    # 開啟IPIP

# 設置 Felix 日志級別
FELIX_LOG_LVL: "warning"

# 設置 calico-node使用的host IP,bgp鄰居通過該地址建立,可手工指定也可以自動發現
#IP_AUTODETECTION_METHOD: "interface=eth0"
IP_AUTODETECTION_METHOD: "can-reach={{ groups['kube-master'][0] }}"

# 更新支持calico 版本: [v3.2.x] [v3.3.x] [v3.4.x]
calico_ver: "v3.4.4"

# calico 主版本
calico_ver_main: "{{ calico_ver.split('.')[0] }}.{{ calico_ver.split('.')[1] }}"

# 離線鏡像tar包
calico_offline: "calico_{{ calico_ver }}.tar"

部署集群

root@master1:/etc/ansible# ansible-playbook 06.network.yml

驗證當前路由表

root@node1:~# calicoctl node status


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM