K8s Pod EIP 使用指南

记录阿里云 ACK、腾讯云 TKE、GCP GKE、AWS EKS 四家的 Pod EIP 用法。

1. 为什么需要 Pod EIP

常规方式下 Pod 访问公网走 NAT 网关,入向走 LoadBalancer Service。但有些场景需要让 Pod 拥有独立公网 IP:

  • 游戏服务器:客户端 UDP 直连,需要固定 IP
  • 独立出口 IP:按 Pod 区分流量来源
  • 安全策略:固定 IP 做白名单

2. 阿里云 ACK

官方文档:为 Pod 挂载独立公网 EIP

2.1 前置条件

  • 网络插件为 Terway
  • 安装 ack-extend-network-controller 组件(推荐,Terway 自带 EIP 功能已在 v1.7.0 移除)
  • Worker 节点 RAM 角色需授权 EIP 相关 API(AllocateEipAddress、AssociateEipAddress 等)

2.2 自动分配 EIP

annotation 声明:

apiVersion: apps/v1
kind: Deployment
metadata:
name: dsagent
spec:
replicas: 1
selector:
matchLabels:
app: dsagent
template:
metadata:
labels:
app: dsagent
annotations:
k8s.aliyun.com/pod-with-eip: "true" # 开启自动分配 EIP
k8s.aliyun.com/eip-bandwidth: "5000" # 带宽上限(Mbps)
k8s.aliyun.com/eip-public-ip-address-pool-id: "pippool-xxxxxx" # 从指定地址池分配(可选)
spec:
containers:
- name: dsagent
image: registry.example.com/game/dsagent:v1.0
env:
- name: POD_EIP # 通过 Downward API 拿到分配的 EIP
valueFrom:
fieldRef:
fieldPath: metadata.annotations['k8s.aliyun.com/allocated-eipAddress']
  • eip-bandwidth 单位是 Mbps,5000 即 5Gbps
  • 默认按流量计费(PayByTraffic),需要按带宽计费可加 eip-internet-charge-type: "PayByBandwidth"
  • eip-public-ip-address-pool-id 可选,不指定则从公共池分配(见 2.5 节)
  • 通过 Downward API 把分配到的 EIP 地址注入环境变量,进程启动后直接读取
  • 更多参数(ISP 线路、安全防护、共享带宽包等)见 官方文档

查看 EIP 分配:

$ kubectl get podeip -n <namespace>
NAME EIP ID EIP ADDRESS PRIVATE IP STATUS
dsagent-5b8c7d6f4-x9k2m eip-uf6xxxxxxxxxx 47.xx.xx.xx 172.16.0.100 InUse

$ kubectl get pod dsagent-5b8c7d6f4-x9k2m -n <namespace> -o jsonpath='{.metadata.annotations.k8s\.aliyun\.com/allocated-eipAddress}'
47.xx.xx.xx

控制器绑定 EIP 后还会写入 network.alibabacloud.com/allocated-eip 等 annotation,包含 EIP ID 和每个网卡的 EIP 映射关系。

2.3 绑定已有 EIP 实例

已有特定 EIP 时,指定实例 ID 绑定:

annotations:
k8s.aliyun.com/pod-eip-instanceid: "eip-bp14qxxxxxxx"
  • 单个 EIP 不能同时绑多个 Pod
  • 官方建议仅在 StatefulSet 中使用;Deployment 的话确保单副本 + Recreate 策略

2.4 EIP 回收策略

回收策略实现固定 EIP,Pod 重建后复用之前的 EIP:

annotations:
k8s.aliyun.com/pod-with-eip: "true"
k8s.aliyun.com/pod-eip-release-strategy: "10m" # Pod 删除 10 分钟后才释放

回收策略取值:

  • Follow(默认):跟随 Pod 生命周期,删除即释放
  • Never:永不释放,需手动删除 PodEIP 资源
  • 时间表达式(如 5m30s10m):Pod 删除后延迟释放
  • 仅 ack-extend-network-controller 支持,且仅适用于有状态类型控制器(StatefulSet 等)
  • 原理(官方文档):Pod 删除后 PodEIP CR 会保留,在保留期内创建的同名 Pod 将继续使用相应的 EIP
  • 指定 EIP 实例 ID(2.3)时,不会释放 EIP 实例

2.5 EIP 地址池(BYOIP)

官方文档:IP 地址池

从特定 IP 段分配时用地址池:

annotations:
k8s.aliyun.com/pod-with-eip: "true"
k8s.aliyun.com/eip-public-ip-address-pool-id: "pippool-xxxxxx" # 地址池 ID

