Goal: 编写一篇面向 CSDN 读者的 Kubernetes Ingress HTTPS 负载均衡生产级实战指南文章,包含完整配置示例、架构图和最佳实践。

Architecture: 基于 Nginx Ingress Controller 的 Kubernetes 入口流量管理方案,集成 cert-manager 实现自动化 TLS 证书管理,涵盖生产级配置、性能调优和监控告警。

Tech Stack: Kubernetes, Nginx Ingress Controller, cert-manager, Let’s Encrypt, Prometheus, Grafana


Task 1: 创建文章框架和元数据

  • **Step 1: 概览
# Kubernetes Ingress HTTPS 负载均衡生产级实战指南

👋 大家好,欢迎来到我的技术博客!可以点点关注、收藏,以后不迷路!
📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。
🎯 本文将围绕 Kubernetes Ingress 这个话题展开,希望能为你带来一些启发或实用的参考。
🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获!

---

## 文章目录

1. 为什么选择 K8s Ingress?
2. 架构原理深入剖析
3. 从零开始:环境准备
4. Nginx Ingress Controller 深度配置
5. HTTPS/TLS 生产级配置
6. 高级路由规则
7. 健康检查与故障转移
8. 会话保持策略
9. 性能调优与限流
10. 监控告警体系
11. 常见问题与踩坑经验
12. 性能对比与最佳实践

---

## 为什么选择 K8s Ingress?

在现代 Kubernetes 生产环境中,传统的 Nginx 配置面临着诸多挑战...
  • **Step 2: 添加传统 Nginx 痛点描述
### 传统 Nginx 配置的痛点

在生产环境中使用传统 Nginx 作为负载均衡器时,运维团队通常会遇到以下问题:

**🔴 证书管理复杂**
- 证书更新需要手动编辑配置文件
- 多域名、多环境配置重复
- 证书过期需要人工监控和更新
- 密钥管理安全性难以保证

**🔴 配置变更风险**
- 配置修改需要手动执行 `nginx -s reload`
- 配置错误可能导致服务中断
- 多服务器配置同步困难
- 缺乏版本控制和审计

**🔴 扩展性受限**
- 水平扩展需要手动配置负载均衡
- 后端健康检查需要额外脚本
- 故障转移不够智能
- 流量调度策略单一

**🔴 缺乏原生云原生集成**
- 无法自动感知 Pod 变化
- 需要手动维护后端服务器列表
- 与 Kubernetes 生态脱节
- 难以实现声明式配置管理
  • **Step 3: 添加 K8s Ingress 价值主张
### K8s Ingress 带来的价值

Kubernetes Ingress 作为云原生架构的入口标准,为生产环境带来了革命性的改进:

**🚀 云原生架构的入口标准**
- 声明式配置,一切皆代码
- 自动感知后端 Pod 变化
- 原生集成 Kubernetes 生态系统
- 支持多云、多集群管理

**🔒 集成 cert-manager 自动管理证书**
- 自动申请和续期 Let's Encrypt 证书
- 支持多种证书颁发机构
- 证书自动更新到 Ingress
- 密钥安全存储在 Secret 中

**🔄 配置即代码,自动热更新**
- GitOps 风格的配置管理
- Ingress 资源变更自动生效
- 配置回滚和版本控制
- 无需手动 reload 操作

**📊 原生集成 K8s 生态系统**
- 与 Service 自动集成
- 支持 Pod 水平扩展
- 原生健康检查和故障转移
- 统一的监控和日志体系

**📈 权威数据支撑**

根据 CNCF 2024 年度云原生调研报告显示:
- 92% 的企业在生产环境中使用 Ingress
- 78% 的组织使用 Nginx Ingress Controller
- 65% 的团队已部署 cert-manager 自动化管理证书

Task 2: 编写架构原理深入剖析

  • **Step 1: 创建架构对比图说明
## 架构原理深入剖析

要理解 Kubernetes Ingress 的强大之处,我们首先来对比传统架构和云原生架构的差异。
  • **Step 2: 创建传统 Nginx 架构图描述
 传统 Nginx 架构

在这里插入图片描述


**特点:**
- 静态配置,后端服务器列表需要手动维护
- 证书管理复杂,需要手动更新
- 配置变更需要 reload
- 健康检查需要额外脚本实现
  • **Step 3: 创建 K8s Ingress 架构图描述
### Kubernetes Ingress 架构

在这里插入图片描述


**特点:**
- 动态配置,自动感知 Pod 变化
- cert-manager 自动管理证书
- Ingress 资源变更自动生效
- K8s 原生健康检查和自动故障转移
  • **Step 4: 添加核心组件详解
### 核心组件解析

Kubernetes Ingress 生态系统包含以下关键组件:

#### 1. Ingress Controller
**职责**:监听 Ingress 资源变化,配置实际负载均衡器

**主流实现**:
- Nginx Ingress Controller(最常用,生产级)
- Traefik Ingress(原生云原生,配置简单)
- HAProxy Ingress(性能优秀)
- AWS ALB Ingress(针对 AWS 优化)

**Nginx Ingress Controller 特点**:
- 基于 Nginx,性能优秀
- 配置灵活,功能强大
- 社区活跃,生态完善
- 支持 HTTP/2、gRPC、WebSocket

#### 2. Ingress 资源
**职责**:定义 HTTP/HTTPS 路由规则

**核心字段**:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    # 控制器特定配置
spec:
  ingressClassName: nginx  # 指定使用的 Controller
  rules:
  - host: example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
3. Service 资源

职责:提供稳定的服务发现

类型

  • ClusterIP:集群内部访问
  • NodePort:通过节点端口访问
  • LoadBalancer:云厂商负载均衡器
4. ConfigMap/Secret

职责:存储配置和敏感信息

  • ConfigMap:存储配置(Nginx 配置片段)
  • Secret:存储 TLS 证书、密钥等敏感数据

- [ ] **Step 5: 添加流量转发原理

```markdown
### 流量转发原理

理解 Ingress 如何转发流量至关重要:

#### 完整请求流程

1. **客户端发起 HTTPS 请求**

Client → https://api.example.com/v1/users


2. **DNS 解析到 LoadBalancer IP**

api.example.com → 203.0.113.10


3. **LoadBalancer 转发到 Ingress Controller**

203.0.113.10:443 → Ingress Controller Pod


4. **Ingress Controller 匹配 Ingress 规则**

Host: api.example.com
Path: /v1/users
→ 匹配到 Ingress: api-ingress
→ 匹配到 Path: /api


5. **查找目标 Service**

Service: api-service
Port: 80
→ 查找 selector: app=api


6. **Service 转发到 Pod**

Pod: api-7d8f9a2c (通过负载均衡选择)
Port: 8080
→ /v1/users


7. **Pod 处理请求并返回**

Pod → Ingress Controller → Client


#### 关键点

- **SSL Termination**:在 Ingress Controller 层解密 HTTPS
- **Header 传递**:自动添加 X-Forwarded-* 头部
- **负载均衡**:Service 层实现 Pod 级负载均衡
- **自动发现**:Ingress Controller 自动感知 Service 变化

Task 3: 编写环境准备部分

  • **Step 1: 创建前置条件章节
## 从零开始:环境准备

在开始配置之前,我们需要准备必要的环境和资源。
  • **Step 2: 添加前置条件列表
### 前置条件

✅ **Kubernetes 集群**
- 版本要求:v1.20+(推荐 v1.26+)
- 集群状态:正常运行,节点 Ready
- 资源配额:至少 2 vCPU,4GB 内存

✅ **kubectl 配置**
```bash
# 验证集群连接
kubectl version --client
kubectl cluster-info
kubectl get nodes

