1. 概述
在 Kubernetes 中,使用 LoadBalancer 类型的服务可以自动分配一个外部 IP 地址,从而让我们无缝地将工作负载暴露到公网。虽然这种机制适用于大多数场景,但某些应用(如 API 或 Web 服务)需要一个固定的、静态 IP 地址来保证通信的稳定性。对于需要高稳定性和系统集成的场景,静态 IP 是必不可少的。
本文将介绍如何在 Amazon EKS(Elastic Kubernetes Service)中为 Kubernetes 的 LoadBalancer 服务分配静态 IP,确保服务访问地址固定且可预测。
2. EKS 上的 Kubernetes Load Balancer 原理
在 EKS 中使用 LoadBalancer 类型的服务时,Kubernetes 会自动创建 AWS 的 Elastic Load Balancer(ELB)。这个负载均衡器负责将外部流量转发到 Kubernetes 的 Pod 中。
默认情况下,ELB 会分配一个动态 IP 地址。虽然这在大多数情况下已经足够,但对于需要固定 IP 的服务(如对外提供接口的 API)来说,这会带来一定挑战。使用静态 IP 可以提升服务的稳定性、简化集成流程,并减少服务更新时 DNS 传播延迟的问题。
EKS 支持 Network Load Balancer(NLB),它专为高吞吐量和低延迟设计,并且支持静态 IP 分配。因此,NLB 是大多数生产级负载的首选方案,可以保证应用在高并发下的稳定性和可靠性。
3. 在 AWS 中预留静态 IP 地址
要在 Kubernetes 中使用静态 IP,第一步是在 AWS 中预留一个 Elastic IP(EIP)。Elastic IP 是一种静态公网 IP,可以绑定到 NLB 等资源上,确保服务拥有稳定的访问地址。
3.1 分配 Elastic IP
可以通过 AWS CLI 来分配一个 Elastic IP:
$ aws ec2 allocate-address --domain vpc
{
"PublicIp": "18.225.3.242",
"AllocationId": "eipalloc-5f747653"
}
输出包含两个关键字段:
- PublicIp:即分配的静态 IP 地址,后续用于绑定到 LoadBalancer
- AllocationId:该 IP 的唯一标识,后续用于配置 NLB 时指定
分配时应使用 --domain vpc
参数,以确保该 IP 能与 NLB 等现代网络资源兼容。
3.2 为 Elastic IP 添加 Kubernetes 标签
为了让 Kubernetes 能识别并使用这个 Elastic IP,需要为其添加特定的标签:
$ aws ec2 create-tags --resources eipalloc-5f747653 \
--tags Key=kubernetes.io/cluster/baeldung-ops-cluster,Value=shared
这个标签告诉 Kubernetes 这个 EIP 是为哪个集群预留的。如果不加这个标签,Kubernetes 将无法识别该 IP,可能导致 LoadBalancer 无法正确绑定。
4. 配置 Kubernetes Load Balancer 使用静态 IP
Elastic IP 预留并打上标签后,接下来就可以配置 Kubernetes 的 Service 使用它了。
4.1 添加必要注解(Annotations)
Kubernetes 中通过注解来定制 LoadBalancer 的行为。要使用 NLB 并绑定 Elastic IP,需要添加以下两个注解:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-eip-allocations: eipalloc-5f747653
第一个注解表示使用 NLB,第二个注解指定之前分配的 Elastic IP 的 AllocationId。
4.2 编写 Service 配置文件
下面是一个完整的 Service YAML 示例:
apiVersion: v1
kind: Service
metadata:
name: baeldung-ops-loadbalancer-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-eip-allocations: eipalloc-5f747653
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8000
protocol: TCP
selector:
app: ops-app
说明:
- annotations:配置使用 NLB 和指定 Elastic IP
- selector:匹配标签为
app: ops-app
的 Pod - ports:定义外部访问端口(80)和容器监听端口(8000)
4.3 应用 Service 配置
使用 kubectl 应用配置:
$ kubectl apply -f service.yaml
service/baeldung-ops-loadbalancer-service created
Kubernetes 会创建对应的 NLB 并绑定之前预留的 Elastic IP。
4.4 验证静态 IP 是否绑定成功
执行以下命令查看 Service 的状态:
$ kubectl get service baeldung-ops-loadbalancer-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
baeldung-ops-loadbalancer-service LoadBalancer 10.0.1.50 18.225.3.242 80:30080/TCP 2m
确认 EXTERNAL-IP
字段显示的是我们预留的 IP(如 18.225.3.242
),说明配置成功。
4.5 注意事项
为了确保服务正常运行,需注意以下几点:
✅ Elastic IP 所在区域与 EKS 集群一致
❌ 如果不在同一区域,NLB 无法绑定该 IP
✅ Pod 状态健康且标签匹配
❌ 如果没有匹配的 Pod 或 Pod 不健康,流量将无法正常转发
✅ 安全组配置允许访问对应端口
❌ 否则外部流量将无法到达 LoadBalancer
5. 最佳实践
为确保静态 IP 的稳定性和安全性,建议遵循以下最佳实践:
- 最小权限 IAM 策略:限制谁可以创建、修改或删除 Elastic IP 和 LoadBalancer,降低安全风险
- 使用 IaC(Infrastructure as Code)管理配置:如 Terraform 或 CloudFormation,便于版本控制和环境一致性
- 监控 LoadBalancer 健康状态:使用 AWS CloudWatch 和 Kubernetes 事件来监控负载均衡器性能
- 配置安全组限制访问来源:只允许特定 IP 段访问,提升安全性
- 在测试环境验证后再上线:避免在生产环境直接部署,减少上线风险
这些做法有助于在问题发生前及时发现并修复。
6. 总结
本文介绍了如何在 Amazon EKS 中为 Kubernetes 的 LoadBalancer 服务分配静态 IP 地址。
通过预留 Elastic IP、添加注解并配置 Service,我们实现了对外服务地址的固定。这种方式不仅提升了服务的稳定性,也为后续的集成和运维提供了便利。
在实际部署中,结合最佳实践,可以进一步提升系统的安全性和可维护性。