地址池管理(控制台或 API):

  1. 创建地址池,选线路类型(BGP / BGP精品)和安全防护级别
  2. 添加网段:掩码范围 /24 到 /28(系统自动分配),或 /23 到 /30(指定目标网段,用于 BYOIP)
  3. 从该地址池创建 EIP 时 IP 从池内分配
  • 配额:每地域最多 16 个地址池,所有地址池 IP 总数默认不超过 256 个(/24 刚好 256 个),需联系商务提额
  • EIP 本身的配额默认每账号每地域 20 个,也可在配额中心申请提额
  • 计费:池内每个 IP 0.05 元/小时/个(无论是否分配为 EIP),BYOIP 地址不收保有费

2.6 常用 Annotation 汇总

Annotation说明
k8s.aliyun.com/pod-with-eip: "true"自动分配 EIP
k8s.aliyun.com/eip-bandwidth: "100"带宽 Mbps
k8s.aliyun.com/eip-internet-charge-typePayByTraffic / PayByBandwidth
k8s.aliyun.com/eip-ispBGP / BGP_PRO
k8s.aliyun.com/pod-eip-instanceid指定已有 EIP 实例 ID
k8s.aliyun.com/pod-eip-release-strategy回收策略:Follow / Never / 时间表达式
k8s.aliyun.com/eip-public-ip-address-pool-id指定 EIP 地址池
k8s.aliyun.com/eip-common-bandwidth-package-id绑定共享带宽包
k8s.aliyun.com/eip-security-protection-types安全防护:空=基础版 / AntiDDoS_Enhanced=增强版
k8s.aliyun.com/eip-tagsEIP 标签(JSON 格式)

2.7 ReadinessGate

EIP 绑定是异步的,加 ReadinessGate 保证 EIP 就绪后 Pod 才 Ready:

spec:
readinessGates:
- conditionType: "k8s.aliyun.com/eip"

控制器绑定成功后会设置该 condition 为 True。

上面 dsagent 的例子没加 ReadinessGate,因为使用 Recreate 策略且进程启动时通过 POD_EIP 环境变量拿 EIP,启动探针(startupProbe)会等到进程就绪。

2.8 注意事项

  • 安全组:EIP 流量受 Pod ENI 绑定的安全组约束。坑点在于:创建集群时系统自动创建的默认安全组会写入 Terway eni_conf,后续如果在控制台更换了集群安全组,eni_conf 不会自动同步,Pod ENI 绑的还是旧安全组——导致在新安全组上加规则不生效。排查看 ECS 弹性网卡页签确认 ENI 实际安全组,修复改 eni_confsecurity_group 后重建 Pod
  • 云防火墙:开了云防火墙的话 EIP 流量还受互联网边界 ACL 约束,需额外放行
  • 绑定延迟:EIP 绑定有秒级延迟,配合 ReadinessGate 用

2.9 替代方案:NAT 网关 DNAT

用 NAT 网关 DNAT 映射端口到 Pod IP:

NAT 网关 EIP:端口A → Pod1 VPC_IP:7777
NAT 网关 EIP:端口B → Pod2 VPC_IP:7777

参考:使用网关 DNAT 规则直接访问 Pod

3. 腾讯云 TKE

腾讯云 TKE 支持 Pod 绑定 EIP。

3.1 标准集群 VPC-CNI 模式

官方文档:为 VPC-CNI 模式的 Pod 绑定 EIP

前置条件:

  • TKE 标准集群,VPC-CNI 模式(共享网卡固定 IP / 共享网卡非固定 IP 均可,独占网卡需 v3.3.9+)
  • IPAMD 组件角色需关联策略 QcloudAccessForIPAMDRoleInQcloudAllocateEIP

annotation 声明 + resources 请求 EIP 资源:

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: game-server
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: game-server
serviceName: ""
template:
metadata:
labels:
app: game-server
annotations:
tke.cloud.tencent.com/networks: "tke-route-eni"
tke.cloud.tencent.com/eip-attributes: '{"Bandwidth":"100","ISP":"BGP"}'
tke.cloud.tencent.com/eip-claim-delete-policy: "Never"
spec:
containers:
- name: game-server
image: your-image
resources:
requests:
tke.cloud.tencent.com/eni-ip: "1"
tke.cloud.tencent.com/eip: "1"
limits:
tke.cloud.tencent.com/eni-ip: "1"
tke.cloud.tencent.com/eip: "1"
  • eip-attributes 是 JSON,支持 Bandwidth(带宽 Mbps)和 ISPBGP / CMCC / CTCC / CUCC),默认 100Mbps + BGP
  • tke.cloud.tencent.com/networks: "tke-route-eni" 声明使用 VPC-CNI 网络
  • resources 里需要同时请求 eni-ipeip 两个资源
  • eip-claim-delete-policy 控制 EIP 回收策略(见 3.3 节)
  • 更多参数见 官方文档

