为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