Kubernetes HTTPS迁移:Ingress到GatewayAPI实战

从 Ingress 到 Gateway API:Web 应用 HTTPS 迁移实战

在 Kubernetes 集群中,Ingress 作为服务暴露的经典方案,曾长期支撑着 Web 应用的外部访问需求。但随着业务复杂度提升,Ingress 的局限性逐渐凸显 ------ 角色边界模糊、路由能力单一、扩展依赖特定控制器,这些问题促使 Kubernetes 社区推出了Gateway API这一下一代流量管理标准。本文将以 "Web 应用从 Ingress 迁移到 Gateway API 并保持 HTTPS 访问" 为核心,拆解迁移所需的关键知识点,提供 step-by-step 实战指南,并附上可直接下载使用的操作文档,助力团队快速落地。

一、为什么要从 Ingress 迁移到 Gateway API?

在动手迁移前,我们先明确 "迁移的价值"------ 理解 Ingress 的痛点与 Gateway API 的优势,才能更好地把控迁移过程。

|------|----------------------------------------------------------|-------------------------------------------------------------------------|
| 维度 | Ingress 痛点 | Gateway API 优势 |
| 角色分离 | 集群管理员与应用开发者需共同修改 Ingress 对象,权限混乱 | 清晰分离三角色:- 基础设施提供者(管 GatewayClass)- 集群管理员(管 Gateway)- 应用开发者(管 HTTPRoute) |
| 路由能力 | 仅支持 Host/Path 匹配,复杂场景需依赖注解(如 Nginx Ingress 的 rewrite 注解) | 原生支持 Header/Query 匹配、权重分流、重定向,配置结构化无注解依赖 |
| 扩展性 | 功能扩展绑定特定 Ingress 控制器(如 Istio 与 Nginx 规则不通用) | 标准化 API,支持多控制器(Nginx/Istio/Traefik 均兼容),无厂商锁定 |
| 故障排查 | 注解配置无类型校验,错误需到控制器日志中排查 | 基于 CRD Schema 校验,配置错误直接返回 API 报错,事件日志清晰 |

简单来说:如果把流量管理比作 "商场客流引导",Ingress 像一张手写的引导牌,而 Gateway API 则是一套 "引导牌设计标准 + 专人分工体系"------ 更规范、更灵活、更易维护。

二、迁移前必须掌握的核心概念

要顺利完成迁移,需先理清 Gateway API 的三大核心资源,以及它们与 Ingress 资源的对应关系:

|------------------|------------------------------------------|-------------------------------------------|
| Gateway API 资源 | 作用说明 | 对应 Ingress 的功能模块 |
| GatewayClass | 定义 "流量管理方案的类型"(如 nginx/istio),由基础设施提供者创建 | Ingress 控制器类型(如 nginx-ingress-controller) |
| Gateway | 定义 "流量入口"(端口、域名、TLS 配置),由集群管理员创建 | Ingress 的spec.tls+spec.rules.host+ 侦听端口 |
| HTTPRoute | 定义 "流量路由规则"(路径匹配、后端服务),由应用开发者创建 | Ingress 的spec.rules.http.paths |

本次迁移场景中,集群已预装nginx类型的 GatewayClass(无需我们创建),我们只需聚焦 "Gateway+HTTPRoute" 的配置,以及与原有 Ingress 的参数对齐。

三、实战迁移步骤(附配置示例)

本次迁移的核心目标是:1:1 复刻原有 Ingress 的 HTTPS 配置与路由规则,确保业务无感知切换。以下步骤基于 "现有 Ingress 名为 web" 的场景展开。

前提条件确认

在开始前,先执行以下命令,收集原有 Ingress 的关键配置(后续迁移需用到):

复制代码
复制代码
# 1. 查看Ingress的TLS配置(获取证书Secret名称)

kubectl get ingress web -o jsonpath='{.spec.tls[0].secretName}{"\n"}'

# 2. 查看Ingress的路由规则(获取后端服务名与端口)

kubectl get ingress web -o jsonpath='{.spec.rules[0].http.paths[0].backend.service.name}{":"}{.spec.rules[0].http.paths[0].backend.service.port.number}{"\n"}'

# 3. 确认GatewayClass存在(集群已预装nginx)

kubectl get gatewayclasses.gateway.networking.k8s.io nginx

假设上述命令返回结果为:

  • TLS 证书 Secret:web-tls-secret
  • 后端服务:web-service:80
  • GatewayClass 状态:Ready

步骤 1:创建 web-gateway(复刻 Ingress 的 HTTPS 入口)

Gateway 资源的核心是 "复刻 Ingress 的 TLS 配置与侦听规则",配置文件如下(保存为web-gateway.yaml):

复制代码
复制代码
apiVersion: gateway.networking.k8s.io/v1beta1 # 若集群支持v1可替换为v1

kind: Gateway

metadata:

name: web-gateway # 任务要求的Gateway名称

namespace: default # 【需修改】替换为原有Ingress的命名空间

