Kubernetes服务发布进阶

目录

一、Ingress 基础概念与工作原理

1.1 Kubernetes 服务暴露方式概述

1.2 Ingress 核心组成

1.2.1 Ingress 对象

1.2.2 Ingress Controller

1.3 Ingress 工作流程

1.4 Ingress 工作原理图解

二、Ingress Nginx Controller 安装

2.1 准备工作

2.1.1 安装 Helm

2.1.2 配置镜像源

2.1.3 关键参数配置

2.2 部署 Ingress Nginx

2.2.1 给节点打标签

2.2.2 创建命名空间

2.2.3 安装 Ingress Nginx

三、Ingress Nginx 基础使用

3.1 创建测试环境

3.1.1 创建命名空间

3.1.2 部署 Nginx 服务

3.2 创建基础 Ingress

3.2.1 编写 Ingress 配置

3.2.2 应用 Ingress 配置

3.2.3 访问测试

四、Ingress Nginx 高级功能

4.1 域名重定向 (Redirect)

4.1.1 场景说明

4.1.2 配置重定向 Ingress

4.1.3 测试重定向

4.2 前后端分离 (Rewrite)

4.2.1 场景说明

4.2.2 部署后端服务

4.2.3 配置 Rewrite 规则

4.2.4 测试 Rewrite

4.3 SSL 配置

4.3.1 生成测试证书

4.3.2 创建证书 Secret

4.3.3 配置 HTTPS Ingress

4.3.4 访问 HTTPS 服务

4.4 基本认证 (Basic Auth)

4.4.1 安装 htpasswd 工具

4.4.2 创建认证用户

4.4.3 创建认证 Secret

4.4.4 配置认证 Ingress

4.4.5 测试认证

4.5 灰度发布 / 金丝雀发布

4.5.1 概念说明

4.5.2 部署 V1 版本

4.5.3 部署 V2 版本(灰度环境)

4.5.4 配置灰度流量控制

4.5.5 测试灰度发布

五、生产环境注意事项

六、总结

七、Ingress Nginx 配置进阶技巧

7.1 Ingress 路径匹配规则详解

7.2 流量管理高级配置

7.2.1 基于权重的流量分发

7.2.2 基于 Header 的流量分流

7.3 错误页面与重试机制

7.3.1 自定义错误页面

7.3.2 失败请求重试

7.4 限流与连接池配置

7.4.1 基于 IP 的限流

7.4.2 连接池与超时配置

八、Ingress Nginx 与微服务架构

8.1 多服务路由案例

8.1.1 场景描述

8.1.2 配置示例

8.2 Ingress 与服务网格集成

8.2.1 Ingress 作为入口网关

8.2.2 集成配置示例

九、故障排查与性能调优

9.1 常见问题排查

9.1.1 Ingress 未生效

9.1.2 流量未正确转发

9.2 性能调优参数

9.2.1 Ingress Controller 资源配置

9.2.2 Nginx 工作进程调优

十、生产环境最佳实践

10.1 高可用架构设计

10.2 安全加固措施

10.3 监控与告警方案

十一、实战案例:电商平台服务发布

11.1 架构需求

11.2 完整配置实现

11.2.1 前端门户 Ingress

11.2.2 前端门户 Ingress

11.2.3 用户服务 Ingress(带认证)

11.2.4 商品服务 Ingress(灰度发布)

11.2.5 订单服务 Ingress(URL 重写)

11.2.6 创建证书与认证 Secret

11.3 部署与验证流程

十二、Ingress Nginx 与其他组件集成

12.1 与 Cert-Manager 集成自动签发证书

12.1.1 安装 Cert-Manager

12.1.2 配置 Let's Encrypt 签发证书

12.1.3 Ingress 中使用自动签发证书

12.2 与 Helm Chart 集成管理 Ingress

12.2.1 自定义 Helm Chart 结构

12.2.2 动态生成 Ingress 配置

十三、Ingress Nginx 的未来发展与替代方案

13.1 Ingress Nginx 的演进方向

13.2 替代方案对比

13.3 技术选型建议


一、Ingress 基础概念与工作原理

1.1 Kubernetes 服务暴露方式概述

