跳到主要内容

高可用

APISIX Ingress Controller 和 API7 Ingress Controller 均通过 Kubernetes 领导者选举支持高可用。运行多个副本时,如果当前领导者不可用,备用副本可以接管,并继续将 Kubernetes 资源变更同步到网关。

了解可用性模型

Ingress Controller 副本以主备模式运行。只有持有领导者选举 Lease 的副本会协调资源并将配置同步到网关。其他副本保持就绪,随时准备获取 Lease;它们不会提高协调吞吐量。

网关流量不会经过 Ingress Controller。如果领导者不可用,网关可以继续使用最近一次应用的配置提供服务,但在另一个副本成为领导者之前,新增或变更的 Kubernetes 资源不会同步。

此部署方式只保护 Ingress Controller 的协调过程。请根据各自的可用性要求配置网关、Kubernetes 控制面,以及 API7 控制面或 APISIX Admin API。

配置多个副本

至少部署两个控制器副本。两种控制器都提供独立 Helm Chart,并使用相同的副本配置路径:

Ingress Controller独立 Helm Chart副本配置路径
APISIX Ingress Controllerapisix/apisix-ingress-controllerdeployment.replicas
API7 Ingress Controllerapi7/api7-ingress-controllerdeployment.replicas

通过任一控制器的独立 Chart 安装时,在 values 文件中添加以下配置:

values.yaml
deployment:
replicas: 2

也可以通过 apisix/apisix Chart 安装 APISIX Ingress Controller。使用这种安装方式时,请将相同的 deployment 配置嵌套在 ingress-controller 下:

values.yaml
ingress-controller:
deployment:
replicas: 2

这些路径也可以作为命令行覆盖项传入。使用任一控制器的独立 Chart 时,传入 --set deployment.replicas=2。通过 apisix/apisix Chart 安装 APISIX Ingress Controller 时,传入 --set ingress-controller.deployment.replicas=2

使用 helm upgrade 应用 values;如果由 GitOps 控制器管理此发布,请更新源仓库。有关安装和 values 管理的说明,请参阅 Helm Chart

跨故障域分布副本

如果未定义部署位置规则,多个副本仍可能被调度到同一节点。请使用 Pod 反亲和性,避免单个节点故障导致所有控制器副本停止运行。

以下示例要求通过任一控制器独立 Chart 安装的两个副本运行在不同节点上:

values.yaml
deployment:
replicas: 2
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app.kubernetes.io/instance: <release-name>
app.kubernetes.io/name: <controller-app-name>
topologyKey: kubernetes.io/hostname

<release-name> 替换为 Helm 发布名称。根据安装方式设置 <controller-app-name>

  • APISIX Ingress Controller 独立 Chart:apisix-ingress-controller
  • API7 Ingress Controller 独立 Chart:api7-ingress-controller
  • 通过 apisix/apisix Chart 安装的 APISIX Ingress Controller:ingress-controller

如果覆盖了 Chart 的标签,请使用渲染后控制器 Deployment 中的标签。

如果通过 apisix/apisix Chart 安装 APISIX Ingress Controller,请将 deployment 块嵌套在 ingress-controller 下。

必需的 Pod 反亲和性会让副本分布在不同节点上,但如果集群没有足够的合格节点,某个副本会保持 Pending 状态。请确认集群容量充足。在多可用区集群中,还可以使用以 topology.kubernetes.io/zone 为键的拓扑分布约束,将副本分布到不同可用区。

设置资源请求和限制,使调度器在负载期间或节点恢复时也能可靠地部署控制器。对于 APISIX Ingress Controller,deployment.resources 同时适用于控制器和 ADC 容器。对于 API7 Ingress Controller,请分别为控制器容器配置 deployment.resources,为 ADC 容器配置 adc.resources

验证中断预算的渲染结果

启用 Chart 的 podDisruptionBudget 选项前,请使用预期 values 运行 helm template,确认渲染成功,并验证输出中包含预期的 PodDisruptionBudget。Chart 模板和支持的 values 可能独立于 Ingress Controller 发生变化,因此 values 文件中存在某个选项并不能保证它能成功渲染。

