K8s 网络进阶实战:Ingress-Nginx、Calico 与 NetworkPolicy 实验 + 排坑记录

Kubernetes Ingress 与容器网络

实验环境:Kubernetes v1.30,containerd,Calico CNI,ingress‑nginx,MetalLB LoadBalancer

一、Ingress 七层代理

1.1 Ingress 简介

Ingress 为 Service 提供外部可访问的 HTTP/HTTPS URL、负载均衡、SSL 终止、基于域名虚拟主机等 7 层能力。

⚠️关键点:

  1. Ingress本身只是配置规则资源,不会自己工作 ,必须部署 Ingress Controller(控制器);
  2. Ingress 只处理 HTTP、HTTPS;TCP/UDP 四层暴露使用 NodePort / LoadBalancer 类型 Service。

ingress‑nginx 工作流程

  1. 部署 Ingress‑nginx Controller Pod(本质是一组 Nginx 代理)
  2. 创建 Ingress YAML(k8s 资源,等价写 Nginx 配置片段)
  3. Controller 监听 apiserver,拉取全部 Ingress 规则
  4. 将规则转换成真实 nginx.conf 配置写入 Pod 内部
  5. reload nginx,完成流量转发

Ingress 本质就是 K8s 集群内部的7 层 HTTP 反向代理。

1.2 ingress‑nginx 部署前提

  1. 集群有可用 LoadBalancer(本实验使用 MetalLB 提供外部 IP)
  2. 必须部署 ingress‑nginx 控制器,Ingress 资源才会生效

1.3 部署 ingress‑nginx‑controller

复制代码
wget https://laoma.cloud/class/course-materials/softwares/stage03/ingress-nginx-controller-v1.11.2.tar.gz
tar -xf ingress-nginx-controller-v1.11.2.tar.gz

# 查看原始镜像
grep image: ingress-nginx-controller-v1.11.2/deploy/static/provider/cloud/deploy.yaml|uniq

# 替换镜像为私有harbor
sed -ir 's#@sha256.*##;s/registry.k8s.io/hub.laoma.cloud/' ingress-nginx-controller-v1.11.2/deploy/static/provider/cloud/deploy.yaml

# 部署
kubectl apply -f ingress-nginx-controller-v1.11.2/deploy/static/provider/cloud/deploy.yaml

# 查看资源
kubectl get all -n ingress-nginx

输出示例:

复制代码
NAME                                           READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-xhvp9       0/1     Completed   0          8m14s
pod/ingress-nginx-admission-patch-j47tm        0/1     Completed   2          8m14s
pod/ingress-nginx-controller-596db54d7-cgbdd   1/1     Running     0          8m14s

NAME                                         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             LoadBalancer   10.107.255.83   10.1.8.40     80:30973/TCP,443:32344/TCP   14s
service/ingress-nginx-controller-admission   ClusterIP      10.106.37.158   <none>        443/TCP                      8m15s

EXTERNAL‑IP 即为 Ingress 对外访问 IP,后续域名解析指向这个 IP。

1.4 Ingress 规则实践

前置环境准备

复制代码
kubectl create ns ingress
kubectl config set-context --current --namespace ingress

# 部署两套httpd测试业务
# webapp01
kubectl create deployment webapp01 --image=hub.laoma.cloud/library/httpd --replicas=2
kubectl exec -it $(kubectl get pods -l app=webapp01 -o name|head -n1) -- bash -c "echo hello webapp01 pod1 > htdocs/index.html"
kubectl exec -it $(kubectl get pods -l app=webapp01 -o name|tail -n1) -- bash -c "echo hello webapp01 pod2 > htdocs/index.html"
kubectl expose deployment webapp01 --port=80 --target-port=80