域名准备

  • 拥有可用的域名(如:demo.example.com)
  • 可以配置 DNS 解析
  • 建议使用子域名方便测试

网络权限

  • 集群 Node 对外开放 80 和 443 端口
  • 如果使用 LoadBalancer,需要云厂商支持
  • 确保防火墙规则允许外部访问

- [ ] **Step 3: 添加示例后端服务部署

```markdown
### 快速部署示例后端服务

为了演示 Ingress 的配置,我们首先部署一个简单的 Nginx 服务作为后端。

#### 创建 Deployment

```yaml
# demo-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-app
  labels:
    app: demo
spec:
  replicas: 3  # 部署 3 个副本
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
        version: v1
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 3
          periodSeconds: 5
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 200m
            memory: 256Mi

部署命令:

kubectl apply -f demo-deployment.yaml
kubectl get pods -l app=demo -w

预期输出:

NAME                       READY   STATUS    RESTARTS   AGE
demo-app-7d8f9a2c-x5q2z   1/1     Running   0          10s
demo-app-7d8f9a2c-7k8m9   1/1     Running   0          10s
demo-app-7d8f9a2c-9j3n1   1/1     Running   0          10s

- [ ] **Step 4: 添加 Service 创建

```markdown
#### 创建 Service

```yaml
# demo-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-service
  labels:
    app: demo
spec:
  type: ClusterIP  # 集群内部访问
  selector:
    app: demo
  ports:
  - name: http
    port: 80        # Service 暴露端口
    targetPort: 80  # Pod 目标端口
    protocol: TCP
  sessionAffinity: None  # 无会话保持

部署命令:

kubectl apply -f demo-service.yaml
kubectl get svc demo-service
kubectl describe svc demo-service

验证服务:

# 获取 Service ClusterIP
SVC_IP=$(kubectl get svc demo-service -o jsonpath='{.spec.clusterIP}')
echo "Service IP: $SVC_IP"

# 从集群内测试访问
kubectl run test-pod --image=busybox --rm -it --restart=Never -- \
  wget -O- http://$SVC_IP

Task 4: 编写 Nginx Ingress Controller 配置

  • **Step 1: 创建安装方式对比
## Nginx Ingress Controller 深度配置

Nginx Ingress Controller 是 Kubernetes 生态中最流行的 Ingress 实现,生产级功能完善,性能优异。
  • **Step 2: 添加安装方式对比表格
### 安装方式对比

| 方式 | 优点 | 缺点 | 适用场景 |
|------|------|------|----------|
| **Helm** | 版本管理清晰,配置灵活,升级回滚方便 | 需要安装 Helm | 生产环境推荐 |
| **YAML manifests** | 简单直接,无需额外工具 | 配置分散,升级复杂 | 测试环境 |
| **Kustomize** | 支持配置覆盖,GitOps 友好 | 学习曲线较陡 | 管理多环境配置 |

**📌 推荐使用 Helm 进行生产环境部署**
  • **Step 3: 添加 Helm 仓库配置
### Helm 安装 Nginx Ingress Controller

#### 1. 添加 Helm 仓库

```bash
# 添加 Nginx Ingress Helm 仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

# 查看可用版本
helm search repo ingress-nginx --versions
2. 查看默认配置
# 查看默认配置 values
helm show values ingress-nginx/ingress-nginx > default-values.yaml
3. 生产级配置

创建 custom-values.yaml

# custom-values.yaml

# Controller 部署类型
controller:
  # 使用 DaemonSet 确保每个节点都运行(适合生产环境)
  kind: DaemonSet
  # 或者使用 Deployment(推荐用于资源受限环境)
  # kind: Deployment
  # replicas: 3

  # Service 配置
  service:
    enabled: true
    type: LoadBalancer  # 使用云厂商 LoadBalancer
    # type: NodePort    # 或使用 NodePort
    annotations:
      # AWS 注解示例
      # service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
      # service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
      
      # GCP 注解示例
      # cloud.google.com/load-balancer-type: "Internal"

  # 资源限制(生产环境必须设置)
  resources:
    requests:
      cpu: 200m
      memory: 256Mi
    limits:
      cpu: 1000m
      memory: 512Mi

  # Pod 反亲和性(分散到不同节点)
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app.kubernetes.io/name
            operator: In
            values:
            - ingress-nginx
          - key: app.kubernetes.io/component
            operator: In
            values:
            - controller
        topologyKey: "kubernetes.io/hostname"

  # 健康检查配置
  healthCheckPath: /healthz

  # 日志配置
  accessLog:
    enabled: true
    format: '$remote_addr - $remote_user [$time_local] "$request" '
              '$status $body_bytes_sent "$http_referer" '
              '"$http_user_agent" $http_x_forwarded_for '
              'upstream: $upstream_addr latency: $upstream_response_time'
  
  # 性能调优
  config:
    worker-processes: "auto"
    worker-connections: "65535"
    keep-alive: "75"
    keep-alive-requests: "100"
    
    # 缓冲区配置
    proxy-body-size: "50m"
    proxy-client-body-buffer-size: "128k"
    proxy-connect-timeout: "60"
    proxy-send-timeout: "60"
    proxy-read-timeout: "60"

# 默认后端(404 处理)
defaultBackend:
  enabled: true
  image:
    repository: registry.k8s.io/defaultbackend-amd64
    tag: "1.5"
  
# RBAC 配置
rbac:
  create: true
  
# 安全上下文
serviceAccount:
  create: true
  name: ""

- [ ] **Step 4: 添加安装命令

```markdown
#### 4. 安装命令

```bash
# 创建命名空间
kubectl create namespace ingress-nginx

# 安装 Ingress Controller
helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --values custom-values.yaml

# 验证安装
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx
kubectl get deployment -n ingress-nginx
5. 验证安装
# 检查 Pod 状态
kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx

# 检查 Service
kubectl get svc -n ingress-nginx

# 获取 LoadBalancer IP
LB_IP=$(kubectl get svc -n ingress-nginx ingress-nginx-controller \
  -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "LoadBalancer IP: $LB_IP"

# 检查 Controller 版本
kubectl exec -n ingress-nginx deploy/ingress-nginx-controller \
  --controller -- nginx -v

# 检查配置
kubectl exec -n ingress-nginx deploy/ingress-nginx-controller \
  --controller -- nginx -T 2>/dev/null | head -50

预期内配置片段:

user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  65535;
    multi_accept        on;
    use                epoll;
}

http {
    ...
    upstream upstream_balancer {
        least_conn;
        server 10.244.0.5:80 max_fails=0 fail_timeout=0;
        server 10.244.0.6:80 max_fails=0 fail_timeout=0;
        server 10.244.0.7:80 max_fails=0 fail_timeout=0;
    }
    ...
}

- [ ] **Step 5: 添加关键配置对比表

```markdown
### 关键配置项详解

