跳到主要内容

在 Kubernetes 上部署 AISIX 网关

使用 api7/aisix Helm Chart 在 Kubernetes 集群中部署、暴露和扩缩 AISIX 网关。网关在你的环境中承载实时 AI 流量,并连接现有 AISIX Cloud 控制面以接收配置。

该 Chart 需要数据面管理器端点,以及为目标环境签发的网关证书包。连接后,网关会从控制面接收模型、调用方 API Key 和策略。

前提条件

  • 一个 Kubernetes 集群,已配置 kubectl 访问权限并安装 Helm 3。
  • 可以访问一个能够签发网关证书的 AISIX Cloud 环境。
  • 集群可以通过网络访问 AISIX Cloud 数据面管理器端点。如果使用 On-Premises,请先完成 On-Premises 安装

安装 Chart

在控制台中打开目标环境的 Data planes 视图并签发网关证书。Kubernetes (Helm) 标签页会生成以下命令,并填入你的端点和证书包。私钥只显示一次。

将证书包存储在 Secret 中,避免私钥出现在 values 文件中:

kubectl create namespace aisix

kubectl -n aisix create secret generic aisix-gateway-certificate \
--from-file=cert.pem=./cert.pem \
--from-file=key.pem=./key.pem \
--from-file=ca.pem=./ca.pem

使用同一视图中的数据面管理器端点安装 Chart:

helm repo add api7 https://charts.api7.ai
helm repo update

helm install aisix api7/aisix --namespace aisix \
--set controlPlane.baseURL=https://dp-manager.example.com:7944 \
--set controlPlane.certificate.existingSecret=aisix-gateway-certificate

网关首次上报心跳后,会出现在环境的 Data planes 视图中。每个副本会注册为独立实例,并共享同一个证书。

查看 Chart 接受的所有值:

helm show values api7/aisix

Chart 源码发布在 api7/api7-helm-chart 仓库中。

暴露网关

代理 Service 默认是在端口 80 上运行的 ClusterIP。如需通过云负载均衡器发布:

service:
type: LoadBalancer
port: 80
# 保留客户端源 IP,按模型配置的 IP 允许列表会使用该地址进行匹配。
externalTrafficPolicy: Local

网关默认在容器内绑定端口 3000。Service 可以暴露端口 80443,无需让进程绑定特权容器端口。

只有当网关必须直接监听某个低于 1024 的端口时,才在容器内绑定该端口。发布的镜像以非 root 用户 UID 10001 运行,网关二进制文件具有生效的 CAP_NET_BIND_SERVICE 文件能力:

containerPorts:
proxy: 80

如果你自定义渲染后的 Pod 并丢弃所有 capability,请为 AISIX 容器重新添加 NET_BIND_SERVICE

spec:
containers:
- name: aisix
securityContext:
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]

Kubernetes Restricted Pod Security Standard 允许此 capability。由于二进制文件的文件 capability 已设置 effective bit,如果运行时阻止授予该 capability,容器可能会因 exec: Operation not permitted 而失败。

只有当网关必须直接绑定节点且集群策略允许时,才使用 hostNetworkhostPort。这些选项会引入节点端口冲突并降低网络隔离;Baseline 和 Restricted Pod Security Standard 也不允许使用它们。

完整的网络暴露和凭证模型请参阅网络与安全

在副本间共享限流计数器

限流计数器默认存储在每个网关自己的内存中,因此 N 个副本实际会执行每项已配置请求、Token 和并发限制的 N 倍。在运行多个副本前——包括自动扩缩容器新增的任何副本——请让所有副本指向同一个 Redis:

rateLimit:
backend: redis
redis:
url: redis://redis.default.svc:6379

当连接 URL 包含密码时,请改用 rateLimit.redis.existingSecret

基于 CPU 或内存扩缩容

autoscaling 会为网关 Deployment 创建 HorizontalPodAutoscaler

autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 20
targetCPUUtilizationPercentage: 70

目标值是 Pod 资源 requests 的百分比,因此 Chart 默认设置 CPU request。它特意不设置 CPU limit:限流会增加代理的长尾延迟,并抑制自动扩缩容器读取的信号。基于 CPU 扩缩容要求集群中安装 metrics-server

启用自动扩缩容后,Deployment 会省略 spec.replicas,避免后续 helm upgrade 重置自动扩缩容器选择的副本数。此后会忽略 replicaCount 值。

所有 behavior 策略都会原样传递,例如让缩容比 Kubernetes 默认行为更平缓:

autoscaling:
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 60

对于 Pods、Object 或 External 指标(例如通过 Prometheus adapter 暴露的序列),请使用 autoscaling.extraMetrics

使用 KEDA 基于请求负载扩缩容

CPU 是负载的间接指标。如需改为根据网关自身流量扩缩容,请使用 KEDA,并针对网关指标执行 Prometheus 查询:

metrics:
serviceMonitor:
enabled: true

keda:
enabled: true
minReplicas: 2
maxReplicas: 20
pollingInterval: 15
cooldownPeriod: 300
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus.monitoring.svc:9090
query: sum(rate(aisix_llm_requests_total[2m]))
threshold: "100"

autoscalingkeda 互斥。同时启用两者会使 Helm 渲染失败,避免两个控制器同时写入 spec.replicas

扩缩容事件期间的行为

自动扩缩容器新增的副本在能够提供服务前不会接收流量。网关应用控制面配置之前,Chart 的就绪探针会报告 503,因此 Kubernetes 会让新 Pod 保持在 Service 端点之外。就绪契约请参阅健康检查

副本缩容时,Kubernetes 会同时开始将其从 Service 端点移除并终止 Pod。以下两个 Chart 默认值会在此过程中保护进行中的请求:

默认值用途
preStopSleepSeconds5端点移除和 SIGTERM 同时发生。暂停会让容器保持运行,直到移除操作传播到每个节点,避免继续向正在终止的 Pod 分配新连接。
terminationGracePeriodSeconds120网关排空本身没有截止时间,因此由该值设置上限。流式响应可能持续数分钟,而 Kubernetes 默认的 30 秒会将其中断。

如果工作负载的流式传输时间超过两分钟,请提高 terminationGracePeriodSeconds

观察扩缩容决策及其依据的指标:

kubectl -n aisix get hpa aisix --watch
kubectl -n aisix describe hpa aisix

应对节点中断

PodDisruptionBudget 可防止节点排空、集群升级等主动中断一次性停止所有网关。分布约束可以避免副本集中在单个故障域:

podDisruptionBudget:
enabled: true
minAvailable: 50%

topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: aisix

Chart 为 /var/lib/aisix 使用 emptyDir 卷,因此其中的状态是临时的,且只属于单个 Pod。Pod 重启后会重新注册,并在接收流量前从控制面下载配置。请跨故障域保留多个副本,使现有副本可以在其他副本重启期间继续提供服务。如果网关必须在控制面不可用时使用缓存配置重启,请自定义工作负载,为每个副本提供独立的持久化状态目录。

更完整的部署模式请参阅高可用

设置其他网关配置

控制面负责动态资源,Chart 负责 Pod。对于 Chart 没有作为 value 暴露的启动配置,请直接设置环境变量;每个配置字段都可以通过 AISIX_<SECTION>__<FIELD> 访问:

extraEnvVars:
- name: AISIX_OBSERVABILITY__LOG_LEVEL
value: "debug"
- name: AISIX_UPSTREAM__POOL_MAX_IDLE_PER_HOST
value: "32"

命名规则请参阅环境变量