Kubernetes Ingress 服务发布进阶

目录

一、核心概念与原理

1. Ingress 基础概念

(1)Ingress 的定位

(2)Ingress 与其他暴露方式对比

(3)Ingress 组成与分工

2. Ingress 工作原理(以 Nginx 为例)

3. 典型流量访问链路

二、Ingress Nginx Controller 安装(Helm 方式)

1. 环境准备与工具安装

2. 核心配置文件修改(values.yaml)

3. 部署与验证命令

三、Ingress 基础使用:域名绑定服务

1. 测试服务准备

2. Ingress 配置详解(web-ingress.yaml)

3. 访问测试步骤

四、进阶功能实现与场景解析

1. 域名重定向(旧域名过渡)

场景:将旧域名 nginx.redirect.com 永久重定向到百度

2. 前后端分离路径重写(Rewrite)

场景:将 /api-a/xxx 重写为 /xxx,适配后端服务

3. SSL 配置(HTTPS 加密访问)

步骤 1:生成自签名证书(测试环境)

步骤 2:创建 Secret 存储证书

步骤 3:Ingress 配置(ingress-ssl.yaml)

4. 基本认证(密码保护)

步骤 1:安装工具并创建密码文件

步骤 2:创建 Secret 存储密码文件

步骤 3:Ingress 配置(ingress-with-auth.yaml)

5. 灰度发布(金丝雀发布)

场景:逐步将流量从 V1 版本切换到 V2 版本,降低发布风险

步骤 1:部署生产环境 V1 版本

步骤 2:创建 V1 版本 Ingress(v1-ingress.yaml)

步骤 3:部署灰度环境 V2 版本

步骤 4:创建灰度 Ingress(canary-v2.yaml)

步骤 5:流量测试与权重调整

五、核心要点总结


一、核心概念与原理

1. Ingress 基础概念

(1)Ingress 的定位
  • 七层负载均衡中枢:在 Kubernetes 架构中,Ingress 作为七层网络流量的调度核心,基于 HTTP/HTTPS 协议实现外部请求到集群内 Service 的精准转发。与传统暴露方式相比,它通过域名和路径规则实现多服务共享公网 IP,解决了 NodePort 端口浪费(30000-32767 范围限制)和 LoadBalancer 依赖云服务商的问题。
  • 核心价值:提供域名访问、负载均衡、SSL 加密、路径重写等高级功能,完美适配微服务架构下多服务协同暴露的需求。
(2)Ingress 与其他暴露方式对比
方式 核心原理 典型场景 局限性
NodePort 节点端口映射(30000-32767) 测试环境快速暴露服务 端口数量有限,运维复杂度高
LoadBalancer 云服务商负载均衡器集成 公有云生产环境 依赖云平台,需额外付费
externalIPs 节点外部 IP 直接绑定 简单网络场景 无负载均衡能力,安全性低
Ingress 七层反向代理(域名 / 路径规则) 复杂微服务架构 需要部署 Ingress Controller
(3)Ingress 组成与分工
  • Ingress 对象(YAML 配置):定义流量转发规则的 API 对象,包含域名(如 nginx.test.com)、路径(如 /api)、目标 Service 映射等配置,类似 Nginx 的虚拟主机配置模板。
  • Ingress Controller(执行组件):负责解析规则并实现转发的组件,常见类型有 ingress-nginx(Kubernetes 官方维护)、Traefik 等。以 ingress-nginx 为例,它动态生成 Nginx 配置并实时更新,实现流量调度。