下表对比了不同部署场景下的推荐配置:

| 配置项 | 开发环境 | 测试环境 | 生产环境 | 说明 |
|--------|----------|----------|----------|------|
| kind | Deployment | Deployment | DaemonSet | 生产环境推荐 DaemonSet |
| replicas | 1 | 2 | - | DaemonSet 不需要 |
| resources.requests.cpu | 100m | 200m | 500m | CPU 请求 |
| resources.requests.memory | 128Mi | 256Mi | 512Mi | 内存请求 |
| resources.limits.cpu | 500m | 1000m | 2000m | CPU 限制 |
| resources.limits.memory | 256Mi | 512Mi | 1Gi | 内存限制 |
| affinity | - | - | podAntiAffinity | 分散部署 |
| service.type | NodePort | LoadBalancer | LoadBalancer | 服务类型 |
| enable-metrics | false | true | true | 启用指标 |

**💡 配置建议**

1. **资源限制**:生产环境必须设置 request 和 limit
2. **节点亲和性**:使用 DaemonSet + antiAffinity 实现高可用
3. **日志配置**:启用访问日志,便于问题排查
4. **指标暴露**:启用 Prometheus metrics,便于监控
5. **安全加固**:禁用未使用的功能,减少攻击面


---

## Task 5: 编写 HTTPS/TLS 配置

- [ ] **Step 1: 创建 TLS 配置章节

```markdown
## HTTPS/TLS 生产级配置

在生产环境中,HTTPS 是标配,而证书管理是运维团队最头疼的问题之一。Kubernetes 生态中的 cert-manager 完美解决了这个痛点。
  • **Step 2: 添加 cert-manager 介绍
### cert-manager 简介

cert-manager 是 Kubernetes 原生的证书管理控制器,可以自动从 Let's Encrypt、HashiCorp Vault 等颁发机构申请和续期证书。

**核心特性:**
- 🔒 自动申请 TLS 证书
- 🔄 自动续期证书
- 📋 支持多种证书颁发机构(CA)
- 🔌 原生集成 Kubernetes Secret
- 🌐 支持 DNS-01 和 HTTP-01 验证

**支持证书颁发机构:**
| 颁发机构 | 免费性 | 验证方式 | 适用场景 |
|----------|--------|----------|----------|
| Let's Encrypt | ✅ 免费 | HTTP-01, DNS-01 | 公网域名 |
| ZeroSSL | ⚠️ 有限免费 | HTTP-01, DNS-01 | 公网域名 |
| HashiCorp Vault | ❌ 付费 | 内部签名 | 内网域名 |
| 自签名 CA | ✅ 免费 | 内部签名 | 测试环境 |
  • **Step 3: 添加 cert-manager 安装
### 安装 cert-manager

#### 1. 添加 Helm 仓库

```bash
# 添加 cert-manager Helm 仓库
helm repo add jetstack https://charts.jetstack.io
helm repo update

# 查看可用版本
helm search repo jetstack/cert-manager --versions
2. 安装 cert-manager
# 安装 cert-manager
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.13.1 \
  --set installCRDs=true

# 验证安装
kubectl get pods -n cert-manager
kubectl get crd | grep cert-manager

预期输出:

NAME                              READY   STATUS    RESTARTS   AGE
cert-manager-7d8f9a2c-x5q2z     1/1     Running   0          30s
cert-manager-cainjector-7d8f9a2c-7k8m9   1/1     Running   0          30s
cert-manager-webhook-7d8f9a2c-9j3n1        1/1     Running   0          30s

验证 CRD 安装:

kubectl get crd clusterissuers.cert-manager.io
kubectl get crd issuers.cert-manager.io
kubectl get crd certificates.cert-manager.io
kubectl get crd certificaterequests.cert-manager.io

- [ ] **Step 4: 添加 Let's Encrypt 配置

```markdown
### 配置 Let's Encrypt

Let's Encrypt 是最流行的免费 SSL/TLS 证书颁发机构,有效期 90 天,支持自动续期。

#### 前提条件

✅ **域名 DNS 解析**
```bash
# 验证域名解析
nslookup demo.example.com

防火墙规则

  • 确保集群 Node 开放 80 端口(HTTP-01 验证需要)
  • 确保域名解析到 LoadBalancer IP
ClusterIssuer 配置

ClusterIssuer 是集群级别的证书颁发机构配置,可以被所有命名空间使用。

# cluster-issuer-letsencrypt.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    # Let's Encrypt 生产环境服务器
    server: https://acme-v02.api.letsencrypt.org/directory
    
    # 邮箱地址(用于证书到期提醒)
    email: your-email@example.com
    
    # 私钥 Secret
    privateKeySecretRef:
      name: letsencrypt-prod
    
    # 求解器配置
    solvers:
    # HTTP-01 验证方式(适合公网域名)
    - http01:
        ingress:
          class: nginx  # 指定 Ingress Class
    
    # DNS-01 验证方式(适合内网或泛域名)
    # - dns01:
    #     cloudflare:
    #       email: cloudflare-email@example.com
    #       apiTokenSecretRef:
    #         name: cloudflare-api-token

部署命令:

kubectl apply -f cluster-issuer-letsencrypt.yaml

# 验证 ClusterIssuer
kubectl get clusterissuer
kubectl describe clusterissuer letsencrypt-prod

⚠️ 测试环境建议

在生产环境之前,建议先使用 Let’s Encrypt Staging 环境测试:

# cluster-issuer-staging.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: your-email@example.com
    privateKeySecretRef:
      name: letsencrypt-staging
    solvers:
    - http01:
        ingress:
          class: nginx

Staging 环境特点:

  • 证书未受信任(浏览器会警告)
  • 请求限制更宽松
  • 适合测试配置是否正确

- [ ] **Step 5: 添加 Ingress TLS 配置

```markdown
### Ingress TLS 配置

配置 Ingress 资源使用 cert-manager 自动管理证书。

#### 基础 TLS 配置

```yaml
# demo-ingress-tls.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-ingress
  annotations:
    # 指定使用 cert-manager 的 ClusterIssuer
    cert-manager.io/cluster-issuer: letsencrypt-prod
    
    # 可选:证书有效期(天)
    # cert-manager.io/duration: "90d"
    
    # 可选:证书续期前续期(天)
    # cert-manager.io/renew-before: "30d"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - demo.example.com
    secretName: demo-tls  # cert-manager 会自动创建此 Secret
  
  rules:
  - host: demo.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: demo-service
            port:
              number: 80

部署命令:

kubectl apply -f demo-ingress-tls.yaml

# 查看 Ingress
kubectl get ingress demo-ingress
kubectl describe ingress demo-ingress

监控证书申请:

# 查看 Certificate 资源
kubectl get certificate -A

# 查看 CertificateRequest
kubectl get certificaterequest -A

# 查看 Order 和 Challenge
kubectl get order -A
kubectl get challenge -A

# 查看证书事件
kubectl describe certificate -l secretName=demo-tls

预期事件流:

