Kubernetes网络模型详解:从Pod到Service实现集群内通信
一、先搞懂一件事:K8s的网络到底是怎么回事?
说实话,第一次接触Kubernetes的时候,我也被它的网络模型搞蒙了。想象一下,你的集群里有几十个Pod在跑,它们分布在不同节点上,每个Pod都有自己的IP,这些IP之间是怎么通信的?Pod怎么找到Service?Service又怎么把流量分发到后面的Pod?
今天咱们就掰开揉碎了,把K8s网络从头到尾讲清楚。放心,不用什么高深数学,咱们用大白话+实际例子来讲。
二、Pod网络:每个Pod都有一张”身份证”
2.1 Pod IP是什么?
在Kubernetes里,每个Pod都会被分配一个唯一的IP地址,这个IP叫做Pod IP。Pod IP是集群内部可见的,不同节点上的Pod可以通过各自的Pod IP直接通信。
这里有个关键概念:Pod是K8s网络的最小单位。什么意思呢?就是说,K8s网络模型的设计原则是——应用开发者不需要知道自己跑在哪个节点上,也不需要关心底层网络怎么搭建的,只要Pod起来了,就能通过IP访问。
举个例子,假设有这样一个场景:
集群有三个节点:node-1, node-2, node-3
node-1上的Pod: 10.244.1.5
node-2上的Pod: 10.244.2.8
node-3上的Pod: 10.244.3.12
这三个Pod虽然跑在不同机器上,但它们在逻辑上属于同一个网络,可以直接互相ping通。这就是K8s网络模型最核心的一点:跨节点Pod网络互通。
2.2 Pod网络是怎么实现的?
这就要说到容器网络接口(CNI)了。
CNI是Kubernetes定义的一套标准,用于给容器分配网络资源。常见的CNI插件有:
- Flannel:最简单,适合新手入门
- Calico:功能强大,支持网络策略
- Cilium:基于eBPF,性能优秀
- Weave Net:支持加密通信
我用Flannel来举个例子,看看Pod网络是怎么搭建的:
# 部署Flannel CNI
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# 查看Pod网络
kubectl get pods -n kube-system | grep flannel
部署完之后,K8s会在每个节点上创建一个flannel.1虚拟网桥,所有节点通过 VXLAN 隧道互联,形成一个大的虚拟二层网络。
# 查看节点上的网络接口
ip addr show flannel.1
你会看到类似这样的输出:
4: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450
inet 10.244.0.1 netmask 255.255.255.255
...
2.3 Pod的网络命名空间
每个Pod有自己独立的网络命名空间。这意味着Pod内的进程看到的网络世界是隔离的。在Pod内部,你可以看到自己的IP:
# 进入Pod查看网络配置
kubectl exec -it my-pod -- ip addr
输出类似:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536
inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450
inet 10.244.1.5/24 scope global eth0
这个eth0就是Pod的虚拟网卡,IP是10.244.1.5。
2.4 Pause容器:Pod网络的基石
你可能不知道,一个Pod里除了你部署的业务容器,还有一个特殊的容器叫pause容器(以前叫infra容器)。
# 查看Pod里的容器
kubectl get pods my-pod -o jsonpath='{.spec.containers[*].name}'
输出:
pause my-app
这个pause容器就是Pod网络的核心。它创建一个网络命名空间,配置好IP地址和路由,然后其他业务容器通过network namespace共享这个网络空间。
┌─────────────────────────────────────────┐
│ Pod Network │
│ ┌──────────┐ ┌──────────┐ │
│ │ eth0 │ │ eth0 │ │
│ │ 10.244.1.5│ │ 10.244.1.5│ │
│ │ pause │◄──►│ my-app │ │
│ │ (网络) │ │ (业务) │ │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────────┘
所有容器共享同一个网络栈,所以它们之间用localhost就能通信。
三、Service网络:给Pod穿上”马甲”
3.1 为什么要用Service?
问题来了:Pod IP是动态的,Pod挂了重启,IP就变了。你的应用怎么可能每次都对着一堆可能变化的IP去访问服务呢?
这就需要Service了。
Service是Kubernetes里非常重要的资源对象,它提供一个稳定的访问入口,后面挂载着一组Pod。无论后面Pod怎么变,Service的IP永远不变。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
这个YAML的意思是:创建一个叫my-service的Service,它会选择所有标签app: my-app的Pod,把80端口的流量转发到Pod的8080端口。
3.2 ClusterIP:最基础的Service类型
Service有几种类型,最常见的是ClusterIP,它会在集群内部分配一个虚拟IP,这个IP只能通过集群内部访问。
# 创建Service
kubectl apply -f service.yaml
# 查看Service
kubectl get svc my-service
输出:
NAME TYPE CLUSTER-IP PORT(S) AGE
my-service ClusterIP 10.96.0.100 80/TCP 5m
这个10.96.0.100就是Service的ClusterIP,它是虚拟IP,不绑定在任何物理网卡上。
3.3 kube-proxy:Service的幕后英雄
你可能会问:这个虚拟IP是怎么工作的?谁来负责把流量从Service IP转发到Pod IP?
答案是kube-proxy。
每个节点上都运行着一个kube-proxy进程,它负责维护网络规则,把发往Service IP的流量转发到后端的Pod IP。
kube-proxy有三种工作模式:
- userspace模式:最早的模式,性能一般,K8s 1.8之后不再推荐
- iptables模式:默认模式,性能好,通过iptables规则实现
- ipvs模式:性能最好,支持更多负载均衡算法
来看看iptables模式下,kube-proxy生成了什么规则:
# 查看iptables规则
sudo iptables -t nat -L -n -v | grep my-service
你会看到类似这样的规则:
Chain KUBE-SERVICES (2 references)
target prot opt source destination
KUBE-SVC-XXXX tcp -- 0.0.0.0/0 10.96.0.100 /* default/my-service cluster IP */ tcp dpt:80
Chain KUBE-SVC-XXXX (1 references)
target prot opt source destination
KUBE-SEP-XXXX all -- 0.0.0.0/0 0.0.0.0/0 statistic mode random probability 0.33333
KUBE-SEP-YYYY all -- 0.0.0.0/0 0.0.0.0/0 statistic mode random probability 0.50000
KUBE-SEP-ZZZZ all -- 0.0.0.0/0 0.0.0.0/0
这些规则最终会把流量导向后端的三个Pod:
10.244.1.5:8080 (概率33%)
10.244.2.8:8080 (概率33%)
10.244.3.12:8080 (概率34%)
如果用ipvs模式,规则会更干净:
# 查看IPVS规则
sudo ipvsadm -Ln
IP Virtual Server version 1.2.1
Size: 131072
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.96.0.100:80 rr
-> 10.244.1.5:8080 Route 1 0 5
-> 10.244.2.8:8080 Route 1 0 3
-> 10.244.3.12:8080 Route 1 0 4
可以看到,ipvs模式用轮询(rr)算法分发流量,比iptables更直观。
3.4 Service的负载均衡算法
默认情况下,Service使用轮询(Round Robin)算法。但你可以修改配置:
apiVersion: v1
kind: Service
metadata:
name: my-service
annotations:
# ipvs模式支持多种算法
service.kubernetes.io/ipvs-scheduling: "rr" # 轮询
service.kubernetes.io/ipvs-scheduling: "lc" # 最少连接
service.kubernetes.io/ipvs-scheduling: "dh" # 目标地址哈希
service.kubernetes.io/ipvs-scheduling: "sh" # 源地址哈希
service.kubernetes.io/ipvs-scheduling: "sed" # 加权最少连接
service.kubernetes.io/ipvs-scheduling: "nq" # 加权轮询
源地址哈希(sh)很有意思——同一个客户端的请求总是转发到同一个Pod,适合有状态的应用。
四、DNS服务:让服务名代替IP地址
4.1 CoreDNS:K8s的DNS心脏
有了Service,我们肯定不希望每次访问服务都记IP。Kubernetes内置了DNS服务,默认使用CoreDNS(以前是kube-dns)。
# 查看CoreDNS Pod
kubectl get pods -n kube-system | grep coredns
输出:
coredns-6d4b78cb4-abc12 1/1 Running 0 5d
coredns-6d4b78cb4-def34 1/1 Running 0 5d
4.2 DNS服务是怎么工作的?
当你在Pod里用my-service访问服务时,K8s会在背后做这样一件事:
- Pod里的DNS客户端查询
my-service的IP - 请求被发送到集群的DNS服务器(CoreDNS)
- CoreDNS返回Service的ClusterIP
- 后续流量通过kube-proxy转发到后端Pod
你可以直接在一个Pod里测试:
# 在Pod里查看DNS配置
kubectl exec -it my-pod -- cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
10.96.0.10就是CoreDNS的ClusterIP。
4.3 DNS记录格式
Kubernetes的DNS规则很简单:
<service-name>.<namespace>.svc.cluster.local
举个例子:
# 默认命名空间的service
my-service.default.svc.cluster.local
# 简写
my-service
# 其他命名空间的service
my-service.staging.svc.cluster.local
# 简写(如果在staging命名空间)
my-service
测试一下:
# 在Pod里解析域名
kubectl exec -it my-pod -- nslookup my-service
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: my-service.default.svc.cluster.local
Address: 10.96.0.100
4.4 Endpoints:Service和Pod的桥梁
Service怎么知道后面有哪些Pod?这就要说到Endpoints资源了。
# 查看Endpoints
kubectl get endpoints my-service
NAME ENDPOINTS AGE
my-service 10.244.1.5:8080,10.244.2.8:8080,10.244.3.12:8080 5m
当你创建Service时,K8s会自动创建对应的Endpoints对象。如果后端Pod挂了,Endpoints会自动从列表里移除。
你也可以手动管理Endpoints(虽然一般不这么做):
apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- ip: 10.244.1.5
- ip: 10.244.2.8
ports:
- port: 8080
4.5 Headless Service:不走负载均衡
有时候你不需要负载均衡,就想直接访问所有Pod的IP。这时候用Headless Service:
apiVersion: v1
kind: Service
metadata:
name: my-headless-service
spec:
clusterIP: None # 关键!设置为None
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
这种Service不会分配ClusterIP,DNS会直接返回所有Pod的IP:
kubectl exec -it my-pod -- nslookup my-headless-service
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: my-headless-service.default.svc.cluster.local
Address: 10.244.1.5
10.244.2.8
10.244.3.12
这对有状态服务(比如数据库集群)特别有用。
五、网络策略:给集群加上”防火墙”
5.1 NetworkPolicy是什么?
光有网络还不够安全。如果集群里有个恶意Pod,它能访问所有其他Pod吗?这显然不行。
NetworkPolicy就是K8s的防火墙规则,用来控制Pod之间的网络访问。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
这个策略的意思是:默认拒绝所有入站流量。所有Pod之间都不能互相访问,除非有明确的允许规则。
5.2 让特定服务可以访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
这个规则的意思是:允许标签为app: frontend的Pod访问标签为app: backend的Pod的8080端口。
5.3 需要CNI支持NetworkPolicy
不是所有CNI都支持NetworkPolicy。前面提到的几个:
- Flannel:不支持
- Calico:支持,且功能强大
- Cilium:支持,基于eBPF性能更好
- Weave Net:支持
如果你用了不支持NetworkPolicy的CNI,创建NetworkPolicy也不会生效,K8s不会报错,但规则就是失效的。这点很容易踩坑!
# 检查当前网络插件
kubectl get pods -n kube-system | grep -E 'calico|flannel|cilium'
六、Ingress:让外部流量进入集群
6.1 什么是Ingress?
Service虽然有稳定的IP,但外部用户怎么访问集群里的服务呢?有几种方式:
- NodePort:在节点上开放一个端口
- LoadBalancer:云厂商提供的外部负载均衡器
- Ingress:七层负载均衡,基于域名和路径路由
Ingress是最灵活的方式,它工作在HTTP/HTTPS层,可以根据域名和路径把流量分发到不同的Service。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
这个配置的意思是:访问example.com/api时转发到api-service,访问example.com时转发到web-service。
6.2 Ingress Controller
Ingress本身只是一个配置,真正起作用的是Ingress Controller。常见的有:
- nginx-ingress:最流行,基于nginx
- traefik:现代化,支持自动发现
- envoy:高性能,云原生
安装nginx-ingress:
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
spec:
controller: k8s.io/ingress-nginx
# 部署nginx-ingress
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml
6.3 外部流量怎么进来?
Ingress Controller通常通过NodePort或LoadBalancer暴露自己:
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 443
selector:
app.kubernetes.io/name: ingress-nginx
在云服务器上,这会自动创建一个负载均衡器,获得一个公网IP。在内网环境中,你可能用NodePort:
kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.96.0.50 80:30080/TCP,443:30443/TCP 5m
然后通过节点的30080端口访问。
七、完整链路:一次请求的完整旅程
7.1 从外部到Pod的完整路径
让我们来追踪一个完整的请求路径,假设外部用户访问example.com/api:
用户浏览器
│
▼
┌─────────────────────────────────────────────────────────┐
│ DNS解析 example.com → 负载均衡器IP(1.2.3.4) │
└─────────────────────────────────────────────────────────┘
│
▼ HTTP请求到 1.2.3.4:80
┌─────────────────────────────────────────────────────────┐
│ LoadBalancer (云厂商提供) │
│ 将流量转发到集群节点:30080 │
└─────────────────────────────────────────────────────────┘
│
▼ 流量到达节点
┌─────────────────────────────────────────────────────────┐
│ iptables/ipvs规则 │
│ 匹配 NodePort 30080 → 转发到 ingress-nginx Pod │
└─────────────────────────────────────────────────────────┘
│
▼ 到达ingress-nginx Pod
┌─────────────────────────────────────────────────────────┐
│ Ingress Controller (nginx) │
│ 解析Host: example.com + Path: /api │
│ 匹配到backend: api-service:80 │
└─────────────────────────────────────────────────────────┘
│
▼ DNS解析 api-service → ClusterIP 10.96.0.200
┌─────────────────────────────────────────────────────────┐
│ kube-proxy iptables/ipvs规则 │
│ 匹配 ClusterIP 10.96.0.200:80 │
│ 负载均衡到后端Pod │
└─────────────────────────────────────────────────────────┘
│
▼ 随机选择一个Pod,比如 10.244.1.5:8080
┌─────────────────────────────────────────────────────────┐
│ Pod (my-app) │
│ 处理请求,返回响应 │
└─────────────────────────────────────────────────────────┘
│
▼ 响应反向走一遍同样的路径
用户收到响应 ✓
7.2 用Wireshark或tcpdump观察流量
如果你想亲眼看到流量是怎么流转的,可以在节点上用tcpdump抓包:
# 在节点上抓包,观察发往Service ClusterIP的流量
sudo tcpdump -i any host 10.96.0.100 and port 80
# 抓包观察Pod之间的流量
sudo tcpdump -i flannel.1
你会看到流量在VXLAN隧道里传输,源地址是Pod IP,目的地址也是Pod IP,但中间经过了节点的网络转发。
八、实战:搭建一个完整的网络环境
8.1 部署一个多层应用
我们来搭一个完整的例子,包含前端、后端、数据库:
# 1. 数据库
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: app
spec:
clusterIP: None # Headless Service
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: app
spec:
serviceName: mysql
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
value: "password123"
ports:
- containerPort: 3306
# 2. 后端API
apiVersion: v1
kind: Service
metadata:
name: api-service
namespace: app
spec:
selector:
app: api
ports:
- port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment
namespace: app
spec:
replicas: 3
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: my-api:latest
ports:
- containerPort: 8080
# 3. 前端
apiVersion: v1
kind: Service
metadata:
name: web-service
namespace: app
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
namespace: app
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: my-web:latest
ports:
- containerPort: 80
# 4. Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
namespace: app
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
8.2 验证网络连通性
# 部署所有资源
kubectl apply -f .
# 查看所有资源
kubectl get all -n app
NAME READY STATUS RESTARTS AGE
pod/api-deployment-5d8f7b-c4x1z 1/1 Running 0 2m
pod/api-deployment-5d8f7b-k9m2n 1/1 Running 0 2m
pod/api-deployment-5d8f7b-p3q4r 1/1 Running 0 2m
pod/mysql-0 1/1 Running 0 2m
pod/web-deployment-6c7d8e-f5g6h 1/1 Running 0 2m
pod/web-deployment-6c7d8e-i7j8k 1/1 Running 0 2m
NAME TYPE CLUSTER-IP PORT(S) AGE
service/api-service ClusterIP 10.96.10.50 80/TCP 2m
service/mysql ClusterIP None 3306/TCP 2m
service/web-service ClusterIP 10.96.20.75 80/TCP 2m
# 测试DNS解析
kubectl exec -it api-deployment-5d8f7b-c4x1z -n app -- nslookup web-service
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: web-service.app.svc.cluster.local
Address: 10.96.20.75
# 测试从API Pod访问Web Service
kubectl exec -it api-deployment-5d8f7b-c4x1z -n app -- curl -s http://web-service | head -20
<!DOCTYPE html>
<html>
<head><title>Welcome</title></head>
<body>
<h1>Hello from web-service!</h1>
</body>
</html>
# 测试从API Pod访问数据库
kubectl exec -it api-deployment-5d8f7b-c4x1z -n app -- nslookup mysql
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: mysql.app.svc.cluster.local
Address: 10.244.1.5 # Pod IP
10.244.2.8 # Pod IP (如果有多个副本)
8.3 网络策略:限制API只能访问MySQL
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-to-mysql
namespace: app
spec:
podSelector:
matchLabels:
app: mysql
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 3306
kubectl apply -f network-policy.yaml
# 验证:API Pod可以访问MySQL
kubectl exec -it api-deployment-5d8f7b-c4x1z -n app -- mysql -h mysql -u root -ppassword123 -e "SELECT 1;"
# 验证:Web Pod不能访问MySQL(应该失败)
kubectl exec -it web-deployment-6c7d8e-f5g6h -n app -- mysql -h mysql -u root -ppassword123 -e "SELECT 1;"
# 应该会超时或连接被拒绝
九、常见问题排查指南
9.1 Pod之间无法通信
# 1. 检查Pod IP是否在同一网段
kubectl get pods -o wide
# 2. 检查CNI是否正常运行
kubectl get pods -n kube-system | grep -E 'calico|flannel|cilium'
# 3. 从Pod内部ping另一个Pod
kubectl exec -it pod-a -- ping <pod-b-ip>
# 4. 检查节点间的网络连通性
# 在节点上ping其他节点的Pod网段
9.2 Service无法访问
# 1. 检查Service是否存在
kubectl get svc <service-name>
# 2. 检查Endpoints是否有值
kubectl get endpoints <service-name>
# 3. 检查Pod标签是否匹配
kubectl get pods --show-labels
# 4. 从集群内访问Service
kubectl run test -it --rm --image=busybox -- wget -qO- http://<service-name>:<port>
# 5. 检查kube-proxy
kubectl get pods -n kube-system | grep proxy
kubectl logs -n kube-system <kube-proxy-pod>
9.3 DNS解析失败
# 1. 检查CoreDNS是否运行
kubectl get pods -n kube-system | grep coredns
# 2. 查看CoreDNS日志
kubectl logs -n kube-system <coredns-pod>
# 3. 在Pod里测试DNS
kubectl exec -it pod-a -- nslookup kubernetes.default
# 4. 检查resolv.conf
kubectl exec -it pod-a -- cat /etc/resolv.conf
十、总结:一张图看懂K8s网络
┌────────────────────────────────────────────────────────────────────────┐
│ K8s网络全景 │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ 外部用户 │
│ │ │
│ ▼ │
│ ┌──────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ Ingress │───►│ Service │───►│ Pod │ │
│ │ Controller│ │ (ClusterIP) │ │ (业务) │ │
│ └──────────┘ └──────────────┘ └──────────┘ │
│ ▲ ▲ ▲ │
│ │ │ │ │
│ ┌──────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ nginx │ │ kube-proxy │ │ CNI │ │
│ │ (L7路由) │ │ (L4转发) │ │ (网络插件)│ │
│ └──────────┘ └──────────────┘ └──────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 集群内部网络 (Pod Network) │ │
│ │ 每个Pod有独立IP,跨节点互通 │ │
│ │ 通过VXLAN/路由等方式实现 │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ DNS服务 (CoreDNS) │ │
│ │ 服务名 → ClusterIP 自动解析 │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 网络策略 (NetworkPolicy) │ │
│ │ 控制Pod间的访问权限 │ │
│ └──────────────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────────┘
写在最后
Kubernetes的网络模型看起来复杂,但核心思想其实很简单:抽象。把底层复杂的网络细节(多节点、多网段、动态IP)全部屏蔽掉,给应用提供一套简单一致的API——Pod IP、Service IP、DNS名称。
理解了这三层(Pod网络 → Service → Ingress),再加上DNS和网络策略,你就掌握了K8s网络的精髓。
记住几个关键点:
- 每个Pod有唯一IP,跨节点互通
- Service提供稳定入口,kube-proxy负责转发
- DNS让服务名代替IP
- NetworkPolicy控制访问权限
- Ingress处理七层路由
希望这篇文章能帮你彻底搞懂Kubernetes网络!如果还有疑问,欢迎留言讨论。