spec:

gatewayClassName: nginx # 集群已有的GatewayClass名称

listeners: # 对应Ingress的侦听配置

- name: https-listener # 自定义侦听器名称,便于识别

protocol: HTTPS # 保持HTTPS协议,与Ingress一致

port: 443 # 标准HTTPS端口,若Ingress用其他端口需同步修改

hostname: gateway.web.k8s.local # 任务要求的主机名

tls: # 复刻Ingress的TLS配置

mode: Terminate # TLS终止模式(在Gateway层解密,后端用HTTP)

certificateRefs: # 引用原有TLS证书Secret

- kind: Secret

name: web-tls-secret # 替换为步骤1获取的证书Secret名称

namespace: default # 【需修改】与Secret所在命名空间一致

执行创建命令:

复制代码

kubectl apply -f web-gateway.yaml

验证 Gateway 状态:确保状态为Ready(表示入口已就绪)

复制代码
复制代码
kubectl get gateways.gateway.networking.k8s.io web-gateway -o wide

# 预期输出:

# NAME CLASS ADDRESS READY AGE

# web-gateway nginx 192.168.56.10 True 2m

步骤 2:创建 web-route(复刻 Ingress 的路由规则)

HTTPRoute 资源用于 "定义流量如何从 Gateway 转发到后端服务",需 1:1 复刻原有 Ingress 的路径匹配与后端映射,配置文件如下(保存为web-route.yaml):

复制代码
复制代码
apiVersion: gateway.networking.k8s.io/v1beta1 # 与Gateway版本保持一致

kind: HTTPRoute

metadata:

name: web-route # 任务要求的HTTPRoute名称

namespace: default # 【需修改】与Gateway、Ingress同命名空间

spec:

parentRefs: # 绑定到步骤1创建的Gateway

- name: web-gateway

namespace: default # 【需修改】与Gateway所在命名空间一致

hostnames: # 仅处理指定主机名的流量,与Gateway对齐

- gateway.web.k8s.local

rules: # 复刻Ingress的路由规则

- matches: # 路径匹配条件(与Ingress的path一致)

- path:

type: PathPrefix # 匹配方式,Ingress默认是PathPrefix

value: / # 匹配所有路径(若Ingress有特定路径需修改,如/apis)

backendRefs: # 转发到原有后端服务

- name: web-service # 步骤1获取的后端服务名

port: 80 # 步骤1获取的后端服务端口

namespace: default # 【需修改】与后端服务同命名空间

执行创建命令:

复制代码
复制代码
kubectl apply -f web-route.yaml

验证 HTTPRoute 状态:确保READY为True(表示路由规则已生效)

复制代码
复制代码
kubectl get httproutes.gateway.networking.k8s.io web-route

# 预期输出:

# NAME HOSTNAMES PARENTS READY AGE

# web-route ["gateway.web.k8s.local"] ["web-gateway"] True 1m

步骤 3:测试 Gateway API 配置有效性

迁移是否成功,关键看业务能否正常访问。使用任务提供的curl命令测试 HTTPS 访问:

复制代码
复制代码
# -L:自动处理重定向;-k:忽略自签名证书(测试环境常用)

# 31443:集群NodePort端口(需与实际环境一致,可通过kubectl get svc查看nginx网关服务端口)

curl -Lk https://gateway.web.k8s.local:31443

预期结果:返回 Web 应用的正常响应(如 HTML 页面、JSON 数据),与迁移前通过 Ingress 访问的结果一致。

异常排查:若访问失败,执行以下命令查看问题日志:

复制代码
复制代码
# 查看Gateway事件(如证书加载失败)

kubectl describe gateway web-gateway

# 查看HTTPRoute事件(如后端服务不可达)

kubectl describe httproutes web-route

# 查看nginx Gateway控制器日志(需替换控制器Pod名)

kubectl logs -n kube-system nginx-gateway-controller-7f98d7c6b4-2xqzk

步骤 4:删除旧 Ingress 资源(完成迁移收尾)

确认 Gateway API 配置正常后,即可安全删除旧的web Ingress,避免资源冲突:

复制代码
复制代码
# 删除原有Ingress

kubectl delete ingress web -n default # 【需修改】替换为Ingress所在命名空间

# 验证删除结果

kubectl get ingress web -n default

# 预期输出:Error from server (NotFound): ingresses.networking.k8s.io "web" not found

四、可下载操作文档(完整版)

为方便团队内部共享与落地,我将上述步骤整理为Markdown 格式的操作手册 ,可直接下载保存为ingress-to-gateway-migration.md文件,适配不同环境的参数修改需求。

下载文档内容框架

复制代码
复制代码
# Ingress迁移到Gateway API操作手册

## 一、文档信息

| 项目 | 内容 |

|--------------|----------------------------------------|

| 文档版本 | v1.0 |

| 适用集群版本 | Kubernetes v1.24+、Gateway API v1beta1/v1 |

