Kubernetes——基于域名访问与东西/南北流量管理

📅 2026/8/14 13:51:09
Kubernetes——基于域名访问与东西/南北流量管理
一、环境说明项目说明集群版本Kubernetes v1.24.17部署方式kubeadm 离线部署容器运行时containerd 1.6.21网络插件Calico镜像仓库672tq9h17eavbw.xuanyuan.runMaster 节点192.168.2.125k8s-master01Worker 节点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创建 Deploymentcat 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 Servicecat 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 Runningnginx-svc 分配了 ClusterIP如10.96.x.x。2.2 集群内部域名解析CoreDNSK8s 内置 CoreDNSService 创建后会自动注册 DNS 记录格式为service-name.namespace.svc.cluster.local启动测试 Pod 验证 DNS kubectl run test-dns --image672tq9h17eavbw.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 cant find nginx-svc.svc.cluster.local: NXDOMAIN ** server cant find nginx-svc.cluster.local: NXDOMAIN ** server cant find nginx-svc.cluster.local: NXDOMAIN ** server cant 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通过域名访问 Nginxkubectl 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将集群外部域名映射为集群内部 ServicePod 内可通过内部域名访问外部服务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-idingress-controller-leader - --controller-classk8s.io/ingress-nginx - --http-port80 - --https-port443 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 --forconditionready pod -n ingress-nginx -l appingress-nginx --timeout120s # 验证核心资源 kubectl get ingressclass nginx kubectl get pods -n ingress-nginx -o widehostNetwork: 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-controller3.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-ingress3.2.3 通过域名访问验证方法一修改本地 hosts 文件测试推荐在访问机器上添加 echo 192.168.2.125 nginx.example.com /etc/hosts 然后浏览器或 curl 访问 curl http://nginx.example.com方法二curl 指定 Host 头无需改 hostscurl -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.1253.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 --forconditionready pod -l apptest-client --timeout60s等待 Pod 就绪kubectl wait --forconditionready pod -l apptest-client --timeout60s4.2 通过 Service 域名访问推荐CLIENT_POD$(kubectl get pod -l apptest-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.local4.3 通过 Pod IP 直接访问不推荐NGINX_POD_IP$(kubectl get pod -l appnginx-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_TCPtcp://10.96.x.x:80 NGINX_SVC_SERVICE_HOST10.96.x.x NGINX_SVC_SERVICE_PORT80kubectl exec $CLIENT_POD -- sh -c curl -s http://$NGINX_SVC_SERVICE_HOST:$NGINX_SVC_SERVICE_PORT4.5 东西流量完整路径┌────────────────┐ ┌─────────────────┐ ┌────────────────────┐ ┌─────────────┐ │ test-client Pod│───▶│ kube-proxy │───▶│ nginx-svc │───▶│ nginx Pods │ │ │ │ (iptables/IPVS) │ │ ClusterIP: 10.96.x │ │ (3 replicas)│ └────────────────┘ └─────────────────┘ └────────────────────┘ └─────────────┘Calico 负责跨节点 Pod 网络的底层路由BGPkube-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.yaml5.2 创建综合 Ingresscat 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.yaml5.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 appfrontend -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-appkube-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.conf6.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.log6.3 Service 与端点验证# Service 详情 kubectl describe svc nginx-svc # Endpoints后端 Pod IP 列表 kubectl get endpoints nginx-svc kubectl describe endpoints nginx-svc6.4 常见故障排查问题排查命令可能原因域名解析失败kubectl exec test-dns -- nslookup nginx-svcCoreDNS 未运行 / 网络策略拦截Ingress 404kubectl describe ingress域名不匹配 / Service 名称错误Ingress 502kubectl logs ingress-controller后端 Pod 未就绪 / 端口错误Pod 间不通kubectl exec podA -- ping podBCalico 异常 / CIDR 冲突NodePort 不通curl NodeIP:NodePortkube-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 域名访问三要素要素说明CoreDNSK8s 内置 DNS 服务自动为 Service 注册域名记录Service域名背后对应的虚拟 IP 负载均衡Ingress集群外部域名入口支持七层路由域名/路径8.2 南北 vs 东西流量对比维度南北流量North-South东西流量East-West方向外部 Client ↔ 集群内部集群内部 Pod ↔ Pod入口Ingress / NodePort / LoadBalancerServiceClusterIPDNS外部 DNS → Ingress ControllerCoreDNS → ClusterIP负载均衡Ingress Controllerkube-proxyiptables/IPVS网络层Calico BGP iptables NATCalico 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 的跨集群边界流量步骤操作命令作用说明验证命令预期结果1kubectl apply -f frontend-deploy.yaml部署前端应用2副本 前端Service作为南北流量入口kubectl get pods -l appfrontendkubectl get svc frontend-svc2个frontend Pod状态为Runningfrontend-svc存在且Endpoints有2个Pod IP2kubectl apply -f full-ingress.yaml配置Ingress路由规则/路由到frontend-svc/api路由到backend-svckubectl get ingress full-ingressIngress规则正常无报错3echo 192.168.2.125 www.example.com /etc/hosts配置本地DNS解析让外部能定位到Ingress节点ping www.example.com解析到192.168.2.1254curl http://www.example.com验证南北流量全链路页面返回内容返回前端页面包含南北流量 (North-South)标识5浏览器访问http://www.example.com可视化验证南北流量页面正常加载同步骤4适合直观验证9.2 东西流量East-West操作步骤定义集群内 Pod → Service → Pod 的集群内部流量步骤操作命令作用说明验证命令预期结果1可选给backend配置标识页面让后端返回带东西流量标识的页面方便区分流量来源kubectl get pods -l appbackend2个backend Pod状态为Running2部署观测Podcurl测试容器作为流量发起方持续观测集群内东西流量kubectl get pods -l apptraffic-observer观测Pod状态为Running3kubectl exec deployment/traffic-observer -- curl http://backend-svc/api验证集群内Pod→Service的基础东西链路返回内容返回后端页面包含东西流量 (East-West)标识4curl http://www.example.com/api验证业务级东西流量前端Pod通过Service访问后端返回内容同步骤3确认前端能调用后端接口5kubectl logs -n ingress-nginx -l appingress-nginx --tail5验证东西流量的访问日志通过Ingress触发时日志内容出现GET /api HTTP/1.1 200记录9.3 核心概念速记表概念对应资源作用备注南北入口Ingress暴露集群内服务到外部需匹配ingressClassName: nginx东西转发核心Service集群内Pod的服务发现和负载均衡南北/东西流量都依赖Service南北流量标识前端页面自定义内容直观区分流量类型无需额外组件东西流量观测traffic-observer Pod持续验证集群内流量用完可删除一句话总结Ingress 管南北外部进来的流量Service 管东西内部 Pod 间流量CoreDNS 让所有流量都能用域名代替 IPCalico 保证所有流量真正通得了路。