HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • 概览

    • K8s 实战学习实验室
    • 服务访问清单
    • K8s-Lab 学习总纲、仓库评估与专家路线图
  • 课程正文

    • 环境验证与第一课:认识你的真实集群
    • 第二课:kubectl apply 之后,到底发生了什么
    • 第三课:调度器如何选节点,为什么 Pod 会 Pending
    • 第四课:Kubernetes 网络、协议分层、VXLAN/IPIP/WireGuard 原理与排障
    • 第五课:NetworkPolicy、零信任网络与流量边界
    • 第六课:身份、认证、授权、准入与 ServiceAccount / RBAC 原理
    • 第七课:ConfigMap 与 Secret 注入模型、更新机制与安全边界
    • 第八课:存储持久化、PV / PVC / StorageClass 与 NFS 原理
    • 第九课:StatefulSet、Headless Service、稳定身份与存储原理
    • 第十课:探针、滚动更新、优雅终止与 PDB 原理
    • 第十一课:requests / limits、QoS、OOM 与驱逐原理
    • 第十二课:HPA、自动扩缩容、指标链路与副本伸缩原理
    • 第十三课:Service、EndpointSlice、kube-proxy、CoreDNS 与服务发现原理
    • 第十四课:Ingress-nginx、反向代理、Host / Path、NodePort 与北南向流量原理
    • 第十五课:HTTPS、TLS、SNI、证书信任与 Ingress 终止原理
    • 第十六课:cert-manager、Ingress 自动签发、证书生命周期与 ACME 工作流原理
    • 第十七课:ACME、Let's Encrypt、HTTP-01 / DNS-01、Orders / Challenges 与生产限制原理
    • 第十八课:大模型全生态,从数据到训练到部署到治理原理
    • 第十九课:大模型数据集、清洗、标注、切分、版本管理与质量治理原理
    • 第二十课:大模型训练、SFT、LoRA、Checkpoint、Adapter 与模型产物原理
    • 第二十一课:大模型推理、量化、KV Cache、vLLM、吞吐/延迟与部署发布链路原理
  • 实验操作记录

    • 本次仓库审查操作记录与命令原理
    • 本轮操作记录:环境验证、集群基线盘点与故障样本采集
    • 本轮操作记录:kubectl apply 主链路实验
    • 本轮操作记录:调度实验与 Pending 排查
    • 本轮操作记录:Kubernetes 网络原理、协议对比与调试实验
    • 本轮操作记录:NetworkPolicy 与零信任网络实验
    • 本轮操作记录:身份、认证、授权、准入实验
    • 本轮操作记录:ConfigMap 与 Secret 注入、更新与安全边界实验
    • 本轮操作记录:存储持久化、PV / PVC / StorageClass 与 NFS 实验
    • 本轮操作记录:StatefulSet、Headless Service 与稳定身份实验
    • 本轮操作记录:探针、滚动更新、优雅终止与 PDB 实验
    • 本轮操作记录:资源模型、QoS、OOM 与 CPU 节流实验
    • 本轮操作记录:HPA 自动扩缩容实验
    • 本轮操作记录:Service、EndpointSlice、CoreDNS 与服务发现排障实验
    • 本轮操作记录:Ingress-nginx、NodePort 与北南向流量实验
    • 本轮操作记录:HTTPS、TLS、自签证书与 Ingress 实验
    • 本轮操作记录:cert-manager 安装、CA 签发与 Ingress 自动证书实验
    • 本轮操作记录:ACME staging、HTTP-01 失败样本与排障实验
    • 本轮操作记录:大模型全生态与基础原理科普文撰写
    • 本轮操作记录:大模型数据集样本与治理文档编写
    • 本轮操作记录:大模型训练与模型产物概念文撰写
    • 本轮操作记录:大模型推理与服务发布概念文撰写

Ingress 与 NetworkPolicy — 流量的入口和隔离

Ingress — 集群的"反向代理"

为什么需要 Ingress?

NodePort 的问题:

  • 每个 Service 一个端口(30000-32767),端口不好记
  • 没有基于域名/路径的路由
  • 没有 TLS 终结

