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,我们实现了对外服务地址的固定。这种方式不仅提升了服务的稳定性,也为后续的集成和运维提供了便利。

在实际部署中,结合最佳实践,可以进一步提升系统的安全性和可维护性。


原始标题:Specify Static IP Address for Kubernetes Load Balancer