說實話,K8s 網(wǎng)絡(luò)是我見過最讓新手頭疼的知識點,沒有之一。記得我剛接觸 K8s 那會兒,看著流量在 Pod、Service、Node 之間穿梭,完全是一臉懵逼。后來踩了無數(shù)坑,熬了無數(shù)夜,總算把這套網(wǎng)絡(luò)模型摸透了。今天這篇文章,我會用最接地氣的方式,帶你徹底搞懂 K8s 網(wǎng)絡(luò)。
一、概述
1.1 背景介紹
在傳統(tǒng)的虛擬機(jī)時代,網(wǎng)絡(luò)相對簡單——每臺 VM 一個 IP,通過交換機(jī)互聯(lián),頂多再加個負(fù)載均衡。但到了容器時代,事情變得復(fù)雜了:
一臺宿主機(jī)上可能跑著幾十上百個容器
容器隨時可能被銷毀重建,IP 地址不固定
跨主機(jī)的容器需要互相通信
還要對外暴露服務(wù)
K8s 的網(wǎng)絡(luò)模型就是為了解決這些問題而生的。它定義了一套清晰的網(wǎng)絡(luò)規(guī)范,讓不同的網(wǎng)絡(luò)插件(CNI)可以按照統(tǒng)一的標(biāo)準(zhǔn)來實現(xiàn)。
K8s 網(wǎng)絡(luò)的四大通信場景:
┌─────────────────────────────────────────────────────────────┐ │ K8s 網(wǎng)絡(luò)通信場景 │ ├─────────────────────────────────────────────────────────────┤ │ 1. 容器間通信 同一 Pod 內(nèi)的容器通過 localhost 通信 │ │ 2. Pod 間通信 不同 Pod 之間直接通過 Pod IP 通信 │ │ 3. Pod-Service Pod 通過 Service 的 ClusterIP 訪問服務(wù) │ │ 4. 外部-Service 外部流量通過 NodePort/LB/Ingress 進(jìn)入集群 │ └─────────────────────────────────────────────────────────────┘
1.2 技術(shù)特點
K8s 網(wǎng)絡(luò)模型有幾個核心設(shè)計原則,理解了這些,后面的內(nèi)容就好懂多了:
扁平化網(wǎng)絡(luò):所有 Pod 都在一個扁平的網(wǎng)絡(luò)空間中,可以直接通過 IP 互訪,不需要 NAT
IP-per-Pod:每個 Pod 擁有獨立的 IP 地址,Pod 內(nèi)的所有容器共享這個 IP
無 NAT 通信:Pod 看到的自己的 IP 就是其他 Pod 看到的 IP,沒有地址轉(zhuǎn)換的困擾
插件化架構(gòu):通過 CNI 標(biāo)準(zhǔn)接口,支持各種網(wǎng)絡(luò)插件(Calico、Cilium、Flannel 等)
2026年主流 CNI 插件對比:
| CNI 插件 | 網(wǎng)絡(luò)模式 | 性能 | NetworkPolicy | eBPF 支持 | 適用場景 |
|---|---|---|---|---|---|
| Cilium | Overlay/路由 | 極高 | 完整+擴(kuò)展 | 原生 | 大規(guī)模生產(chǎn)、安全敏感 |
| Calico | BGP/IPIP/VXLAN | 高 | 完整 | 可選 | 通用生產(chǎn)環(huán)境 |
| Flannel | VXLAN/host-gw | 中 | 不支持 | 不支持 | 小規(guī)模、學(xué)習(xí)環(huán)境 |
| Weave | VXLAN | 中 | 支持 | 不支持 | 簡單部署場景 |
| Antrea | Geneve/VXLAN | 高 | 完整 | 可選 | VMware 生態(tài) |
“
個人建議:2026年了,新集群直接上 Cilium。eBPF 帶來的性能提升和可觀測性是傳統(tǒng)方案沒法比的。我們公司去年從 Calico 遷移到 Cilium 后,網(wǎng)絡(luò)延遲降低了約 15%,而且 Hubble 的可視化簡直是排障神器。
1.3 適用場景
不同的網(wǎng)絡(luò)方案適用于不同場景,選錯了后期改造成本很高(別問我怎么知道的...):
Overlay 網(wǎng)絡(luò)(VXLAN/Geneve):
適合:跨云部署、網(wǎng)絡(luò)環(huán)境復(fù)雜、IP 地址受限
缺點:有封裝開銷,性能略低
典型:Flannel VXLAN、Calico IPIP
路由網(wǎng)絡(luò)(BGP/Host-Gateway):
適合:數(shù)據(jù)中心內(nèi)部、對性能要求高、有 BGP 基礎(chǔ)設(shè)施
缺點:需要網(wǎng)絡(luò)團(tuán)隊配合,配置相對復(fù)雜
典型:Calico BGP、Cilium Native Routing
eBPF 網(wǎng)絡(luò):
適合:大規(guī)模集群、需要高級網(wǎng)絡(luò)策略、追求極致性能
缺點:內(nèi)核版本要求高(建議 5.10+)
典型:Cilium、Calico eBPF 模式
1.4 環(huán)境要求
| 組件 | 版本要求 | 說明 |
|---|---|---|
| Kubernetes | 1.28+ | 建議使用 1.29/1.30,支持最新網(wǎng)絡(luò)特性 |
| Linux 內(nèi)核 | 5.10+ | 使用 eBPF 特性建議 5.15+,生產(chǎn)推薦 6.1 LTS |
| CNI 插件 | Cilium 1.15+ / Calico 3.27+ | 2026年主流版本 |
| kube-proxy | 可選 | 使用 Cilium 可完全替代 kube-proxy |
| CoreDNS | 1.11+ | 集群 DNS 服務(wù) |
內(nèi)核版本檢查:
# 檢查當(dāng)前內(nèi)核版本 uname -r # 檢查 eBPF 支持情況 # 如果輸出包含 CONFIG_BPF=y 說明支持 grep CONFIG_BPF /boot/config-$(uname -r) # 檢查 BTF 支持(Cilium 需要) ls -la /sys/kernel/btf/vmlinux
二、詳細(xì)步驟
2.1 準(zhǔn)備工作
2.1.1 網(wǎng)絡(luò)基礎(chǔ)概念回顧
在深入 K8s 網(wǎng)絡(luò)之前,先確保你理解這些基礎(chǔ)概念(老手可以跳過):
┌────────────────────────────────────────────────────────────────┐ │ Linux 網(wǎng)絡(luò)命名空間 │ ├────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ veth pair ┌─────────────┐ │ │ │ 容器網(wǎng)絡(luò) │?──────────────────?│ 宿主機(jī)網(wǎng)絡(luò) │ │ │ │ namespace │ (虛擬網(wǎng)線) │ namespace │ │ │ │ │ │ │ │ │ │ eth0 │ │ vethXXX │ │ │ │ 10.244.1.5 │ │ │ │ │ └─────────────┘ └──────┬──────┘ │ │ │ │ │ ┌──────▼──────┐ │ │ │ cni0/ │ │ │ │ cilium_ │ │ │ │ host │ │ │ │ (網(wǎng)橋) │ │ │ └─────────────┘ │ └────────────────────────────────────────────────────────────────┘
關(guān)鍵概念解釋:
Network Namespace:Linux 內(nèi)核提供的網(wǎng)絡(luò)隔離機(jī)制,每個 Pod 有自己的網(wǎng)絡(luò)命名空間
veth pair:虛擬以太網(wǎng)設(shè)備對,像一根網(wǎng)線連接兩個網(wǎng)絡(luò)命名空間
Bridge(網(wǎng)橋):二層交換設(shè)備,連接同一主機(jī)上的多個 veth 設(shè)備
路由表:決定數(shù)據(jù)包下一跳去哪里
2.1.2 實驗環(huán)境搭建
為了更好地理解網(wǎng)絡(luò)原理,建議搭建一個測試環(huán)境:
# 使用 kind 快速創(chuàng)建多節(jié)點集群(推薦用于學(xué)習(xí)) cat <kind-config.yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 networking: disableDefaultCNI:true# 禁用默認(rèn) CNI,手動安裝 podSubnet:"10.244.0.0/16" serviceSubnet:"10.96.0.0/12" nodes: - role: control-plane - role: worker - role: worker EOF kind create cluster --config kind-config.yaml --name network-lab # 安裝 Cilium(2026年推薦方案) helm repo add cilium https://helm.cilium.io/ helm install cilium cilium/cilium --version 1.15.0 --namespace kube-system --setkubeProxyReplacement=true --setk8sServiceHost=kind-control-plane --setk8sServicePort=6443
2.1.3 網(wǎng)絡(luò)診斷工具準(zhǔn)備
這些工具是排查網(wǎng)絡(luò)問題的必備神器:
# 創(chuàng)建一個網(wǎng)絡(luò)調(diào)試 Pod kubectl run netshoot --image=nicolaka/netshoot --command-- sleep infinity # 常用診斷命令 kubectlexec-it netshoot -- bash # 在 Pod 內(nèi)可以使用: # - ip addr / ip route / ip neigh # - ping / traceroute / mtr # - curl / wget # - tcpdump / tshark # - nslookup / dig # - ss / netstat # - iperf3(性能測試)
2.2 核心配置
2.2.1 CNI 插件工作原理
CNI(Container Network Interface)是 K8s 網(wǎng)絡(luò)的核心。當(dāng) kubelet 創(chuàng)建 Pod 時,會調(diào)用 CNI 插件來配置網(wǎng)絡(luò)。
CNI 調(diào)用流程:
┌─────────────────────────────────────────────────────────────────────┐ │ CNI 插件調(diào)用流程 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 1. kubelet 創(chuàng)建 Pod │ │ │ │ │ ▼ │ │ 2. 創(chuàng)建 pause 容器(持有網(wǎng)絡(luò)命名空間) │ │ │ │ │ ▼ │ │ 3. 調(diào)用 CNI 插件(/opt/cni/bin/) │ │ │ │ │ ├──? 讀取配置(/etc/cni/net.d/) │ │ │ │ │ ├──? 創(chuàng)建 veth pair │ │ │ │ │ ├──? 配置 IP 地址(IPAM) │ │ │ │ │ └──? 配置路由規(guī)則 │ │ │ │ │ ▼ │ │ 4. 返回網(wǎng)絡(luò)配置給 kubelet │ │ │ │ │ ▼ │ │ 5. 啟動業(yè)務(wù)容器(共享網(wǎng)絡(luò)命名空間) │ │ │ └─────────────────────────────────────────────────────────────────────┘
CNI 配置文件示例(Cilium):
# 查看 CNI 配置 cat /etc/cni/net.d/05-cilium.conflist
{
"cniVersion":"0.3.1",
"name":"cilium",
"plugins": [
{
"type":"cilium-cni",
"enable-debug":false,
"log-file":"/var/run/cilium/cilium-cni.log"
}
]
}
2.2.2 Pod 網(wǎng)絡(luò)模型詳解
這是理解 K8s 網(wǎng)絡(luò)的關(guān)鍵!每個 Pod 都有自己的網(wǎng)絡(luò)棧:
┌─────────────────────────────────────────────────────────────────────┐ │ Pod 網(wǎng)絡(luò)模型 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Pod │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ Container A │ │ Container B │ │ Pause │ │ │ │ │ │ (app) │ │ (sidecar) │ │ (infra容器) │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ localhost: │ │ localhost: │ │ 持有網(wǎng)絡(luò) │ │ │ │ │ │ 8080 │ │ 9090 │ │ 命名空間 │ │ │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ │ │ │ │ │ │ │ │ └────────────────┴────────────────┘ │ │ │ │ │ │ │ │ │ 共享網(wǎng)絡(luò)命名空間 │ │ │ │ │ │ │ │ │ ┌─────▼─────┐ │ │ │ │ │ eth0 │ │ │ │ │ │10.244.1.5 │ │ │ │ │ └───────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘
關(guān)鍵點:
同一 Pod 內(nèi)的容器共享網(wǎng)絡(luò)命名空間,可以通過localhost互訪
Pause 容器(也叫 infra 容器)負(fù)責(zé)持有網(wǎng)絡(luò)命名空間
每個 Pod 有獨立的 IP,端口空間也是獨立的
驗證 Pod 網(wǎng)絡(luò):
# 創(chuàng)建測試 Pod kubectl run nginx --image=nginx:alpine # 查看 Pod IP kubectl get pod nginx -o wide # 進(jìn)入 Pod 查看網(wǎng)絡(luò)配置 kubectlexec-it nginx -- sh /# ip addr /# ip route /# cat /etc/resolv.conf
2.2.3 Service 四種類型詳解
Service 是 K8s 網(wǎng)絡(luò)的核心抽象,它為一組 Pod 提供穩(wěn)定的訪問入口。說白了,Pod IP 會變,但 Service IP 不會變。
┌─────────────────────────────────────────────────────────────────────┐ │ Service 四種類型對比 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │ │ │ ClusterIP │ │ NodePort │ │LoadBalancer │ │ExternalName│ │ │ │ (默認(rèn)) │ │ │ │ │ │ │ │ │ ├─────────────┤ ├─────────────┤ ├─────────────┤ ├───────────┤ │ │ │ 僅集群內(nèi)部 │ │ 節(jié)點端口 │ │ 云LB + NP │ │ DNS別名 │ │ │ │ 訪問 │ │ 30000-32767 │ │ 自動創(chuàng)建 │ │ 無代理 │ │ │ │ │ │ │ │ │ │ │ │ │ │ 10.96.x.x │ │ NodeIP:Port │ │ External IP │ │ CNAME記錄 │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └───────────┘ │ │ │ │ 適用場景: │ │ - ClusterIP: 內(nèi)部微服務(wù)通信 │ │ - NodePort: 開發(fā)測試、簡單暴露 │ │ - LoadBalancer: 生產(chǎn)環(huán)境對外服務(wù) │ │ - ExternalName: 訪問集群外部服務(wù) │ │ │ └─────────────────────────────────────────────────────────────────────┘
1. ClusterIP(默認(rèn)類型)
apiVersion:v1 kind:Service metadata: name:my-service spec: type:ClusterIP# 可省略,默認(rèn)就是 ClusterIP selector: app:my-app ports: -port:80 # Service 端口 targetPort:8080# Pod 端口
2. NodePort
apiVersion:v1 kind:Service metadata: name:my-nodeport-service spec: type:NodePort selector: app:my-app ports: -port:80 targetPort:8080 nodePort:30080# 可選,不指定會自動分配 30000-32767
3. LoadBalancer
apiVersion:v1 kind:Service metadata: name:my-lb-service annotations: # 云廠商特定注解 service.beta.kubernetes.io/aws-load-balancer-type:"nlb" spec: type:LoadBalancer selector: app:my-app ports: -port:80 targetPort:8080
4. ExternalName
apiVersion:v1 kind:Service metadata: name:external-db spec: type:ExternalName externalName:db.example.com# 返回 CNAME 記錄
2.2.4 kube-proxy 三種模式深度解析
kube-proxy 是實現(xiàn) Service 負(fù)載均衡的關(guān)鍵組件。它有三種工作模式,理解它們的區(qū)別對于性能調(diào)優(yōu)和故障排查非常重要。
模式對比:
| 特性 | iptables | IPVS | nftables (1.31+) |
|---|---|---|---|
| 性能 | O(n) 規(guī)則匹配 | O(1) 哈希查找 | O(1) 集合查找 |
| 大規(guī)模支持 | 差(>1000 Service 性能下降) | 優(yōu)秀 | 優(yōu)秀 |
| 負(fù)載均衡算法 | 隨機(jī) | rr/lc/dh/sh/sed/nq | 隨機(jī) |
| 連接追蹤 | 依賴 conntrack | 內(nèi)置 | 依賴 conntrack |
| 調(diào)試難度 | 中等 | 較難 | 中等 |
| 內(nèi)核要求 | 3.10+ | 4.0+ | 5.13+ |
1. iptables 模式(傳統(tǒng)默認(rèn))
┌─────────────────────────────────────────────────────────────────────┐ │ iptables 模式工作原理 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ Client Pod │ │ │ │ │ │ dst: 10.96.0.10:80 (ClusterIP) │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ iptables 規(guī)則鏈 │ │ │ │ │ │ │ │ PREROUTING → KUBE-SERVICES → KUBE-SVC-XXX │ │ │ │ │ │ │ │ │ ┌───────────────┼───────────────┐ │ │ │ │ ▼ ▼ ▼ │ │ │ │ KUBE-SEP-A KUBE-SEP-B KUBE-SEP-C │ │ │ │ (Pod A) (Pod B) (Pod C) │ │ │ │ 33.3% 33.3% 33.3% │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ │ DNAT: dst → 10.244.1.5:8080 (Pod IP) │ │ ▼ │ │ Backend Pod │ │ │ └─────────────────────────────────────────────────────────────────────┘
# 查看 iptables 規(guī)則 iptables -t nat -L KUBE-SERVICES -n --line-numbers # 查看特定 Service 的規(guī)則 iptables -t nat -L KUBE-SVC-XXXXXXXXXXXXXXXX -n
2. IPVS 模式(推薦大規(guī)模集群)
┌─────────────────────────────────────────────────────────────────────┐ │ IPVS 模式工作原理 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ Client Pod │ │ │ │ │ │ dst: 10.96.0.10:80 │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ IPVS Virtual Server │ │ │ │ │ │ │ │ VIP: 10.96.0.10:80 │ │ │ │ 調(diào)度算法: rr (round-robin) │ │ │ │ │ │ │ │ Real Servers: │ │ │ │ ├── 10.244.1.5:8080 weight=1 │ │ │ │ ├── 10.244.2.3:8080 weight=1 │ │ │ │ └── 10.244.3.7:8080 weight=1 │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ │ 直接轉(zhuǎn)發(fā)到選中的 Real Server │ │ ▼ │ │ Backend Pod │ │ │ └─────────────────────────────────────────────────────────────────────┘
# 啟用 IPVS 模式 kubectl edit configmap kube-proxy -n kube-system # 修改 mode: "ipvs" # 查看 IPVS 規(guī)則 ipvsadm -Ln # 查看特定 Service ipvsadm -Ln -t 10.96.0.10:80
3. nftables 模式(K8s 1.31+ 新增)
這是 2025 年底新增的模式,用于替代老舊的 iptables。如果你的內(nèi)核版本夠新(5.13+),建議嘗試。
# 啟用 nftables 模式(需要 K8s 1.31+) kubectl edit configmap kube-proxy -n kube-system # 修改 mode: "nftables" # 查看 nftables 規(guī)則 nft list ruleset | grep -A 20"chain services"
“
踩坑經(jīng)驗:我們在一個 500+ Service 的集群上從 iptables 切換到 IPVS 后,Service 訪問延遲從平均 2ms 降到了 0.5ms。但要注意,IPVS 模式下需要確保ip_vs、ip_vs_rr、ip_vs_wrr、ip_vs_sh等內(nèi)核模塊已加載。
2.3 DNS 解析流程
2.3.1 CoreDNS 工作原理
K8s 集群內(nèi)的服務(wù)發(fā)現(xiàn)主要依賴 DNS。CoreDNS 是集群的 DNS 服務(wù)器,負(fù)責(zé)解析 Service 名稱到 ClusterIP。
┌─────────────────────────────────────────────────────────────────────┐ │ K8s DNS 解析流程 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ Pod (curl my-service) │ │ │ │ │ │ 1. 查詢 my-service │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ /etc/resolv.conf │ │ │ │ nameserver 10.96.0.10 (CoreDNS ClusterIP) │ │ │ │ search default.svc.cluster.local svc.cluster.local │ │ │ │ cluster.local │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ │ 2. 依次嘗試: │ │ │ - my-service.default.svc.cluster.local │ │ │ - my-service.svc.cluster.local │ │ │ - my-service.cluster.local │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ CoreDNS │ │ │ │ │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ kubernetes │ │ forward │ │ │ │ │ │ plugin │ │ plugin │ │ │ │ │ │ │ │ │ │ │ │ │ │ 查詢 K8s API│ │ 轉(zhuǎn)發(fā)到上游 │ │ │ │ │ │ 獲取 Service│ │ DNS 服務(wù)器 │ │ │ │ │ └─────────────┘ └─────────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ │ 3. 返回 ClusterIP: 10.96.100.50 │ │ ▼ │ │ Pod 訪問 10.96.100.50 │ │ │ └─────────────────────────────────────────────────────────────────────┘
DNS 記錄類型:
| 記錄類型 | 格式 | 示例 |
|---|---|---|
| Service A 記錄 |
|
nginx.default.svc.cluster.local |
| Pod A 記錄 |
|
10-244-1-5.default.pod.cluster.local |
| Headless Service | 返回所有 Pod IP | 用于 StatefulSet |
| SRV 記錄 |
_ |
包含端口信息 |
2.3.2 CoreDNS 配置優(yōu)化
# CoreDNS ConfigMap
apiVersion:v1
kind:ConfigMap
metadata:
name:coredns
namespace:kube-system
data:
Corefile:|
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
常見 DNS 問題排查:
# 測試 DNS 解析 kubectl run dnstest --image=busybox:1.28 --rm -it --restart=Never -- nslookup kubernetes # 查看 CoreDNS 日志 kubectl logs -n kube-system -l k8s-app=kube-dns -f # 檢查 CoreDNS Pod 狀態(tài) kubectl get pods -n kube-system -l k8s-app=kube-dns # 查看 DNS 配置 kubectl get configmap coredns -n kube-system -o yaml
“
踩坑提醒:曾經(jīng)遇到過一個詭異的問題,Pod 內(nèi) DNS 解析偶發(fā)超時。排查了半天,發(fā)現(xiàn)是ndots配置的鍋。默認(rèn)ndots:5意味著域名中點數(shù)少于 5 個時,會先嘗試加上 search 域。建議在 Pod spec 中顯式設(shè)置:
spec: dnsConfig: options: -name:ndots value:"2"# 減少不必要的 DNS 查詢 -name:single-request-reopen# 避免 conntrack 競爭
三、NetworkPolicy 實戰(zhàn)
3.1 NetworkPolicy 基礎(chǔ)
NetworkPolicy 是 K8s 的網(wǎng)絡(luò)安全策略,用于控制 Pod 之間的流量。默認(rèn)情況下,K8s 集群內(nèi)所有 Pod 可以互相訪問,這在生產(chǎn)環(huán)境是很危險的。
┌─────────────────────────────────────────────────────────────────────┐ │ NetworkPolicy 工作原理 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 默認(rèn)行為(無 NetworkPolicy): │ │ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │Pod A│?───?│Pod B│?───?│Pod C│ 所有 Pod 互通 │ │ └─────┘ └─────┘ └─────┘ │ │ │ │ 應(yīng)用 NetworkPolicy 后: │ │ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │Pod A│────?│Pod B│ ? │Pod C│ 只允許特定流量 │ │ └─────┘ └─────┘ └─────┘ │ │ │ ▲ │ │ │ │ 只允許來自 Pod A 的流量 │ │ └───────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘
重要概念:
NetworkPolicy 是白名單機(jī)制
一旦對 Pod 應(yīng)用了 NetworkPolicy,默認(rèn)拒絕所有未明確允許的流量
需要 CNI 插件支持(Flannel 不支持!)
3.2 實戰(zhàn)案例
案例一:默認(rèn)拒絕所有入站流量
# deny-all-ingress.yaml
apiVersion:networking.k8s.io/v1
kind:NetworkPolicy
metadata:
name:deny-all-ingress
namespace:production
spec:
podSelector:{}# 選擇該命名空間所有 Pod
policyTypes:
-Ingress
# 沒有 ingress 規(guī)則 = 拒絕所有入站
案例二:只允許特定 Pod 訪問數(shù)據(jù)庫
# allow-app-to-db.yaml
apiVersion:networking.k8s.io/v1
kind:NetworkPolicy
metadata:
name:allow-app-to-db
namespace:production
spec:
podSelector:
matchLabels:
app:mysql# 應(yīng)用到 mysql Pod
policyTypes:
-Ingress
ingress:
-from:
-podSelector:
matchLabels:
app:backend# 只允許 backend Pod 訪問
ports:
-protocol:TCP
port:3306
案例三:允許來自特定命名空間的流量
# allow-from-namespace.yaml
apiVersion:networking.k8s.io/v1
kind:NetworkPolicy
metadata:
name:allow-monitoring
namespace:production
spec:
podSelector:{}
policyTypes:
-Ingress
ingress:
-from:
-namespaceSelector:
matchLabels:
name:monitoring# 允許 monitoring 命名空間的所有 Pod
ports:
-protocol:TCP
port:9090# Prometheus 指標(biāo)端口
案例四:限制出站流量(防止數(shù)據(jù)泄露)
# restrict-egress.yaml
apiVersion:networking.k8s.io/v1
kind:NetworkPolicy
metadata:
name:restrict-egress
namespace:production
spec:
podSelector:
matchLabels:
app:sensitive-app
policyTypes:
-Egress
egress:
# 允許訪問 DNS
-to:
-namespaceSelector:{}
podSelector:
matchLabels:
k8s-app:kube-dns
ports:
-protocol:UDP
port:53
# 允許訪問內(nèi)部數(shù)據(jù)庫
-to:
-podSelector:
matchLabels:
app:mysql
ports:
-protocol:TCP
port:3306
# 禁止其他所有出站流量
3.3 NetworkPolicy 調(diào)試技巧
# 查看命名空間下的所有 NetworkPolicy kubectl get networkpolicy -n production # 查看詳細(xì)規(guī)則 kubectl describe networkpolicy allow-app-to-db -n production # 使用 Cilium 的話,可以用 Hubble 可視化流量 hubble observe --namespace production # 測試連通性 kubectlexec-ittest-pod -- nc -zv mysql-service 3306
“
生產(chǎn)經(jīng)驗:建議采用"默認(rèn)拒絕 + 顯式允許"的策略。先在每個命名空間部署 deny-all 策略,然后根據(jù)實際需求逐步開放。這樣可以最大程度減少攻擊面。
四、最佳實踐和注意事項
4.1 最佳實踐
4.1.1 CNI 選型建議
根據(jù)我這些年的經(jīng)驗,給出以下選型建議:
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 學(xué)習(xí)/測試環(huán)境 | Flannel | 簡單易用,資源占用少 |
| 中小規(guī)模生產(chǎn) | Calico | 成熟穩(wěn)定,社區(qū)活躍 |
| 大規(guī)模生產(chǎn) | Cilium | eBPF 性能優(yōu)異,可觀測性強(qiáng) |
| 多集群/混合云 | Cilium Cluster Mesh | 原生支持跨集群通信 |
| 安全敏感場景 | Cilium + Tetragon | 內(nèi)核級安全監(jiān)控 |
4.1.2 性能優(yōu)化
# 1. 啟用 IPVS 模式(大規(guī)模集群必備) kubectl edit configmap kube-proxy -n kube-system # 設(shè)置 mode: "ipvs" # 2. 調(diào)整 conntrack 參數(shù) cat >> /etc/sysctl.conf << EOF net.netfilter.nf_conntrack_max = 1000000 net.netfilter.nf_conntrack_tcp_timeout_established = 86400 net.netfilter.nf_conntrack_tcp_timeout_close_wait = 3600 EOF sysctl -p # 3. 如果使用 Cilium,啟用 BPF 主機(jī)路由 helm upgrade cilium cilium/cilium ? --set?bpf.masquerade=true? ? --set?routingMode=native ? --set?autoDirectNodeRoutes=true
4.1.3 高可用配置
# CoreDNS 高可用配置
apiVersion:apps/v1
kind:Deployment
metadata:
name:coredns
namespace:kube-system
spec:
replicas:3# 至少 3 副本
strategy:
type:RollingUpdate
rollingUpdate:
maxUnavailable:1
template:
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
-labelSelector:
matchLabels:
k8s-app:kube-dns
topologyKey:kubernetes.io/hostname# 分散到不同節(jié)點
4.2 注意事項
4.2.1 常見陷阱
| 問題 | 原因 | 解決方案 |
|---|---|---|
| Pod 無法訪問 Service | kube-proxy 未運(yùn)行或規(guī)則未同步 | 檢查 kube-proxy 日志,重啟 Pod |
| 跨節(jié)點 Pod 不通 | CNI 配置錯誤或防火墻阻斷 | 檢查節(jié)點間網(wǎng)絡(luò),開放 VXLAN 端口 |
| DNS 解析超時 | CoreDNS 資源不足或 ndots 配置 | 增加副本數(shù),調(diào)整 ndots |
| Service 負(fù)載不均 | 會話親和性或 IPVS 調(diào)度算法 | 檢查 sessionAffinity 配置 |
| NetworkPolicy 不生效 | CNI 不支持或規(guī)則配置錯誤 | 確認(rèn) CNI 支持,檢查 selector |
4.2.2 安全加固
# 1. 禁用 NodePort 范圍外的端口 # 在 kube-apiserver 配置中設(shè)置 --service-node-port-range=30000-32767 # 2. 啟用 Pod 安全策略(或 Pod Security Standards) kubectl label namespace production pod-security.kubernetes.io/enforce=restricted # 3. 限制 hostNetwork 使用 # 在 NetworkPolicy 中明確禁止
五、故障排查和監(jiān)控
5.1 故障排查
5.1.1 網(wǎng)絡(luò)排查流程圖
┌─────────────────────────────────────────────────────────────────────┐ │ K8s 網(wǎng)絡(luò)故障排查流程 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ Pod 網(wǎng)絡(luò)不通? │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────┐ │ │ │ 1. 檢查 Pod 狀態(tài) │ │ │ │ kubectl get pod -o wide │ │ │ │ Pod 是否 Running?IP 是否分配? │ │ │ └─────────────────┬───────────────────────┘ │ │ │ │ │ ┌───────────┴───────────┐ │ │ ▼ ▼ │ │ Pod 異常 Pod 正常 │ │ 檢查 CNI 日志 │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ 2. 檢查同節(jié)點 Pod 互通 │ │ │ │ kubectlexecpod1 -- ping pod2 │ │ │ └─────────────────┬───────────────────┘ │ │ │ │ │ ┌───────────┴───────────┐ │ │ ▼ ▼ │ │ 同節(jié)點不通 同節(jié)點通 │ │ 檢查 CNI/網(wǎng)橋 │ │ │ ▼ │ │ ┌─────────────────────────────┐ │ │ │ 3. 檢查跨節(jié)點 Pod 互通 │ │ │ └─────────────────┬───────────┘ │ │ │ │ │ ┌───────────┴───────────┐ │ │ ▼ ▼ │ │ 跨節(jié)點不通 跨節(jié)點通 │ │ 檢查 Overlay/路由 │ │ │ 檢查防火墻 ▼ │ │ ┌─────────────┐ │ │ │ 4. 檢查 │ │ │ │ Service/DNS │ │ │ └─────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘
5.1.2 常用排查命令
# === Pod 層面 === # 查看 Pod 網(wǎng)絡(luò)配置 kubectlexec-it-- ip addr kubectlexec-it -- ip route kubectlexec-it -- cat /etc/resolv.conf # 測試連通性 kubectlexec-it -- ping kubectlexec-it -- curl -v : kubectlexec-it -- nslookup # === 節(jié)點層面 === # 查看網(wǎng)橋和 veth ip link showtypebridge ip link showtypeveth brctl show # 如果使用網(wǎng)橋模式 # 查看路由表 ip route show ip route get # 查看 iptables 規(guī)則 iptables -t nat -L -n -v | grep iptables -t filter -L -n -v # 查看 IPVS 規(guī)則 ipvsadm -Ln ipvsadm -Ln --stats # === CNI 層面 === # Cilium 狀態(tài)檢查 cilium status cilium connectivitytest # Calico 狀態(tài)檢查 calicoctl node status calicoctl get ippool -o wide
5.1.3 抓包分析
# 在節(jié)點上抓取特定 Pod 的流量 # 首先找到 Pod 的 veth 接口 POD_ID=$(crictl pods --name-q) VETH=$(ip link | grep -A1"veth"| grep$POD_ID| awk'{print $2}'| tr -d':') # 抓包 tcpdump -i$VETH-nn -w pod-traffic.pcap # 或者使用 nsenter 進(jìn)入 Pod 網(wǎng)絡(luò)命名空間 PID=$(crictl inspect$POD_ID| jq'.info.pid') nsenter -t$PID-n tcpdump -i eth0 -nn
5.2 性能監(jiān)控
5.2.1 關(guān)鍵指標(biāo)
| 指標(biāo) | 正常范圍 | 告警閾值 | 說明 |
|---|---|---|---|
| DNS 查詢延遲 | < 5ms | > 50ms | CoreDNS 響應(yīng)時間 |
| Service 延遲 | < 1ms | > 10ms | kube-proxy 轉(zhuǎn)發(fā)延遲 |
| 跨節(jié)點延遲 | < 1ms | > 5ms | Overlay 網(wǎng)絡(luò)開銷 |
| conntrack 使用率 | < 70% | > 85% | 連接跟蹤表使用 |
| 丟包率 | 0% | > 0.1% | 網(wǎng)絡(luò)丟包 |
5.2.2 Prometheus 監(jiān)控配置
# 網(wǎng)絡(luò)相關(guān)告警規(guī)則 apiVersion:monitoring.coreos.com/v1 kind:PrometheusRule metadata: name:network-alerts spec: groups: -name:network rules: -alert:HighDNSLatency expr:histogram_quantile(0.99,rate(coredns_dns_request_duration_seconds_bucket[5m]))>0.05 for:5m labels: severity:warning annotations: summary:"DNS 查詢延遲過高" -alert:ConntrackTableFull expr:node_nf_conntrack_entries/node_nf_conntrack_entries_limit>0.85 for:5m labels: severity:critical annotations: summary:"Conntrack 表即將滿"
六、總結(jié)
6.1 技術(shù)要點回顧
Pod 網(wǎng)絡(luò)模型:每個 Pod 獨立 IP,同 Pod 容器共享網(wǎng)絡(luò)命名空間
CNI 插件:2026年首選 Cilium,eBPF 帶來性能和可觀測性優(yōu)勢
Service 類型:ClusterIP(內(nèi)部)、NodePort(測試)、LoadBalancer(生產(chǎn))、ExternalName(外部)
kube-proxy 模式:大規(guī)模集群用 IPVS,新集群可嘗試 nftables
DNS 解析:CoreDNS 負(fù)責(zé)服務(wù)發(fā)現(xiàn),注意 ndots 配置優(yōu)化
NetworkPolicy:白名單機(jī)制,生產(chǎn)環(huán)境必須配置
6.2 進(jìn)階學(xué)習(xí)方向
eBPF 深入學(xué)習(xí)
學(xué)習(xí)資源:Cilium 官方文檔、eBPF.io
實踐建議:部署 Hubble 可視化,學(xué)習(xí) BPF 程序編寫
服務(wù)網(wǎng)格(Service Mesh)
學(xué)習(xí)資源:Istio、Linkerd 官方文檔
實踐建議:理解 Sidecar 模式,對比 Cilium Service Mesh
多集群網(wǎng)絡(luò)
學(xué)習(xí)資源:Cilium Cluster Mesh、Submariner
實踐建議:搭建跨集群通信實驗環(huán)境
6.3 參考資料
Kubernetes 官方網(wǎng)絡(luò)文檔
Cilium 官方文檔
Calico 官方文檔
CoreDNS 官方文檔
附錄
A. 命令速查表
# Pod 網(wǎng)絡(luò) kubectl get pod -o wide # 查看 Pod IP kubectlexec-it-- ip addr # 查看 Pod 網(wǎng)絡(luò)配置 # Service kubectl get svc # 查看 Service kubectl get endpoints # 查看 Endpoints # DNS kubectl run -it --rm debug --image=busybox -- nslookup # CNI cilium status # Cilium 狀態(tài) calicoctl node status # Calico 狀態(tài) # kube-proxy iptables -t nat -L KUBE-SERVICES -n # iptables 規(guī)則 ipvsadm -Ln # IPVS 規(guī)則
B. 術(shù)語表
| 術(shù)語 | 英文 | 解釋 |
|---|---|---|
| CNI | Container Network Interface | 容器網(wǎng)絡(luò)接口標(biāo)準(zhǔn) |
| IPAM | IP Address Management | IP 地址管理 |
| VXLAN | Virtual Extensible LAN | 虛擬可擴(kuò)展局域網(wǎng) |
| BGP | Border Gateway Protocol | 邊界網(wǎng)關(guān)協(xié)議 |
| eBPF | extended Berkeley Packet Filter | 擴(kuò)展伯克利包過濾器 |
寫在最后:K8s 網(wǎng)絡(luò)確實復(fù)雜,但只要理解了核心概念,剩下的就是實踐和積累。建議大家多動手搭建測試環(huán)境,用 tcpdump 抓包分析,這樣才能真正掌握。有問題歡迎交流,我們下篇文章見!
-
網(wǎng)絡(luò)
+關(guān)注
關(guān)注
14文章
8249瀏覽量
94669 -
模型
+關(guān)注
關(guān)注
1文章
3749瀏覽量
52091 -
負(fù)載均衡
+關(guān)注
關(guān)注
0文章
133瀏覽量
12874
原文標(biāo)題:萬字長文圖解 K8s 網(wǎng)絡(luò):從 Pod 到 Service 的流量奇幻漂流
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
什么是 K8S,如何使用 K8S
OpenStack與K8s結(jié)合的兩種方案的詳細(xì)介紹和比較
如何使用kubernetes client-go實踐一個簡單的與K8s交互過程
k8s容器運(yùn)行時演進(jìn)歷史
Docker不香嗎為什么還要用K8s
簡單說明k8s和Docker之間的關(guān)系
K8S集群服務(wù)訪問失敗怎么辦 K8S故障處理集錦
k8s是什么意思?kubeadm部署k8s集群(k8s部署)|PetaExpres
什么是K3s和K8s?K3s和K8s有什么區(qū)別?
k8s生態(tài)鏈包含哪些技術(shù)
常用的k8s容器網(wǎng)絡(luò)模式有哪些?
k8s云原生開發(fā)要求
一文帶你徹底搞懂K8s網(wǎng)絡(luò)
評論