Kubernetes——基于域名访问与东西/南北流量管理
一、环境说明
|
项目 |
说明 |
|
集群版本 |
Kubernetes v1.24.17 |
|
部署方式 |
kubeadm 离线部署 |
|
容器运行时 |
containerd 1.6.21 |
|
网络插件 |
Calico |
|
镜像仓库 |
|
|
Master 节点 |
192.168.2.125(k8s-master01) |
|
Worker 节点 |
192.168.2.126 / 192.168.30.127 |
⚠️ 所有镜像必须提前导入 containerd 的 k8s.io 命名空间:ctr -n k8s.io images import xxx.tar
二、基于域名访问 K8s 应用
2.1 部署 Nginx 应用(Deployment + Service)
创建 Deployment:
cat > nginx-new-deploy.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-new-deploy
labels:
app: nginx-new
spec:
replicas: 3
selector:
matchLabels:
app: nginx-new
template:
metadata:
labels:
app: nginx-new
spec:
containers:
- name: nginx
image: 672tq9h17eavbw.xuanyuan.run/library/nginx:1.26.0-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
EOF
# 构建
kubectl apply -f nginx-new-deploy.yaml
# 查看
kubectl get pods
kubectl get deploy


创建 ClusterIP Service:
cat > nginx-svc.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx-new
spec:
selector:
app: nginx-new
ports:
- port: 80
targetPort: 80
type: ClusterIP
EOF
# 构建
kubectl apply -f nginx-svc.yaml

验证部署:
kubectl get pods -o wide
kubectl get svc nginx-svc

预期输出:3 个 Pod Running,nginx-svc 分配了 ClusterIP(如 10.96.x.x)。
2.2 集群内部域名解析(CoreDNS)
K8s 内置 CoreDNS,Service 创建后会自动注册 DNS 记录,格式为:
<service-name>.<namespace>.svc.cluster.local
启动测试 Pod 验证 DNS:
kubectl run test-dns --image=672tq9h17eavbw.xuanyuan.run/library/busybox:1.35 -- sleep 3600
解析 Service 短域名:
kubectl exec test-dns -- nslookup nginx-svc
输出示例:
Server: 10.96.0.10
Address: 10.96.0.10:53
Name: nginx-svc.default.svc.cluster.local
Address: 10.104.178.59
** server can't find nginx-svc.svc.cluster.local: NXDOMAIN
** server can't find nginx-svc.cluster.local: NXDOMAIN
** server can't find nginx-svc.cluster.local: NXDOMAIN
** server can't find nginx-svc.svc.cluster.local: NXDOMAIN
command terminated with exit code 1
![]()

解析 Service 完整域名:
kubectl exec test-dns -- nslookup nginx-svc.default.svc.cluster.local

输出示例:
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-svc
Address 1: 10.96.x.x nginx-svc.default.svc.cluster.local
通过域名访问 Nginx:
kubectl exec test-dns -- wget -q -O- http://nginx-svc
kubectl exec test-dns -- wget -q -O- http://nginx-svc.default.svc.cluster.local

✅ 至此,集群内部已可通过域名访问应用。
2.3 外部域名映射(ExternalName Service)
将集群外部域名映射为集群内部 Service,Pod 内可通过内部域名访问外部服务:
cat > external-svc.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
name: external-nginx
spec:
type: ExternalName
externalName: nginx.example.com
EOF
kubectl apply -f external-svc.yaml

验证解析:
kubectl exec test-dns -- nslookup external-nginx.default.svc.cluster.local

输出中会看到 CNAME 指向 nginx.example.com。
三、南北流量演示(外部 → 集群内部)
南北流量指 外部客户端访问集群内服务 的流量方向。
3.1 方式一:NodePort 直接暴露
cat > nginx-nodeport-svc.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
name: nginx-31318-svc
spec:
selector:
app: nginx-new
ports:
- port: 80
targetPort: 80
nodePort: 31818
type: NodePort
EOF
kubectl apply -f nginx-nodeport-svc.yaml

验证访问:
# 通过任意节点 IP + NodePort 访问
curl http://192.168.2.125:31818
curl http://192.168.2.126:31818
curl http://192.168.2.127:31818



