Kubernetes Ingress 资源对象

一、简介与核心作用

Ingress 是 K8S 暴露 HTTP/HTTPS 服务的标准方式,核心价值:七层负载均衡 + 域名/路径路由

对比项 ClusterIP NodePort Ingress
暴露范围 集群内部 节点端口 外部 HTTP/HTTPS
路由能力 域名+路径+Header
SSL 终止 手动 手动 自动
依赖组件 Ingress Controller

二、工作原理

plaintext

复制代码
请求流程: 用户 → DNS → Ingress Controller → Service → Pod
                    ↓
           解析 host/path 执行路由
           执行 TLS 终止
           生成 Nginx 配置

plaintext

复制代码
┌────────────────────────────────────────────────────────────────────────────┐
│  Ingress Controller 架构                                                    │
├────────────────────────────────────────────────────────────────────────────┤
│  K8s API Server: Ingress ← Service ← Endpoints ← Secret(TLS)             │
│                          ↓ List/Watch                                      │
│  Ingress Controller: Config Reloader → nginx.conf → Nginx Worker          │
└────────────────────────────────────────────────────────────────────────────┘

三、关键 YAML 配置

3.1 基础 Ingress(域名+路径路由)

yaml

复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-service-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /users
        pathType: Prefix
        backend:
          service:
            name: user-service
            port:
              number: 80
      - path: /orders
        pathType: Prefix
        backend:
          service:
            name: order-service
            port:
              number: 80
      - path: /
        pathType: Prefix
        backend:
          service:
            name: default-backend
            port:
              number: 80

3.2 TLS 配置

yaml

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

bash

复制代码
kubectl create secret tls example-tls --cert=server.crt --key=server.key

3.3 Ingress Controller(DaemonSet + hostNetwork)

yaml