2. Ingress 工作原理(以 Nginx 为例)

  1. 规则监听循环
    Ingress Controller 通过 Kubernetes API Server 持续监听 Ingress 资源的创建、更新事件,例如新增一条域名转发规则时,控制器会立即感知变化。
  2. 配置动态生成
    控制器根据 Ingress 规则生成 Nginx 配置,例如将 host: nginx.test.com 映射为 Nginx 的 server_name,将路径规则转换为 location 块。
  3. 配置热加载
    生成的配置被写入容器内的 /etc/nginx/nginx.conf,并通过 nginx -s reload 命令重新加载配置,确保新规则秒级生效。
  4. 流量转发流程
    外部请求 → Ingress Controller(Nginx)→ 匹配域名 / 路径规则 → 转发至对应 Service → 到达目标 Pod。

3. 典型流量访问链路

用户浏览器输入域名(如 nginx.test.com)
↓
域名解析至 Ingress 节点公网 IP 或负载均衡器
↓
Ingress Controller 解析规则(如匹配 host: nginx.test.com)
↓
根据规则转发至对应 Service(如 nginx-service)
↓
Service 将请求分发至后端 Pod 集群

二、Ingress Nginx Controller 安装(Helm 方式)

1. 环境准备与工具安装

# 下载 Helm 3.9.4(Linux AMD64 版本)
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/  # 将 helm 命令添加到系统路径

# 添加 Ingress Nginx 官方 Helm 仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update  # 同步仓库最新图表,确保获取最新版本

关键点:Helm 是 Kubernetes 的包管理器,通过图表(Chart)简化复杂组件的部署,避免手动编写大量 YAML。

2. 核心配置文件修改(values.yaml)

controller:
  image:
    registry: registry.cn-hangzhou.aliyuncs.com  # 切换至阿里云镜像源,解决国外镜像拉取慢问题
    image: tanzu/controller
    tag: "v1.6.4"
    # 注释 digest 字段(镜像摘要),避免因网络波动导致镜像校验失败
hostNetwork: true  # 关键配置!使 Pod 共享节点网络命名空间,允许外部直接访问 Controller 所在节点端口
dnsPolicy: ClusterFirstWithHostNet  # 配合 hostNetwork,确保 Pod 域名解析正常工作
nodeSelector:
  ingress: "true"  # 节点选择器:仅部署到打有 ingress=true 标签的节点
  kubernetes.io/os: linux
kind: DaemonSet  # 部署模式为 DaemonSet,确保每个符合条件的节点运行一个 Controller 实例,提升可用性

配置说明

  • hostNetwork: true 是外部访问的必要条件,否则需通过 LoadBalancer 暴露,增加部署复杂度。
  • nodeSelector 用于指定 Controller 部署节点,避免与其他服务竞争资源。

3. 部署与验证命令

# 给目标节点打标签(例如 k8s-node01 节点)
kubectl label node k8s-node01 ingress=true

# 创建 ingress-nginx 命名空间
kubectl create ns ingress-nginx

# 安装 Ingress Nginx(. 表示当前目录的 Chart,-n 指定命名空间)
helm install ingress-nginx . -n ingress-nginx

# 验证部署状态
kubectl get po -n ingress-nginx -o wide
# 预期输出:ingress-nginx-controller-xxx 状态为 Running,IP 为节点 IP

常见问题

  • 若镜像拉取失败,检查国内镜像配置是否正确,可尝试手动拉取镜像验证网络。
  • 若 Pod 无法启动,查看事件 kubectl describe po -n ingress-nginx,常见原因为节点标签不匹配。

三、Ingress 基础使用:域名绑定服务

1. 测试服务准备

# 创建测试命名空间
kubectl create ns study-ingress

# 部署 Nginx 应用(版本 1.7.9)
kubectl create deployment nginx --image=nginx:1.7.9 -n study-ingress

# 暴露为 ClusterIP 类型 Service(默认端口 80)
kubectl expose deployment nginx --port=80 -n study-ingress

说明

  • Service 是 Ingress 的转发目标,通过 --port=80 暴露部署的 Nginx 服务。
  • 此时 Service 仅在集群内部可访问,需通过 Ingress 暴露到外部。

2. Ingress 配置详解(web-ingress.yaml)