3.2 指定已有 EIP

annotations:
tke.cloud.tencent.com/eip-id-list: "eip-xxx1,eip-xxx2"

适合配合 StatefulSet 使用:Pod 按名字末尾编号(如 busybox-0 用第 1 个、busybox-1 用第 2 个)依次选用列表中的 EIP。Deployment 类型的 Pod 名字末尾无固定编号,会随机选用,多副本时会冲突(只能有一个 Pod 关联成功),建议只指定单个 EIP。

3.3 固定 EIP

在 annotation 中设置 tke.cloud.tencent.com/eip-claim-delete-policy: "Never",Pod 删除后 EIPClaim CR 会保留,同名 Pod 重建时复用之前的 EIP。

回收固定 EIP 的三种方式:

方式说明
过期回收IPAMD v3.5.0+:在组件管理页面设置”固定 IP 回收策略”的过期时间;低版本:启动参数 --claim-expired-duration=1h(不小于 5m)
手动回收kubectl delete eipc <podname> -n <namespace>(需确保对应 Pod 已销毁)
级联回收删除 Workload 时联动删除 EIP。IPAMD v3.5.0+:组件管理页面勾选”固定 IP 模式级联回收”;低版本(v3.3.9+):启动参数 --enable-ownerref

3.4 获取 EIP 地址

EIP 绑定成功后,公网地址会写入 Pod annotation tke.cloud.tencent.com/eip-public-ip,跟阿里云一样可以通过 Downward API 读取。也可以通过 EIPClaim CR 查看:

kubectl get eipc <podname> -n <namespace> -o yaml

3.5 Serverless 集群 / EKSCI

官方文档:Serverless 集群 Pod EIPEKSCI 绑定 EIP

用法和标准集群基本一致,区别是 annotation 前缀多了 eks.

annotations:
eks.tke.cloud.tencent.com/eip-attributes: "" # 空字符串表示 EIP 默认配置

3.6 注意事项

  • 安全组:IPAMD 默认未开启安全组能力(--enable-security-groups),此时弹性网卡未绑定安全组。如需为 Pod 弹性网卡绑定安全组,需手动开启并配置。详见 VPC-CNI 模式安全组使用说明
  • 出向流量默认不走 EIP:集群内 ip-masq-agent 会对 Pod 外访流量做节点地址 SNAT,需要在 ip-masq-agent-configNonMasqueradeSrcCIDRs 中加入 Pod 内网 IP。如果 VPC 内有 NAT 网关,还需要调整 NAT 网关和 EIP 的优先级。详见 官方文档

4. GCP GKE

官方文档:概念使用指南

GCP 的方案叫 Persistent IP Addresses for GKE Pods,基于 Gateway API + GKEIPRoute CRD。