流量路径:
Client → NodeIP:31818 → kube-proxy(iptables/IPVS) → Pod:80
⚠️ NodePort 方式简单直接,但端口范围受限(30000-32767),且缺乏域名和路径路由能力。
3.2 方式二:Ingress + 域名(推荐)
Ingress 是 K8s 南北流量的 标准入口,支持基于域名、路径的路由转发。
3.2.1 部署 NGINX Ingress Controller
# 拉取镜像到k8s.io命名空间
ctr -n k8s.io images pull registry.cn-hangzhou.aliyuncs.com/acs/aliyun-ingress-controller:v1.8.2-aliyun.1
# 验证镜像已存在
ctr -n k8s.io images list | grep aliyun-ingress
# 配置yaml文件
cat > ingress-all.yaml << 'EOF'
---
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ingress-nginx-controller
rules:
- apiGroups: [""]
resources: ["configmaps","endpoints","nodes","pods","secrets","services","namespaces","events"]
verbs: ["get","list","watch","create","update","patch"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses","ingressclasses"]
verbs: ["get","list","watch","update"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses/status"]
verbs: ["update"]
- apiGroups: ["discovery.k8s.io"]
resources: ["endpointslices"]
verbs: ["get","list","watch"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get","list","watch","create","update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ingress-nginx-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingress-nginx-controller
subjects:
- kind: ServiceAccount
name: ingress-nginx-controller
namespace: ingress-nginx
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
spec:
controller: k8s.io/ingress-nginx
---
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
selector:
app: ingress-nginx
ports:
- port: 80
targetPort: 80
name: http
- port: 443
targetPort: 443
name: https
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
labels:
app: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app: ingress-nginx
template:
metadata:
labels:
app: ingress-nginx
spec:
hostNetwork: true
serviceAccountName: ingress-nginx-controller
tolerations:
- operator: Exists
nodeSelector:
kubernetes.io/hostname: k8s-master01
containers:
- name: controller
image: registry.cn-hangzhou.aliyuncs.com/acs/aliyun-ingress-controller:v1.8.2-aliyun.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: http
- containerPort: 443
name: https
args:
- /nginx-ingress-controller
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
- --election-id=ingress-controller-leader
- --controller-class=k8s.io/ingress-nginx
- --http-port=80
- --https-port=443
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
livenessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
EOF
# 应用配置
kubectl apply -f ingress-all.yaml
# 等待 Pod 就绪
kubectl wait --for=condition=ready pod -n ingress-nginx -l app=ingress-nginx --timeout=120s
# 验证核心资源
kubectl get ingressclass nginx
kubectl get pods -n ingress-nginx -o wide




💡 hostNetwork: true 让 Ingress Controller 直接使用宿主机网络,外部可通过 NodeIP:80/443 访问,无需额外 NodePort 映射。
验证 Ingress Controller 就绪:
kubectl get pods -n ingress-nginx -o wide
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller
3.2.2 创建 Ingress 规则
cat > nginx-ingress.yaml << 'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
ingressClassName: nginx
rules:
- host: nginx.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
EOF
kubectl apply -f nginx-ingress.yaml
# 验证
kubectl get ingress nginx-ingress
kubectl describe ingress nginx-ingress

查看 Ingress 状态:
kubectl get ingress nginx-ingress
kubectl describe ingress nginx-ingress

3.2.3 通过域名访问验证
方法一:修改本地 hosts 文件(测试推荐)
在访问机器上添加:
echo "192.168.2.125 nginx.example.com" >> /etc/hosts
然后浏览器或 curl 访问:
curl http://nginx.example.com

方法二:curl 指定 Host 头(无需改 hosts)
curl -H "Host: nginx.example.com" http://192.168.2.125

方法三:多域名路由演示
cat > multi-host-ingress.yaml << 'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-host-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-31318-svc
port:
number: 80
EOF
kubectl apply -f multi-host-ingress.yaml
验证多域名:
curl -H "Host: web.example.com" http://192.168.2.125
curl -H "Host: api.example.com" http://192.168.2.125


3.2.4 南北流量完整路径
┌──────────┐ ┌──────────────┐ ┌──────────────────┐ ┌────────────┐ ┌─────────────┐
│ Client │────▶│ DNS 解析 │────▶│ Ingress Controller│────▶│ nginx-svc │────▶│ nginx Pods │
│ (浏览器) │ │ nginx.example│ │ (hostNetwork) │ │ ClusterIP │ │ (3 replicas)│
└──────────┘ │ .com → NodeIP│ └──────────────────┘ └────────────┘ └─────────────┘
└──────────────┘
四、东西流量演示(集群内部 Pod → Pod)
东西流量指 集群内部 Pod 之间互相访问 的流量方向。
4.1 部署测试客户端
cat > test-client.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-client
spec:
replicas: 1
selector:
matchLabels:
app: test-client
template:
metadata:
labels:
app: test-client
spec:
containers:
- name: client
# 阿里云 ACS 官方 curl 镜像(固定版本,可复现)
image: registry.cn-hangzhou.aliyuncs.com/acs/curl:8.1.2
command: ["sleep", "3600"]
imagePullPolicy: IfNotPresent
EOF
kubectl apply -f test-client.yaml
# 等待 Pod 就绪
kubectl wait --for=condition=ready pod -l app=test-client --timeout=60s

等待 Pod 就绪:
kubectl wait --for=condition=ready pod -l app=test-client --timeout=60s
4.2 通过 Service 域名访问(推荐)
CLIENT_POD=$(kubectl get pod -l app=test-client -o jsonpath='{.items[0].metadata.name}')
# 短域名
kubectl exec $CLIENT_POD -- curl -s nginx-svc
# 完整域名
kubectl exec $CLIENT_POD -- curl -s nginx-svc.default.svc.cluster.local


4.3 通过 Pod IP 直接访问(不推荐)
NGINX_POD_IP=$(kubectl get pod -l app=nginx-new -o jsonpath='{.items[0].status.podIP}')
echo "Nginx Pod IP: $NGINX_POD_IP"
kubectl exec $CLIENT_POD -- curl -s $NGINX_POD_IP

⚠️ Pod IP 是临时的,Pod 重建后会变化,生产环境应始终通过 Service 域名访问。
4.4 通过环境变量访问
K8s 会为每个 Service 自动注入环境变量到同命名空间的 Pod 中:
kubectl exec $CLIENT_POD -- env | grep NGINX_SVC
输出示例:
NGINX_SVC_PORT_80_TCP=tcp://10.96.x.x:80
NGINX_SVC_SERVICE_HOST=10.96.x.x
NGINX_SVC_SERVICE_PORT=80
kubectl exec $CLIENT_POD -- sh -c 'curl -s http://$NGINX_SVC_SERVICE_HOST:$NGINX_SVC_SERVICE_PORT'

4.5 东西流量完整路径
┌────────────────┐ ┌─────────────────┐ ┌────────────────────┐ ┌─────────────┐
│ test-client Pod│───▶│ kube-proxy │───▶│ nginx-svc │───▶│ nginx Pods │
│ │ │ (iptables/IPVS) │ │ ClusterIP: 10.96.x │ │ (3 replicas)│
└────────────────┘ └─────────────────┘ └────────────────────┘ └─────────────┘
Calico 负责跨节点 Pod 网络的底层路由(BGP),kube-proxy 负责 Service 的负载均衡转发。
五、综合演示:南北 + 东西流量同时观测
5.1 部署多层级应用
cat > frontend-deploy.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 2
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: 672tq9h17eavbw.xuanyuan.run/library/nginx:1.26.0-alpine
ports:
- containerPort: 80
EOF
cat > backend-deploy.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 2
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: 672tq9h17eavbw.xuanyuan.run/library/nginx:1.26.0-alpine
ports:
- containerPort: 80
EOF
cat > backend-svc.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
name: backend-svc
spec:
selector:
app: backend
ports:
- port: 80
targetPort: 80
EOF
kubectl apply -f frontend-deploy.yaml
kubectl apply -f backend-deploy.yaml
kubectl apply -f backend-svc.yaml




5.2 创建综合 Ingress
cat > full-ingress.yaml << 'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: full-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-svc
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: backend-svc
port:
number: 80
---
# frontend 也需要一个 Service
apiVersion: v1
kind: Service
metadata:
name: frontend-svc
spec:
selector:
app: frontend
ports:
- port: 80
targetPort: 80
EOF
kubectl apply -f full-ingress.yaml


5.3 流量全景图
南北流量(外部 → 集群)
┌──────────────────────────────────────────────────────────────────┐
│ │
│ Client ──▶ DNS ──▶ Ingress Controller ──┬──▶ frontend-svc ──▶ frontend Pods │
│ │ │
│ └──▶ backend-svc ──▶ backend Pods │
│ │
└──────────────────────────────────────────────────────────────────┘
东西流量(集群内部 Pod → Pod)
┌──────────────────────────────────────────────────────────────────┐
│ │
│ frontend Pod ──▶ backend-svc(ClusterIP) ──▶ backend Pod │
│ │ │
│ │ (通过域名 backend-svc.default.svc.cluster.local) │
│ ▼ │
│ kube-proxy(iptables/IPVS) 负载均衡到后端 Pod │
│ │
└──────────────────────────────────────────────────────────────────┘
5.4 验证综合访问
# 南北流量 - 访问前端
curl -H "Host: www.example.com" http://192.168.30.125/
# 南北流量 - 访问后端 API
curl -H "Host: www.example.com" http://192.168.30.125/api
# 东西流量 - 从 frontend Pod 调用 backend Service
FRONTEND_POD=$(kubectl get pod -l app=frontend -o jsonpath='{.items[0].metadata.name}')
kubectl exec $FRONTEND_POD -- wget -q -O- http://backend-svc



六、验证与排障命令速查
6.1 域名解析验证
# CoreDNS Pod 状态
kubectl get pods -n kube-system -l k8s-app=kube-dns
# DNS 解析测试
kubectl exec test-dns -- nslookup nginx-svc
kubectl exec test-dns -- nslookup nginx-svc.default.svc.cluster.local
kubectl exec test-dns -- cat /etc/resolv.conf


6.2 Ingress 验证
# Ingress 状态
kubectl get ingress -A
kubectl describe ingress nginx-ingress
# Ingress Controller 日志
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller -f
# 访问日志
kubectl exec -n ingress-nginx deployment/ingress-nginx-controller -- tail -f /var/log/nginx/access.log


6.3 Service 与端点验证
# Service 详情
kubectl describe svc nginx-svc
# Endpoints(后端 Pod IP 列表)
kubectl get endpoints nginx-svc
kubectl describe endpoints nginx-svc

6.4 常见故障排查
|
问题 |
排查命令 |
可能原因 |
|
域名解析失败 |
|
CoreDNS 未运行 / 网络策略拦截 |
|
Ingress 404 |
|
域名不匹配 / Service 名称错误 |
|
Ingress 502 |
|
后端 Pod 未就绪 / 端口错误 |
|
Pod 间不通 |
|
Calico 异常 / CIDR 冲突 |
|
NodePort 不通 |
|
kube-proxy 异常 / 防火墙未关 |
七、资源清理
# 删除所有测试资源
kubectl delete -f full-ingress.yaml
kubectl delete -f frontend-deploy.yaml
kubectl delete -f backend-deploy.yaml
kubectl delete -f backend-svc.yaml
kubectl delete -f test-client.yaml
kubectl delete -f nginx-ingress.yaml
kubectl delete -f multi-host-ingress.yaml
kubectl delete -f ingress-controller.yaml
kubectl delete -f nginx-nodeport-svc.yaml
kubectl delete -f nginx-svc.yaml
kubectl delete -f nginx-new-deploy.yaml
kubectl delete -f external-svc.yaml
kubectl delete pod test-dns
八、关键知识点总结
8.1 域名访问三要素
|
要素 |
说明 |
|
CoreDNS |
K8s 内置 DNS 服务,自动为 Service 注册域名记录 |
|
Service |
域名背后对应的虚拟 IP + 负载均衡 |
|
Ingress |
集群外部域名入口,支持七层路由(域名/路径) |
8.2 南北 vs 东西流量对比
|
维度 |
南北流量(North-South) |
东西流量(East-West) |
|
方向 |
外部 Client ↔ 集群内部 |
集群内部 Pod ↔ Pod |
|
入口 |
Ingress / NodePort / LoadBalancer |
Service(ClusterIP) |
|
DNS |
外部 DNS → Ingress Controller |
CoreDNS → ClusterIP |
|
负载均衡 |
Ingress Controller |
kube-proxy(iptables/IPVS) |
|
网络层 |
Calico BGP + iptables NAT |
Calico BGP 路由 |
|
典型场景 |
用户访问网站 |
微服务间 API 调用 |
8.3 核心架构图
┌─────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
┌────────┐ │ ┌──────────────────────────────────┐ │
│ Client │───────┼─▶│ Ingress Controller (hostNetwork) │ │
└────────┘ │ └────────┬─────────────────────────┘ │
│ │ 南北流量(七层路由) │
│ ▼ │
│ ┌─────────────┐ ┌──────────────┐ │
│ │ Service │───▶│ Pod Replicas │ │
│ │ ClusterIP │ │ (Nginx etc.) │ │
│ └──────┬──────┘ └──────────────┘ │
│ │ │
│ │ 东西流量(服务间调用) │
│ ▼ │
│ ┌─────────────┐ ┌──────────────┐ │
│ │ Other Pod │───▶│ Other Service│ │
│ │ (caller) │ │ (callee) │ │
│ └─────────────┘ └──────────────┘ │
│ │
│ CoreDNS ── 域名解析服务 │
│ Calico ── Pod 网络 + BGP 路由 │
│ kube-proxy ── Service 负载均衡 │
└─────────────────────────────────────────┘
九、操作步骤
9.1 南北流量(North-South)操作步骤
定义:外部客户端 → Ingress → Service → Pod 的跨集群边界流量
|
步骤 |
操作命令 |
作用说明 |
验证命令 |
预期结果 |
|
1 |
|
部署前端应用(2副本)+ 前端Service,作为南北流量入口 |
|
2个frontend Pod状态为 frontend-svc存在且Endpoints有2个Pod IP |
|
2 |
|
配置Ingress路由规则: 路由到frontend-svc 路由到backend-svc |
|
Ingress规则正常,无报错 |
|
3 |
|
配置本地DNS解析,让外部能定位到Ingress节点 |
|
解析到192.168.2.125 |
|
4 |
|
验证南北流量全链路 |
页面返回内容 |
返回前端页面,包含 标识 |
|
5 |
浏览器访问 |
可视化验证南北流量 |
页面正常加载 |
同步骤4,适合直观验证 |
9.2 东西流量(East-West)操作步骤
定义:集群内 Pod → Service → Pod 的集群内部流量
|
步骤 |
操作命令 |
作用说明 |
验证命令 |
预期结果 |
|
1 |
(可选)给backend配置标识页面 |
让后端返回带东西流量标识的页面,方便区分流量来源 |
|
2个backend Pod状态为 |
|
2 |
部署观测Pod(curl测试容器) |
作为流量发起方,持续观测集群内东西流量 |
|
观测Pod状态为 |
|
3 |
|
验证集群内Pod→Service的基础东西链路 |
返回内容 |
返回后端页面,包含 标识 |
|
4 |
|
验证业务级东西流量:前端Pod通过Service访问后端 |
返回内容 |
同步骤3,确认前端能调用后端接口 |
|
5 |
|
验证东西流量的访问日志(通过Ingress触发时) |
日志内容 |
出现 记录 |
9.3 核心概念速记表
|
概念 |
对应资源 |
作用 |
备注 |
|
南北入口 |
Ingress |
暴露集群内服务到外部 |
需匹配 |
|
东西转发核心 |
Service |
集群内Pod的服务发现和负载均衡 |
南北/东西流量都依赖Service |
|
南北流量标识 |
前端页面自定义内容 |
直观区分流量类型 |
无需额外组件 |
|
东西流量观测 |
traffic-observer Pod |
持续验证集群内流量 |
用完可删除 |
一句话总结:Ingress 管南北(外部进来的流量),Service 管东西(内部 Pod 间流量),CoreDNS 让所有流量都能用域名代替 IP,Calico 保证所有流量真正通得了路。
更多推荐

所有评论(0)