需求:
在某种情况下,创建 Pod 时主动给它分配IP地址,并要求即使重启Pod IP地址也不变。
这里演示 Calico 网络插件环境中,如何给 Pod 分配固定的 IP 地址。
一、确认环境
1. 修改 calico 配置文件
修改配置文件 vim /etc/cni/net.d/10-calico.conflist
,将 ipam
类型修改为 calico-ipam
$ vim /etc/cni/net.d/10-calico.conflist
"ipam": {
"type": "calico-ipam"
}
2. 安装 calicoctl 工具
二进制方式安装 calicoctl 工具,版本号选择 Calico 相同的版本,这里是 3.26.3
2.1 安装 calicoctl
# 下载 calicoctl 二进制包
$ wget https://github.com/projectcalico/calico/releases/download/v3.26.3/calicoctl-linux-amd64
# 将二进制包放到指定目录
$ mv calicoctl-linux-amd64 /usr/local/bin/calicoctl
# 授权
$ chmod +x /usr/local/bin/calicoctl
# 永久设置环境变量
calicoctl get ippool --show-ip-allocations
2.2 配置 calicoctl
calicoctl 通过读写 calico 的数据存储系统( datastore )进行查看或者其他各类管理操作,通常,它需要提供认证信息经由相应的数据存储完成认证。在使用Kubernetes API
数据存储时,需要使用类似 kubectl 的认证信息完成认证。它可以通过环境变量声明的 DATASTORE_TYPE
和 KUBECONFIG
接入集群,例如以下命令格式运行 calicoctl :
# 临时设置环境变量
$ export CALICO_DATASTORE_TYPE=kubernetes
$ export CALICO_KUBECONFIG=~/.kube/config
# 测试
$ calicoctl get nodes
NAME
k8s-master01
k8s-node01
k8s-node02
k8s-node03
也可以直接将认证信息等保存于配置文件中,calicoctl 默认加载 /etc/calico/calicoctl.cfg
配置文件读取配置信息,如下所示:
$ cat /etc/calico/calicoctl.cfg
apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:
datastoreType: "kubernetes"
kubeconfig: "/root/.kube/config"
3. 查看 calico 的 CIDR 地址范围
$ calicoctl get ippool
NAME CIDR SELECTOR
default-ipv4-ippool 171.20.0.0/16 all()
4. 创建 Pod
在 CIDR 地址范围内给 Pod 设定一个 IP 地址。
IP 地址范围:171.20.0.0 到 171.20.255.255
4.1 直接创建 Pod
资源清单1:fixed-pod-ip.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx
annotations:
# 设置Pod固定ip地址
"cni.projectcalico.org/ipAddrs": "[\"171.20.45.27\"]"
name: fixed-pod-ip
namespace: default
spec:
containers:
- image: nginx:1.29.0
imagePullPolicy: IfNotPresent
name: nginx
执行资源清单
# 执行资源清单,创建Pod
$ kubectl apply -f fixed-pod-ip.yaml
# 查看Pod,使用的正是分配的IP
$ kubectl get pods -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
fixed-pod-ip 0/1 ContainerCreating 0 3s <none> k8s-node01 <none> <none>
fixed-pod-ip 0/1 ContainerCreating 0 3s <none> k8s-node01 <none> <none>
fixed-pod-ip 1/1 Running 0 7s 171.20.45.27 k8s-node01 <none> <none>
# 测试访问
$ curl http://171.20.45.27:80
<!DOCTYPE html>
<html>
<body>
<h1>Welcome to nginx!</h1>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
4.2 创建 Deployment
资源清单:fixed-deploy-ip.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: fixed-deploy-ip
labels:
app: my-deploy
spec:
selector:
matchLabels:
app: fixed-deploy
template:
metadata:
labels:
app: fixed-deploy
annotations:
# 设置Pod固定ip地址
"cni.projectcalico.org/ipAddrs": "[\"171.20.42.65\"]"
spec:
containers:
- image: nginx:1.29.0
imagePullPolicy: IfNotPresent
name: nginx
执行资源清单
# 执行资源清单,创建Pod
$ kubectl apply -f fixed-deploy-ip.yaml
# Pod使用Ip为手动分配的IP
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
fixed-deploy-ip-6fcf56c75b-tk6nb 1/1 Running 0 78s 171.20.42.65 k8s-node01 <none> <none>
# 删除Pod,重新生成Pod
$ kubectl delete pod fixed-deploy-ip-6fcf56c75b-tk6nb
# 新的Pod ip 依旧是手动分配的IP
$ kubectl get pods -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
fixed-deploy-ip-6fcf56c75b-25pxm 1/1 Running 0 11s 171.20.42.65 k8s-node02 <none> <none>
注意: 使用 Deployment 自动分配IP, replicas 副本数必须是1,多个Pod会存在IP冲突问题,如下:
$ kubectl describe pod fixed-deploy-ip-6fcf56c75b-cgksd
Name: fixed-deploy-ip-6fcf56c75b-cgksd
Namespace: default
Priority: 0
Service Account: default
Node: k8s-node01/10.20.1.140
Start Time: Mon, 28 Jul 2025 10:59:27 +0800
Labels: app=fixed-deploy
pod-template-hash=6fcf56c75b
Annotations: cni.projectcalico.org/ipAddrs: ["171.20.42.65"]
cni.projectcalico.org/podIP:
cni.projectcalico.org/podIPs:
Status: Pending
IP:
IPs: <none>
Controlled By: ReplicaSet/fixed-deploy-ip-6fcf56c75b
Containers:
nginx:
Container ID:
Image: nginx:1.29.0
Image ID:
Port: <none>
Host Port: <none>
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-dd6zw (ro)
Conditions:
Type Status
PodReadyToStartContainers False
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
kube-api-access-dd6zw:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 28s default-scheduler Successfully assigned default/fixed-deploy-ip-6fcf56c75b-cgksd to k8s-node01
Warning FailedCreatePodSandBox 24s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "f1b3f4fc77eeca1672a1ddd935bdbda2d7a1dbd237a5be89b7422a56a315dc0a" network for pod "fixed-deploy-ip-6fcf56c75b-cgksd": networkPlugin cni failed to set up pod "fixed-deploy-ip-6fcf56c75b-cgksd_default" network: plugin type="calico" failed (add): error getting IP from IPAM: resource already exists: 171.20.42.65
Warning FailedCreatePodSandBox 20s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "bf2d21340a820b55b1f202d2f89f68d42523859dacd1e1c9a5d757e814fc34b4" network for pod "fixed-deploy-ip-6fcf56c75b-cgksd": networkPlugin cni failed to set up pod "fixed-deploy-ip-6fcf56c75b-cgksd_default" network: plugin type="calico" failed (add): error getting IP from IPAM: resource already exists: 171.20.42.65
Warning FailedCreatePodSandBox 16s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "230660cce4caaf260bfb2079479d8885aa19059441759246db3ef8ac5f93ba6c" network for pod "fixed-deploy-ip-6fcf56c75b-cgksd": networkPlugin cni failed to set up pod "fixed-deploy-ip-6fcf56c75b-cgksd_default" network: plugin type="calico" failed (add): error getting IP from IPAM: resource already exists: 171.20.42.65
Warning FailedCreatePodSandBox 11s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "7b28648e2799adc7c5e73f5038279586ac36226f157349ae8054b0048953f41c" network for pod "fixed-deploy-ip-6fcf56c75b-cgksd": networkPlugin cni failed to set up pod "fixed-deploy-ip-6fcf56c75b-cgksd_default" network: plugin type="calico" failed (add): error getting IP from IPAM: resource already exists: 171.20.42.65
Warning FailedCreatePodSandBox 5s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "2eed3030e3bfecbc5668a1621454a26dfd67688c5d152e638c86b58baa66b826" network for pod "fixed-deploy-ip-6fcf56c75b-cgksd": networkPlugin cni failed to set up pod "fixed-deploy-ip-6fcf56c75b-cgksd_default" network: plugin type="calico" failed (add): error getting IP from IPAM: resource already exists: 171.20.42.65
5. 手动释放IP
在使用过程中可能会遇到 IP 没有释放等问题导致 pod 启动失败,导致这种原因可能是 pod 被删除后,使用的 IP 地址未被释放,所以需要使用以下命令对地址池的 IP 进行释放,才能够被 pod 重新使用
$ calicoctl ipam release --ip 171.20.42.65
参考链接
https://blog.csdn.net/weixin_48711696/article/details/135749305
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 george_95@126.com