复制代码
apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ingress-nginx
rules:
- apiGroups: [""]
  resources: ["configmaps", "endpoints", "pods", "secrets"]
  verbs: ["list", "watch"]
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get"]
- apiGroups: ["networking.k8s.io"]
  resources: ["ingresses", "ingressclasses"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["events"]
  verbs: ["create", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingress-nginx
subjects:
- kind: ServiceAccount
  name: ingress-nginx
  namespace: ingress-nginx
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: nginx
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"
spec:
  controller: k8s.io/ingress-nginx
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  selector:
    matchLabels:
      app: ingress-nginx
  template:
    metadata:
      labels:
        app: ingress-nginx
    spec:
      serviceAccountName: ingress-nginx
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      containers:
      - name: controller
        image: registry.k8s.io/ingress-nginx/controller:v1.9.4
        args:
        - /nginx-ingress-controller
        - --election-id=ingress-controller-leader
        - --controller-class=k8s.io/ingress-nginx
        - --ingress-class=nginx
        - --configmap=$(POD_NAMESPACE)/nginx-configuration
        securityContext:
          capabilities:
            drop: ["ALL"]
            add: ["NET_BIND_SERVICE"]
          runAsUser: 101
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: https
          containerPort: 443
          hostPort: 443
        livenessProbe:
          httpGet:
            path: /healthz
            port: 10254
          initialDelaySeconds: 10
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
data:
  proxy-body-size: "50m"
  proxy-read-timeout: "300"
  use-forwarded-headers: "true"

3.4 路径重写

yaml

复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rewrite-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: app.example.com
    http:
      paths:
      # /api/v1/users → 后端收到 /v1/users
      - path: /api(/|$)(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: api-service
            port:
              number: 80

3.5 金丝雀发布

yaml

复制代码
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
    nginx.ingress.kubernetes.io/canary-by-header-value: "always"

四、常用操作命令

bash

复制代码
kubectl get ingress -n default           # 查看 Ingress
kubectl get ing -A                       # 全命名空间
kubectl describe ingress <name>          # 查看详情

# 查看 Nginx 配置
kubectl exec -n ingress-nginx \
  $(kubectl get pods -n ingress-nginx -l app=ingress-nginx -o name) \
  -- cat /etc/nginx/conf.d/default.conf

kubectl logs -n ingress-nginx -l app=ingress-nginx -f   # 实时日志
curl -H "Host: api.example.com" http://<node-ip>/users  # 测试

# 检查 Endpoints
kubectl get endpoints -n default

# 重启加载配置
kubectl delete pod -n ingress-nginx -l app=ingress-nginx

五、常见问题与排查

5.1 404/502/503 错误

plaintext

复制代码
排查步骤:
1. kubectl describe ing <name>     # 检查规则
2. kubectl get svc && kubectl get endpoints  # 检查后端
3. kubectl get pods -o wide         # 检查 Pod 状态
4. 检查 pathType: Prefix/Exact vs 实际路径
5. 检查 rewrite-target 配置

常见原因:

bash

复制代码
# Service Selector 与 Pod Labels 不匹配
kubectl get svc api-service -o yaml | grep selector
kubectl get pods -l app=api --show-labels

# 路径末尾斜杠: /users ≠ /users/

5.2 TLS 证书问题

bash

复制代码
# 检查证书
kubectl get secret example-tls -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -no_text -enddate

# 常见错误:
# - secret 与 Ingress 不在同一 namespace
# - 类型应为 kubernetes.io/tls
# - 证书 CN/SAN 与 host 不匹配

5.3 路径匹配不生效

yaml

复制代码
# pathType:
# Prefix:  /users 匹配 /users, /users/, /users/123
# Exact:   /users 仅精确匹配 /users

# 正则匹配:
annotations:
  nginx.ingress.kubernetes.io/use-regex: "true"
# path: /api(/|$)(.*) + rewrite-target: /$2

六、最佳实践

  1. hostNetwork + DaemonSet:性能最优,高可用

  2. IngressClass 设为默认

    yaml

    复制代码
    annotations:
      ingressclass.kubernetes.io/is-default-class: "true"
  3. 路径重写 :统一用 use-regex + rewrite-target

  4. TLS 强制跳转

    yaml

    复制代码
    annotations:
      nginx.ingress.kubernetes.io/ssl-redirect: "true"
      nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
  5. 健康检查:Controller 和后端 Pod 必须配置

  6. ConfigMap 全局配置

    yaml

    复制代码
    data:
      proxy-body-size: "50m"
      proxy-read-timeout: "300"
  7. IP 白名单

    yaml

    复制代码
    nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8"
  8. cert-manager:自动管理证书续期

核心命令速查:

bash

复制代码
kubectl get ing -A                                  # 查看所有
kubectl describe ing <name>                         # 详情
kubectl logs -n ingress-nginx -l app=ingress-nginx -f  # 日志
相关推荐
Nice_Fold2 小时前
Kubernetes Ingress 七层负载均衡与Nginx实现
nginx·kubernetes·负载均衡
步步为营DotNet2 小时前
NET 11 中 C# 14 新特性在云原生微服务架构的深度实践
云原生·架构·c#
ん贤2 小时前
Kubernetes入门
云原生·容器·kubernetes
赵优秀一一2 小时前
Docker1: 安装、镜像和容器概念
运维·docker·容器
shizhan_cloud2 小时前
K8S部署LNMP架构 ECShop
kubernetes
milo.qu11 小时前
RockyLinux9.7 docker部署Jisti Meet
linux·docker·容器
梦想与想象-广州大智汇13 小时前
自建docker加速镜像,使用 Cloudflare Workers/Pages 部署加速教程
运维·docker·容器
AI攻城狮16 小时前
为什么主流大厂 LLM 必须亲自下场做 Harness CLI:从 DeepSeek TUI 说开去
云原生
阿里云云原生17 小时前
阿里云 AI 网关支持 DeepSeek V4
云原生