为Pod配置固定IP地址

IP敏感型应用升级时,由于Pod重建会导致IP的变化,可能会影响到实际业务。ACS提供Pod重建后IP保持不变的能力,以满足固定IP地址场景的业务升级需求。

适用范围

  • 仅支持计算类型为通用型性能型CPU Pod。

  • 不支持跨ECS节点和ACS虚拟节点保留固定IP地址。

    如果一个Pod先被调度到ECS节点,Pod重建时被调度到ACS虚拟节点,此时无法保留固定IP地址。反之如果先被调度到ACS虚拟节点,后被调度到ECS节点,固定IP地址同样无法保留。

功能说明

Kubernetes集群中常使用诸如StatefulSet工作负载来管理有状态应用,在应用升级时工作负载通过先删除老版本的Pod、再创建新版本Pod的方式来实现滚动升级。对于大多数符合微服务架构的服务,此种方式能够满足业务升级需求。由于Pod重建会导致IP的变化,所以对于一些IP敏感型应用无法直接升级,例如:

  • Pod来源IP做白名单校验(例如DB授权)。

  • 基于Pod IP来实现服务发现、路由分配。

ACS针对有状态应用提供Pod重建后IP保持不变的能力,当Pod释放后,系统会在有效期内保留其固定的IP地址。该能力依赖于StatefulSet提供的稳定、可预测的Pod名称(例如web-0web-1),如果新创建的Pod与被释放的Pod的集群ID、命名空间和Pod名称一致,且启用了固定IP地址,则系统会将保留的IP地址分配给新创建的Pod,从而实现同一StatefulSetPodIP地址保持不变。

前一个Pod未完全删除前会一直占用IP地址,会影响新Pod的创建速度。

配置说明

Podmetadata中添加注解来启用固定IP地址,以及固定IP地址空闲后的保留时长。相关注解说明如下:

注解(Annotations)

示例值

说明

network.alibabacloud.com/enable-fixed-ip

"true"

取值说明:

  • true:表示Pod启用固定IP地址,默认保留时长为48小时。

  • false或不配置该注解:表示Pod不使用固定IP地址。

network.alibabacloud.com/fixed-ip-release-after

"48"

固定IP地址空闲后的保留时长。即启用固定IP地址的Pod释放后,其固定IP地址的保留时长,单位为小时。

只有同时配置了network.alibabacloud.com/enable-fixed-ip: "true"时才会生效。

固定IP地址保持时间是从您删除Pod的时间开始计算。若您重复删除创建Pod,则以最后一次删除时间为准。

使用示例

  1. 使用以下内容创建fixed-ip.yaml文件,然后执行kubectl apply -f fixed-ip.yaml命令创建示例应用。

    本示例表示创建一个StatefulSet,该StatefulSet中包含两个Pod,该Pod配置了启用固定IP地址的注解network.alibabacloud.com/enable-fixed-ip: "true"
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: web
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 2
      template:
        metadata:
          name: nginx
          labels:
            app: nginx
          annotations:
            network.alibabacloud.com/enable-fixed-ip: "true"
        spec:
          containers:
          - name: nginx
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            ports:
            - containerPort: 80
    
  2. 监控Pod状态变化。

    kubectl get pod -o wide -w

    预期输出:

    成功创建后会自动显示2Pod对应的IP地址,如web-0192.168.1.8web-1192.168.2.2
    NAME    READY   STATUS              RESTARTS   AGE   IP            NODE                              NOMINATED NODE   READINESS GATES
    web-0   0/1     Pending             0          1s    <none>        <none>                            <none>           <none>
    web-0   0/1     Pending             0          20s   <none>        <none>                            <none>           <none>
    web-0   0/1     Pending             0          20s   <none>        virtual-kubelet-cn-wulanchabu-b   <none>           <none>
    web-0   0/1     ContainerCreating   0          24s   192.168.1.8   virtual-kubelet-cn-wulanchabu-b   <none>           <none>
    web-0   1/1     Running             0          25s   192.168.1.8   virtual-kubelet-cn-wulanchabu-b   <none>           <none>
    web-1   0/1     Pending             0          0s    <none>        <none>                            <none>           <none>
    web-1   0/1     Pending             0          21s   <none>        <none>                            <none>           <none>
    web-1   0/1     Pending             0          21s   <none>        virtual-kubelet-cn-wulanchabu-c   <none>           <none>
    web-1   0/1     ContainerCreating   0          24s   192.168.2.2   virtual-kubelet-cn-wulanchabu-c   <none>           <none>
    web-1   1/1     Running             0          25s   192.168.2.2   virtual-kubelet-cn-wulanchabu-c   <none>           <none>
  3. 打开一个新的命令行终端,滚动更新示例应用。

    kubectl rollout restart statefulset web
  4. 切换回之前的终端,观察Pod滚动更新过程中的状态变化。

    预期输出如下,可以看到删除Pod后,StatefulSet会自动创建新的Pod,新的PodIP地址保持192.168.1.8192.168.2.2不变。

    NAME    READY   STATUS              RESTARTS   AGE   IP            NODE                              NOMINATED NODE   READINESS GATES
    ...
    web-1   1/1     Terminating         0          25m   192.168.2.2   virtual-kubelet-cn-wulanchabu-c   <none>           <none>
    web-1   0/1     Completed           0          25m   192.168.2.2   virtual-kubelet-cn-wulanchabu-c   <none>           <none>
    web-1   0/1     Pending             0          0s    <none>        <none>                            <none>           <none>
    web-1   0/1     Pending             0          1s    <none>        <none>                            <none>           <none>
    web-1   0/1     Pending             0          17s   <none>        <none>                            <none>           <none>
    web-1   0/1     Pending             0          17s   <none>        virtual-kubelet-cn-wulanchabu-c   <none>           <none>
    web-1   0/1     Pending             0          17s   <none>        virtual-kubelet-cn-wulanchabu-c   <none>           <none>
    web-1   0/1     ContainerCreating   0          21s   192.168.2.2   virtual-kubelet-cn-wulanchabu-c   <none>           <none>
    web-1   1/1     Running             0          22s   192.168.2.2   virtual-kubelet-cn-wulanchabu-c   <none>           <none>
    web-0   1/1     Terminating         0          26m   192.168.1.8   virtual-kubelet-cn-wulanchabu-b   <none>           <none>
    web-0   0/1     Completed           0          26m   192.168.1.8   virtual-kubelet-cn-wulanchabu-b   <none>           <none>
    web-0   0/1     Pending             0          0s    <none>        <none>                            <none>           <none>
    web-0   0/1     Pending             0          1s    <none>        <none>                            <none>           <none>
    web-0   0/1     Pending             0          20s   <none>        <none>                            <none>           <none>
    web-0   0/1     Pending             0          20s   <none>        virtual-kubelet-cn-wulanchabu-b   <none>           <none>
    web-0   0/1     Pending             0          20s   <none>        virtual-kubelet-cn-wulanchabu-b   <none>           <none>
    web-0   0/1     ContainerCreating   0          24s   192.168.1.8   virtual-kubelet-cn-wulanchabu-b   <none>           <none>
    web-0   1/1     Running             0          24s   192.168.1.8   virtual-kubelet-cn-wulanchabu-b   <none>           <none>