如果 Chart 无法渲染 PodDisruptionBudget,请保持禁用该选项。执行计划内维护时,请分阶段排空或升级节点,并确认始终有一个控制器副本处于 Ready 状态。

PodDisruptionBudget 只限制自愿中断,不能替代多个副本或跨故障域部署。

配置领导者选举

Helm 安装默认会配置并启用领导者选举。通常应保留渲染后的设置。

同一逻辑控制器部署中的所有副本必须使用相同的领导者选举 ID。如果有意在同一命名空间运行多个独立控制器部署,请为每个部署设置唯一 ID,并将其配置为协调互不重叠的资源集合。否则,这些部署可能相互抑制或冲突。

直接管理 config.yaml 时,请使用 snake_case 字段名。以下示例使用有效的时间配置:

config.yaml
leader_election_id: apisix-ingress-gateway-leader
leader_election:
lease_duration: 30s
renew_deadline: 20s
retry_period: 2s
disable: false

部署多个副本时,请保持启用领导者选举。

实际生效的值来自运行中 Pod 挂载的 config.yaml,可能与控制器内置默认值和 Helm 输入值都不同。通过 Helm 应用时间覆盖项后,请检查挂载的文件,确认其中包含预期的 snake_case 字段和值。如果字段缺失或以不同名称渲染,控制器会使用其内置时间值。请按照查看渲染后的控制器配置检查实际生效的文件。

实际生效的 lease_duration 是非自愿故障转移时间的主要上限。最后一次成功续约后,已就绪的备用副本通常会在 Lease 到期后接管,此外还需加上一次获取重试间隔和 Kubernetes API 延迟。Pod 调度时间会影响 Deployment 恢复备用容量的速度;如果另一个副本已处于 Ready 状态,则不会延迟接管。

缩短这些值可以缩短故障转移间隔,但也会增加 Lease 流量,并提高 API Server 或网络延迟期间发生领导者变更的风险。请在具有代表性的故障条件下测试所有调整。控制器要求 lease_duration 大于 renew_deadline,且 renew_deadline 大于 retry_period 的 1.2 倍。无效组合会阻止控制器启动。

验证高可用

首先,确认 Deployment 的可用副本数符合预期,并且 Pod 运行在不同故障域:

kubectl get deployment <deployment-name> -n <namespace>
kubectl get pods -n <namespace> -o wide

如果命名空间中有许多工作负载,请在第二条命令中添加渲染后控制器 Deployment 的标签选择器。

然后确定控制器的 Lease。使用渲染后 config.yaml 中实际生效的 leader_election_id 作为 <leader-election-id>。请列出 Lease 资源,不要假设生成的名称:

kubectl get leases -n <namespace>

检查控制器 Lease,记录当前持有者、续约时间和转换次数:

kubectl get lease <leader-election-id> -n <namespace> -o yaml

相关字段为 spec.holderIdentityspec.renewTimespec.leaseTransitions

仅在非生产环境或经过批准的维护窗口中测试故障转移。在一个终端中监视 Lease

kubectl get lease <leader-election-id> -n <namespace> --watch

在另一个终端中,根据 holderIdentity 解析 Pod 名称并删除领导者 Pod。该值由 Pod 名称、下划线和唯一后缀组成:

LEADER_HOLDER=$(kubectl get lease <leader-election-id> -n <namespace> \
-o jsonpath='{.spec.holderIdentity}')
kubectl delete pod "${LEADER_HOLDER%%_*}" -n <namespace>

确认 Lease 持有者发生变化、替代 Pod 进入 Ready 状态,并且 Deployment 恢复到预期副本数。直接删除 Pod 是故障模拟,不受 PodDisruptionBudget 限制。

最后,创建或更新测试路由,并通过网关发送请求。这可以确认新领导者已恢复配置同步,而不仅仅是获取了 Lease。有关完整测试路由和请求,请参阅代理请求到服务

如果 Lease 已变更,但网关配置没有更新,请参阅排查清单转换和同步问题

监控可用性

监控以下信号:

  • 控制器 Deployment 的可用副本少于预期副本数。
  • 控制器 Pod 长时间处于 Pending 状态或反复重启。
  • 领导者选举 Lease 停止续约。
  • 配置同步报告错误。

结合这些信号,可以区分调度或领导者选举故障与下游网关或控制面问题。