kubernetes指定固定的Pod IP

半兽人 发表于: 2022-11-01   最后更新时间: 2022-11-02 15:51:30  
{{totalSubscript}} 订阅, 3,408 游览

为Pod指定一个固定IP地址,而不是让Calico自动选择。

价值

一些应用程序需要使用固定的IP地址。

概念

Kubernetes pod CIDR

Kubernetes pod CIDR是Kubernetes期望分配给pod IP的IP范围。它是为整个集群定义的,被各种Kubernetes组件用来确定一个IP是否属于哪个pod。例如,kube-proxy在处理流量时,如果一个IP来自一个pod,与不属于pod的流量是不同的。所有的pod IP都必须在CIDR范围内,以便Kubernetes能够正常运行。

IP Pools

IP池是IP地址的范围,Calico从中分配Pod IP。指定的固定IP必须在一个IP池中。

开始之前...

你的集群必须使用Calico IPAM,才能使用这个功能。如果你不确定你的集群使用的是哪种IPAM,分辨的方法取决于安装方式。

1、检查IPAM

IPAM插件可以在默认的安装资源上进行查询。

kubectl get installation default -o go-template --template {{.spec.cni.ipam.type}}

如果你的集群使用Calico IPAM,上述命令应该返回Calico

2、检查CNI配置

SSH到你的一个Kubernetes节点:

cat /etc/cni/net.d/10-calico.conflist

返回如下。

     "ipam": {
          "type": "calico-ipam"
      },

如果以上都返回正确,你正在使用Calico IPAM。如果IPAM不是Calico,或者10-calico.conflist文件不存在,你不能在你的集群中使用这些功能。

固定单个Pod Ip地址

cni.projectcalico.org/ipAddrs来注释pod,设置为要分配的IP地址的列表,用括号括起来。比如说:

"cni.projectcalico.org/ipAddrs": "[\"192.168.0.1\"]"

例如:

apiVersion: v1
kind: Pod
metadata:
  name: staticIpPod
  annotations:
    cni.projectcalico.org/ipAddrs: "[\"192.168.0.1\"]"
...

注意在地址周围使用转义的\"作为内部双引号。

当然,该地址必须在配置的Calico IP池内,并且目前没有被使用。注释必须在创建pod时存在;后来添加它没有任何效果。

限制 Pod 使用特定范围内的 IP 地址

查看现有地址池:

calicoctl get ippool
NAME                  CIDR            SELECTOR   
default-ipv4-ippool   172.23.0.0/16   a

准备ippool-1.yaml文件

apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: my.ippool-1
spec:
  cidr: 172.23.19.0/30    # 这里设置的地址池可用 IP 的个数是四个,从 0--3
  ipipMode: CrossSubnet
  natOutgoing: true
  disabled: false
  nodeSelector: all()
  allowedUses:
  - Workload
  - Tunnel

准备ippool-2.yaml文件

apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: my.ippool-2
spec:
  cidr: 172.23.19.4/30    # 这里设置的地址池可用 IP 的个数是四个,从 4--5
  ipipMode: CrossSubnet
  natOutgoing: true
  disabled: false
  nodeSelector: all()
  allowedUses:
  - Workload
  - Tunnel

创建:

calicoctl create -f ippool-1.yaml 
calicoctl create -f ippool-2.yaml

查看地址池:

calicoctl get ippool
NAME                  CIDR            SELECTOR   
default-ipv4-ippool   172.23.0.0/16    all()      
new-pool1             172.23.19.0/30   all()      
new-pool2             172.23.19.4/31   all()

在注解种加入 cni.projectcalico.org/ipv4pools和/或cni.projectcalico.org/ipv6pools,值为IP池的名称,用括号括起来。比如:

cni.projectcalico.org/ipv4pools: '["pool-1", "pool-2"]'

例如:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-cluster
  annotations:
    cni.projectcalico.org/ipv4pools: '["pool-1", "pool-2"]'
...

查看运行结果:

kubectl get pods -o wide | grep redis
redis-cluster-0                1/1     Running   0          37h   172.23.19.5       node3   <none>           <none>
redis-cluster-1                1/1     Running   0          37h   172.23.19.3       node5   <none>           <none>
redis-cluster-2                1/1     Running   0          37h   172.23.19.2       node2   <none>           <none>
redis-cluster-3                1/1     Running   0          37h   172.23.19.1       node4   <none>           <none>
redis-cluster-4                1/1     Running   0          37h   172.23.19.0       node1   <none>           <none>
redis-cluster-5                1/1     Running   0          37h   172.23.19.4       node3   <none>           <none>

可以看出,创建的 6 个 pod 的 IP 地址为0–5

释放已分配的 IP

在使用过程中可能会遇到 IP 没有释放等问题导致 pod 启动失败,导致这种原因可能是 pod 被删除后,使用的 IP 地址未被释放,所以需要使用以下命令对地址池的 IP 进行释放,才能够被 pod 重新使用。

calicoctl ipam release --ip 172.23.19.0

保留IP

在默认情况下,Calico可能将你设置的IP地址用于其他工作负载或内部隧道地址。为了防止被占用,有几个选项:

  • 为了保留整个IPPool用于手动分配,你可以将其节点选择器设置为"!all()"。由于!all()不能匹配任何节点,该IPPool将不会被用于任何自动分配。

  • 保留一个池的一部分,你可以创建一个IPReservation。这允许保留某些IP,这样Calico IPAM就不会自动使用它们。

  • 为了防止Calico将某个池子的IP用于内部IPIP和/或VXLAN隧道地址,你可以将IPPool上的allowedUses设置为["Workload"]

相关链接

https://projectcalico.docs.tigera.io/networking/use-specific-ip
https://projectcalico.docs.tigera.io/networking/legacy-firewalls

更新于 2022-11-02

查看kubernetes更多相关的文章或提一个关于kubernetes的问题,也可以与我们一起分享文章