一些廢話
k8s 的 cni 其中一個(gè)重要的功能是將 Pod 的網(wǎng)絡(luò)棧接管后使用某種協(xié)議封包從而在 node 之間傳輸。比如:
- flanal:基于 udp 的私有協(xié)議
- cilium:vxlan
- calico:IPIP
在通過路由和轉(zhuǎn)發(fā)將數(shù)據(jù)包發(fā)送至目標(biāo)地址所在的 Node 節(jié)點(diǎn)上,讓 Node 節(jié)點(diǎn)上運(yùn)行的網(wǎng)絡(luò)組件解包后將原始網(wǎng)絡(luò)數(shù)據(jù)通過 CNI 接口傳遞給 Pod 容器。
這樣一來,要完成傳統(tǒng)網(wǎng)絡(luò)與 k8s 的 SDN 網(wǎng)絡(luò)互聯(lián)互通,需要解決封包格式與路由條目這兩個(gè)問題。
好在我們的 calico 這個(gè)網(wǎng)絡(luò)組件誕生就是為了和傳統(tǒng)網(wǎng)絡(luò)協(xié)議所兼容。通過簡單的配置,可以使 calico 對虛擬網(wǎng)絡(luò)的數(shù)據(jù)不封包,直接三層轉(zhuǎn)發(fā)。即 calico 的 BGP 模式。
calico 在每個(gè) Node 節(jié)點(diǎn)上運(yùn)行 BGP 協(xié)議以和集群其他節(jié)點(diǎn)交換路由表,使每個(gè) Node 節(jié)點(diǎn)都變成了一臺 BGP 路由器。從而使得 k8s 的虛擬網(wǎng)絡(luò),在原有的網(wǎng)絡(luò)上直接三層轉(zhuǎn)發(fā)。
同時(shí),我們還可以在內(nèi)網(wǎng)的 DNS 服務(wù)器上為集群的域名配置解析委派,將 cluster.local 域轉(zhuǎn)發(fā)至集群 coreDNS 進(jìn)行解析,即可完成集群域名互通。
實(shí)操
在(一)中,我們使用 cilium 替換了 kubeadm 預(yù)裝的 kube-proxy 組件。但我們這里要用 calico ,就需要把 kube-proxy 請回來。
在生成默認(rèn)配置后,我們需要向 kubeadm.init.yaml 文件追加以下內(nèi)容:
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
ipvs:
strictARP: true
kubeadm 會(huì)在初始化集群時(shí)傳將上面的配置傳給 kube-proxy。kube-proxy 默認(rèn)會(huì)使用 iptables 規(guī)則做 DNAT 來實(shí)現(xiàn) service,效率略低,因此我們改用了 ipvs 模式,也就是經(jīng)典 lvs。同時(shí),我們這里設(shè)置 ipvs 的 ARP 模式為 strict,方便后期使用 metal-lb 的 2 層模式。
在 啟動(dòng)第一個(gè) controlplane 節(jié)點(diǎn) 中,將 --skip-phases=addon/kube-proxy 參數(shù)去掉,即:
kubeadm init \
--config kubeadm.init.yaml \
--upload-certs
calico 從 3.15 開始學(xué)壞了,你往集群里直接安裝的不是 calico ,而是一個(gè)叫做 tigeraOperator 的控制器。這個(gè)控制器會(huì)通過 Installation.operator.tigera.io 這個(gè) CRD 里設(shè)置的安裝參數(shù)來幫你安裝 calico。不過,比起之前 calico 放棄 helm 安裝,這個(gè) tigeraOperator 是支持 helm 的,并且支持使用 helm values 設(shè)置 Installation 這個(gè) CRD。
helm repo add projectcalico https://projectcalico.docs.tigera.io/charts
helm install calico projectcalico/tigera-operator \
--version v3.22.1 \
--set installation.registry=192.168.1.10:8082' \
--set tigeraOperator.registry=null \
--set calicoctl.image='calico/ctl'
還記得 192.168.1.10:8082 么,這是我們在(一)中搭建的私庫。由于 tigeraOperator 寫死了要在鏡像名里帶上倉庫地址,installation.registry 留空會(huì)導(dǎo)致直接使用 docker.io 倉庫——這樣每個(gè) node 都需要直接連接公網(wǎng)倉庫下載一次鏡像,過于浪費(fèi)帶寬了。我們還是提前把鏡像下載好 push 進(jìn)咱們自己的倉庫里吧。
設(shè)置
雖說 calico 使用 BGP 協(xié)議與路由器或者三層交換機(jī)協(xié)商路由表,但其實(shí)用的是 iBGP 協(xié)議,和運(yùn)營商、IDC 之間的 eBGP 還是有區(qū)別的。
用 BGP 呢首先就要有 AS 號,這個(gè)號和 IP 地址一樣是需要統(tǒng)一分配和購買的。好在 64512 - 65534 這一段是專門分配用來做私有編號的,就像 IP 里面的私有地一樣。這里我們就用 64512:
kind: BGPConfiguration
apiVersion: crd.projectcalico.org/v1
metadata:
generation: 1
name: default
spec:
asNumber: 64512
logSeverityScreen: Info
nodeToNodeMeshEnabled: false
serviceClusterIPs:
- cidr: 10.43.0.0/16
---
kind: BGPPeer
apiVersion: crd.projectcalico.org/v1
metadata:
generation: 1
name: router-or-l3sw
spec:
asNumber: 64512
peerIP: 192.168.1.1
這里我們預(yù)設(shè)了 192.168.1.1 這個(gè) ip 是你的路由器或者三層交換機(jī)——不管是啥,你需要在這個(gè)設(shè)備上開啟 BGP 協(xié)議,使用同樣的 AS 號碼 64512來開啟 iBGP,同時(shí)設(shè)置集群所有 node 的 IP 為 peer,并設(shè)置 Route Reflector。之后導(dǎo)入上文的 calico 的 CRD 配置,就可以去路由器上觀察 BGP 狀態(tài)和路由表了。
使用
- Pod 容器 IP 和 Service 服務(wù) clusterip 集群 IP 均可直接訪問,注意需要添加端口訪問。
- Pod 容器 IP 直接使用服務(wù)本身監(jiān)聽的端口訪問。Service 服務(wù) clusterip 集群 IP 使用服務(wù)映射端口訪問。
- Pod 容器 IP 每次重啟、部署、更新均會(huì)發(fā)生變更。Service 服務(wù) clusterip 集群 IP 不會(huì)。
- 集群服務(wù)可以通過域名訪問。格式是【服務(wù)名】.【命名空間】.svc.cluster.local:【服務(wù)端口】。