Ingress 的解决方案:一个统一入口,通过域名和路径分发到不同 Service。

架构

外部请求 → NodePort 30080 → Ingress Controller (nginx)
                                  │
                                  ├── app.k8s-lab.local/     → nginx-svc
                                  ├── app.k8s-lab.local/web  → web-headless
                                  ├── grafana.k8s-lab.local  → grafana-svc
                                  └── harbor.k8s-lab.local   → harbor-svc

安装 nginx-ingress

helm install ingress-nginx ingress-nginx/ingress-nginx \
  --set controller.service.type=NodePort \
  --set controller.service.nodePorts.http=30080 \
  --set controller.service.nodePorts.https=30443 \
  --set controller.nodeSelector.workload=general   # 避开 VPN 节点

为什么用 NodePort 而不是 LoadBalancer? 裸金属环境没有云厂商的 LB 服务。如果需要,可以装 MetalLB 模拟。

Ingress 资源定义

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-ingress
  namespace: dev
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx    # 指定使用哪个 Ingress Controller
  rules:
  - host: app.k8s-lab.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-svc
            port:
              number: 80
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: web-headless
            port:
              number: 80

验证

$ curl -H "Host: app.k8s-lab.local" http://154.9.27.60:30080/
<!DOCTYPE html>...    ← nginx 欢迎页

Ingress Controller 的工作原理

nginx-ingress controller 本质上是一个监听 Ingress 资源变化的 nginx 进程:

  1. Watch API Server 中所有 Ingress 资源
  2. 根据 Ingress 规则生成 nginx.conf
  3. 热重载 nginx(nginx -s reload)
  4. 流量进入 nginx → 按 host/path 路由到后端 Service 的 Pod

面试题: "Ingress 和 Gateway API 的区别?"

  • Ingress 是 K8s 的第一代入口方案,功能有限(只支持 HTTP/HTTPS)
  • Gateway API 是下一代,支持 TCP/UDP/gRPC,更灵活的路由规则,跨 namespace 引用
  • Gateway API 正在逐步替代 Ingress,但 Ingress 目前仍是主流

NetworkPolicy — 集群内防火墙

默认行为:全通

K8s 默认所有 Pod 之间可以互相通信,包括跨 namespace。这在生产中是不可接受的。

我们的实验

步骤 1: dev 的 Pod → prod 的 Pod = 通(默认)
步骤 2: prod 加 default-deny → dev 的 Pod → prod = 不通
步骤 3: prod 加白名单(同 namespace)→ prod 内部互通,dev 仍不通

default-deny 策略

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: prod
spec:
  podSelector: {}      # 选择所有 Pod
  policyTypes:
  - Ingress            # 限制入站流量
  # 没有 ingress 规则 = 拒绝所有入站

关键理解: NetworkPolicy 是累加的。只要有任何一条 NetworkPolicy 选中了某个 Pod,该 Pod 就从"默认全通"变为"默认拒绝 + 只允许策略中定义的流量"。

白名单:只允许同 namespace

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-same-namespace
  namespace: prod
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {}    # 同 namespace 的所有 Pod

验证结果

dev web-0 → prod test-server:  不通 (exit 28, timeout)  ← 跨 NS 被阻断
prod test-client → prod test-server:  通 (<!DOCTYPE html>)  ← 同 NS 放行

零信任网络设计模式

生产环境推荐的模式:

1. 每个 namespace 加 default-deny-ingress + default-deny-egress
2. 按需开放:
   - frontend → backend (端口 8080)
   - backend → database (端口 5432)
   - backend → cache (端口 6379)
   - 所有 Pod → kube-dns (端口 53, UDP)
3. 禁止:
   - frontend → database (直接)
   - 任何 Pod → 外部互联网 (除了必要的 API)

Calico 的优势: 标准 K8s NetworkPolicy 只支持 L3/L4(IP + 端口),Calico 还支持:

  • 基于 Service Account 的策略
  • 全局 NetworkPolicy(跨 namespace)
  • DNS 策略(按域名过滤出站)
  • 应用层策略(L7,需要 Envoy sidecar)

→ 04-monitoring-observability.md