在 Kubernetes 集群中,Pod 的 IP 和 Service 的 ClusterIP 仅在集群内部可见,为实现外部访问,Kubernetes 提供了多种服务暴露方案:

  • NodePort:将 Service 映射到节点的 30000-32767 端口,适合测试环境,但端口管理复杂
  • LoadBalancer:依赖云服务商的负载均衡器,需额外费用,仅适用于公有云
  • externalIPs:手动分配外部 IP,流量通过该 IP 路由到 Service
  • Ingress:七层反向代理,通过域名和 URL 规则转发请求,适合复杂微服务架构

1.2 Ingress 核心组成

1.2.1 Ingress 对象
  • 是 Kubernetes 的 API 资源,通过 YAML 定义请求转发规则
  • 可配置域名、URL 路径、负载均衡、SSL 等功能
  • 需依赖 Ingress Controller 实现具体转发
1.2.2 Ingress Controller
  • 具体实现反向代理的组件,常见类型有:
    • ingress-nginx:Kubernetes 官方维护
    • nginx-ingress:Nginx 官方维护
    • Traefik、Istio 等
  • 工作模式:
    • 监控 Ingress 规则变化
    • 生成 Nginx 配置并动态更新
    • 重载 Nginx 使配置生效

1.3 Ingress 工作流程

用户访问流程:

  1. 浏览器输入域名
  2. 域名解析到外部负载均衡器(如 SLB)
  3. 负载均衡器转发到 Ingress Controller
  4. Ingress 根据规则找到对应 Service
  5. 流量最终到达 Service 对应的 Pod

1.4 Ingress 工作原理图解

Client --> 负载均衡器 --> Ingress Controller
       |                     |
       v                     v
   域名解析               规则匹配
       |                     |
       v                     v
   Service --> Pod集群

二、Ingress Nginx Controller 安装

2.1 准备工作

2.1.1 安装 Helm
# 下载Helm
wget https://get.helm.sh/helm-v3.9.4-linux-amd64.tar.gz
# 解压
tar zxvf helm-v3.9.4-linux-amd64.tar.gz
# 移动到执行目录
mv linux-amd64/helm /usr/local/bin/
2.1.2 配置镜像源

由于默认镜像源在国外,需修改为国内镜像:

# 修改ingress-nginx/values.yaml
controller:
  name: controller
  image:
    chroot: false
    registry: registry.cn-hangzhou.aliyuncs.com  # 国内镜像仓库
    image: tanzu/controller
    tag: "v1.6.4"
    # 注释掉摘要信息
    # digest: sha256:15be4666c53052484dd2992efacf2f50ea77a78ae8aa21ccd91af6baaa7ea22f

# 修改opentelemetry镜像
opentelemetry:
  enabled: false
  image: registry.cn-hangzhou.aliyuncs.com/tanzu/opentelemetry:v20230107

# 修改admissionWebhook镜像
patchWebhookJob:
  securityContext:
    allowPrivilegeEscalation: false
  resources: {}
  patch:
    enabled: true
    image:
      registry: registry.cn-hangzhou.aliyuncs.com
      image: tanzu/kube-webhook-certgen
      tag: v20220916-gd32f8c343
2.1.3 关键参数配置
# 设置网络模式
hostNetwork: true  # Pod与节点共享网络命名空间

# DNS策略
dnsPolicy: ClusterFirstWithHostNet  # 适用于hostNetwork模式

# 节点选择器
nodeSelector:
  ingress: "true"
  kubernetes.io/os: linux

# 部署类型改为DaemonSet
kind: DaemonSet

2.2 部署 Ingress Nginx

2.2.1 给节点打标签
# 给k8s-node01节点打标签
kubectl label node k8s-node01 ingress=true
2.2.2 创建命名空间
# 创建ingress-nginx命名空间
kubectl create ns ingress-nginx
2.2.3 安装 Ingress Nginx
# 下载ingress-nginx chart
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm pull ingress-nginx/ingress-nginx --version 4.7.1
tar xvf ingress-nginx-4.7.1.tgz

# 安装ingress-nginx
cd ingress-nginx
helm install ingress-nginx . -n ingress-nginx

# 验证安装
kubectl get po -n ingress-nginx -o wide

三、Ingress Nginx 基础使用

3.1 创建测试环境

3.1.1 创建命名空间
# 创建学习用命名空间
kubectl create ns study-ingress
3.1.2 部署 Nginx 服务
# 创建Nginx部署
kubectl create deployment nginx --image=nginx:1.7.9 -n study-ingress

