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
service
DNS recordpod
DNS 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
「沒有這個人啦!」。這也是為什麼前面提到 「pod
create 時並不會自動被產生 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)