hostNetwork:讓 Pod 直接使用主機網路
在 Kubernetes 中設定 hostNetwork: true,Pod 就會直接使用節點的網路命名空間——共用節點的 IP、Port 和所有網路設定。這在某些場景下很有用(例如網路監控、Ingress Controller),但也帶來一些需要注意的問題。
DNS 策略設定
使用 hostNetwork 後,Pod 預設會繼承主機的 DNS 設定,無法使用 K8s 內部的 Service DNS 解析。解決方法是設定 DNS 策略為 ClusterFirstWithHostNet:
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
K8s 提供的四種 DNS 策略:
| 策略 | 行為 |
|---|---|
Default |
繼承節點的 DNS 設定(hostNetwork 的預設值) |
ClusterFirst |
優先用 K8s DNS,無法解析的轉給主機 DNS(一般 Pod 預設值) |
ClusterFirstWithHostNet |
同 ClusterFirst,但明確適用於 hostNetwork Pod |
None |
完全自訂,透過 spec.dnsConfig 設定 |
hostNetwork 範例
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
hostPort vs NodePort
| 特性 | hostPort | NodePort |
|---|---|---|
| 開放範圍 | 只在 Pod 所在節點開端口 | 所有節點都開端口 |
| 實作方式 | 由 portmap CNI 插件透過 iptables NAT 轉發 | kube-proxy 在 KUBE-SERVICES 鏈中設定規則 |
| netstat/lsof 可見 | 否(iptables 轉發,無實際監聽) | 是 |
| iptables 優先順序 | 在 KUBE-SERVICES 之前 | 在 KUBE-SERVICES 之中 |
| 生產環境建議 | 不建議使用 | 視需求使用 |
生產環境中不建議使用 hostPort,因為它會佔用節點端口且排障困難。
NetworkPolicy:K8s 的網路防火牆
NetworkPolicy 讓你在 IP 位址和端口層面(L3/L4)控制 Pod 的網路流量。它是一種以應用為中心的防火牆規則,定義哪些流量允許進出 Pod。
前提:CNI 插件必須支援
| CNI | NetworkPolicy 支援 |
|---|---|
| Flannel | 不支援(只提供基本網路連通) |
| Calico | 完整支援,功能豐富 |
| Cilium | 完整支援,還支援 L7 策略 |
如果你用 Flannel,NetworkPolicy 定義了也不會生效——這是很常見的踩坑點。
兩種隔離方向
- Ingress(入站):控制哪些來源可以存取目標 Pod
- Egress(出站):控制目標 Pod 可以存取哪些目的地
預設情況下,Pod 的出入站都是完全開放的。一旦有任何 NetworkPolicy 選中了某個 Pod,該 Pod 就進入「隔離」狀態——只有策略明確允許的流量才能通過。
NetworkPolicy 範例解析
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
這個策略做了什麼:
| 方向 | 規則 |
|---|---|
| 適用對象 | default namespace 中帶有 role=db 標籤的 Pod |
| 入站允許 | 以下三類來源存取 TCP 6379: 1. 同 namespace 帶 role=frontend 的 Pod2. 帶 project=myproject 標籤的 namespace 中所有 Pod3. IP 範圍 172.17.0.0/16(排除 172.17.1.0/24) |
| 出站允許 | 只能連線到 10.0.0.0/24 的 TCP 5978 |
選擇器的 AND vs OR 邏輯
這是 NetworkPolicy 最容易搞混的地方。看兩個例子:
AND 邏輯(同一個清單元素):
from:
- namespaceSelector:
matchLabels:
user: alice
podSelector:
matchLabels:
role: client
= namespace 標籤有 user=alice 且 Pod 標籤有 role=client
OR 邏輯(不同的清單元素):
from:
- namespaceSelector:
matchLabels:
user: alice
- podSelector:
matchLabels:
role: client
= namespace 標籤有 user=alice 的所有 Pod 或 同 namespace 中標籤有 role=client 的 Pod
差一個破折號,意思完全不同。寫 YAML 時務必特別小心。
重點整理
- NetworkPolicy 是白名單機制——只有明確允許的才放行,其餘全擋
- 沒指定
namespaceSelector時,規則只作用於 NetworkPolicy 所在的 namespace - 多個 NetworkPolicy 是相加的,不會互相衝突
- 入站和出站需要兩端都允許,連線才能建立
- hostNetwork Pod 使用
ClusterFirstWithHostNetDNS 策略才能解析 K8s 內部 Service 名稱

發佈留言