为Pod挂载独立公网EIP

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

前提条件

已创建以下集群中的一个或多个。创建集群,请参见创建Kubernetes托管版集群创建Kubernetes专有版集群创建ASK集群

  • ACK托管版集群

    说明

    集群的网络插件必须为terway-eniipterway-eni

  • ACK专有版集群

    说明

    集群的网络插件必须为terway-eniipterway-eni

  • ASK集群

背景信息

一般情况下,Terway网络模式中的Pod访问公网的流量是通过主机SNAT(Source Network Address Translation)或者外部SNAT通过EIP而实现,对于Pod的公网入口流量一般是通过LoadBalancer类型的Service流入。在有的场景中Pod需要独立的公网地址,例如:

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

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

关于ACK集群Terway网络模式的更多信息,请参见使用Terway网络插件

组件差异对比

以下两个组件均支持为Pod挂载公网EIP能力,组件的差异对比如下。

说明

您不能同时启用ack-extend-network-controller与Terway的EIP配置能力。

-

ack-extend-network-controller

terway

支持的集群类型

  • ACK托管版集群

  • ACK专有版集群

  • ASK集群

  • ACK托管版集群

  • ACK专有版集群

固定EIP

支持

不支持

配置阶段

Pod IP分配后,控制器将为Pod分配、绑定EIP地址。

在CNI执行过程中分配、绑定EIP地址。

开启方式

可以在ACK应用市场中安装ack-extend-network-controller组件,并且开启EIP控制器。详细信息,请参见应用市场

Terway的EIP配置方法,请参见下文在Terway中启用EIP功能

支持版本

v0.2.0及以上

v1.0.10.280-gdc2cb6c-aliyun及以上

使用限制

  • 不支持ACK边缘托管版集群。

  • 在使用弹性公网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

value

k8s.aliyun.com/pod-eip-instanceid

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

k8s.aliyun.com/eci-eip-instanceid(兼容)

自动分配EIP

Pod Annotations

value

k8s.aliyun.com/pod-with-eip

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

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

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

k8s.aliyun.com/eci-with-eip(兼容)

k8s.aliyun.com/eip-bandwidth

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

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

EIP的计费方式。取值:

  • PayByTraffic:按使用流量计费。

  • PayByBandwidth:按带宽计费。

更多信息,请参见申请EIP

说明
  • 在Terway模式下, 默认选择PayByTraffic。

  • 在ack-extend-network-controller模式下,默认选择PayByBandwidth。

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

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

绑定已有的共享带宽包。

说明

使用此Annotation,需要terway组件版本为v1.2.3及以上;对ack-extend-network-controller组件版本无限制。

k8s.aliyun.com/eip-isp

EIP的线路类型。取值:

  • BGP:BGP(多线)线路。

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

更多信息,请参见申请EIP

说明

使用此Annotation,需要terway组件版本为v1.2.3及以上;对ack-extend-network-controller组件版本无限制。

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

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

说明

此Annotation仅在ack-extend-network-controller中支持。

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

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

说明

此Annotation仅ack-extend-network-controller组件版本为v0.4.0及以上支持使用。

设置固定EIP

固定EIP可以保证Pod重建后依然使用之前的EIP地址,仅在ack-extend-network-controller中支持。该策略可与自动分配EIP能力结合,用于有状态应用的固定EIP。

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

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

Pod Annotations

value

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配置Readiness gates仅在ack-extend-network-controller中支持。

当在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配置init container

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

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功能

ack-extend-network-controller需要访问阿里云OpenAPI来创建资源,您需要在RAM中配置相应的权限。 然后再在应用市场中安装ack-extend-network-controller,并通过注解为指定Pod创建和关联EIP 。

步骤一:配置EIP所需的 RAM 权限

  • 对于ACK集群,按照如下步骤操作。

    1. 登录容器服务管理控制台,在左侧导航栏单击集群
    2. 在集群列表页面中,单击目标集群名称。

    3. 在集群信息页面,单击集群资源页签,单击Worker RAM角色右侧链接。

    4. 在RAM角色基本信息的权限管理页签,单击目标权限策略名称。

    5. 单击修改策略内容,在策略内容区域增加如下内容,单击确定

           {
            "Effect": "Allow",
            "Action": [
              "vpc:DescribeVSwitches",
              "vpc:AllocateEipAddress",
              "vpc:AllocateEipAddressPro",
              "vpc:DescribeEipAddresses",
              "vpc:AssociateEipAddress",
              "vpc:UnassociateEipAddress",
              "vpc:ReleaseEipAddress",
              "vpc:AddCommonBandwidthPackageIp",
              "vpc:RemoveCommonBandwidthPackageIp",
              "vpc:TagResources",
              "ecs:DescribeNetworkInterfaces"
            ],
            "Resource": [
              "*"
            ],
            "Condition": {}
          }
      授权
  • 对于ASK集群,请为RAM用户生成访问密钥(AccessKey)。具体操作,请参见创建RAM用户创建自定义权限策略

步骤二:在应用市场安装ack-extend-network-controller

在ACK应用市场中安装ack-extend-network-controller。详细信息,请参见应用市场

控制器配置参数如下:

clusterID: "c11ba338192xxxxxxx"          # 请按实际情况填写。
regionID: "cn-hangzhou"                  # 请按实际情况填写。
vpcID: "vpc-bp1rkq0zxxxxxx"              # 请按实际情况填写。
enableControllers:
  - eip                                  # 启用EIP。