1. Ingress 创建 → cert-manager 检测到 cert-manager.io/cluster-issuer 注解
2. Certificate 资源自动创建
3. CertificateRequest 发起证书申请
4. ACME Order 请求创建
5. HTTP-01 Challenge 验证
6. 证书签发成功
7. Secret 自动创建/更新
8. Ingress 引用 Secret 生效

- [ ] **Step 6: 添加证书自动续期

```markdown
### 证书自动续期机制

cert-manager 内置了自动续期机制,无需人工干预。

#### 续期流程图

在这里插入图片描述


#### 续期配置调整

```yaml
# 自定义续期策略
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: demo-cert
spec:
  secretName: demo-tls
  duration: 2160h      # 90 天(默认)
  renewBefore: 720h    # 提前 30 天续期(默认)
  dnsNames:
  - demo.example.com
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer

监控续期:

# 查看 Certificate 状态
kubectl get certificate demo-cert -o yaml

# 查看 NotBefore 和 NotAfter
kubectl get certificate demo-cert \
  -o jsonpath='{.status.notBefore}{"\n"}{.status.notAfter}'

# 查看续期日志
kubectl logs -n cert-manager deploy/cert-manager -f

续期失败告警:
建议配置 Prometheus AlertManager 告警:

groups:
- name: cert-manager
  rules:
  - alert: CertificateExpiringSoon
    expr: cert_manager_certificate_expiration_timestamp_seconds < time() + 604800
    for: 1h
    labels:
      severity: warning
    annotations:
      summary: "Certificate {{ $labels.name }} expiring soon"
      description: "Certificate {{ $labels.name }} will expire in less than 7 days"

Task 6: 编写高级路由规则

  • **Step 1: 创建高级路由章节
## 高级路由规则

Kubernetes Ingress 不仅支持基础的路径和域名路由,还提供了丰富的高级路由能力。
  • **Step 2: 添加路径重写规则
### 路径重写规则

在实际场景中,客户端请求的路径可能与后端服务的路径不一致,这时需要使用路径重写。