# 暴露为Service
kubectl expose deployment nginx --port=80 -n study-ingress

3.2 创建基础 Ingress

3.2.1 编写 Ingress 配置
# web-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: study-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.test.com
    http:
      paths:
      - backend:
          service:
            name: nginx
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific
3.2.2 应用 Ingress 配置
# 创建Ingress
kubectl create -f web-ingress.yaml
3.2.3 访问测试
  • 在客户端 hosts 文件中添加:192.168.10.102 nginx.test.com(替换为实际节点 IP)
  • 浏览器访问http://nginx.test.com,应看到 Nginx 默认页面

四、Ingress Nginx 高级功能

4.1 域名重定向 (Redirect)

4.1.1 场景说明

当服务需要更换域名时,需将旧域名访问重定向到新域名

4.1.2 配置重定向 Ingress
# redirect.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com
  name: nginx-redirect
  namespace: study-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.redirect.com
    http:
      paths:
      - backend:
          service:
            name: nginx
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific
4.1.3 测试重定向
# 添加域名解析
192.168.10.102 nginx.redirect.com

# 访问测试
curl http://nginx.redirect.com
# 应自动跳转到百度

4.2 前后端分离 (Rewrite)

4.2.1 场景说明

前后端分离架构中,需将/api-a路径重写为后端服务可识别的路径

4.2.2 部署后端服务
# 创建后端部署
kubectl create deployment backend-api --image=nginx:1.7.9 -n study-ingress

# 暴露为Service
kubectl expose deployment backend-api --port=80 -n study-ingress
4.2.3 配置 Rewrite 规则
# rewrite.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: backend-api
  namespace: study-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.test.com
    http:
      paths:
      - backend:
          service:
            name: backend-api
            port:
              number: 80
        path: /api-a(/|$)(.*)
        pathType: ImplementationSpecific
4.2.4 测试 Rewrite
  • 访问http://nginx.test.com/api-a,应看到 Nginx 默认页面
  • 说明路径已重写为/并正确转发到后端服务

4.3 SSL 配置

4.3.1 生成测试证书
# 生成自签名证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout tls.key -out tls.crt -subj "/CN=nginx.test.com"
4.3.2 创建证书 Secret
# 创建TLS Secret
kubectl create secret tls ca-secret \
  --cert=tls.crt --key=tls.key -n study-ingress
4.3.3 配置 HTTPS Ingress
# ingress-ssl.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress-ssl
  namespace: study-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.test.com
    http:
      paths:
      - backend:
          service:
            name: nginx
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific
  tls:
  - hosts:
    - nginx.test.com
    secretName: ca-secret
4.3.4 访问 HTTPS 服务
  • 浏览器访问https://nginx.test.com
  • 由于是自签名证书,会提示不安全,可忽略继续访问

4.4 基本认证 (Basic Auth)

4.4.1 安装 htpasswd 工具
# 安装httpd获取htpasswd
yum -y install httpd
4.4.2 创建认证用户
# 创建用户zhangsan
htpasswd -c auth zhangsan
# 输入密码并确认
4.4.3 创建认证 Secret
# 创建Basic Auth Secret
kubectl create secret generic basic-auth \
  --from-file=auth -n study-ingress
4.4.4 配置认证 Ingress
# ingress-with-auth.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-with-auth
  namespace: study-ingress
  annotations:
    nginx.ingress.kubernetes.io/auth-realm: "Please Input Your Username and Password"
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-type: basic
spec:
  ingressClassName: nginx
  rules:
  - host: auth.test.com
    http:
      paths:
      - backend:
          service:
            name: nginx
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific
4.4.5 测试认证
  • 访问http://auth.test.com
  • 浏览器会弹出认证框,输入用户名zhangsan和设置的密码即可访问

4.5 灰度发布 / 金丝雀发布

4.5.1 概念说明
  • 灰度发布:将部分流量切换到新版本,逐步扩大范围
  • 金丝雀发布:先在小部分用户中测试新版本,再全量发布
  • 蓝绿部署:同时运行新旧版本,一键切换流量
4.5.2 部署 V1 版本
# 创建生产环境命名空间
kubectl create ns production

# 部署V1版本应用
kubectl create deployment canary-v1 \
  --image=registry.cn-beijing.aliyuncs.com/dotbalo/canary:v1 -n production

