一 Flannel組件
1.1 Flannel介紹
Kubernetes的網路模型假定了所有Pod都在一個可以直接連通的扁平網路空間中,若需要實作這個網路假設,需要實作不同節點上的Docker容器之間的互相訪問,然后運行Kubernetes,目前已經有多個開源組件支持容器網路模型,如Flannel、Open vSwitch、直接路由和Calico, Flannel之所以可以搭建Kubernetes依賴的底層網路,是因為它能實作以下兩點,- 它能協助Kubernetes,給每一個Node上的Docker容器都分配互相不沖突的IP地址,
- 它能在這些IP地址之間建立一個覆寫網路(Overlay Network),通過這個覆寫網路,將資料包原封不動地傳遞到目標容器內,
如上圖所示,Flannel首先創建了一個名為flannel0的網橋,而且這個網橋的一端連接docker0網橋,另一端連接一個叫作flanneld的服務行程,flanneld行程上連etcd,利用etcd來管理可分配的IP地址段資源,同時監控etcd中每個Pod的實際地址,并在記憶體中建立了一個Pod節點路由表;flanneld行程下連docker0和物理網路,使用記憶體中的Pod節點路由表,將docker0發給它的資料包包裝起來,利用物理網路的連接將資料包投遞到目標flanneld上,從而完成Pod到Pod之間的直接地址通信,
Flannel之間的底層通信協議的可選技術包括UDP、VxLan、AWS VPC等多種方式,通過源flanneld封包、目標flanneld解包,最終docker0收到的就是原始的資料,對容器應用來說是透明的,感覺不到中間Flannel的存在,
Flannel每次分配的地址段都在同一個公共區域獲取,從而實作不同Node上的Pod分配的IP不產生沖突,而且在Flannel分配好地址段后,其余操作由Docker完成的,Flannel通過修改Docker的啟動引數將分配給它的地址段傳遞進去:
--bip=172.17.18.1/24
通過如上方式,Flannel就控制了每個Node上的docker0地址段的地址,從而保障了所有Pod的IP地址在同一個水平網路中且不產生沖突,Flannel完美地實作了對Kubernetes網路的支持,但是它引入了多個網路組件,在網路通信時需要轉到flannel0網路介面,再轉到用戶態的flanneld程式,到對端后還需要走這個程序的反程序,所以也會引入一些網路的時延損耗,另外,Flannel模型默認采用了UDP作為底層傳輸協議,UDP本身是非可靠協議,雖然兩端的TCP實作了可靠傳輸,但在大流量、高并發的應用場景下還建議多次測驗,
提示:更多flannel實作和部署參考:《008.Docker Flannel+Etcd分布式網路部署》,
二 Calico組件
2.1 Calco組件簡介
Calico是一個基于BGP的純三層的網路方案,與OpenStack、Kubernetes、AWS、GCE等云平臺都能夠良好地集成,Calico在每個計算節點都利用Linux Kernel實作了一個高效的vRouter來負責資料轉發,每個vRouter都通過BGP1協議把在本節點上運行的容器的路由資訊向整個Calico網路廣播,并自動設定到達其他節點的路由轉發規則, Calico保證所有容器之間的資料流量都是通過IP路由的方式完成互聯互通的,Calico節點組網時可以直接利用資料中心的網路結構(L2或者L3),不需要額外的NAT、隧道或者Overlay Network,沒有額外的封包解包,能夠節約CPU運算,提高網路效率,
Calico在小規模集群中可以直接互聯,在大規模集群中可以通過額外的BGP route reflector來完成,Calico基于iptables還提供了豐富的網路策略,實作了Kubernetes的Network Policy策略,提供容器間網路可達性限制的功能,
2.2 Calico架構
Calico的主要組件:
Felix:Calico Agent,運行在每個Node上,負責為容器設定網路資源(IP地址、路由規則、iptables規則等),保證跨主機容器網路互通,
etcd:Calico使用的后端存盤,
BGP Client:負責把Felix在各Node上設定的路由資訊通過BGP協議廣播到Calico網路,
Route Reflector:通過一個或者多個BGP Route Reflector來完成大規模集群的分級路由分發,
CalicoCtl:Calico命令列管理工具,
2.3 Calico步驟程序
在Kubernetes中部署Calico的主要步驟如下:- 修改Kubernetes服務的啟動引數,并重啟服務,
- 設定Master上kube-apiserver服務的啟動引數:--allow-privileged=true(因為calico-node需要以特權模式運行在各Node上),
- 設定各Node上kubelet服務的啟動引數:--networkplugin=cni(使用CNI網路插件),
- 創建Calico服務,主要包括calico-node和calico policy controller,需要創建的資源物件如下:
- 創建ConfigMap calico-config,包含Calico所需的配置引數,
- 創建Secret calico-etcd-secrets,用于使用TLS方式連接etcd,
- 在每個Node上都運行calico/node容器,部署為DaemonSet,
- 在每個Node上都安裝Calico CNI二進制檔案和網路配置引數(由install-cni容器完成),
- 部署一個名為calico/kube-policy-controller的Deployment,以對接Kubernetes集群中為Pod設定的Network Policy,
2.4 正式部署
[root@k8smaster01 ~]# curl \ https://docs.projectcalico.org/v3.6/getting-started/kubernetes/installation/hosted/canal/canal.yaml \ -O [root@k8smaster01 ~]# POD_CIDR="<your-pod-cidr>" \ sed -i -e "s?10.10.0.0/16?$POD_CIDR?g" canal.yaml 如上yaml檔案包括Calico所需全部配置,如下為重點部分分段決議:- ConfigMap決議
1 kind: ConfigMap 2 apiVersion: v1 3 metadata: 4 name: calico-config 5 namespace: kube-system 6 data: 7 typha_service_name: "none" 8 calico_backend: "bird" 9 veth_mtu: "1440" 10 cni_network_config: |- 11 { 12 "name": "k8s-pod-network", 13 "cniVersion": "0.3.0", 14 "plugins": [ 15 { 16 "type": "calico", 17 "log_level": "info", 18 "datastore_type": "kubernetes", 19 "nodename": "__KUBERNETES_NODE_NAME__", 20 "mtu": __CNI_MTU__, 21 "ipam": { 22 "type": "calico-ipam" 23 }, 24 "policy": { 25 "type": "k8s" 26 }, 27 "kubernetes": { 28 "kubeconfig": "__KUBECONFIG_FILEPATH__" 29 } 30 }, 31 { 32 "type": "portmap", 33 "snat": true, 34 "capabilities": {"portMappings": true} 35 } 36 ] 37 }對主要引數說明如下, etcd_endpoints:Calico使用etcd來保存網路拓撲和狀態,該引數指定etcd服務的地址,可手動設定, calico_backend:Calico的后端,默認為bird, cni_network_config:符合CNI規范的網路配置,其中type=calico表示kubelet將從/opt/cni/bin目錄下搜索名為calico的可執行檔案,并呼叫它來完成容器網路的設定,ipam中的type=calico-ipam表示kubelet將在/opt/cni/bin目錄下搜索名為calico-ipam的可執行檔案,用于完成容器IP地址的分配, 提示:如果etcd服務配置了TLS安全認證,則還需指定相應的ca、cert、key等檔案,
- Secret決議
1 apiVersion: v1 2 kind: Secret 3 type: Opaque 4 metadata: 5 name: calico-etcd-secrets 6 namespace: kube-system 7 data: 8 # Populate the following with etcd TLS configuration if desired, but leave blank if 9 # not using TLS for etcd. 10 # The keys below should be uncommented and the values populated with the base64 11 # encoded contents of each file that would be associated with the TLS data. 12 # Example command for encoding a file contents: cat <file> | base64 -w 0 13 # 如果配置了TLS ,則需要設定相應的證書和密鑰檔案路徑 14 # etcd-key: null 15 # etcd-cert: null 16 # etcd-ca: null
- DaemonSet決議
1 kind: DaemonSet 2 apiVersion: extensions/v1beta1 3 metadata: 4 name: calico-node 5 namespace: kube-system 6 labels: 7 k8s-app: calico-node 8 spec: 9 selector: 10 matchLabels: 11 k8s-app: calico-node 12 updateStrategy: 13 type: RollingUpdate 14 rollingUpdate: 15 maxUnavailable: 1 16 template: 17 metadata: 18 labels: 19 k8s-app: calico-node 20 annotations: 21 scheduler.alpha.kubernetes.io/critical-pod: '' 22 spec: 23 nodeSelector: 24 beta.kubernetes.io/os: linux 25 hostNetwork: true 26 tolerations: 27 - effect: NoSchedule 28 operator: Exists 29 - key: CriticalAddonsOnly 30 operator: Exists 31 - effect: NoExecute 32 operator: Exists 33 serviceAccountName: calico-node 34 terminationGracePeriodSeconds: 0 35 initContainers: 36 - name: upgrade-ipam 37 image: calico/cni:v3.6.0 38 command: ["/opt/cni/bin/calico-ipam", "-upgrade"] 39 env: 40 - name: KUBERNETES_NODE_NAME 41 valueFrom: 42 fieldRef: 43 fieldPath: spec.nodeName 44 - name: CALICO_NETWORKING_BACKEND 45 valueFrom: 46 configMapKeyRef: 47 name: calico-config 48 key: calico_backend 49 volumeMounts: 50 - mountPath: /var/lib/cni/networks 51 name: host-local-net-dir 52 - mountPath: /host/opt/cni/bin 53 name: cni-bin-dir 54 - name: install-cni 55 image: calico/cni:v3.6.0 56 command: ["/install-cni.sh"] 57 env: 58 - name: CNI_CONF_NAME 59 value: "10-calico.conflist" 60 - name: CNI_NETWORK_CONFIG 61 valueFrom: 62 configMapKeyRef: 63 name: calico-config 64 key: cni_network_config 65 - name: KUBERNETES_NODE_NAME 66 valueFrom: 67 fieldRef: 68 fieldPath: spec.nodeName 69 - name: CNI_MTU 70 valueFrom: 71 configMapKeyRef: 72 name: calico-config 73 key: veth_mtu 74 - name: SLEEP 75 value: "false" 76 volumeMounts: 77 - mountPath: /host/opt/cni/bin 78 name: cni-bin-dir 79 - mountPath: /host/etc/cni/net.d 80 name: cni-net-dir 81 containers: 82 - name: calico-node 83 image: calico/node:v3.6.0 84 env: 85 - name: DATASTORE_TYPE 86 value: "kubernetes" 87 - name: WAIT_FOR_DATASTORE 88 value: "true" 89 - name: NODENAME 90 valueFrom: 91 fieldRef: 92 fieldPath: spec.nodeName 93 - name: CALICO_NETWORKING_BACKEND 94 valueFrom: 95 configMapKeyRef: 96 name: calico-config 97 key: calico_backend 98 - name: CLUSTER_TYPE 99 value: "k8s,bgp" 100 - name: IP 101 value: "autodetect" 102 - name: IP_AUTODETECTION_METHOD 103 value: "can-reach=172.24.8.2" 104 - name: CALICO_IPV4POOL_IPIP 105 value: "Always" 106 - name: FELIX_IPINIPMTU 107 valueFrom: 108 configMapKeyRef: 109 name: calico-config 110 key: veth_mtu 111 - name: CALICO_IPV4POOL_CIDR 112 value: "10.10.0.0/16" 113 - name: CALICO_DISABLE_FILE_LOGGING 114 value: "true" 115 - name: FELIX_DEFAULTENDPOINTTOHOSTACTION 116 value: "ACCEPT" 117 - name: FELIX_IPV6SUPPORT 118 value: "false" 119 - name: FELIX_LOGSEVERITYSCREEN 120 value: "info" 121 - name: FELIX_HEALTHENABLED 122 value: "true" 123 securityContext: 124 privileged: true 125 resources: 126 requests: 127 cpu: 250m 128 livenessProbe: 129 httpGet: 130 path: /liveness 131 port: 9099 132 host: localhost 133 periodSeconds: 10 134 initialDelaySeconds: 10 135 failureThreshold: 6 136 readinessProbe: 137 exec: 138 command: 139 - /bin/calico-node 140 - -bird-ready 141 - -felix-ready 142 periodSeconds: 10 143 volumeMounts: 144 - mountPath: /lib/modules 145 name: lib-modules 146 readOnly: true 147 - mountPath: /run/xtables.lock 148 name: xtables-lock 149 readOnly: false 150 - mountPath: /var/run/calico 151 name: var-run-calico 152 readOnly: false 153 - mountPath: /var/lib/calico 154 name: var-lib-calico 155 readOnly: false 156 volumes: 157 - name: lib-modules 158 hostPath: 159 path: /lib/modules 160 - name: var-run-calico 161 hostPath: 162 path: /var/run/calico 163 - name: var-lib-calico 164 hostPath: 165 path: /var/lib/calico 166 - name: xtables-lock 167 hostPath: 168 path: /run/xtables.lock 169 type: FileOrCreate 170 - name: cni-bin-dir 171 hostPath: 172 path: /opt/cni/bin 173 - name: cni-net-dir 174 hostPath: 175 path: /etc/cni/net.d 176 - name: host-local-net-dir 177 hostPath: 178 path: /var/lib/cni/networks在該Pod中包括如下兩個容器:
- install-cni:在Node上安裝CNI二進制檔案到/opt/cni/bin目錄下,并安裝相應的網路組態檔到/etc/cni/net.d目錄下,設定為initContainers并在運行完成后退出,
- calico-node:Calico服務程式,用于設定Pod的網路資源,保證Pod的網路與各Node互聯互通,它還需要以hostNetwork模式運行,直接使用宿主機網路,
- CALICO_IPV4POOL_CIDR:Calico IPAM的IP地址池,Pod的IP地址將從該池中進行分配,
- CALICO_IPV4POOL_IPIP:是否啟用IPIP模式,啟用IPIP模式時,Calico將在Node上創建一個名為tunl0的虛擬隧道,
- IP_AUTODETECTION_METHOD:獲取Node IP地址的方式,默認使用第1個網路介面的IP地址,對于安裝了多塊網卡的Node,可以使用正則運算式選擇正確的網卡,例如"interface=eth.*"表示選擇名稱以eth開頭的網卡的IP地址,
- FELIX_IPV6SUPPORT:是否啟用IPv6,
- FELIX_LOGSEVERITYSCREEN:日志級別,
- securityContext.privileged=true:以特權模式運行,
- calico-kube-controllers決議
1 apiVersion: extensions/v1beta1 2 kind: Deployment 3 metadata: 4 name: calico-kube-controllers 5 namespace: kube-system 6 labels: 7 k8s-app: calico-kube-controllers 8 annotations: 9 scheduler.alpha.kubernetes.io/critical-pod: '' 10 spec: 11 replicas: 1 12 strategy: 13 type: Recreate 14 template: 15 metadata: 16 name: calico-kube-controllers 17 namespace: kube-system 18 labels: 19 k8s-app: calico-kube-controllers 20 spec: 21 nodeSelector: 22 beta.kubernetes.io/os: linux 23 tolerations: 24 - key: CriticalAddonsOnly 25 operator: Exists 26 - key: node-role.kubernetes.io/master 27 effect: NoSchedule 28 serviceAccountName: calico-kube-controllers 29 containers: 30 - name: calico-kube-controllers 31 image: calico/kube-controllers:v3.6.0 32 env: 33 - name: ENABLED_CONTROLLERS 34 value: node 35 - name: DATASTORE_TYPE 36 value: kubernetes 37 readinessProbe: 38 exec: 39 command: 40 - /usr/bin/check-status 41 - -r如果啟用RBAC權限控制,則可以設定ServiceAccount,用戶在Kubernetes集群中設定了Pod的Network Policy之后,calicokube-controllers就會自動通知各Node上的calico-node服務,在宿主機上設定相應的iptables規則,完成Pod間網路訪問策略的設定, [root@k8smaster01 ~]# docker pull calico/cni:v3.9.0 [root@k8smaster01 ~]# docker pull calico/node:v3.9.0 [root@k8smaster01 ~]# docker pull calico/kube-controllers:v3.9.0 #建議提前pull鏡像 [root@k8smaster01 ~]# kubectl apply -f calico.yaml
2.5 查看驗證
[root@k8smaster01 ~]# kubectl get pods --all-namespaces -o wide #查看部署
[root@k8smaster01 ~]# ll /etc/cni/net.d/
calico-node在正常運行之后,會根據CNI規范,在/etc/cni/net.d/目錄下生成如下檔案和目錄,并在/opt/cni/bin/目錄下安裝二進制檔案calico和calico-ipam,供kubelet呼叫,
- 10-calico.conf:符合CNI規范的網路配置,其中type=calico表示該插件的二進制檔案名為calico,
- calico-kubeconfig:Calico所需的kubeconfig檔案,
- calico-tls目錄:以TLS方式連接etcd的相關檔案,
如上可查看到不同節點的相應路由,從而通過Calico就完成了Node間容器網路的設定,在后續的Pod創建程序中,kubelet將通過CNI介面呼叫Calico進行Pod網路的設定,包括IP地址、路由規則、iptables規則等,
如果設定CALICO_IPV4POOL_IPIP="off",即不使用IPIP模式,則Calico將不會創建tunl0網路介面,路由規則直接使用物理機網卡作為路
由器進行轉發,
2.6 運行測驗
[root@k8smaster01 ~]# kubectl run nginx --replicas=2 --labels="run=load-balancer-example" --image=nginx --port=80 [root@k8smaster01 ~]# kubectl expose deployment nginx --type=NodePort --name=example-service #暴露埠 [root@k8smaster01 ~]# kubectl get service #查看服務狀態 [root@k8smaster01 ~]# kubectl describe service example-service #查看資訊
[root@k8smaster01 ~]# curl 10.97.91.153:80
[root@k8smaster01 ~]# kubectl get pod -o wide #查看endpoint
[root@k8smaster01 ~]# curl 10.10.32.129:80 #訪問endpoint,與訪問服務ip結果相同
[root@k8smaster01 ~]# curl 10.10.154.1:80
部署參考檔案:https://docs.projectcalico.org/v3.6/getting-started/kubernetes/installation/flannel
https://github.com/projectcalico/calico/blob/master/v3.8/getting-started/kubernetes/installation/hosted/calico.yaml
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/120917.html
標籤:Linux
