CKA Note Section 9 Networking
Contents
前言
既然這個章節是介紹 Kubernetes Networking 那就先來複習一下之前看過的優質文章吧!
188. Prerequisite - Network Namespaces

▲ 使用 ip netns exec <NAMESPACE> ip link 能以 <NAMESPACE> 的視角查看,或者更快的 ip -n <NAMESPACE> link。

▲ 使用 ip netns exec <NAMESPACE> arp 顯示 namespace 內的 arp table。

▲ 使用 ip netns exec <NAMESPACE> route 顯示 namespace 內的 routing table。

▲ (上面 ip addr add 漏掉 netmask 了) 這邊講師跟邱牛這篇 Docker 網路入門篇(二) - Bridge 網路模型 做的事情差不多,都是打造 veth pair,只不過邱牛是在 runtime == docker 下解釋,講師則是將 red, blue 這兩個 namespace 從 host OS 透過 ip link add 的方式加在原始路徑裡面。
P.S. 若要刪除 veth pair 的話只需要下達一次 ip -n <NAMESPACE> link del <veth_name> 即可。

▲ 透過 ip link add v-net-0 type bridge && ip link set dev v-net-o up 產生的 bridge 可以把他想像成放在 host 的 virtual switch。

▲ 如果想從 host ping 到這四個 namespace 的話只需要將 linux bridge binding IP 即可 (讓 host 有 route table)。

▲ 我們想從 blue 碰到 192.168.1.3 就必須在 blue namespace 裡面加給他 static route (建議直接用 default gateway) 不過還是沒辦法收到 ping reply (先暴雷,因為要請 host eth0 幫我們做 SNAT 「看到來自 192.168.15.0/24 的封包請幫我用 192.168.1.2 host eth0 的身分送出!」)

▲ 如果謹慎一點應該要 iptables -t nat -I POSTROUTING -s 192.168.15.0/24 -i v-net-0 -o eth0 -j MASQUARADE 來限制 --in-interface 與 --out-interface。
191. Prerequisite - CNI

▲ 既然各個 container runtime 都需要在 host 做這些必要事情,CNI 的誕生提供業界標準避免重複造輪。

▲ Who is using CNI 可以看到一些官方列出的 container runtime,以及第三方 plugins。
CNI 還有提供 library 可以自行開發屬於你自己的 CNI plugins~

▲ CNI 切了兩個責任區,上方是 container runtime 必須要負責的;下方則是 plugin,達成 any runtime should be able to work with any plugins.
2022.08.03 更新:
參加完 2022 COSCUP X KCD 之後 eBPF-based Container Networking#5 當中就有提到 CNI spec 基本要求 與 次要支援目標

▲ 原來 IPAM, SNAT, Port mapping 都被歸類在次要目標。

▲ CNI 自帶一些基本的 plugin,下方是第三方 plugin。延伸閱讀: [Hwchiu]常見 CNI (Container Network Interface) Plugin 介紹 而 docker 並不使用 CNI,而是自身的 CNM (container network model)

▲ K8s 各個元件需求的 port,如果是 multi-master 架構的話 etcd 需要額外開啟 2380/tcp 來同步。
官方有提供檢查表 Ports and Protocols
193. Important Note about CNI and CKA Exam
- 在 LAB 當中考生將被要求安裝 Network Addons (包含 plugin)
- plugin 將使用 weave-net 作為範例,當然考生可以自由選擇其他 solution
- 實際考試除非題目指定要求,不然也是自由選擇。
- 從上方提供的 自由選擇其他 solution 可以發現所有選項點進去都是其官方網站/GitHub,正式考試時只能看官方文件!
好哩加在,小飛機推薦的 CKA Bookmark 有包含官方文件安裝 Weave-net 的方式。(後來查看,並沒有! 請自行新增 link,或者使用我的 Bookmark)
196. Pod Networking

▲ 這個章節主要介紹 pod 在跨 worker node 要怎麼互相碰到。