# 暴露为Service
kubectl expose deployment canary-v1 --port=8080 -n production

# 创建Ingress
cat > v1-ingress.yaml << EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-v1
  namespace: production
spec:
  ingressClassName: nginx
  rules:
  - host: canary.com
    http:
      paths:
      - backend:
          service:
            name: canary-v1
            port:
              number: 8080
        path: /
        pathType: ImplementationSpecific
EOF

# 应用Ingress
kubectl create -f v1-ingress.yaml
4.5.3 部署 V2 版本(灰度环境)
# 创建灰度命名空间
kubectl create ns canary

# 部署V2版本应用
kubectl create deployment canary-v2 \
  --image=registry.cn-beijing.aliyuncs.com/dotbalo/canary:v2 -n canary

# 暴露为Service
kubectl expose deployment canary-v2 --port=8080 -n canary

# 测试V2服务
kubectl get svc -n canary
# 记录ClusterIP,用curl测试应返回"Canary v2"
4.5.4 配置灰度流量控制
# canary-v2.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-v2
  namespace: canary
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"        # 标记为灰度环境
    nginx.ingress.kubernetes.io/canary-weight: "10"  # 分配10%流量
spec:
  ingressClassName: nginx
  rules:
  - host: canary.com
    http:
      paths:
      - backend:
          service:
            name: canary-v2
            port:
              number: 8080
        path: /
        pathType: ImplementationSpecific
4.5.5 测试灰度发布
# 测试10次访问
for i in $(seq 10); do curl -s canary.com; done
# 应看到约1次V2,9次V1

# 修改权重为50%
kubectl edit ingress canary-v2 -n canary
# 修改annotations中的canary-weight为50

# 再次测试
for i in $(seq 10); do curl -s canary.com; done
# V1和V2访问次数应大致相等

五、生产环境注意事项

  1. 高可用性

    • 使用 DaemonSet 部署 Ingress Controller
    • 为 Controller 节点单独配置资源
    • 考虑多节点部署并配合外部负载均衡
  2. 性能优化

    • 开启 Nginx 缓存
    • 配置连接超时参数
    • 启用 gzip 压缩
  3. 安全加固

    • 使用正规 SSL 证书
    • 配置 IP 白名单
    • 启用 WAF 防护
  4. 监控告警

    • 监控 Ingress Controller 指标
    • 配置服务健康检查
    • 建立告警机制

六、总结

介绍了 Kubernetes 中 Ingress Nginx 的核心概念、安装配置及高级功能:

  1. Ingress 作为七层负载均衡器,通过域名和 URL 规则转发请求,是生产环境服务暴露的首选方案
  2. Ingress Nginx Controller 的安装需注意镜像源、网络配置等细节
  3. 利用 Ingress 可实现域名重定向、前后端分离、HTTPS、认证及灰度发布等功能
  4. 生产环境中需考虑高可用、性能和安全等因素

七、Ingress Nginx 配置进阶技巧

7.1 Ingress 路径匹配规则详解