4.1 前置条件

  • GKE 版本 1.31+
  • 启用 GKE Dataplane V2
  • 启用 Gateway API(--gateway-api=standard

4.2 工作原理

GCP 不是直接给 Pod 绑 EIP,而是通过 Gateway + GKEIPRoute 路由模型实现:

  1. 预留一个 Static External IP
  2. 创建 Gateway(gke-persistent-regional-external-managedgke-persistent-regional-internal-managed),关联该 IP
  3. 创建 GKEIPRoute CRD,把 Gateway 流量路由到目标 Pod
kind: GKEIPRoute
apiVersion: networking.gke.io/v1
metadata:
name: ds-route
namespace: default
spec:
parentRefs:
- name: allowed-pod-ips
namespace: default
addresses:
- value: "34.123.10.1/32"
type: "gke.networking.io/cidr"
network: default
reactionMode: ReadyCondition
podSelector:
matchLabels:
component: ds

4.3 关键能力

  • BYOIP:支持预留静态 IP 或自带 IP
  • 快速故障转移:使用 gke-persistent-fast-* Gateway Class(如 gke-persistent-fast-regional-external-managed),需要额外开启 device-type multi-network,并在 GKEIPRoute 里设置 nodeSelector 指定节点标签(最多选中 64 个节点),Pod 也需要调度到这些节点上。文档称故障转移可将停机时间缩短到几秒级别
  • 健康检查联动reactionMode: ReadyCondition(默认值),Pod Not Ready 时自动停止路由;也可设为 Exists 只关注 Pod 是否存在
  • 全端口/协议透传:Gateway 的 forwarding rule 使用 L3_DEFAULT,允许所有 TCP/UDP 端口流量

注意:对于 gke-persistent-* Gateway Class,每个 Persistent IP 同一时间只能绑定一个 Pod(You can associate each persistent IP address with a single Pod at a time)。多个 Pod 可用时,流量会路由到最新的健康 Pod。GCP 另有 gke-passthrough-lb-* Gateway Class 支持 1:N(一个 IP 分发到多个 Pod),适合负载均衡场景,详见 health-check-based load balancing

4.4 与阿里云/腾讯云的区别

阿里云和腾讯云通过 annotation 声明即可完成 EIP 绑定,GCP 需要创建 Gateway + GKEIPRoute 两层资源。GCP 的 IP 生命周期由 Gateway 资源管理(文档原文Gateway objects serve as the central point for managing and configuring persistent IP addresses),同时通过不同的 Gateway Class 支持故障转移(gke-persistent-fast-*)和负载均衡(gke-passthrough-lb-*)。

5. AWS EKS

AWS EKS 提供了 aws-pod-eip-controller(发布在 aws-samples 组织下的示例项目)来实现 Pod 级 EIP 绑定。

5.1 aws-pod-eip-controller

GitHub:aws-samples/aws-pod-eip-controller
AWS 博客:实现 EIP Controller 为 EKS 的 Pod 增加公网访问能力

原理:

  1. Controller 通过 Informer watch 带特定 annotation 的 Pod
  2. Pod 创建 → 调 AWS API AllocateAddress + AssociateAddress 绑 EIP 到 Pod
  3. Pod 删除 → DisassociateAddress + ReleaseAddress

部署流程(README Walkthrough):

# 1. 构建镜像推 ECR
git clone https://github.com/aws-samples/aws-pod-eip-controller.git
docker buildx build --tag <your-ecr>/aws-pod-eip-controller:latest --push .

# 2. 创建 IAM Policy + IRSA ServiceAccount
aws iam create-policy --policy-name AWSPodEIPControllerIAMPolicy --policy-document file://iam-policy.json
eksctl create iamserviceaccount --cluster=<cluster> --name=aws-pod-eip-controller --attach-policy-arn=<policy-arn> --approve

# 3. Helm 安装
helm install aws-pod-eip-controller ./charts/aws-pod-eip-controller \
--namespace kube-system \
--set image=<your-ecr>/aws-pod-eip-controller:latest \
--set clusterName=<cluster> \
--set serviceAccountName=aws-pod-eip-controller

使用(annotation 声明):

annotations:
aws-samples.github.com/aws-pod-eip-controller-type: auto # 自动分配
aws-samples.github.com/aws-pod-eip-controller-public-ipv4-pool: "amazon" # 可选:指定 IP 池

通过 Tag 实现固定 EIP(fixed-tag 模式):

annotations:
aws-samples.github.com/aws-pod-eip-controller-type: fixed-tag
aws-samples.github.com/aws-pod-eip-controller-fixed-tag: "my-eip-tag" # EIP 上预设的 Tag Key

还有 fixed-tag-value 模式,适合 StatefulSet——按 Tag Key + Pod 名字匹配特定 EIP:

annotations:
aws-samples.github.com/aws-pod-eip-controller-type: fixed-tag-value
aws-samples.github.com/aws-pod-eip-controller-fixed-tag-value: "my-eip-tag"

fixed-tag 只匹配 Tag Key 存在的 EIP;fixed-tag-value 额外要求 Tag Value 等于 namespace/podname,实现 Pod 和 EIP 的一一对应。两种固定模式下 Pod 删除时只解绑不释放 EIP。

与其他三家的差异:

  • README Walkthrough 中需要自行构建镜像并推送到 ECR
  • Pod 出向流量默认走节点 SNAT,需设 AWS_VPC_K8S_CNI_EXTERNALSNAT=true 才走 EIP 出网(见 repo FAQ.md
  • README 示例通过 initContainer 轮询 downwardAPI labels 等待 EIP 绑定完成后再启动主容器
  • 固定 EIP 通过预设 Tag 匹配,阿里云用 releaseStrategy annotation、腾讯云用 eip-claim-delete-policy annotation 声明式管理

6. 小结

四家主流云厂商都支持 Pod 级 EIP 绑定,实现路径各有不同:阿里云和腾讯云通过 annotation 声明,集群组件自动完成绑定;GCP 走 Gateway API + GKEIPRoute CRD 声明式模型;AWS 通过 aws-samples 下的 Controller 示例项目实现。具体的 annotation、部署方式、固定 EIP 策略等细节见各章节。

7. 参考