为Pod挂载独立公网EIP

更新时间: 2024-02-23 14:58:05

Pod的IP地址一般是私网的IP地址,但是在ACS某些场景下,Pod需要独立的公网IP地址。本文介绍如何为ACS中的Pod挂载独立的公网EIP。

前提条件

创建ACS集群

背景信息

在ACS集群中Pod默认无法访问公网,一般情况下可以考虑“外部SNAT+EIP”的方式实现,详情请参见为已有集群开启公网访问能力。对于Pod的公网入口流量一般是通过LoadBalancer类型的Service流入。在有的场景中Pod需要独立的公网地址,例如:

  • Pod的对外映射端口是随机的,一般常见于UDP(User Datagram Protocol)的游戏服务器或电话会议等。例如RTSP协议,对不同的客户端使用不同的端口。

  • Pod访问公网流量存在争抢,Pod需要独立的公网出口。

使用限制

  • 在使用弹性公网IP(Elastic IP Address,简称EIP)前,请先了解EIP的使用限制。详细信息,请参见使用限制

  • 如果您使用自动分配EIP能力,在Pod重建、CNI执行失败等情况下,可能会反复申请、释放EIP资源,这种情况下,可能会触发EIP使用限制。如果您想避免这种情况,可以通过配置Pod Annotation k8s.aliyun.com/pod-eip-instanceid为Pod指定EIP。

Pod配置

指定EIP实例ID

此模式不会对EIP实例配置进行修改,仅绑定EIP到指定Pod。不支持多副本类型的控制器,请确保EIP实例仅有一个Pod引用。

Pod Annotations

说明

k8s.aliyun.com/pod-eip-instanceid

使用指定EIP,请填写EIP实例ID, 例如:eip-bp14qxxxxxxx

自动分配EIP

Pod Annotations

说明

k8s.aliyun.com/pod-with-eip

是否自动创建并绑定EIP。取值:

  • true:自动创建并绑定EIP。

  • false:不自动创建并绑定EIP。

k8s.aliyun.com/eip-bandwidth

EIP峰值带宽。单位:Mbps。更多信息,请参见申请EIP

k8s.aliyun.com/eip-internet-charge-type

EIP的计费方式。取值:

  • PayByTraffic:按使用流量计费。

  • PayByBandwidth:按带宽计费。

更多信息,请参见申请EIP

说明
  • 默认选择PayByBandwidth。

k8s.aliyun.com/eip-charge-type(兼容)

k8s.aliyun.com/eip-common-bandwidth-package-id

绑定已有的共享带宽包。

k8s.aliyun.com/eip-isp

EIP的线路类型。取值:

  • BGP:BGP(多线)线路。

  • BGP_PRO:BGP(多线)精品线路。

更多信息,请参见申请EIP

k8s.aliyun.com/eip-public-ip-address-pool-id

EIP地址池。更多信息,请参见申请EIP

k8s.aliyun.com/eip-resource-group-id

EIP资源组。更多信息,请参见申请EIP

k8s.aliyun.com/eip-name

EIP名称。更多信息,请参见申请EIP

k8s.aliyun.com/eip-description

EIP描述。更多信息,请参见申请EIP

设置固定EIP

固定EIP可以保证Pod重建后依然使用之前的EIP地址。该策略可与自动分配EIP能力结合,用于有状态应用的固定EIP。

说明
  • 此能力对有状态类型副本控制器适用,您无法为无状态类型控制器使用。

  • 指定EIP实例ID,不会释放EIP实例。

Pod Annotations

说明

k8s.aliyun.com/pod-eip-release-strategy

PodEIP回收策略。取值:

  • Follow:默认值,跟随Pod生命周期。

  • Never:不删除PodEIP。当不需要时需要手动删除这个PodEIP。

  • 可直接配置过期时间,例如5m30s,表示Pod删除5.5分钟后删除PodEIP。支持Go类型时间表达式。

控制Pod Ready状态

控制器会在Pod IP分配后,为Pod配置EIP地址,Pod Ready状态可能早于EIP绑定成功时间。您可以尝试使用下面的方式,控制Pod Ready状态。

为Pod配置Readiness gates

当在Pod中配置readinessGates,并且绑定EIP成功后,控制器会设置Pod conditions。在EIP未绑定前,Pod不会处于Ready状态。

kind: Pod
...
spec:
  readinessGates:
  - conditionType: "k8s.aliyun.com/eip"
status:
  conditions:
  - lastProbeTime: "2022-12-12T03:45:48Z"
    lastTransitionTime: "2022-12-12T03:45:48Z"
    reason: Associate eip succeed
    status: "True"
    type: k8s.aliyun.com/eip
...

为Pod配置initContainers

为Pod配置initContainers,在initContainers中检查EIP是否已经分配成功。您可以参考以下示例配置initContainers

apiVersion: v1
kind: Pod
metadata:
  name: example
  annotations:
    k8s.aliyun.com/pod-with-eip: "true"
spec:
  containers:
  - name: example
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init
    image: busybox:1.28
    command: ['timeout', '-t' ,'60', 'sh','-c', "until grep -E '^k8s.aliyun.com\\/pod-ips=\\S?[0-9]+\\S?' /etc/podinfo/annotations; do echo waiting for annotations; sleep 2; done"]
    volumeMounts:
      - name: podinfo
        mountPath: /etc/podinfo
  volumes:
    - name: podinfo
      downwardAPI:
        items:
          - path: "labels"
            fieldRef:
              fieldPath: metadata.labels
          - path: "annotations"
            fieldRef:
              fieldPath: metadata.annotations

安装ACK Extend Network Controller组件启用EIP功能

为了使用EIP功能,您需要安装ACK Extend Network Controller组件,并通过注解为指定Pod创建和关联EIP。