# webapp02
kubectl create deployment webapp02 --image=hub.laoma.cloud/library/httpd --replicas=2
kubectl exec -it $(kubectl get pods -l app=webapp02 -o name|head -n1) -- bash -c "echo hello webapp02 pod1 > htdocs/index.html;mkdir -p htdocs/games;echo hello webapp02 game1 > htdocs/games/index.html"
kubectl exec -it $(kubectl get pods -l app=webapp02 -o name|tail -n1) -- bash -c "echo hello webapp02 pod2 > htdocs/index.html;mkdir -p htdocs/games;echo hello webapp02 game2 > htdocs/games/index.html"
kubectl expose deployment webapp02 --port=80 --target-port=80
示例 1:多域名虚拟主机(多 host)

同一个 Ingress,不同域名转发到不同 Service

复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-host-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: webapp01.laoma.cloud
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: webapp01
            port:
              number: 80
  - host: webapp02.laoma.cloud
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: webapp02
            port:
              number: 80
kubectl apply -f multi-host-ingress.yaml
kubectl describe ingress multi-host-ingress

本地 hosts 增加解析:

复制代码
10.1.8.40 webapp01.laoma.cloud
10.1.8.40 webapp02.laoma.cloud

测试:

复制代码
curl webapp01.laoma.cloud
curl webapp02.laoma.cloud
示例 2:同一域名多 path 路径路由

同一个域名,不同 URL 路径转发不同后端服务

复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-path-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: www.laoma.cloud
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: webapp01
            port:
              number: 80
      - path: /games
        pathType: Prefix
        backend:
          service:
            name: webapp02
            port:
              number: 80
kubectl apply -f multi-path-ingress.yaml
curl www.laoma.cloud
curl www.laoma.cloud/games/

pathType 三种类型

  1. Prefix:前缀匹配;
  2. Exact:严格完整路径匹配;
  3. ImplementationSpecific:交由 ingress 控制器自行实现,正则重写场景使用。
示例 3:路径重写裁剪(rewrite‑target)

访问 /webapp01/xxx,转发后端去掉 /webapp01,直接访问 /xxx,等价 nginx proxy_pass /