▲ 範例有三個 worker node,首先要先解決同 worker node 內互連的問題: (1) 建立一個 bridge (2) veth pair 接上 bridge <=> container (3) 為 bridge 與 container 設定 IP。

▲ 想從 bluepod 去找位在 node2 的 purple pod 10.244.2.2,卻發現 ping 不到,原因是沒有路由。手動增加一筆靜態路由 (非永久) ip route add 10.244.2.2/32 via 192.168.1.12 請 node1 的 eth0 幫我們送件~
eth0 收到之後會向 L2 domain 發送 broadcast 「誰有 10.244.2.2 呀,請給我他的 MAC address 謝謝」

▲ 實際做一次實驗 Eric_minikube 192.168.199.62 eth0 收到 arp broadcast 之後就單獨回覆 (unicast) 192.168.199.63 說 「我有,挖來出力!」
因為該 network 是本身就有的,無論是否開啟 net.ipv4.ip_forward =1 都能送達。

▲ 接著在每一個 worker node 都加上一筆 static route。

▲ 實際上不會這樣一筆一筆加,太麻煩了。直接給整個網段一個 gateway 就好!

▲ kubelet 會從 --cni-conf-dir 找到設定的 .json 然後 pass 給 --cni-bin-dir 執行,創造屬於該 container 的 network namespace。
197. CNI in kubernetes

▲ --cni-bin-dir 下面有可供使用的 plugin binary file。

▲ isGateway 代表是否要給 bridge binding 一個 IP address,好讓它變成 gateway 的角色;ipMasq 是否要在 host 針對這個 network 做 NAT。詳細 Container Network Interface (CNI) Specification
198. CNI weave

▲ Weave (CNI) 運作的方式就是在各個 worker node 部屬一個 agent,每個 agent 會告知彼此身上有哪些路由 (聽起來有點像 BGP),並且重新封裝 (encapsulation) 把原始封包變成它的 payload

▲ 不管 CNI 為何,container 內的 routing table 都必須存在。
Understanding Weave Net

- Weave Network 各個節點稱做 peer。
- 每個 peer 都會自己的名子 (預設是 MAC address) 方便人類辨識,即使 restart 也會保留,唯一會改變的是 UID。
- Weave 透過 TCP 連線來執行交握 (perform a protocol handshake) 並且 交換網路拓譜 (topology),通訊過程是可以被設定加密的。
- Weave 透過 UDP 「連線」來傳輸 payload (來自 container 的原始封包),全雙工而且穿透防火牆。
- Weave 會建立 network bridge 在各個 worker node 身上,並且有 IPAM 功能。
- Weave 傳輸封包的方式有兩種: (1) fast data path 完全在 kernel space 處理 packet。 (2) sleeve mode,封包目的若是 non-local container 的話會被 kernel 捕捉,並且交由位於 user space 的 Weave Net router 處理。

▲ Deploy Weave via kubectl

▲ 如果安裝方式是 kubeadm 的話可以使用 kubectl logs weave-net -n kube-system -c weave 來查詢 log (通常用於 debug)
199. Practice Test - Explore CNI Weave
Q: kubelet 使用何種 CNI Plugin ?
A: ps -aux | grep 'kubelet' | grep -i 'network'
Q: CNI plugin binary 在哪裡 ?
A: ps -aux | grep 'kubelet' | grep -i 'cni' 沒有找到 --cni-bin-dir => 預設在 /opt/cni/bin 底下。
Q: 有哪些 CNI binary 可以使用 ?
A: ls -al /opt/cni/bin
Q: 哪一個 CNI plugin config 被使用 ?
A: ll /etc/cni/net.d/
Q: 該 config 預設使用哪個 bin file ?
A: less /etc/cni/net.d/10-flannel.conflist 找 type 欄位。
(可能要背喔!) 201. Practice Test - Deploy Network Solution
若要更改 Weave 預設使用的 IP 範圍必須使用 kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')&env.IPALLOC_RANGE=10.50.0.0/16"
若考試沒有給 Weave Config 的選項的話 &env.IPALLOC_RANGE= 必須背起來!!
若考試沒有給 Weave Config 的選項的話 &env.IPALLOC_RANGE= 必須背起來!!
若考試沒有給 Weave Config 的選項的話 &env.IPALLOC_RANGE= 必須背起來!!
203. IP Address Management - Weave