apiVersion: networking.k8s.io/v1  # API 版本,v1 为稳定版本
kind: Ingress  # 资源类型:Ingress
metadata:
  name: nginx-ingress  # Ingress 名称,需在命名空间内唯一
  namespace: study-ingress  # 所属命名空间,与服务一致
spec:
  ingressClassName: nginx  # 指定使用 nginx 类型的 Ingress Controller
  rules:
  - host: nginx.test.com  # 外部访问域名,需提前配置 DNS 解析
    http:
      paths:
      - path: /  # 匹配根路径(如 http://nginx.test.com/)
        pathType: ImplementationSpecific  # 路径匹配方式,由控制器决定(Nginx 中类似 Prefix)
        backend:
          service:
            name: nginx  # 目标 Service 名称
            port:
              number: 80  # Service 端口号

路径类型对比

  • Exact:精确匹配(如 /api 仅匹配 /api,不匹配 /api/)。
  • Prefix:前缀匹配(如 /api/ 匹配 /api/user,但不匹配 /apiuser)。
  • ImplementationSpecific:由控制器实现,Nginx 中默认按 Prefix 处理。

3. 访问测试步骤

  1. 本地域名解析
    修改 /etc/hosts 文件,添加 192.168.10.102 nginx.test.com(替换为 Ingress 节点 IP)。
  2. 浏览器访问
    输入 http://nginx.test.com,应看到 Nginx 默认页面 Welcome to nginx!,证明 Ingress 规则生效。

四、进阶功能实现与场景解析

1. 域名重定向(旧域名过渡)

场景:将旧域名 nginx.redirect.com 永久重定向到百度
# redirect.yaml 配置文件
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-redirect
  namespace: study-ingress
  annotations:
    # 关键注解:设置永久重定向目标(308 状态码)
    nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.redirect.com  # 旧域名,访问此域名时触发重定向
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: nginx
            port:
              number: 80

测试验证
访问 http://nginx.redirect.com,浏览器会自动跳转到百度,地址栏显示 https://www.baidu.com,状态码为 308(永久重定向)。

2. 前后端分离路径重写(Rewrite)

场景:将 /api-a/xxx 重写为 /xxx,适配后端服务
# rewirte.yaml 配置文件
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: backend-api
  namespace: study-ingress
  annotations:
    # 重写规则:将匹配到的路径替换为 /$2($2 为正则表达式第二个捕获组)
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.test.com
    http:
      paths:
      - path: /api-a(/|$)(.*)  # 正则匹配:/api-a 或 /api-a/ 开头的路径
        pathType: ImplementationSpecific
        backend:
          service:
            name: backend-api  # 后端 Service 名称
            port:
              number: 80

正则解析

  • (/|$):匹配路径末尾的 / 或路径结束(确保 /api-a 和 /api-a/ 都能匹配)。
  • (.*):匹配任意字符,作为第二个捕获组($2),例如 /api-a/user 中 $2 为 /user
  • rewrite-target: /$2:将请求路径重写为 /user,转发至后端服务。

3. SSL 配置(HTTPS 加密访问)

步骤 1:生成自签名证书(测试环境)
# 生成 2048 位 RSA 密钥对和自签名证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout tls.key -out tls.crt -subj "/CN=nginx.test.com"

参数说明

  • -x509:生成自签名证书,而非证书请求(CSR)。
  • -nodes:不加密私钥(测试用,生产环境需移除该参数并设置密码)。
  • -subj "/CN=nginx.test.com":证书绑定的域名,必须与 Ingress 配置中的 host 一致。
步骤 2:创建 Secret 存储证书
# 创建 TLS 类型 Secret,存储证书和私钥
kubectl create secret tls ca-secret \
  --cert=tls.crt --key=tls.key -n study-ingress
步骤 3: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:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: nginx
            port:
              number: 80
  tls:
  - hosts:
    - nginx.test.com  # 必须与证书 CN 一致
    secretName: ca-secret  # 引用创建的 Secret

