运维实战

Kubernetes 网络全链路:Service、DNS、Ingress 与 NetworkPolicy

从 Pod 网络模型到 Service、EndpointSlice、集群 DNS、入口流量和 NetworkPolicy,逐层验证服务发现与访问控制。

TY
Tycho
技术博主
• 2026-09-17 • 19 分钟阅读 • 1 次浏览
Kubernetes 网络全链路:Service、DNS、Ingress 与 NetworkPolicy

实验基线:Kubernetes v1.37.0、kubectl v1.37.0。先在测试环境执行,记录变更前状态与回滚点;生产集群不得直接照抄节点地址、网段、存储类或资源额度。

从 EndpointSlice 开始理解 Service

Service 通过标签选择后端 Pod,控制器生成 EndpointSlice,数据面组件据此转发。Service 可用但访问失败时,要依次检查 selector、Pod Ready、EndpointSlice、端口映射和网络策略。

kubectl expose deployment web -n lab --port=80 --target-port=80
kubectl get service web -n lab -o wide
kubectl get endpointslice -n lab -l kubernetes.io/service-name=web
kubectl run curl -n lab --rm -it --restart=Never --image=curlimages/curl -- \
  curl -fsS http://web.lab.svc.cluster.local

DNS 排障顺序

kubectl exec -n lab <client-pod> -- cat /etc/resolv.conf
kubectl exec -n lab <client-pod> -- nslookup web.lab.svc.cluster.local
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=100

先验证完整域名,再验证短名称;跨命名空间应显式写 service.namespace。Ingress 资源只有安装对应控制器后才生效;新项目也可评估 Gateway API,但控制器实现仍是必要条件。

默认拒绝与 DNS 放行

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: {name: default-deny-egress, namespace: lab}
spec:
  podSelector: {}
  policyTypes: [Egress]

NetworkPolicy 只有在 CNI 支持策略时才有效。应用默认拒绝 egress 后,DNS 也会被阻断;必须根据集群 DNS 的命名空间、标签和 UDP/TCP 53 端口添加精确放行,再逐项允许业务目的地。

端口字段一次说清

字段含义
containerPort文档与命名用途,不会自动开放防火墙
Service port客户端访问 Service 的端口
targetPort转发到 Pod 的端口或命名端口
nodePortNodePort 类型在节点暴露的端口

逐层连通性验证

  1. 在 Pod 内访问 127.0.0.1:容器端口,确认进程监听。
  2. 从同命名空间测试 Pod IP。
  3. 检查 EndpointSlice 是否包含 Ready 地址。
  4. 访问 Service ClusterIP 和 DNS 名。
  5. 最后验证 Ingress/Gateway、负载均衡器和外部 DNS。
kubectl get pod -n lab -l app=web -o wide
kubectl get svc web -n lab -o yaml
kubectl get endpointslice -n lab -l kubernetes.io/service-name=web -o yaml
kubectl run netcheck -n lab --rm -it --restart=Never --image=curlimages/curl -- sh
# 容器内执行:curl -v http://web.lab.svc.cluster.local

NetworkPolicy 分阶段上线

先确认 CNI 支持策略,再记录现有流量。第一阶段只在测试命名空间启用 ingress 默认拒绝并添加明确允许;第二阶段处理 egress,先放行 DNS,再放行数据库和外部 API。每条策略同时做“应通”和“应拒绝”测试。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: {name: allow-web-from-gateway, namespace: lab}
spec:
  podSelector: {matchLabels: {app: web}}
  policyTypes: [Ingress]
  ingress:
  - from:
    - namespaceSelector: {matchLabels: {kubernetes.io/metadata.name: gateway}}
    ports:
    - {protocol: TCP, port: 80}

namespaceSelector 与 podSelector 在同一数组项中表示“同时满足”,分成两个数组项则表示“任一满足”,这是常见的放大授权错误。

DNS 故障判断

若 IP 可通但域名不通,检查 resolv.conf、CoreDNS、Service/EndpointSlice 与 egress 策略;若域名解析正常但连接拒绝,检查 targetPort、进程监听地址和 readiness。不要一看到超时就重启 CoreDNS。

Service 类型与入口边界

类型用途注意
ClusterIP集群内部服务默认选择
NodePort每节点暴露端口通常由更上层 LB 使用
LoadBalancer云/控制器创建外部入口依赖具体实现与费用
ExternalName返回外部 CNAME没有代理与健康检查

Ingress/Gateway 负责 HTTP/TCP 入口路由,但资源对象本身不转发流量;必须安装兼容控制器,并确认它已更新 status 和后端健康。

默认拒绝后放行 DNS

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: {name: allow-dns, namespace: lab}
spec:
  podSelector: {}
  policyTypes: [Egress]
  egress:
  - to:
    - namespaceSelector: {matchLabels: {kubernetes.io/metadata.name: kube-system}}
      podSelector: {matchLabels: {k8s-app: kube-dns}}
    ports:
    - {protocol: UDP, port: 53}
    - {protocol: TCP, port: 53}

不同发行版的 DNS Pod 标签可能不同,应用前先查询 kubectl get pod -n kube-system --show-labels。如果使用 NodeLocal DNSCache,放行目标可能是节点本地地址,必须按发行版文档调整。

抓取网络证据

kubectl get networkpolicy -n lab -o yaml
kubectl get endpointslice -n lab -o wide
kubectl exec -n lab netcheck -- nslookup web.lab.svc.cluster.local
kubectl exec -n lab netcheck -- curl -sv --connect-timeout 3 http://web:80

DNS 超时、TCP timeout、connection refused 和 HTTP 5xx 是不同层的问题,应保留原始错误而不是统称“网络不通”。

可复现记录模板

每次实验记录:集群版本、容器运行时、CNI/CSI 版本、命名空间、使用的 YAML Git 提交、开始与结束时间。命令输出至少保留对象状态、事件、关键日志和回滚结果。文中的占位符必须替换成自己的值,生产执行前应由第二人复核。

故障处理原则

  1. 先缩小影响面,不删除现场。
  2. 按对象状态—事件—日志—依赖顺序收集证据。
  3. 提出可证伪假设,一次只改变一个变量。
  4. 验证恢复后清理临时权限、调试 Pod、端口转发和测试数据。

完成检查

  • 命令退出码为 0,目标对象状态与预期一致。
  • 保存执行前后 YAML、事件与关键日志,确认没有把测试命名空间以外的对象改动。
  • 故障演练完成后执行清理或回滚,再进行下一章。

官方资料

TY

Tycho

热爱分享技术知识,帮助开发者成长。

评论 (0)

评论功能当前已关闭
暂无评论,快来抢沙发吧!