VPC-ENI指定子网分配IP(容器网络 v2)
概览
VPC-ENI容器网络模式支持指定子网为Pod分配IP,用户可以使用这个能力为不同的业务应用Pod规划分配不同子网的IP地址。
说明:使用该功能需要联系百度智能云客服开启白名单。
需求场景
需求场景1:指定子网动态分配IP
从与Pod匹配的子网拓扑约束策略关联的子网中动态为Pod分配IP。匹配了子网拓扑约束策略(psts)的所有Pod只从策略包含的子网分配IP地址。
场景2:手动分配 IP
手动分配 IP 策略的含义是给定一个IP列表,CCE从这个IP列表中给 Pod 分配 IP 。Pod 删除后 IP 地址保留,在 IP 地址过期之前,Pod重建或者迁移后,IP地址仍然不变。默认情况下,Pod 删除后,IP 地址会保留 7 天。
场景3:固定IP
固定 IP 策略的含义是给定一个IP列表,CCE从这个IP列表中给有状态负载的Pod分配IP。Pod删除后IP地址保留,Pod重建或者迁移后,IP地址仍然不变。 无论 Pod 是否删除,已经分配的IP地址不会被释放,直到工作负载被删除后,IP 地址才会被回收。
方案概述
如下CRD数据结构所示,CCE提供了自定义CRD来指定Pod子网拓扑分布策略,用于在CCE集群中实施制定子网分配IP功能。
关键数据结构介绍
Pod子网拓扑分布 PodSubnetTopologySpread
子网拓扑分布对象是指定子网分配IP的核心工作对象,它的核心数据结构定义如下:
1apiVersion: cce.baidubce.com/v2
2kind: PodSubnetTopologySpread
3metadata:
4  name: example-subnet-topology
5  namespace: default
6spec:
7  # 拓扑分布对象名
8  name: example-subnet-topology
9  # 多个子网拓扑约束之间的优先级,数字越大,优先级越高。默认值0
10  priority: 0
11  subnets:
12    # 必须是与当前集群同VPC的子网ID,格式为sbn-*例如sbn-ccfud13pwcqf
13    # 使用专属子网,用户要确认该子网只有当前CCE集群使用
14    sbn-ccfud13pwcqf: []
15  strategy:
16    releaseStrategy: TTL
17    ttl: 168h0m0s
18    type: Elastic
19  # 选择要使用该子网拓扑分布的Pod
20  selector: 
21    matchLabels:
22      app: foo该对象的核心字段如下:
| 域 | 数据类型 | 必须 | 默认值 | 描述 | 
|---|---|---|---|---|
| name | string | 拓扑分布对象名,在通过 PodSubnetTopologySpread创建子网拓扑分布时必填。 | ||
| priority | int32 | 否 | 0 | 多个子网拓扑约束之间的优先级,数字越大,优先级越高。 | 
| selector | object | 否 | 使用该条件对Pod做标签匹配,符合条件的Pod将在分配IP地址时使用该规则。如果 selector为空,则同namespace下的所有Pod都匹配该规则。 | |
| subnets | object | 是 | 策略要使用的子网。CCE会从这些子网中为Pod分配IP地址。 | |
| subnets.[].family | string | 是 | IP 地址协议族。取值 "4"或"6" | |
| subnets.[].range | array | 是 | IP 地址范围 | |
| subnets.[].range[].start | string | 是 | 起始 IP 地址 | |
| subnets.[].range[].end | string | 是 | 结束 IP 地址 | |
| strategy | object | 是 | IP 地址使用和回收策略 | |
| strategy.type | string | 是 | Elastic | Elastic: 动态分配 IP 地址,可以使用任意工作负载;Fixed:永久固定 IP 地址,仅搭配 sts 工作负载使用;PrimaryENI:独占 ENI 专用 IP 地址 | 
| strategy.releaseStrategy | string | 是 | TTL | IP 地址释放策略。 TTL: Pod 被删除后,IP 地址随时间过期。其中在动态 IP 分配模式下,Pod 删除后,IP 立刻回收。 开启enableReuseIPAddress时,默认 7 天回收。Never: 仅搭配strategy.type: Fixed使用,代表永不回收。 | 
| strategy.enableReuseIPAddress | bool | 否 | false | 是否在 strategy.type: Elastic的场景下开启 IP 重用。如开启 IP 重用,则在 IP 地址过期之前,如果有同名的 Pod 重复创建,则尽力去复用 IP,以达到类似固定 IP 的效果。 | 
| strategy.ttl | string | 否 | 168h0m0s | 在开启 IP 地址重用时,Pod 删除后,保留 IP 的时间。默认值是 7 天(168h0m0s) | 
使用限制
- 该功能需使用VPC的ENI跨子网分配IP功能,请提交工单申请使用ENI跨子网分配IP功能。
- kube-system命名空间的Pod无法使用指定子网分配IP功能。
- 在使用 ipRange功能时,请确保指定的IP范围不包括特殊IP地址,如IPv4的网络地址、网关地址、广播地址和多播地址。包含这些特殊地址可能会导致IP分配出现问题。
- 指定子网的Pod只能调度到子网所在可用区的节点,请确认可用区有Ready状态的节点。
- 固定IP和IP复用场景下只能使用专属子网(指定的子网只能供单个CCE集群使用),专属子网不支持变更为普通子网、不支持从集群内删除,详情见专属子网说明。
- 该功能仅适用于容器网络 v2 版本的集群。
专属子网: 当用户需要为Pod分配指定子网下的某几个IP时,IP所属的子网将自动被标记为手动分配IP模式。手动分配IP模式下的子网有以下特征:
- 专属子网应为当前CCE集群专属,CCE会自动为子网增加专属标签,其它的CCE集群拒绝使用该子网。(用户可以操作百度云其它产品使用该子网)
- 对专属子网仅支持手动分配IP,不会自动分配IP。这需要用户自己管理IP地址规划
- 专属子网下IP和Pod的关系可以有优先分配和固定绑定两种。固定绑定策略使用Pod名作为绑定标识,同一个Pod名的IP地址相同
- 集群Pod的默认子网不能是专属子网,否则可能导致集群中的其它Pod无法正常分配IP
- 专属子网不支持变更为普通子网、不支持从集群内删除
配置步骤
环境准备
创建私有子网
在百度智能云VPC控制台->子网选项卡,为自己的VPC新建一个子网,并保存子网ID (以sbn-xxx格式命名的是子网ID)。注意创建子网时应选择与CCE集群节点相关的可用区,否则可能导致调度失败。
说明: 如需使用ENI跨子网分配IP功能,请提交工单申请。
在CCE上操作指定子网分配IP
场景1: 指定子网动态分配IP
从与Pod匹配的子网拓扑约束策略关联的子网中动态为Pod分配IP。匹配了子网拓扑约束策略(psts)的所有Pod只从策略包含的子网分配IP地址。
适用场景:
- 以子网维度对流量做统计
- 以子网维度做安全策略,如ACL规则控制
- 通过NAT网关为特定子网开启互联网访问
1. 创建psts
1apiVersion: cce.baidubce.com/v2
2# pod 拓扑分布表
3kind: PodSubnetTopologySpread
4metadata:
5  name: default
6  namespace: default
7spec:
8  # 多个子网拓扑约束之间的优先级,排序越靠前,优先级越大
9  priority: 0
10  name: default-psts
11  strategy:
12    releaseStrategy: TTL
13    type: Elastic
14  subnets:
15    # 必须是与当前集群同VPC的子网ID,格式为sbn-*例如sbn-ccfud13pwcqf
16    sbn-ccfud13pwcqf: []
17    sbn-e8rk4zxn2ys6: []
18  # 选择要使用该子网拓扑分布的pod,如果为空则表示所有pod都使用该子网拓扑分布
19    selector: 
20      matchLabels:
21        app: foo2. 创建工作负载
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: elastic-deploy
5  namespace: default
6spec:
7  replicas: 1
8  selector: 
9    matchLabels:
10      app: foo
11  template:
12    metadata:
13      labels:
14        app: foo
15    spec:
16      containers:
17      - image: nginx
18        name: nginx3. 验证IP分配结果
1# kubectl get pod {podName} -oyaml
2apiVersion: v1
3kind: Pod
4metadata:
5  annotations:
6    cce.baidubce.com/PodSubnetTopologySpread: example-subnet-topology
7  generateName: elastic-deploy-56dc49b486-
8  labels:
9    app: foo
10  name: elastic-deploy-56dc49b486-d6z7b
11  namespace: default
12spec:
13  affinity:
14    nodeAffinity:
15      requiredDuringSchedulingIgnoredDuringExecution:
16        nodeSelectorTerms:
17        - matchExpressions:
18          - key: topology.kubernetes.io/zone
19            operator: In
20            values:
21            - zoneF
22  containers:
23  - image: nginx
24    imagePullPolicy: IfNotPresent
25    name: nginx
26    resources:
27      limits:
28        cce.baidubce.com/ip: "1"
29      requests:
30        cce.baidubce.com/ip: "1"场景2:手动分配 IP
手动分配 IP 策略的含义是给定一个IP列表,CCE从这个IP列表中给 Pod 分配 IP 。Pod 删除后 IP 地址保留,在 IP 地址过期之前,Pod重建或者迁移后,IP地址仍然不变。默认情况下,Pod 删除后,IP 地址会保留 7 天。
适用场景:
- 固定Pod IP,要求Pod迁移后IP支持不变
- 使用专属子网,并完全手动管理该子网的IP
- Pod 多次重建后名字不变,例如使用有状态工作负载(apps/v1 StatefulSet)创建的 Pod
1. 创建 psts
1apiVersion: cce.baidubce.com/v2
2kind: PodSubnetTopologySpread
3metadata:
4  name: example-subnet-topology
5  namespace: default
6spec:
7  priority: 0
8  subnets:
9    sbn-6mrkdcsyzpaw:
10    # 非必须,固定 IP 的范围,不填表示使用子网默认 IP 范围
11    - family: 4
12      range:
13      - start: 10.0.0.2
14        end: 10.0.0.254
15  strategy:
16    releaseStrategy: TTL
17    ttl: 168h0m0s
18    type: Elastic
19    # 必须,开启 IP 重用
20    enableReuseIPAddress: true   
21  selector:
22    matchLabels:
23      workloadType: sts
24      fixedIP: "true"
25      app: fixedIPApp2. 创建工作负载
1apiVersion: apps/v1
2# 必须使用有状态工作负载
3kind: StatefulSet
4metadata:
5  name: foo
6  namespace: default
7spec:
8  replicas: 1
9  selector:
10    matchLabels:
11      app: fixedIPApp
12  serviceName: foo
13  template:
14    metadata:
15      labels:
16        workloadType: sts
17        fixedIP: "true"
18        app: fixedIPApp
19    spec:
20      containers:
21      - image: nginx
22        name: nginx3. 验证IP分配结果
1# kubectl get pod {podName} -oyaml
2apiVersion: v1
3kind: Pod
4metadata:
5  annotations:
6    cce.baidubce.com/PodSubnetTopologySpread: example-subnet-topology
7  labels:
8    app: foo
9  name: foo-0
10  namespace: default
11spec:
12  affinity:
13    nodeAffinity:
14      requiredDuringSchedulingIgnoredDuringExecution:
15        nodeSelectorTerms:
16        - matchExpressions:
17          - key: topology.kubernetes.io/zone
18            operator: In
19            values:
20            - zoneF
21  containers:
22  - image: nginx
23    imagePullPolicy: IfNotPresent
24    name: nginx
25    resources:
26      limits:
27        cce.baidubce.com/ip: "1"
28      requests:
29        cce.baidubce.com/ip: "1"场景3:固定IP
固定 IP 策略的含义是给定一个IP列表,CCE从这个IP列表中给有状态负载的Pod分配IP。Pod删除后IP地址保留,Pod重建或者迁移后,IP地址仍然不变。 无论 Pod 是否删除,已经分配的IP地址不会被释放,直到工作负载被删除后,IP 地址才会被回收。
适用场景:
- 指定的子网必须是单个CCE集群使用,且该子网不再用于动态分配IP地址(子网会被CCE标记为专属子网)。
- 以IP地址为维度做安全策略,如以子网维度制定ACL。
- 仅适用于有状态工作负载(apps/v1 StatefulSet)创建的 Pod。
1. 创建 psts
1apiVersion: cce.baidubce.com/v2
2kind: PodSubnetTopologySpread
3metadata:
4  name: example-subnet-topology
5  namespace: default
6spec:
7  subnets:
8    sbn-6mrkdcsyzpaw:
9    # 非必须,固定 IP 的范围,不填表示使用子网默认 IP 范围
10    - family: 4
11      range:
12      - start: 10.0.0.2
13        end: 10.0.0.254
14  strategy:
15    releaseStrategy: Never
16    type: Fixed
17    enableReuseIPAddress: true
18  # 选择要使用该子网拓扑分布的Pod
19  selector: 
20    matchLabels:
21      app: foo2. 创建工作负载
1apiVersion: apps/v1
2# 必须使用有状态工作负载
3kind: StatefulSet
4metadata:
5  name: foo
6  namespace: default
7spec:
8  replicas: 1
9  selector:
10    matchLabels:
11      app: fixedIPApp
12  serviceName: foo
13  template:
14    metadata:
15      labels:
16        workloadType: sts
17        fixedIP: "true"
18        app: fixedIPApp
19    spec:
20      containers:
21      - image: nginx
22        name: nginx3. 验证IP分配结果
1# kubectl get pod {podName} -oyaml
2apiVersion: v1
3kind: Pod
4metadata:
5  annotations:
6    cce.baidubce.com/PodSubnetTopologySpread: example-subnet-topology
7  labels:
8    app: foo
9  name: foo-0
10  namespace: default
11spec:
12  affinity:
13    nodeAffinity:
14      requiredDuringSchedulingIgnoredDuringExecution:
15        nodeSelectorTerms:
16        - matchExpressions:
17          - key: topology.kubernetes.io/zone
18            operator: In
19            values:
20            - zoneF
21  containers:
22  - image: nginx
23    imagePullPolicy: IfNotPresent
24    name: nginx
25    resources:
26      limits:
27        cce.baidubce.com/ip: "1"
28      requests:
29        cce.baidubce.com/ip: "1"