测试说明
访问 https://nginx.test.com,浏览器会提示证书不安全(自签名特性),点击 “继续访问” 可看到 Nginx 页面,地址栏显示 HTTPS 图标。

4. 基本认证(密码保护)

步骤 1:安装工具并创建密码文件
yum -y install httpd  # 安装 httpd 以获取 htpasswd 工具
htpasswd -c auth zhangsan  # 创建用户 zhangsan,-c 表示创建新密码文件

交互说明
执行命令后需输入两次密码,密码会以加密形式存储在 auth 文件中,例如:zhangsan:$apr1$YpX...$123456

步骤 2:创建 Secret 存储密码文件
# 创建通用 Secret,存储密码文件
kubectl create secret generic basic-auth \
  --from-file=auth -n study-ingress
步骤 3: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: "请输入用户名密码"  # 认证弹窗提示文本
    nginx.ingress.kubernetes.io/auth-secret: basic-auth  # 引用密码 Secret
    nginx.ingress.kubernetes.io/auth-type: basic  # 认证类型:基本认证
spec:
  ingressClassName: nginx
  rules:
  - host: auth.test.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: nginx
            port:
              number: 80

访问验证
访问 http://auth.test.com 会弹出认证弹窗,输入 zhangsan 和设置的密码即可访问,未认证时返回 401 Unauthorized 状态码。

5. 灰度发布(金丝雀发布)

场景:逐步将流量从 V1 版本切换到 V2 版本,降低发布风险
步骤 1:部署生产环境 V1 版本
kubectl create ns production  # 创建生产环境命名空间
kubectl create deployment canary-v1 --image=registry.cn-beijing.aliyuncs.com/dotbalo/canary:v1 -n production
kubectl expose deployment canary-v1 --port=8080 -n production  # 暴露 Service
步骤 2:创建 V1 版本 Ingress(v1-ingress.yaml)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-v1
  namespace: production
spec:
  ingressClassName: nginx
  rules:
  - host: canary.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: canary-v1
            port:
              number: 8080
步骤 3:部署灰度环境 V2 版本
kubectl create ns canary  # 创建灰度环境命名空间
kubectl create deployment canary-v2 --image=registry.cn-beijing.aliyuncs.com/dotbalo/canary:v2 -n canary
kubectl expose deployment canary-v2 --port=8080 -n canary
步骤 4:创建灰度 Ingress(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:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: canary-v2
            port:
              number: 8080
步骤 5:流量测试与权重调整
# 循环访问 10 次,观察版本分布
for i in $(seq 10); do curl -s canary.com; done
# 预期输出:约 1 次 V2(

Canary v2

),9 次 V1 # 修改流量权重为 50% kubectl edit ingress canary-v2 -n canary # 将 canary-weight 修改为 "50" # 再次测试,预期 V1 和 V2 出现次数接近 1:1

灰度原理
通过 canary-weight 配置流量比例,控制器按权重将请求分发到不同版本,实现渐进式发布,便于监控新版本稳定性。

五、核心要点总结

  1. Ingress 本质:通过规则文件(Ingress 对象)+ 控制器(Ingress Controller)实现七层流量转发,替代传统 Nginx 配置。
  2. 安装关键:使用国内镜像、开启 hostNetwork、节点打标签,确保外部可访问。
  3. 功能场景
    • 重定向:旧域名过渡;
    • Rewrite:前后端路径适配;
    • SSL:生产环境加密;
    • 认证:敏感服务保护;
    • 灰度:新版本风险控制。
  4. 注意
    • 所有配置需指定正确命名空间;
    • 测试域名需在本地 hosts 解析;
    • 生产环境用正式 SSL 证书;
    • 灰度从低权重开始逐步调整。

 

你可能感兴趣的:(kubernetes,容器,云原生)