| 迁移目标 | Web应用从Ingress迁移到Gateway API,保持HTTPS访问 |

| 维护人 | 【填写维护人/团队】 |

## 二、前提条件清单

1. 集群已安装Gateway API CRDs(执行`kubectl api-resources | grep gateway`验证);

2. 存在名为`nginx`的GatewayClass(执行`kubectl get gatewayclasses nginx`验证);

3. 收集原有`web` Ingress的关键信息(填写下表):

| 信息类型 | 取值(需手动填写) |

|------------------|--------------------|

| Ingress命名空间 | |

| TLS证书Secret名称| |

| 后端服务名:端口 | |

| Ingress侦听端口 | |

## 三、详细操作步骤

### 步骤1:创建web-gateway

1. 编写配置文件`web-gateway.yaml`:

```yaml

apiVersion: gateway.networking.k8s.io/v1beta1

kind: Gateway

metadata:

name: web-gateway

namespace: 【替换为Ingress命名空间】

spec:

gatewayClassName: nginx

listeners:

- name: https-listener

protocol: HTTPS

port: 【替换为Ingress侦听端口】

hostname: gateway.web.k8s.local

tls:

mode: Terminate

certificateRefs:

- kind: Secret

name: 【替换为TLS证书Secret名称】

namespace: 【替换为Secret命名空间】
  1. 执行创建命令:kubectl apply -f web-gateway.yaml;
  1. 验证:kubectl get gateways web-gateway -o wide,确保READY为True。

步骤 2:创建 web-route

(省略,与前文步骤 2 一致,含可编辑占位符)

步骤 3:测试访问

(省略,含 curl 命令与异常排查)

步骤 4:删除旧 Ingress

(省略,含删除命令与验证)

四、注意事项

  1. 生产环境建议 "先并行运行 Gateway 与 Ingress,验证正常后再删除 Ingress";
  1. 若后端服务有多个副本,HTTPRoute 支持通过weight字段配置流量权重;
  1. 迁移前备份 Ingress 配置:kubectl get ingress web -o yaml > web-ingress-backup.yaml。

五、附录:常用命令

|-----------------|------------------------------------------|
| 操作需求 | 命令 |
| 查看 Gateway 事件 | kubectl describe gateway web-gateway |
| 查看 HTTPRoute 规则 | kubectl get httproutes web-route -o yaml |
| 查看网关服务端口 | `kubectl get svc -n kube-system |

复制代码

下载方式

  1. 复制上述框架内容,粘贴到本地文本编辑器;
  1. 将文件保存为ingress-to-gateway-migration.md
  1. 根据实际环境修改文档中的【】占位符内容,即可直接使用。

五、迁移后最佳实践

  1. 权限管控:基于 Gateway API 的角色分离特性,给集群管理员授予Gateway创建权限,给应用开发者仅授予HTTPRoute创建权限,避免越权操作;
  1. 监控告警:为 Gateway 与 HTTPRoute 配置监控(如 Prometheus+Grafana),监控指标包括gateway_ready(入口就绪状态)、httproute_rule_matches(路由匹配次数),异常时触发告警;
  1. 灰度扩展:后续若需新增功能(如基于 Header 的 A/B 测试),可直接在 HTTPRoute 中添加matches.header规则,无需修改 Gateway,实现 "无侵入扩展"。

六、总结

从 Ingress 到 Gateway API 的迁移,不仅是 "资源类型的替换",更是 "流量管理体系的升级"。通过本文的知识点解析与实战步骤,你可以在保持业务不中断的前提下,完成迁移落地;而可下载的操作文档,也能帮助团队快速标准化迁移流程。随着 Gateway API 的不断成熟,它将成为 Kubernetes 流量管理的主流方案 ------ 掌握这一技能,能让你的集群管理更规范、更灵活。

复制代码
相关推荐
BullSmall17 分钟前
Sonarqube9.9 docker 镜像启动后 conf 下的配置文件没有了
docker·容器·eureka
hay_lee2 小时前
Kubernetes StatefulSet:OrderedReady 极简指南
云原生·容器·kubernetes
晚风吹长发2 小时前
Docker使用——Docker容器及相关命令
linux·运维·服务器·docker·容器·架构
ShiXZ2132 小时前
Docker Compose 安装与配置指南
运维·docker·容器
BullSmall3 小时前
Anolis OS 8.10 Docker 部署 SonarQube 9.9 完整教程
运维·docker·容器
成为你的宁宁4 小时前
【K8s HPA 水平扩缩容】
kubernetes·hpa
欢醉4 小时前
k8s调度容器失败The node had condition: [DiskPressure]
kubernetes·springcloud
生活爱好者!20 小时前
我把NAS当作下载机,docker一键部署qb
运维·docker·容器
Hui Baby21 小时前
K8S使用CRD和控制器简单应用
云原生·容器·kubernetes
做个文艺程序员1 天前
Linux第22篇:用Docker容器化你的Java SaaS应用:一次构建,随处运行
java·docker·容器