▲ CNI plugin 自帶 DHCP 與 host-local 兩種 IPAM type,host-local 就是將 IP 使用狀態存在一個 file@local。延伸閱讀: [HWchiu Day13] 初探 CNI 的 IP 分配問題 (IPAM)
206. Service Networking
上面幾個章節都是在介紹 pod networking,這個章節要介紹的是 service networking。

▲ kubelet 會去詢問 api-server 有沒有新任務;kube-proxy 也一樣只不過他的任務是詢問是否有 service 被建立。
先前我們在 CKA_Note_Section_2_Core_Concepts#18. Kube Proxy 就有提到 service 並不實體存在 worker node 身上,他只是一個紀錄 service 資訊的地方。
以 ClusterIP type 的 service 為例,當 service 被建立時會拿到一個 IP (含 port number),其 IP address range 被設定在 api-server config。同時在 worker node 上面建立 routing rule。

▲ kube-proxy 可以透過 userspace, iptables (預設), ipvs 來建立 routing rules。

▲ service IP address range 被設定在 api-server。

▲ iptables 規則就會被 kube-proxy 增加一條 「所有要去 (dst) 10.103.132.104 3306/TCP packet 全部 DNAT 去 10.244.1.2 3306/TCP,也就是 pod 的 IP address」

▲ kube-proxy 的變動可以在 /var/log/kube-proxy.log 底下查看。

▲ 如果是 kubeadm 安裝的話可以 透過 kubectl logs -n kube-system kube-proxy 查看。
209. DNS in kubernetes
這個章節會講到:
- 哪些元件會被分配到 DNS domain name
serviceDNS recordpodDNS record

▲ FQDN 就是 Hostname + Namespace + Type + Root Domain 串在一起。 其中 pod create 時並不會自動被產生 DNS record 除非另外設定。
註: 同一個 Namespace 可以透過 Hostname 碰到彼此,不需要完整 FQDN。
210. CoreDNS in Kubernetes

▲ CoreDNS 被以 Deployment 的形式部屬。

▲ CoreDNS (kube-dns) 需要一個 “Corefile” 的設定檔,通常會被弄成 configMaps。更多資訊: CoreDNS ConfigMap options

▲ 橘字的部分被稱為 plugin,kubernetes 就是其中一個! cluster.local 設定前面提到的 Root domain 為何。
我聽不懂講師講的 pod insecure 到底在幹嘛,所以就自己去翻書 (CoreDNS-Kubernetes) 了~
pods 主要設定該怎麼處裡 IP-based 的 A record,舉例: 1-2-3-4.ns.pod.cluster.local => A 1.2.3.4
這關係到使用 HTTPS (會用到 TLS cert) 直接與 pod 通訊的安全性
- disable: 預設選項,直接不處理、直接回
NXDOMAIN「沒有這個人啦!」。這也是為什麼前面提到 「podcreate 時並不會自動被產生 DNS record 除非另外設定」的原因,設定就在這裡。 - insecre: 不向 K8s 檢查 pod 是否存在,直接回對應的 A record。
- verified: 先向 K8s 詢問確認有這個 pod 存在後才回復對映 A record,不過這會使用更高的記憶體。

▲ kubelet 負責設定 pod 使用的 DNS server 為何,使用者不必自己手動加入。

▲ 在 /etc/resolv.conf 當中定義 search,使得我們直接打 dig web-service 可能找到正確的 FQDN。

▲ 不過僅限 service (原因就是在 /etc/resolv.conf search 裡面沒有 pod 呀!)
213. Ingress
請參考 CKAD Note Section 7 Service and Networking#94. Ingress Networking
Author
LastMod 2022-08-03 (13ba6cd)