#### 基础路径重写

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-rewrite
  annotations:
    # 重写目标路径(移除 /api 前缀)
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      # 捕获组:/api/(.*)
      - path: /api(/|$)(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: api-service
            port:
              number: 80

请求映射:

客户端请求 重写后路径
/api/users /users
/api/products /products
/api/v1/orders /v1/orders
高级重写规则
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: advanced-rewrite
  annotations:
    # 使用正则表达式重写
    nginx.ingress.kubernetes.io/server-snippets: |
      location ~* ^/api/v1/(.*) {
        proxy_pass http://backend-v1/$1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
      }
      
      location ~* ^/api/v2/(.*) {
        proxy_pass http://backend-v2/$1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
      }
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - { path: /, pathType: Prefix, backend: { service: { name: default-backend, port: { number: 80 } } }

- [ ] **Step 3: 添加多域名路由

```markdown
### 多域名/多路径路由

支持在同一 Ingress 中配置多个域名和路径规则。

#### 多域名配置

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-domain
spec:
  ingressClassName: nginx
  rules:
  # 域名 1:api.example.com
  - host: api.example.com
    http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: api-v1-service
            port:
              number: 80
      
  # 域名 2:api2.example.com
  - host: api2.example.com
    http:
      paths:
      - path: /v2
        pathType: Prefix
        backend:
          service:
            name: api-v2-service
            port:
              number: 80
      
  # 域名 3:admin.example.com
  - host: admin.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: admin-service
            port:
              number: 80
单域名多路径配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: single-domain-multi-path
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      # /api/v1/* -> api-v1-service
      - path: /api/v1
        pathType: Prefix
        backend:
          service:
            name: api-v1-service
            port:
              number: 80
      
      # /api/v2/* -> api-v2-service
      - path: /api/v2
        pathType: Prefix
        backend:
          service:
            name: api-v2-service
            port:
              number: 80
      
      # /admin/* -> admin-service
      - path: /admin
        pathType: Prefix
        backend:
          service:
            name: admin-service
            port:
              number: 80
      
      # /* -> default-backend
      - path: /
        pathType: Prefix
        backend:
          service:
            name: default-backend
            port:
              number: 80

- [ ] **Step 4: 添加基于 Header 的路由

```markdown
### 基于 Header 的路由

通过自定义 HTTP Header 实现更灵活的路由策略。

#### Annotation 配置

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: header-routing
  annotations:
    # 根据 Header 路由到不同后端
    nginx.ingress.kubernetes.io/server-snippets: |
      # API 版本路由
      if ($http_x_api_version = "v1") {
        proxy_pass http://api-v1-service;
        break;
      }
      
      if ($http_x_api_version = "v2") {
        proxy_pass http://api-v2-service;
        break;
      }
      
      # 租户隔离路由
      if ($http_x_tenant_id) {
        set $tenant_service "tenant-$http_x_tenant_id-service";
        proxy_pass http://$tenant_service;
        break;
      }
      
      # 默认后端
      proxy_pass http://default-backend;
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: default-backend
            port:
              number: 80

测试命令:

# API v1
curl -H "X-API-Version: v1" https://api.example.com

# API v2
curl -H "X-API-Version: v2" https://api.example.com

# 租户路由
curl -H "X-Tenant-ID: 1001" https://api.example.com
多条件路由
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: complex-routing
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      # 移动端路由
      if ($http_user_agent ~* "Mobile|Android|iPhone") {
        proxy_pass http://mobile-service;
        break;
      }
      
      # 内部 IP 路由
      if ($remote_addr ~* "10\.0\.|192\.168\.") {
        proxy_pass http://internal-service;
        break;
      }
      
      # 海外用户路由
      if ($geoip_country_code !~ "CN") {
        proxy_pass http://oversea-service;
        break;
      }
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: default-service
            port:
              number: 80

Task 7: 编写健康检查和故障转移

  • **Step 1: 创建健康检查章节
## 健康检查与故障转移

生产环境中,服务的稳定性和可用性至关重要。Kubernetes 提供了完善的原生健康检查机制。
  • **Step 2: 添加 K8s 原生健康检查
### K8s 原生健康检查

Kubernetes 提供三种探针(Probe)来实现健康检查:

#### 1. Liveness Probe(存活探针)

**作用**:判断容器是否存活,如果失败则重启容器。

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: healthy-app
spec:
  template:
    spec:
      containers:
      - name: app
        image: my-app:latest
        livenessProbe:
          httpGet:
            path: /health/live
            port: 8080
          initialDelaySeconds: 30  # 容器启动后等待 30 秒
          periodSeconds: 10        # 每 10 秒检查一次
          timeoutSeconds: 5        # 超时时间 5 秒
          successThreshold: 1        # 成功 1 次认为健康
          failureThreshold: 3        # 失败 3 次认为不健康
2. Readiness Probe(就绪探针)

作用:判断容器是否准备好接收流量,如果不就绪则从 Service 中移除。

readinessProbe:
  httpGet:
    path: /health/ready
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 5
  timeoutSeconds: 3
  successThreshold: 1
  failureThreshold: 3
3. Startup Probe(启动探针)

作用:用于启动慢的应用,保护 Liveness Probe 不会误杀。

startupProbe:
  httpGet:
    path: /health/startup
    port: 8080
  initialDelaySeconds: 0
  periodSeconds: 5
  timeoutSeconds: 3
  successThreshold: 1
  failureThreshold: 30  # 允许最多 150 秒启动时间
探针配置最佳实践
探针类型 初始延迟 检查间隔 超时时间 失败阈值
Liveness 30s 10s 5s 3
Readiness 10s 5s 3s 3
Startup 0s 5s 3s 30

💡 配置建议

  • Readiness 必须配置,防止流量打到未就绪的 Pod
  • 启动慢的应用必须配置 Startup Probe
  • Liveness 失败阈值不宜过短,避免误杀

- [ ] **Step 3: 添加 Nginx Ingress 健康检查

```markdown
### Nginx Ingress 健康检查

Nginx Ingress Controller 本身也支持后端健康检查。

#### Annotation 配置

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: health-check
  annotations:
    # 健康检查路径
    nginx.ingress.kubernetes.io/healthcheck-path: /health
    
    # 健康检查间隔
    nginx.ingress.kubernetes.io/healthcheck-interval: "10s"
    
    # 健康检查超时
    nginx.ingress.kubernetes.io/healthcheck-timeout: "5s"
    
    # 健康检查成功阈值
    nginx.ingress.kubernetes.io/healthcheck-success-threshold: "1"
    
    # 健康检查失败阈值
    nginx.ingress.kubernetes.io/healthcheck-unhealthy-threshold: "3"
    
    # 健康检查请求头
    nginx.ingress.kubernetes.io/healthcheck-headers: "X-Health-Check:true"
    
    # 健康检查端口
    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
验证健康检查
# 查看 Nginx 配置中的健康检查配置
kubectl exec -n ingress-nginx deploy/ingress-nginx-controller -- \
  cat /etc/nginx/nginx.conf | grep -A 5 healthcheck

# 监控日志
kubectl logs -n ingress-nginx deploy/ingress-nginx-controller -f | grep healthcheck

- [ ] **Step 4: 添加故障转移机制

```markdown
### 故障转移机制

Kubernetes 提供了多层次的故障转移能力。

#### 1. Pod 级故障转移

当 Pod 不健康时,Kubernetes 自动重启或重新调度:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: resilient-app
spec:
  replicas: 3
  template:
    spec:
      # 节点选择器(避免单点故障)
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: my-app
            topologyKey: "kubernetes.io/hostname"
      
      containers:
      - name: app
        image: my-app:latest
        # 健康检查配置
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
          failureThreshold: 3
2. Service 级故障转移

Service 自动将流量路由到健康的 Pod:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 8080
  # 健康检查注解(部分云厂商支持)
  # annotations:
  #   service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: "10s"
  #   service.beta.kubernetes.io/aws-load-balancer-healthcheck-timeout: "5s"
3. 节点级故障转移

当节点故障时,Pod 自动调度到其他节点:

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: my-pdb
spec:
  minAvailable: 2  # 至少保持 2 个可用 Pod
  selector:
    matchLabels:
      app: my-app
4. 滚动更新零停机

Deployment 支持滚动更新,实现零停机发布:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rolling-update-app
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%       # 最多额外增加 25% 的 Pod
      maxUnavailable: 25%  # 最多 25% 的 Pod 不可用
  template:
   spec:
      containers:
      - name: app
        image: my-app:v2.0

验证滚动更新:

# 触发更新
kubectl set image deployment/rolling-update-app app=my-app:v2.0

# 监控更新状态
kubectl rollout status deployment/rolling-update-app

# 查看更新历史
kubectl rollout history deployment/rolling-update-app

# 回滚到上一版本
kubectl rollout undo deployment/rolling-update-app

Task 8: 编写会话保持章节

  • **Step 1: 创建会话保持章节
## 会话保持策略

对于有状态服务(如购物车、WebSocket 连接等),需要确保同一用户的请求路由到同一个后端。
  • **Step 2: 添加基于 Cookie 的会话保持
### 基于 Cookie 的会话保持

Nginx Ingress Controller 支持通过 Cookie 实现会话保持。

#### Cookie Affinity 配置

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cookie-affinity
  annotations:
    # 启用 Cookie 会话保持
    nginx.ingress.kubernetes.io/affinity: "cookie"
    
    # Cookie 名称
    nginx.ingress.kubernetes.io/session-cookie-name: "route"
    
    # Cookie Hash 算法(md5 | sha1)
    nginx.ingress.kubernetes.io/session-cookie-hash: "sha1"
    
    # Cookie 过期时间(秒)
    nginx.ingress.kubernetes.io/session-cookie-max-age: "3600"
    
    # Cookie 路径
    nginx.ingress.kubernetes.io/session-cookie-path: "/"
    
    # Cookie 是否仅 HTTPS
    nginx.ingress.kubernetes.io/session-cookie-secure: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

工作原理:

  1. 客户端首次请求
  2. Nginx 选择后端 Pod(如:pod-1)
  3. 设置 Cookie:route=sha1(pod-1)
  4. 后续请求携带 Cookie
  5. Nginx 根据 Cookie 路由到同一 Pod

测试验证:

# 首次请求(获取 Cookie)
curl -c cookies.txt -v https://api.example.com

# 后续请求(携带 Cookie)
curl -b cookies.txt -v https://api.example.com

# 查看 Cookie
cat cookies.txt

- [ ] **Step 3: 添加基于 Header 的会话保持

```markdown
### 基于 Header 的会话保持

对于不支持 Cookie 的客户端(如移动应用),可以使用 Header 会话保持。

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: header-affinity
  annotations:
    # 启用 Header 会话保持
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/rewrite-target: /
    
    # 自定义 Header 名称
    nginx.ingress.kubernetes.io/session-cookie-name: "X-Session-ID"
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

客户端请求示例:

curl -H "X-Session-ID: user-12345" https://api.example.com

- [ ] **Step 4: 添加 Redis 共享 Session

```markdown
### Redis 共享 Session(推荐)

对于分布式系统,推荐使用 Redis 共享 Session,彻底解决会话保持问题。

**优势:**
- ✅ 无需关心路由策略
- ✅ 负载均衡更均匀
- ✅ 故障转移更灵活
- ✅ 支持水平扩展

**架构图:**

在这里插入图片描述


**配置示例:**

需要修改应用配置,使用 Redis 存储 Session:

```yaml
# Spring Boot 配置
spring:
  session:
    store-type: redis
    redis:
      namespace: spring:session
  redis:
    host: redis-service
    port: 6379

Task 9: 编写性能调优和限流

  • **Step 1: 创建性能调优章节
## 性能调优与限流

在生产环境中,性能和稳定性是关键指标。Nginx Ingress Controller 提供了丰富的性能调优选项。
  • **Step 2: 添加性能调优参数
### 性能调优参数

通过 Annotation 配置 Nginx 性能参数。

#### 连接优化

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: performance-tuning
  annotations:
    # Keep-Alive 连接保持时间
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    
    # Keep-Alive 请求数
    nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
    
    # 缓冲区大小
    nginx.ingress.kubernetes.io/proxy-buffering: "on"
    nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
    nginx.ingress.kubernetes.io/proxy-buffers-number: "4"
    
    # 上传大小限制
    nginx.ingress.kubernetes.io/client-max-body-size: "50m"
    
    # 启用 HTTP/2
    nginx.ingress.kubernetes.io/http2-push-preload: "true"
    
    # 启用 Gzip 压缩
    nginx.ingress.kubernetes.io/enable-modsecurity: "false"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      gzip on;
      gzip_min_length 1000;
      gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
性能参数对比表
参数 默认值 生产推荐值 说明
proxy-connect-timeout 60s 30s 连接超时
proxy-send-timeout 60s 60s 发送超时
proxy-read-timeout 60s 60s 读取超时
client-max-body-size 1m 50m 客户端最大请求体
proxy-buffer-size 4k 16k 缓冲区大小
proxy-buffers-number 8 4 缓冲区数量

- [ ] **Step 3: 添加限流配置

```markdown
### 限流配置

防止恶意流量和高并发攻击,保护后端服务。

#### 连接数限流

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rate-limiting
  annotations:
    # 每秒请求数
    nginx.ingress.kubernetes.io/limit-rps: "100"
    
    # 并发连接数限制
    nginx.ingress.kubernetes.io/limit-connections: "50"
    
    # 突发请求数
    nginx.ingress.kubernetes.io/limit-burst: "20"
    
    # 限流响应状态码
    nginx.ingress.kubernetes.io/limit-rate-code: "429"
    
    # 限流响应头
    nginx.ingress.kubernetes.io/limit-rate-after: "1024"
    
    # 限流响应体
    nginx.ingress.kubernetes.io/limit-rate-interval: "1s"
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
IP 级限流
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ip-rate-limiting
  annotations:
    # 启用 IP 级限流
    nginx.ingress.kubernetes.io/limit-connections: "10"
    nginx.ingress.kubernetes.io/limit-rate-per-second: "5"
    nginx.ingress.kubernetes.io/limit-burst: "10"
    
    # 白名单 IP
    nginx.ingress.kubernetes.io/server-snippets: |
      geo $limit_key {
        default $binary_remote_addr;
        10.0.0.0/8  "";
        192.168.0.0/16  "";
      }
      
      limit_conn_zone $limit_key zone=conn_limit:10m;
      limit_req_zone $limit_key zone=req_limit:10m rate=5r/s;
      limit_conn conn_limit 10;
      limit_req zone=req_limit burst=10 nodelay;
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
测试限流
# 使用 Apache Bench 压测
ab -n 1000 -c 50 -k https://api.example.com

# 使用 wrk 压测
wrk -t4 -c100 -d30s https://api.example.com

# 观察限流日志
kubectl logs -n ingress-nginx deploy/ingress-nginx-controller | grep 429

Task 10: 编写监控告警章节

  • **Step 1: 创建监控告警章节
## 监控告警体系

生产环境的可观测性至关重要,包括指标、日志和追踪。
  • **Step 2: 添加 Prometheus 监控
### Prometheus 监控

Nginx Ingress Controller 内置了 Prometheus metrics 支持。

#### 启用 Metrics

```yaml
# custom-values.yaml
controller:
  metrics:
    enabled: true
    service:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "10254"
        prometheus.io/path: "/metrics"
    
    serviceMonitor:
      enabled: true
      
    PrometheusRule:
      enabled: true
      rules:
      - alert: NGINXIngressControllerTooMany502
        expr: sum(rate(nginx_ingress_controller_requests{status=~"5..",controller_class="nginx"}[5m])) / sum(rate(nginx_ingress_controller_requests{controller_class="nginx"}[5m])) > 0.05
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Nginx Ingress Controller too many 502"
Prometheus Scrape Config
# prometheus-values.yaml
scrapeConfigs:
  - job_name: 'nginx-ingress'
    metrics_path: /metrics
    scheme: https
    tls_config:
      insecure_skip_verify: true
    kubernetes_sd_configs:
    - role: pod
      namespaces:
        names:
        - ingress-nginx
    relabel_configs:
    - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_component]
      action: keep
      regex: controller
    - source_labels: [__meta_kubernetes_pod_name]
      target_label: pod
    - source_labels: [__meta_kubernetes_namespace]
      target_label: namespace
关键监控指标
指标名称 类型 说明
nginx_ingress_controller_requests Counter 请求总数
nginx_ingress_controller_response_duration_seconds Histogram 响应时间
nginx_ingress_controller_ingress_up Gauge Ingress 健康状态
nginx_ingress_controller_config_last_reload_successful Gauge 配置重载状态
nginx_ingress_controller_success Counter 成功请求数
nginx_ingress_controller_ssl Counter HTTPS 请求数

- [ ] **Step 3: 添加 Grafana 仪表盘

```markdown
### Grafana 仪表盘

推荐使用官方 Nginx Ingress Dashboard。

#### 导入仪表盘

官方 Dashboard ID: `9614` (Nginx Ingress)

**步骤:**
1. 访问 Grafana: `http://grafana.example.com`
2. 点击 `+` → `Import`
3. 输入 Dashboard ID: `9614`
4. 选择 Prometheus 数据源
5. 点击 `Import`

#### 自定义指标查询

```promql
# QPS (每秒请求数)
sum(rate(nginx_ingress_controller_requests[1m]))

# 错误率
sum(rate(nginx_ingress_controller_requests{status=~"5.."}[5m])) / sum(rate(nginx_ingress_controller_requests[5m])) * 100

# P95 响应时间
histogram_quantile(0.95, sum(rate(nginx_ingress_controller_response_duration_seconds_bucket[5m])) by (le))

# HTTPS 比例
sum(rate(nginx_ingress_controller_ssl[5m])) / sum(rate(nginx_ingress_controller_requests[5m])) * 100

- [ ] **Step 4: 添加告警规则

```markdown
### 告警规则

配置 Prometheus AlertManager 实现智能告警。

#### 核心告警规则

```yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: nginx-ingress-alerts
  labels:
    release: prometheus
spec:
  groups:
  - name: nginx-ingress
    rules:
    # 5xx 错误率告警
    - alert: NginxIngressHigh5xxRate
      expr: |
        sum(rate(nginx_ingress_controller_requests{status=~"5..",controller_class="nginx"}[5m])) 
        / sum(rate(nginx_ingress_controller_requests{controller_class="nginx"}[5m])) > 0.05
      for: 5m
      labels:
        severity: critical
      annotations:
        summary: "Nginx Ingress 5xx 错误率过高"
        description: "5xx 错误率: {{ $value | humanizePercentage }}"
    
    # P95 响应时间告警
    - alert: NginxIngressHighLatency
      expr: |
        histogram_quantile(0.95, sum(rate(nginx_ingress_controller_response_duration_seconds_bucket[5m])) by (le)) > 1
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "Nginx Ingress P95 延迟过高"
        description: "P95 响应时间: {{ $value }}s"
    
    # 配置重载失败告警
    - alert: NginxIngressConfigReloadFailed
      expr: nginx_ingress_controller_config_last_reload_successful == 0
      for: 1m
      labels:
        severity: critical
      annotations:
        summary: "Nginx Ingress 配置重载失败"
    
    # Ingress Controller Down 告警
    - alert: NginxIngressControllerDown
      expr: up{job="nginx-ingress"} == 0
      for: 2m
      labels:
        severity: critical
      annotations:
        summary: "Nginx Ingress Controller 不可用"

告警通知渠道:

  • 钉钉 Webhook
  • 企业微信 Webhook
  • Slack Webhook
  • 邮件通知
  • 短信通知

Task 11: 编写常见问题与踩坑经验

  • **Step 1: 创建故障排查章节
## 常见问题与踩坑经验

在实际使用过程中,我总结了一些常见问题和解决方案。
  • **Step 2: 添加常见问题
### 问题 1: 证书申请失败

**现象:**
```bash
kubectl get certificate -l secretName=demo-tls
# STATUS: False, READY: False

原因排查:

  1. DNS 解析问题
# 验证域名解析
nslookup demo.example.com

# 验证解析到正确的 IP
nslookup demo.example.com | grep A
  1. 防火墙问题
# 验证 80 端口是否开放
telnet your-lb-ip 80

# 检查防火墙规则
sudo ufw status
sudo iptables -L -n | grep 80
  1. ACME 挑战超时
# 查看 Challenge 状态
kubectl get challenge -A

# 查看 Challenge 详细信息
kubectl describe challenge <challenge-name>
  1. Ingress Class 配置错误
# 验证 Ingress Class
kubectl get ingressclass

# 验证 ClusterIssuer
kubectl get clusterissuer

解决方案:

# 1. 确认 DNS 解析正确
# 2. 确认 80/443 端口开放
# 3. 确认 Ingress Class 配置正确
# 4. 检查 cert-manager 日志
kubectl logs -n cert-manager deploy/cert-manager -f

# 5. 重试证书申请
kubectl delete certificate demo-cert
kubectl delete -f demo-ingress-tls.yaml
kubectl apply -f demo-ingress-tls.yaml

问题 2: 502 Bad Gateway

现象:
浏览器访问返回 502 Bad Gateway

原因排查:

  1. 后端服务未启动
# 检查 Service
kubectl get svc demo-service

# 检查 Pod
kubectl get pods -l app=demo

# 检查 Pod 日志
kubectl logs -l app=demo
  1. Service 选择器错误
# 验证 Service selector
kubectl get svc demo-service -o yaml | grep -A 5 selector

# 验证 Pod labels
kubectl get pods -l app=demo -o yaml | grep -A 3 labels:
  1. 端口不匹配
# 验证 Service 配置
kubectl get svc demo-service -o yaml | grep -A 5 ports

# 验证 Pod 端口
kubectl get pods -l app=demo -o yaml | grep -A 5 ports
  1. 网络策略限制
# 检查网络策略
kubectl get networkpolicy -A

解决方案:

# 1. 启动后端服务
kubectl scale deployment demo-app --replicas=3

# 2. 修正 Service selector
kubectl edit svc demo-service

# 3. 验证端口配置
kubectl port-forward svc/demo-service 8080:80

# 4. 测试后端服务
kubectl run test-pod --image=busybox --rm -it --restart=Never -- \
  wget -O- http://demo-service

问题 3: 负载不均

现象:
流量集中到部分 Pod,其他 Pod 流量很少

原因:

  • 长连接导致连接复用
  • Keep-Alive 时间过长
  • 负载均衡算法问题

解决方案:

# 调整 Keep-Alive 参数
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: load-balance-fix
  annotations:
    # 缩短 Keep-Alive 时间
    nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
    nginx.ingress.kubernetes.io/configuration-snippet: |
      keepalive 30;
      keepalive_requests 100;

问题 4: 配置不生效

现象:
修改 Ingress 配置后,访问无变化

原因排查:

# 1. 检查 Ingress 配置
kubectl describe ingress demo-ingress

# 2. 检查 Ingress Controller 日志
kubectl logs -n ingress-nginx deploy/ingress-nginx-controller | grep RELOAD

# 3. 检查 Nginx 配置
kubectl exec -n ingress-nginx deploy/ingress-nginx-controller -- \
  cat /etc/nginx/nginx.conf | grep -A 10 demo-ingress

解决方案:

# 1. 验证 Ingress Class 配置
kubectl get ingressclass

# 2. 删除并重建 Ingress
kubectl delete ingress demo-ingress
kubectl apply -f demo-ingress.yaml

# 3. 重启 Ingress Controller
kubectl rollout restart deployment/ingress-nginx-controller -n ingress-nginx

- [ ] **Step 3: 添加真实踩坑案例

```markdown
### 真实踩坑案例

#### 案例 1: 生产环境证书过期导致服务中断

**背景:**
某电商网站在黑色星期五期间,证书突然过期,导致所有用户无法访问。

**原因:**
- 使用手动申请的证书,忘记设置自动续期
- 证书到期前没有收到告警
- 备用证书也未及时更新

**解决方案:**
```bash
# 1. 安装 cert-manager
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace

# 2. 配置自动续期告警
# 添加 Prometheus 告警规则
# 配置 AlertManager 通知

# 3. 设置证书监控
# 每周检查证书有效期

教训:

  • 生产环境必须使用 cert-manager 自动管理证书
  • 配置证书过期告警
  • 定期备份证书
案例 2: 负载不均导致后端雪崩

背景:
某 API 服务在流量高峰期,所有请求集中到单个 Pod,导致 CPU 100%,服务不可用。

原因:

  • 长连接导致连接复用
  • Keep-Alive 时间过长(默认 75s)
  • 负载均衡算法不合理

解决方案:

# 调整 Ingress 配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: load-balance-fix
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      keepalive 30;
      keepalive_requests 50;
      # 使用最少连接数算法
      upstream demo-service {
        least_conn;
        server backend1;
        server backend2;
        server backend3;
      }

效果:

  • 请求分布更均匀
  • 单个 Pod CPU 降至 30%
  • 服务稳定性大幅提升

教训:

  • 生产环境必须配置合理的负载均衡算法
  • 监控负载分布情况
  • 及时调整参数

- [ ] **Step 4: 添加互动引导

```markdown
### 💬 互动话题

你在生产环境使用 Ingress 时遇到过哪些问题?

**常见场景:**
- 证书管理问题?
- 负载不均?
- 性能瓶颈?
- 配置复杂?
- 监控告警?

欢迎在评论区分享你的经验和解决方案,帮助更多开发者!

**🗳 投票话题**

你所在团队是否已经在生产环境使用 Ingress?

- [ ] A. 是的,稳定运行中
- [ ] B. 正在测试中
- [ ] C. 计划迁移
- [ ] D. 暂无计划

## Task 12: 编写性能对比与最佳实践

- [ ] **Step 1: 创建最佳实践章节

```markdown
## 性能对比与最佳实践

通过对比分析,帮助你做出技术选型决策。
  • **Step 2: 添加传统 Nginx vs K8s Ingress 对比
### 传统 Nginx vs Kubernetes Ingress

| 维度 | 传统 Nginx | Kubernetes Ingress | 胜者 | 说明 |
|------|------------|-------------------|--------|------|
| **证书管理** | 手动更新 | cert-manager 自动 | K8s | 自动续期,无需人工干预 |
| **配置热更新** | 手动 reload | 自动生效 | K8s | Ingress 资源变更自动生效 |
| **健康检查** | 被动(付费) | K8s 原生 | K8s | Liveness/Readiness Probe |
| **扩展性** | 手动配置 | 自动发现 | K8s | 自动感知 Pod 变化 |
| **故障转移** | 需要脚本 | 原生支持 | K8s | Pod 自动重启和调度 |
| **多云支持** | 难以统一 | 天然支持 | K8s | 同一套配置跨云 |
| **学习成本** | 低 | 中 | Nginx | 需要学习 K8s 生态 |
| **资源消耗** | 低 | 中 | Nginx | 需要额外的 Controller Pod |
| **监控集成** | 需要手动 | 原生支持 | K8s | Prometheus metrics |
| **权限管理** | 手动配置 | RBAC 原生 | K8s | 原生权限控制 |
| **成本效益** | 低 | 高 | K8s | 长期维护成本低 |

**💡 结论:**
- 对于 **Kubernetes 环境**:强烈推荐使用 K8s Ingress
- 对于 **传统 VM 环境**:继续使用传统 Nginx
- 对于 **混合环境**:使用传统 Nginx 统一入口,后端使用 K8s Ingress
  • **Step 3: 添加生产环境最佳实践
### 生产环境最佳实践 CheckList

#### ✅ 证书管理

- [ ] 使用 cert-manager 自动管理证书
- [ ] 配置证书自动续期
- [ ] 配置证书过期告警
- [ ] 定期备份证书
- [ ] 生产环境使用正式 CA,避免使用自签名

#### ✅ Ingress Controller 配置

- [ ] 设置资源限制(request/limit)
- [ ] 使用 DaemonSet 部署(高可用)
- [ ] 配置 Pod 反亲和性(分散部署)
- [ ] 启用健康检查
- [ ] 配置合理的超时参数

#### ✅ 安全加固

- [ ] 隐藏 Nginx 版本号
- [ ] 限制 HTTP 方法(GET/POST/PUT/DELETE)
- [ ] 启用 SSL/TLS
- [ ] 配置安全 Header(HSTS, X-Frame-Options)
- [ ] 启用 WAF(Web Application Firewall)
- [ ] 配置速率限制

#### ✅ 性能优化

- [ ] 启用 HTTP/2
- [ ] 启用 Gzip 压缩
- [ ] 配置合理的 Keep-Alive 参数
- [ ] 启用缓存
- [ ] 优化缓冲区大小

#### ✅ 监控告警

- [ ] 配置 Prometheus metrics 采集
- [ ] 配置 Grafana 仪表盘
- [ ] 配置关键指标告警
- [ ] 配置错误率告警
- [ ] 配置响应时间告警

#### ✅ 网络策略

- [ ] 配置 NetworkPolicy 限制访问
- [ ] 使用 IngressClass 隔离多租户
- [ ] 配置 IP 白名单
- [ ] 限制外部访问内部服务

#### ✅ 日志管理

- [ ] 配置访问日志
- [ ] 配置错误日志
- [ ] 集成日志收集系统(ELK/Loki)
- [ ] 配置日志轮转
- [ ] 敏感信息脱敏
  • **Step 4: 添加成本效益分析
### 成本效益分析

#### 初期投入

| 项目 | 传统 Nginx | K8s Ingress |
|------|------------|--------------|
| 学习成本 | 低 | 中(需要学习 K8s 生态) |
| 部署时间 | 短(1-2 天) | 中(3-5 天) |
| 人员要求 | 运维工程师 | K8s 运维工程师 |

#### 长期收益

| 项目 | 传统 Nginx | K8s Ingress |
|------|------------|--------------|
| 证书管理 | 高(手动更新) | 低(自动续期) |
| 配置变更 | 高(手动操作) | 低(声明式配置) |
| 故障恢复 | 中(需要脚本) | 低(原生支持) |
| 水平扩展 | 高(手动配置) | 低(自动感知) |
| 多云管理 | 高(配置分散) | 低(统一管理) |
| 监控告警 | 中(需要集成) | 低(原生支持) |

#### ROI 分析

**假设场景:**
- 管理规模:10 个微服务,50 个域名
- 证书数量:50 个
- 配置变更频率:每周 2 次

**传统 Nginx:**
- 证书更新:50 个 × 4 次/年 = 200 人时
- 配置变更:2 次/周 × 52 周 × 0.5 小时 = 52 人时
- 故障处理:10 次/年 × 2 小时 = 20 人时
- **总成本:272 人时/年**

**K8s Ingress:**
- 证书更新:5 人时/年(仅初始化)
- 配置变更:2 次/周 × 52 周 × 0.1 小时 = 5.2 人时
- 故障处理:2 次/年 × 0.5 小时 = 1 人时
- **总成本:11.2 人时/年**

**结论:**
- **节省人力:260.8 人时/年**
- **ROI:2434%(初期投入 / 长期收益)**
- **回本周期:1-2 个月**

**💡 建议:**
对于中大型项目(>5 个服务,>10 个域名),强烈推荐使用 K8s Ingress
  • **Step 5: 添加总结
## 总结

本文详细介绍了 Kubernetes Ingress HTTPS 负载均衡的生产级配置,包括:

### 核心知识点

1. **架构原理**:理解 Ingress Controller、Ingress 资源、Service 的关系
2. **环境准备**:K8s 集群、域名、网络权限
3. **Ingress Controller**:Nginx Ingress Controller 深度配置
4. **TLS 证书管理**:cert-manager + Let's Encrypt 自动化
5. **高级路由**:路径重写、多域名、Header 路由
6. **健康检查**:Liveness/Readiness Probe
7. **会话保持**:Cookie/Header/Redis 方案
8. **性能调优**:连接优化、限流配置
9. **监控告警**:Prometheus + Grafana
10. **故障排查**:常见问题和解决方案

### 生产环境建议

✅ **必须配置:**
- cert-manager 自动管理证书
- 资源限制和健康检查
- 安全加固和限流
- 监控告警体系

✅ **强烈推荐:**
- DaemonSet + AntiAffinity 高可用
- Prometheus + Grafana 监控
- 声明式配置管理(GitOps)
- 定期备份和演练

### 后续学习

- [ ] Kubernetes Ingress 多集群实战
- [ ] Nginx vs Traefik vs Istio Gateway 对比
- [ ] Service Mesh 与 Ingress 协同
- [ ] K8s 网络策略详解
- [ ] 云原生安全最佳实践

### 💬 互动交流

如果你觉得这篇文章有帮助,欢迎:
- 👍 点赞支持
- ⭐ 收藏备用
- 💬 评论区分享经验
- 📤 转发给需要的同事

**关于 Ingress 你还有哪些疑问?欢迎在评论区留言!**

---

**相关阅读:**
- [Kubernetes 官方文档](https://kubernetes.io/docs/concepts/services-networking/ingress/)
- [Nginx Ingress Controller GitHub](https://github.com/kubernetes/ingress-nginx)
- [cert-manager 官方文档](https://cert-manager.io/docs/)
- [LoadBalancer- Nginx 配置 SSL 证书:HTTPS 负载均衡完整实操](https://blog.csdn.net/qq_41187124/article/details/157545081)


Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