复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-trimming-ingress
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  ingressClassName: nginx
  rules:
  - host: www.laoma.cloud
    http:
      paths:
      - path: /webapp01/(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: webapp01
            port:
              number: 80
      - path: /webapp02/(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: webapp02
            port:
              number: 80
kubectl apply -f path-trimming-ingress.yaml
curl www.laoma.cloud/webapp01/
curl www.laoma.cloud/webapp02/
示例 4:TLS HTTPS + 80 强制跳转 443

生成自签名证书,存入 k8s secret:

复制代码
openssl genrsa -out www.key 2048
openssl req -new -key www.key -out www.csr -subj "/C=CN/ST=JS/L=NJ/O=LM/OU=DEVOPS/CN=www.laoma.cloud/emailAddress=webadmin@laoma.cloud"
openssl x509 -req -days 3650 -in www.csr -signkey www.key -out www.crt

kubectl create secret tls www-tls --cert=./www.crt --key=./www.key

Ingress TLS 配置:

复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
      - www.laoma.cloud
    secretName: www-tls
  rules:
  - host: www.laoma.cloud
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: webapp01
            port:
              number: 80

测试:

复制代码
curl -Lk http://www.laoma.cloud
curl -k https://www.laoma.cloud

1.5 ingress‑nginx 常用注解速查表

注解 功能说明
nginx.ingress.kubernetes.io/force-ssl-redirect: "true" HTTP 80 强制跳转 HTTPS 443
nginx.ingress.kubernetes.io/rewrite-target: /$1 URL 路径重写,裁剪前缀
nginx.ingress.kubernetes.io/whitelist-source-range: "10.1.8.0/24" IP 访问白名单
nginx.ingress.kubernetes.io/limit-rps: "20" 单 IP 每秒请求数限流,防刷
nginx.ingress.kubernetes.io/enable-cors: "true" 开启跨域,前后端分离项目
nginx.ingress.kubernetes.io/proxy-read-timeout: "60" 代理后端接口超时时间
nginx.ingress.kubernetes.io/x-forwarded-for: "true" 向后端透传真实客户端 IP
nginx.ingress.kubernetes.io/canary: "true" canary‑weight: "10" 金丝雀灰度,按百分比切流量

清理 ingress 实验环境

复制代码
kubectl delete ns ingress

二、Kubernetes 容器网络体系

2.1 Underlay 与 Overlay 概念

  • Underlay:底层物理网络直连,无报文封装,性能高;节点之间直接路由 Pod 网段
  • Overlay:隧道封装,原始数据包外层再套一层宿主机 IP 头;对底层网络无要求,有少量性能开销

2.2 主流 CNI 方案对比

CNI 方案 网络模式 是否隧道 支持 NetworkPolicy 适用场景
Flannel host‑gw(Underlay)/VXLAN(Overlay) VXLAN 封装;host‑gw 无封装 ❌不支持网络策略 追求简单,不需要 Pod 防火墙
Calico BGP(Underlay) / IPIP/VXLAN(Overlay) IPIP/VXLAN 封装;BGP 无封装 ✅原生支持 企业最常用,需要 Pod 网络隔离策略
WeaveNet UDP 隧道 Overlay UDP 封装 ✅支持 小规模测试环境
Macvlan Underlay 二层直连物理网卡 ❌无封装 依赖配套插件 Pod 需要拿到局域网独立 IP,追求极低延迟

Calico 两大隧道模式对比 | 项目 | IPIP 隧道 | VXLAN 隧道 | |---|---|---| | 协议 | IP 协议号 4|UDP 4789 端口 | | 虚拟网卡 | tunl0|vxlan.calico| | 是否带二层 MAC | 不带,纯三层 IP 包 | 完整二层帧,支持广播组播 | | 公有云兼容性 | 很多云厂商封禁协议 4,容易不通 | UDP 端口一般放行,公有云更稳 |
ipipMode /vxlanMode 三种取值:

  1. Always:全部跨节点流量都走隧道;
  2. Never:关闭隧道,BGP 发布 Pod 路由,Underlay 直连;
  3. CrossSubnet混合模式:同子网不走隧道,跨子网自动启用隧道。

查看当前 Calico IPPool 配置

复制代码
kubectl get ippool -o yaml |egrep 'ipip|vxlan'
# 宿主机看路由,dev tunl0代表IPIP隧道模式
ip route

修改 IPPool 隧道模式(生产建议业务低峰操作)

复制代码
kubectl get ippool default-ipv4-ippool -o yaml > ippool-backup.yaml
kubectl edit ippool default-ipv4-ippool

2.3 CNI 与 CNM 网络模型

  1. CNM(Docker libnetwork):Docker 原生网络模型,Sandbox (netns)、Endpoint (veth‑pair)、Network (bridge);绑定 dockerd 守护进程。
  2. CNI(Container Network Interface) :Google+CoreOS 制定,Kubernetes 标准网络接口;不依赖守护进程,插件可插拔,分为 CNI 插件(配置网络)、IPAM 插件(分配 PodIP)。

CNI 工作对象是Pod,CNM 工作对象是容器。

三、NetworkPolicy 网络策略(Pod 防火墙)

⚠️前提条件:CNI 插件必须支持 NetworkPolicy,本实验 Calico 支持;Flannel 原生不支持。

3.1 基础概念

  • 默认状态:集群所有 Pod 之间全部互通,没有任何隔离。
  • NetworkPolicy 作用对象:Pod,控制 Pod 的入站 Ingress、出站 Egress 流量。
  • NetworkPolicy 是白名单机制:一旦 Pod 被 NetworkPolicy 选中,没有被规则允许的流量全部拒绝。
  • policyTypes: [Ingress,Egress] 显式声明要管控的流量方向。

重要:访问连通需要两端同时放行: 源 Pod 的 Egress 出站策略允许出去,目标 Pod 的 Ingress 入站策略允许进来,连接才能建立。

3.2 四种选择器

  1. podSelector:选择同一个命名空间内的 Pod;
  2. namespaceSelector:选择其他整个命名空间;
  3. namespaceSelector + podSelector:组合,选中其他命名空间下指定标签 Pod;
  4. ipBlock:基于 IP 网段 CIDR 过滤,多用于集群外部 IP。

3.3 实验示例

准备实验环境

复制代码
kubectl create ns web
kubectl create ns laoma

# web命名空间
kubectl run web1 -n web --image=hub.laoma.cloud/library/nginx
kubectl run web2 -n web --image=hub.laoma.cloud/library/nginx
kubectl expose pod web1 -n web --port=80
kubectl expose pod web2 -n web --port=80

# laoma命名空间
kubectl run test -n laoma --image=hub.laoma.cloud/library/nginx
示例 1:仅同命名空间指定标签 Pod 可以访问 web1
复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: my-network-policy
  namespace: web
spec:
  podSelector:
    matchLabels:
      run: web1
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          run: test
    ports:
    - protocol: TCP
      port: 80
示例 2:允许本命名空间所有 Pod 访问目标 Pod
复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: my-network-policy
  namespace: web
spec:
  podSelector:
    matchLabels:
      run: web1
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {}
    ports:
    - protocol: TCP
      port: 80
示例 3:根据命名空间标签放行访问

给 namespace 打标签:

复制代码
kubectl label namespaces laoma project=myproject

网络策略:

复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: my-network-policy
  namespace: web
spec:
  podSelector:
    matchLabels:
      run: web1
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          project: myproject
    ports:
    - protocol: TCP
      port: 80
示例 4:基于 IP 网段 ipBlock 放行
复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: my-network-policy
  namespace: web
spec:
  podSelector:
    matchLabels:
      run: web1
  policyTypes:
  - Ingress
  ingress:
  - from:
    - ipBlock:
        cidr: 10.1.8.0/24
        except:
        - 10.1.8.128/26
    ports:
    - protocol: TCP
      port: 80
示例 5:默认拒绝全部入站流量(命名空间全局隔离)
复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: web
spec:
  podSelector: {}
  policyTypes:
  - Ingress
示例 6:默认拒绝全部入站 + 全部出站
复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: web
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

注意 NetworkPolicy 做不到的事情:

  1. 无法写显式拒绝规则,只有白名单允许;
  2. 不能针对整个集群所有 namespace 全局生效;
  3. Pod 内部localhost本地回环流量无法拦截。

网络策略环境清理

复制代码
kubectl delete ns web laoma

小结

  1. Ingress‑nginx 实现 k8s 集群 7 层 HTTP 反向代理,支持域名、路径、重写、HTTPS、限流、灰度;
  2. CNI 分为 Overlay 隧道封装与 Underlay 底层直连;Calico 支持 BGP/IPIP/VXLAN 多种模式,支持 NetworkPolicy;
  3. NetworkPolicy 为 Pod 提供防火墙,白名单模型,可以基于 Pod 标签、Namespace 标签、IP 网段做访问控制;
  4. 连通需要 Ingress 入站、Egress 出站两端同时放行。
相关推荐
倔强的石头1061 小时前
【Linux指南】进程通信系列(四):命名管道 FIFO —— 让陌生进程按名字见面
linux·服务器·网络
updayday8541 小时前
电脑换了硬盘、加了内存,资产台账却没更新 - Ping64 硬件资产管理
大数据·网络·数据库·安全·智能路由器
fengkai45452 小时前
7、Kubernetes的Ingress&Network&Scheduler
运维·kubernetes·k8s·ingress·network·scheduler
yyuuuzz13 小时前
跨境站点日志时区混乱的排查记录
运维·服务器·网络·云计算·aws·1024程序员节
GlobalInfo14 小时前
全球及中国风电叶片检测机器人行业研究报告(2026版):市场现状、行业前景与占有率分析
运维·网络·人工智能·机器人
运维行者_16 小时前
网络监控工具怎么选?从设备监控到智能运维的能力清单
运维·服务器·开发语言·网络·人工智能·支持向量机·php
2401_8685347816 小时前
陈冲2026年上海纽约大学全英文毕业演讲
服务器·网络
孔令飞17 小时前
知己知彼,百战不殆:AI SKILL 实现原理剖析
云原生·go·ai编程
姜鱼问生19 小时前
网页一片白?Docker 跑 Nginx 读不到文件,403 Forbidden 排查实录
nginx·docker·容器