知易通
第二套高阶模板 · 更大气的阅读体验

Kubernetes网络架构怎么用?从Pod通信到Service暴露全说清

发布时间:2026-01-23 11:50:30 阅读:171 次

公司新上线的微服务系统跑在ref="/tag/2020/" style="color:#874873;font-weight:bold;">Kubernetes上,结果前端调用订单服务老是超时——查日志发现不是代码问题,是Pod之间根本连不通。这事儿在运维群里炸了锅,最后发现是CNI插件配置漏了一行,集群里跨节点的Pod压根没走对路由。

Pod之间怎么说话?别想得太复杂

K8s里每个Pod都有独立IP,同一节点上的Pod走cni0网桥直通;跨节点时,靠CNI插件(比如Calico、Flannel)在宿主机间建隧道或改路由表。比如Flannel用host-gw模式,就在每个Node上加一条静态路由:

ip route add 10.244.2.0/24 via 192.168.56.112 dev eth0
这条命令的意思是:发往2号Node上所有Pod的流量,下一跳指向它的物理IP。没有它,包就卡在本地出不去。

Service不是“服务”,是负载均衡入口

写个Deployment起了3个Nginx Pod,直接curl它们的Pod IP能通,但换一个Pod就失效——因为Pod IP会变。这时候Service就派上用场了:

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
集群内任何地方访问nginx-svc:80,请求就会被kube-proxy自动转到后端某个Pod。它背后要么是iptables规则链,要么是IPVS哈希表,你不用管,但得知道:Service ClusterIP只在集群内部生效,对外暴露得靠NodePort或Ingress。

Ingress不是万能钥匙,得配对用

有次把Ingress资源对象写了,域名也绑了,但浏览器还是打不开。后来发现Ingress Controller根本没装——Ingress只是个YAML定义,真正干活的是Nginx Ingress Controller或者Traefik这些Pod。就像写了份快递单,没快递员接单,货永远发不出去。装好之后,再加一条规则:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
spec:
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-svc
            port:
              number: 80
这时访问app.example.com,流量才真正落地到你的web-svc。

网络策略(NetworkPolicy)不是摆设

测试环境没开NetworkPolicy,数据库Pod被前端Pod直接telnet通了,上线前安全团队立刻叫停。加了策略后:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: db-policy
spec:
  podSelector:
    matchLabels:
      app: mysql
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: api-server
    ports:
    - protocol: TCP
      port: 3306
现在只有带app: api-server标签的Pod才能连3306端口,其他一概拒绝。这不是锦上添花,是上线前必须过的关。

实际跑起来才发现,K8s网络没那么玄乎——它就是一堆可配置的路由、NAT和策略组合。关键不在记住名词,而在每次连不上时,先看Pod有没有IP、再查Service endpoints有没有列表、接着确认kube-proxy是否正常、最后翻NetworkPolicy有没有拦路。一步步摸过去,比背概念管用得多。