networkController:
  eipController:
    maxConcurrentReconciles: 1            # 控制器并发数量。
    garbageCollectionPeriodInMinutes: 1   # 固定EIP清理周期。
  customStatefulWorkloadKinds:            # 自定义的有状态控制器,默认支持StatefulSet。
  - foo

credential:                               # 使用AK/SK,对ACK集群,推荐使用RamRole模式配置。
  accessKey: ""
  accessSecret: ""

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

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

示例

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

    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同名的资源podeips.alibabacloud.com,跟踪分配的EIP信息。

    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。

    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信息。

    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。

在Terway中启用EIP功能

步骤一:升级Terway组件至最新版本

您需升级Terway组件到支持EIP功能的版本。关于升级Terway组件的具体步骤,请参见管理组件

说明

目前Terway组件v1.0.10.280-gdc2cb6c-aliyun及以上版本支持EIP功能。建议您升级Terway组件至最新版本。

步骤二:为Terway部署EIP相关的配置和权限

Terway为Pod配置EIP需要EIP相关的权限去申请和配置EIP,所以需要部署额外的配置和权限。

  1. 为Terway模式的RAM角色配置EIP相关权限。

    • 对于专有版集群或者2020年06月份之前创建的托管版集群,Terway的权限是通过Worker节点上的RAM角色进行配置。

      1. 登录容器服务管理控制台,在左侧导航栏单击集群
      2. 集群列表页面中,单击目标集群名称。然后单击集群资源页签,单击Worker RAM角色链接。

      3. 权限管理页签,单击目标授权策略名称,进入授权策略详情页面。授权策略详情

      4. 单击修改策略内容,从右侧滑出侧边栏修改策略内容面板,在策略内容Action字段中补充以下策略,然后单击确定修改策略内容

        "vpc:DescribeVSwitches",
        "vpc:AllocateEipAddress",
        "vpc:DescribeEipAddresses",
        "vpc:AssociateEipAddress",
        "vpc:UnassociateEipAddress",
        "vpc:ReleaseEipAddress",
        "vpc:AddCommonBandwidthPackageIp",
        "vpc:RemoveCommonBandwidthPackageIp"
        说明

        在策略内容的任意一个Action字段的最后一行补充英文半角逗号()。

    • 对于Pro托管版集群,或者是2020年6月份及之后创建的标准托管版集群,Terway的权限是通过RAM角色AliyunCSManagedNetworkRole进行配置。您需要在RAM控制台中为这个角色添加EIP相关权限。

      1. RAM角色AliyunCSManagedNetworkRole页面的RAM角色列表中,单击目标授权策略名称右侧的添加权限

      2. 添加权限面板的选择权限区域,单击+新建权限策略创建自定义策略。

        关于如何创建自定义策略,请参见创建自定义权限策略

      3. 在您创建的自定义权限策略中添加以下权限。

        关于如何修改自定义策略内容,请参见改自定义权限策略内容和备注

        "vpc:DescribeVSwitches",
        "vpc:AllocateEipAddress",
        "vpc:DescribeEipAddresses",
        "vpc:AssociateEipAddress",
        "vpc:UnassociateEipAddress",
        "vpc:ReleaseEipAddress",
        "vpc:AddCommonBandwidthPackageIp",
        "vpc:RemoveCommonBandwidthPackageIp"
  2. 部署Terway配置以支持EIP功能。

    1. 执行以下命令修改Terway的配置ConfigMap。

      kubectl edit cm eni-config -n kube-system
    2. eni_conf中增加以下内容。

      "enable_eip_pool": "true"
      说明

      如果您希望在指定EIP的时候能够强制解绑之前的实例,还需要在eni_conf中增加参数"allow_eip_rob": "true"

    3. 修改完成后,按Esc键,输入:wq!并按Enter键,保存修改后的配置文件并退出编辑模式。

    4. 执行以下命令重建Terway实例。

      kubectl delete pod -n kube-system -l app=terway-eniip

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

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

根据不同场景,配置注解方式如下:

  • 自动分配EIP场景

    • 添加以下注解,为Pod创建并绑定一个EIP:

      k8s.aliyun.com/pod-with-eip: "true"

      示例YAML如下。

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx-deployment-basic
        labels:
          app: nginx
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            annotations:
              k8s.aliyun.com/pod-with-eip: "true" # 为Nginx容器自动分配公网EIP地址。
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: nginx
    • 添加以下注解,指定EIP的带宽,默认带宽5 Mbps(与EIP的默认值保持一致):

      k8s.aliyun.com/eip-bandwidth: "5"
  • 指定EIP场景

    添加以下注解,为Pod指定EIP实例ID:

    k8s.aliyun.com/pod-eip-instanceid: "<youreipInstanceId>"
    说明
    • 由于单个EIP不支持关联多个Pod,所以不适用于Deployment和StatefulSet等场景。

    • 默认情况下如果EIP已经绑定了实例,则会创建EIP失败。如果希望解绑之前的实例再绑定新的实例,需要在上述修改ConfigMap中配置"allow_eip_rob": "true"

    • 指定EIP实例ID的场景只能用于单个副本实例的情况,例如,Deployment不能超过1个Replicas。

验证配置

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

阿里云首页 容器服务Kubernetes版 相关技术圈