步骤一:安装ACK Extend Network Controller组件

组件管理页面安装ACK Extend Network Controller。具体操作,请参见管理组件

步骤二:通过注解为指定Pod创建和关联EIP

通过指定Pod中的Annotations可以创建或者关联EIP到此Pod中。注解内容,请参见上文Pod配置

示例

  1. 使用如下示例创建一个Deployment控制器,从EIP地址池pippool-bp1bbpq1jjncxxxx为每个Pod自动分配一个EIP实例,实例带宽为5 Mbps。

    展开查看Deployment YAML

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: example
      labels:
        app: example
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: example
      template:
        metadata:
          labels:
            app: example
          annotations:
            k8s.aliyun.com/pod-with-eip: "true"
            k8s.aliyun.com/eip-bandwidth: "5"
            k8s.aliyun.com/eip-public-ip-address-pool-id: "pippool-bp1bbpq1jjncxxxx"
        spec:
          readinessGates:
          - conditionType: "k8s.aliyun.com/eip"
          containers:
          - name: example
            image: nginx
  2. Pod创建成功后,访问Pod同名的“PodEIP”CR对象podeips.alibabacloud.com,跟踪分配的EIP信息。

    展开查看PodEIP YAML

    apiVersion: alibabacloud.com/v1beta1
    kind: PodEIP
    metadata:
      annotations:
        k8s.aliyun.com/eip-controller: ack-extend-network-controller
      creationTimestamp: "2022-11-18T07:46:18Z"
      finalizers:
      - podeip-controller.alibabacloud.com/finalizer
      generation: 1
      name: example-xxxx-xxxx
      namespace: default
      resourceVersion: "597256"
      uid: 2fd39250-7cf0-4b6e-a581-xxxxxx
    spec:
      allocationID: eip-bp1rcs9ilupxxxxx
      allocationType:
        releaseStrategy: Follow
        type: Auto
    status:
      bandwidth: "5"
      eipAddress: 112.xx.xx.xx
      internetChargeType: PayByBandwidth
      isp: BGP
      networkInterfaceID: eni-bp14qrdskvxxxxx
      podLastSeen: "2022-11-18T08:42:29Z"
      privateIPAddress: 172.18.XX.XX
      publicIpAddressPoolID: pippool-bp1bbpq1jjncxxxx
      resourceGroupID: rg-acfm2omxxxxx
      status: InUse
  3. 使用如下示例创建一个StatefulSet资源,创建两个Pod,并为每个Pod自动分配一个EIP实例,并设置回收策略为Pod删除10分钟后删除PodEIP。

    展开查看StatefulSet YAML

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: example
      labels:
        app: example
    spec:
      serviceName: "example"
      replicas: 2
      selector:
        matchLabels:
          app: example
      template:
        metadata:
          labels:
            app: example
          annotations:
            k8s.aliyun.com/pod-with-eip: "true"
            k8s.aliyun.com/pod-eip-release-strategy: "10m"
        spec:
          containers:
          - name: example
            image: nginx
  4. Pod创建成功后,访问Pod同名的资源podeips.alibabacloud.com,跟踪分配的EIP信息。

    展开查看PodEIP YAML

    apiVersion: v1
    items:
    - apiVersion: alibabacloud.com/v1beta1
      kind: PodEIP
      metadata:
        annotations:
          k8s.aliyun.com/eip-controller: ack-extend-network-controller
        creationTimestamp: "2022-12-01T02:56:27Z"
        finalizers:
        - podeip-controller.alibabacloud.com/finalizer
        generation: 1
        name: example-0
        namespace: default
        resourceVersion: "393589"
        uid: c4a69543-ef01-4596-a1ff-d3199624****
      spec:
        allocationID: eip-bp1tqnbtwxxxxx
        allocationType:
          releaseAfter: 10m
          releaseStrategy: TTL
          type: Auto
      status:
        eipAddress: 121.40.XX.XX
        internetChargeType: PayByBandwidth
        isp: BGP
        networkInterfaceID: eni-bp1d9uh1tphxxxx
        podLastSeen: "2022-12-01T02:57:05Z"
        privateIPAddress: 172.16.XX.XX
        resourceGroupID: rg-acfm2om7xxxxx
        status: InUse
    - apiVersion: alibabacloud.com/v1beta1
      kind: PodEIP
      metadata:
        annotations:
          k8s.aliyun.com/eip-controller: ack-extend-network-controller
        creationTimestamp: "2022-12-01T02:56:42Z"
        finalizers:
        - podeip-controller.alibabacloud.com/finalizer
        generation: 1
        name: example-1
        namespace: default
        resourceVersion: "393590"
        uid: 3a4fbc70-1bed-4e32-8961-da84768e****
      spec:
        allocationID: eip-bp1sdp3axxxx
        allocationType:
          releaseAfter: 10m
          releaseStrategy: TTL
          type: Auto
      status:
        eipAddress: 121.199.XX.XX
        internetChargeType: PayByBandwidth
        isp: BGP
        networkInterfaceID: eni-bp1d9uh1tphxxxx
        podLastSeen: "2022-12-01T02:57:05Z"
        privateIPAddress: 172.16.1.145
        resourceGroupID: rg-acfm2omxxxxxx
        status: InUse
    kind: List
    metadata:
      resourceVersion: ""
  5. Pod删除后,PodEIP CR会保持10分钟后再删除,在此期间创建的同名称Pod,将继续使用相应的EIP。

验证配置

当Pod变成Running状态之后,可以观察部署完后的Pod中Annotations k8s.aliyun.com/allocated-eipAddress的值来查看它分配到的关联EIP地址,通过该EIP即可访问到Pod。