Ingress 支持三种路径匹配类型,在pathType字段中定义:

  1. ImplementationSpecific

    • 由 Ingress 控制器决定匹配逻辑,Nginx 会将其视为PrefixExact类型处理
    • 是默认的路径类型,使用时需结合控制器特性配置
  2. Exact

    • 精确匹配 URL 路径,区分大小写
    • 示例:path: /api 仅匹配完全等于/api的路径
  3. Prefix

    • 匹配 URL 路径前缀,按/分割的路径元素进行匹配
    • 示例:path: /api/ 匹配以/api/开头的路径,如/api/user,但不匹配/apiuser
    • 规则:若路径最后一个元素是请求路径的子字符串,则不匹配(如/foo/bar不匹配/foo/barbaz

配置示例

spec:
  rules:
  - http:
      paths:
      - path: /exact-path
        pathType: Exact
        backend: ...
      - path: /prefix-path/
        pathType: Prefix
        backend: ...

7.2 流量管理高级配置

7.2.1 基于权重的流量分发

除灰度发布中的canary-weight外,还可通过nginx.ingress.kubernetes.io/weight为不同 Ingress 规则分配权重:

# 多个Ingress规则示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: traffic-split
  annotations:
    nginx.ingress.kubernetes.io/weight: "70"  # 规则权重70%
spec:
  rules:
  - host: app.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: v1-service
            port:
              number: 80

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: traffic-split-v2
  annotations:
    nginx.ingress.kubernetes.io/weight: "30"  # 规则权重30%
spec:
  rules:
  - host: app.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: v2-service
            port:
              number: 80
7.2.2 基于 Header 的流量分流

通过nginx.ingress.kubernetes.io/canary-by-header可基于请求 Header 分流:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-by-header
  namespace: canary
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "User-Agent"  # 基于User-Agent分流
    nginx.ingress.kubernetes.io/canary-by-header-value: "Chrome"  # 匹配Chrome用户
spec:
  rules:
  - host: app.com
    http:
      paths:
      - backend:
          service:
            name: canary-service
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific

7.3 错误页面与重试机制

7.3.1 自定义错误页面

通过nginx.ingress.kubernetes.io/server-snippet添加 Nginx 配置段:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: error-pages
  annotations:
    nginx.ingress.kubernetes.io/server-snippet: |
      error_page 404 /404.html;
      error_page 500 502 503 504 /5xx.html;
      location = /404.html {
        root /usr/share/nginx/html/errors;
        internal;
      }
      location = /5xx.html {
        root /usr/share/nginx/html/errors;
        internal;
      }
spec:
  rules:
  - host: app.com
    http:
      paths:
      - backend:
          service:
            name: web-service
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific
7.3.2 失败请求重试

通过nginx.ingress.kubernetes.io/proxy-next-upstream配置重试策略:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: retry-policy
  annotations:
    nginx.ingress.kubernetes.io/proxy-next-upstream: "timeout,connect_timeout,server_error,temp_error"
    nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "3"  # 最多重试3次
    nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "10s"  # 重试间隔
spec:
  rules:
  - host: app.com
    http:
      paths:
      - backend:
          service:
            name: web-service
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific

7.4 限流与连接池配置

7.4.1 基于 IP 的限流

通过nginx.ingress.kubernetes.io/limit-rps限制每秒请求数:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rate-limit
  annotations:
    nginx.ingress.kubernetes.io/limit-rps: "10"  # 每秒最多10个请求
    nginx.ingress.kubernetes.io/limit-rpm: "600"  # 每分钟最多600个请求
    nginx.ingress.kubernetes.io/limit-whitelist: "192.168.1.0/24,10.0.0.1"  # 白名单IP
spec:
  rules:
  - host: app.com
    http:
      paths:
      - backend:
          service:
            name: web-service
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific
7.4.2 连接池与超时配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: connection-pool
  annotations:
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "10"  # 连接超时(秒)
    nginx.ingress.kubernetes.io/proxy-read-timeout: "30"     # 读取超时(秒)
    nginx.ingress.kubernetes.io/proxy-send-timeout: "30"    # 发送超时(秒)
    nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"    # 缓冲区大小
    nginx.ingress.kubernetes.io/proxy-buffers: "4 16k"      # 缓冲区数量和大小
spec:
  rules:
  - host: app.com
    http:
      paths:
      - backend:
          service:
            name: web-service
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific

八、Ingress Nginx 与微服务架构

8.1 多服务路由案例

8.1.1 场景描述
  • 前端服务:frontend.com 根路径访问
  • 用户服务:api.frontend.com/user 路径访问
  • 订单服务:api.frontend.com/order 路径访问
8.1.2 配置示例
# 前端服务Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: frontend-ingress
  namespace: microservices
spec:
  ingressClassName: nginx
  rules:
  - host: frontend.com
    http:
      paths:
      - backend:
          service:
            name: frontend-svc
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific

# 后端API服务Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  namespace: microservices
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - host: api.frontend.com
    http:
      paths:
      - backend:
          service:
            name: user-svc
            port:
              number: 80
        path: /user(/|$)(.*)
        pathType: ImplementationSpecific
      - backend:
          service:
            name: order-svc
            port:
              number: 80
        path: /order(/|$)(.*)
        pathType: ImplementationSpecific

8.2 Ingress 与服务网格集成

8.2.1 Ingress 作为入口网关
  • Ingress Nginx 作为 Kubernetes 集群的统一入口
  • 配合 Istio 等服务网格实现内部服务流量管理
8.2.2 集成配置示例
# Ingress配置(与Istio集成)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: istio-ingress
  namespace: istio-system
  annotations:
    kubernetes.io/ingress.class: "nginx"  # 使用Nginx Ingress
    nginx.ingress.kubernetes.io/enable-global-configuration: "true"
spec:
  rules:
  - host: app.com
    http:
      paths:
      - backend:
          service:
            name: istio-ingressgateway
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific

九、故障排查与性能调优

9.1 常见问题排查

9.1.1 Ingress 未生效
  1. 检查 Ingress 状态

    kubectl get ingress -n study-ingress
    kubectl describe ingress nginx-ingress -n study-ingress
    
  2. 查看 Ingress Controller 日志

    kubectl logs -n ingress-nginx $(kubectl get po -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx -o name)
    
  3. 检查 Nginx 配置生成

    # 进入Ingress Controller Pod
    kubectl exec -n ingress-nginx -it $(kubectl get po -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx -o name) -- /bin/bash
    # 查看生成的Nginx配置
    cat /etc/nginx/nginx.conf
    
9.1.2 流量未正确转发
  1. 检查 Service 与 Pod 连通性

    kubectl get svc -n study-ingress
    kubectl get endpoints -n study-ingress
    kubectl get pods -n study-ingress
    
  2. 测试 Service 访问

    # 通过ClusterIP访问Service
    kubectl run -it --rm curl --image=curl images.cisco.com/cisco/pxe/curltools:latest -- curl :
    

9.2 性能调优参数

9.2.1 Ingress Controller 资源配置
# values.yaml中配置资源限制
controller:
  resources:
    limits:
      cpu: "2"
      memory: "2Gi"
    requests:
      cpu: "500m"
      memory: "512Mi"
9.2.2 Nginx 工作进程调优
# 通过configMap配置Nginx参数
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
data:
  worker-processes: "4"  # 工作进程数,建议与CPU核心数一致
  worker-connections: "8192"  # 每个进程最大连接数
  worker-rlimit-nofile: "100000"  # 最大打开文件数

十、生产环境最佳实践

10.1 高可用架构设计

  1. 多节点部署

    • 使用 DaemonSet 在多个节点部署 Ingress Controller
    • 配合外部负载均衡器(如 HAProxy、F5)实现入口流量分发
  2. 节点亲和性与污点

    controller:
      nodeSelector:
        kubernetes.io/role: ingress-node  # 专用Ingress节点
      tolerations:
        - key: "ingress-node"
          operator: "Exists"
          effect: "NoSchedule"
    
  3. 会话保持

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: sticky-session
      annotations:
        nginx.ingress.kubernetes.io/affinity: "cookie"
        nginx.ingress.kubernetes.io/session-cookie-name: "route"
        nginx.ingress.kubernetes.io/session-cookie-expires: "86400"
        nginx.ingress.kubernetes.io/session-cookie-max-age: "86400"
    spec:
      # 配置规则...
    

10.2 安全加固措施

  1. 网络策略控制

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: ingress-nginx-network-policy
      namespace: ingress-nginx
    spec:
      podSelector:
        matchLabels:
          app.kubernetes.io/name: ingress-nginx
      ingress:
        - from:
            - ipBlock:
                cidr: 10.0.0.0/8  # 允许集群内部访问
            - namespaceSelector:
                matchLabels:
                  kubernetes.io/metadata.name: kube-system
          ports:
            - protocol: TCP
              port: 80
            - protocol: TCP
              port: 443
    
  2. 防止恶意请求

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: security-ingress
      annotations:
        nginx.ingress.kubernetes.io/security-block-sqli: "true"  # 阻止SQL注入
        nginx.ingress.kubernetes.io/security-block-xss: "true"   # 阻止XSS攻击
        nginx.ingress.kubernetes.io/modsecurity-snippet: |
          SecRuleEngine On
          SecRequestBodyAccess On
    spec:
      # 配置规则...
    

10.3 监控与告警方案

  1. Prometheus 监控配置

    # 通过configMap启用Prometheus指标
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-configuration
      namespace: ingress-nginx
    data:
      enable-ssl-passthrough: "true"
      metrics-allow-ips: "0.0.0.0/0"  # 允许所有IP访问指标
    
  2. Grafana 仪表盘

    • 导入 Nginx Ingress 官方仪表盘(ID: 3593)
    • 监控指标包括:
      • 请求量、错误率、延迟
      • 后端服务健康状态
      • 连接数、资源使用情况
  3. 告警规则示例

    # Prometheus告警规则
    groups:
    - name: ingress-nginx-alerts
      rules:
      - alert: IngressHighErrorRate
        expr: nginx_ingress_controller_requests{status_code=~"5.."} / nginx_ingress_controller_requests_total > 0.05
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Ingress错误率过高"
          description: "错误率超过5%,请检查后端服务"
    

十一、实战案例:电商平台服务发布

11.1 架构需求

  • 前端门户:www.ecommerce.com,使用 HTTPS
  • 用户服务:api.ecommerce.com/user,需要基本认证
  • 商品服务:api.ecommerce.com/product,支持灰度发布
  • 订单服务:api.ecommerce.com/order,需 URL 重写

11.2 完整配置实现

11.2.1 前端门户 Ingress
# frontend-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: frontend-ssl
  namespace: ecommerce
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"  # 强制HTTPS
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    nginx.ingress.kubernetes.io/proxy

11.2.2 前端门户 Ingress
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
spec:
  tls:
  - hosts:
    - www.ecommerce.com
    secretName: frontend-tls  # 前端HTTPS证书Secret
  rules:
  - host: www.ecommerce.com
    http:
      paths:
      - backend:
          service:
            name: frontend-svc
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific
11.2.3 用户服务 Ingress(带认证)
# user-service-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: user-service
  namespace: ecommerce
  annotations:
    nginx.ingress.kubernetes.io/auth-realm: "User Service Authentication"
    nginx.ingress.kubernetes.io/auth-secret: "user-auth"  # 用户认证Secret
    nginx.ingress.kubernetes.io/auth-type: "basic"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "10"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "30"
spec:
  rules:
  - host: api.ecommerce.com
    http:
      paths:
      - backend:
          service:
            name: user-svc
            port:
              number: 8080
        path: /user
        pathType: Prefix
11.2.4 商品服务 Ingress(灰度发布)
# product-service-canary.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: product-service-canary
  namespace: ecommerce
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "20"  # 20%流量到灰度版本
    nginx.ingress.kubernetes.io/canary-by-header: "X-User-Type"
    nginx.ingress.kubernetes.io/canary-by-header-value: "VIP"  # VIP用户访问灰度版本
spec:
  rules:
  - host: api.ecommerce.com
    http:
      paths:
      - backend:
          service:
            name: product-svc-canary
            port:
              number: 8080
        path: /product
        pathType: Prefix
11.2.5 订单服务 Ingress(URL 重写)
# order-service-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: order-service
  namespace: ecommerce
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /api$2  # 重写路径为/api开头
spec:
  rules:
  - host: api.ecommerce.com
    http:
      paths:
      - backend:
          service:
            name: order-svc
            port:
              number: 8080
        path: /order(/|$)(.*)
        pathType: ImplementationSpecific
11.2.6 创建证书与认证 Secret
# 生成前端HTTPS证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout frontend.tls.key -out frontend.tls.crt -subj "/CN=www.ecommerce.com"

# 创建TLS Secret
kubectl create secret tls frontend-tls \
  --cert=frontend.tls.crt --key=frontend.tls.key -n ecommerce

# 创建用户认证文件
htpasswd -c user.auth admin
htpasswd -b user.auth developer dev123

# 创建认证Secret
kubectl create secret generic user-auth \
  --from-file=user.auth -n ecommerce

11.3 部署与验证流程

  1. 部署服务

    # 部署前端服务
    kubectl apply -f frontend-deployment.yaml -n ecommerce
    
    # 部署用户服务
    kubectl apply -f user-service-deployment.yaml -n ecommerce
    
    # 部署商品服务(包括灰度版本)
    kubectl apply -f product-service-deployment.yaml -n ecommerce
    kubectl apply -f product-service-canary-deployment.yaml -n ecommerce
    
    # 部署订单服务
    kubectl apply -f order-service-deployment.yaml -n ecommerce
    
  2. 应用 Ingress 配置

    kubectl apply -f frontend-ingress.yaml -n ecommerce
    kubectl apply -f user-service-ingress.yaml -n ecommerce
    kubectl apply -f product-service-canary.yaml -n ecommerce
    kubectl apply -f order-service-ingress.yaml -n ecommerce
    
  3. 验证访问

    • 前端门户:https://www.ecommerce.com(应显示前端页面)
    • 用户服务:http://api.ecommerce.com/user(应弹出认证框)
    • 商品服务灰度测试:
      # 普通用户访问(应返回稳定版本)
      curl http://api.ecommerce.com/product
      # VIP用户访问(通过Header指定)
      curl -H "X-User-Type: VIP" http://api.ecommerce.com/product
      
    • 订单服务:http://api.ecommerce.com/order/list(应重写为/api/list并访问订单服务)

十二、Ingress Nginx 与其他组件集成

12.1 与 Cert-Manager 集成自动签发证书

12.1.1 安装 Cert-Manager
# 添加Cert-Manager仓库
helm repo add jetstack https://charts.jetstack.io
helm repo update

# 安装Cert-Manager
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.11.0 \
  --set installCRDs=true
12.1.2 配置 Let's Encrypt 签发证书
# cluster-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod-key
    solvers:
    - http01:
        ingress:
          class: nginx
12.1.3 Ingress 中使用自动签发证书
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: frontend-ssl-auto
  namespace: ecommerce
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"  # 引用ClusterIssuer
spec:
  tls:
  - hosts:
    - www.ecommerce.com
    secretName: www-ecommerce-com-tls  # 自动生成的证书Secret
  rules:
  - host: www.ecommerce.com
    http:
      paths:
      - backend:
          service:
            name: frontend-svc
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific

12.2 与 Helm Chart 集成管理 Ingress

12.2.1 自定义 Helm Chart 结构
my-ingress-chart/
├── Chart.yaml
├── values.yaml
├── templates/
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── deployment.yaml
│   └── secret.yaml
└── README.md
12.2.2 动态生成 Ingress 配置
# templates/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ .Chart.Name }}
  namespace: {{ .Values.namespace }}
  annotations:
    {{- if .Values.ingress.tls.enabled }}
    kubernetes.io/ingress.class: "nginx"
    {{- if .Values.ingress.certManager.enabled }}
    cert-manager.io/cluster-issuer: "{{ .Values.ingress.certManager.issuer }}"
    {{- end }}
    {{- end }}
    {{- range $key, $value := .Values.ingress.annotations }}
    {{ $key }}: {{ $value | quote }}
    {{- end }}
spec:
  {{- if .Values.ingress.tls.enabled }}
  tls:
  - hosts:
    - {{ .Values.ingress.host }}
    secretName: {{ .Values.ingress.tls.secretName }}
  {{- end }}
  rules:
  - host: {{ .Values.ingress.host }}
    http:
      paths:
      - backend:
          service:
            name: {{ .Chart.Name }}
            port:
              number: {{ .Values.service.port }}
        path: /
        pathType: ImplementationSpecific

十三、Ingress Nginx 的未来发展与替代方案

13.1 Ingress Nginx 的演进方向

  1. 与 Gateway API 集成

    • Gateway API 是 Kubernetes 下一代网络 API,提供更灵活的流量管理能力
    • Ingress Nginx 计划支持 Gateway API,逐步替代现有的 Ingress 资源
  2. 性能优化

    • 支持更多内核级优化(如 eBPF)
    • 增强流式处理能力,优化长连接场景
  3. 安全增强

    • 内置 WAF 规则升级
    • 支持更多认证协议(如 OIDC、JWT)

13.2 替代方案对比

方案 特点 适用场景
Ingress Nginx 官方维护,功能全面,社区活跃,支持七层流量管理 大多数 Kubernetes 服务发布场景
Traefik 自动服务发现,支持动态配置,适合微服务架构 快速迭代的开发团队
Istio 服务网格,提供流量管理、安全、可观测性等完整功能 复杂微服务架构,需要深度流量控制
Kong 基于 NGINX 的 API 网关,支持插件扩展,适合 API 管理 大型企业 API 网关场景
APISIX 云原生 API 网关,支持热加载、多集群管理,性能优越 高并发、多集群部署场景

13.3 技术选型建议

  1. 中小型应用

    • 首选 Ingress Nginx,配置简单,社区支持好,满足基本流量转发需求
  2. 复杂微服务架构

    • Ingress Nginx 作为入口网关,配合 Istio 实现内部服务流量管理
  3. API 管理需求

    • 考虑 Kong 或 APISIX,提供更完善的 API 治理功能
  4. 边缘计算场景

    • Traefik 轻量级特性更适合边缘节点资源有限的环境

你可能感兴趣的:(k8s)