Spiderpool:Calico 固定应用 IP 的一种新选择¶
Calico 是一套开源的网络和网络安全解决方案,也是作为 Kubernetes 容器网络解决方案 (CNI: Container Network Interface) 的一种实现。 它基于 Linux 纯三层路由实现,在一些场景下用户可以将 Pod 子网的路由通过 Calico BGP 模式宣告到网关, 来自集群外的客户端可以直接通过 Pod 的 IP 访问 Pod,同时还可以保留客户端的源 IP。
当前痛点¶
在 Calico Underlay 网络模式下,用户还希望 Deployment 或 StatefulSet 类型应用的 IP 地址,能够被固定或是在一个指定的 IP 范围中浮动,因为:
- Pod 的 IP 地址常常受防火墙策略管控,防火墙只会允许特定的 IP 或者 IP 范围内的目标访问
- 传统微服务应用直接使用 Pod IP 进行微服务注册
- 一些场景下业务 IP 为固定的 IP,不会变化
Calico 通过在 Pod 中注入注解: cni.projectcalico.org/ipAddrs 可以实现 Pod 级别的 IP 固定,但是 在使用中我们发现以下不足 :
- 固定 IP 只在 Pod 级别生效,对 Deployment、StatefulSet 类型无能为力;
- 需要管理员保证 Pod 的注解 IP 是不重叠的,避免出现 IP冲突。尤其是在大规模集群下,难以排查冲突的 IP;
- 固定 IP 地址的配置、管理繁琐,不具有云原生化。
解决方式:Spiderpool¶
针对上述不足,我们尝试通过 Spiderpool 来实现这点需求。 Spiderpool 是一个 Kubernetes 的 IPAM 插件项目,其主要针对于 Underlay 网络的 IP 地址管理需求而设计, 能够为任何兼容第三方 IPAM 插件的 CNI 项目所使用。它主要具有以下几个特点:
- 能为 Deployment、StatefulSet 类型自动化分配固定 IP 地址,并且做到 IP 地址数量随副本数量自动扩缩容
- 以 CRD 方式管理、配置 IP 池,极大减少运维成本
- 支持第三方控制器创建的 Pod
- 支持为 Pod 多网卡指定不同子网
下面将对 Spiderpool 进行展开介绍。
安装 Spiderpool¶
以下是笔者参考 Spiderpool 官方文档搭建了一套 Calico BGP 模式搭配 Spiderpool 的环境,网络环境拓扑图如下:
根据自身环境创建 SpiderSubnet 实例: nginx-subnet-v4,体验 Spiderpool 固定 IP 等功能。
[root@master ~]# kubectl get ss
NAME VERSION SUBNET ALLOCATED-IP-COUNT TOTAL-IP-COUNT
nginx-subnet-v4 4 10.244.0.0/16 0 25602
自动为应用固定 IP 池¶
该功能支持从 SpiderSubnet(10.244.0.0/16) 子网中自动创建 IP 池,并绑定到应用 Pod。并且支持 Pod IP 固定、IP 池数量随副本数量自动扩缩容等功能。
使用 Spiderpool 自动池功能, 创建两个副本的 Nginx Deployment 应用:
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
annotations:
ipam.spidernet.io/subnet: '{"ipv4":["nginx-subnet-v4"]}'
ipam.spidernet.io/ippool-ip-number: '+3'
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
- ipam.spidernet.io/subnet:Spiderpool 从 "nginx-subnet-v4" 子网中随机选择一些 IP 来创建固定 IP 池,并与应用绑定
- ipam.spidernet.io/ippool-ip-number:'+3' 表示 IP 池的 IP 总量为比副本数多三个,解决应用滚动发布时有临时 IP 可用
当应用 Deployment 被创建,Spiderpool 中自动创建了一个名为 auto-nginx-v4-eth0-452e737e5e12 的 IP 池, 并与应用绑定。IP 范围为:10.244.100.90-10.244.100.95,池 IP 数量为 5:
[root@master1 ~]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-644659db67-6lsmm 1/1 Running 0 12s 10.244.100.93 worker5 <none> <none>
nginx-644659db67-n7ttd 1/1 Running 0 12s 10.244.100.91 master1 <none> <none>
[root@master1 ~]# kubectl get sp
NAME VERSION SUBNET ALLOCATED-IP-COUNT TOTAL-IP-COUNT DEFAULT DISABLE
auto-nginx-v4-eth0-452e737e5e12 4 10.244.0.0/16 2 5 false false
[root@master ~]# kubectl get sp auto-nginx-v4-eth0-452e737e5e12 -o jsonpath='{.spec.ips}'
["10.244.100.90-10.244.100.95"]
Pod 的 IP 被固定在自动池: auto-nginx-v4-eth0-452e737e5e12(10.244.100.90-10.244.100.95) 中范围内,重启 Pod 其 IP 也被固定在此范围内:
[root@master1 ~]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-644659db67-szgcg 1/1 Running 0 23s 10.244.100.90 worker5 <none> <none>
nginx-644659db67-98rcg 1/1 Running 0 23s 10.244.100.92 master1 <none> <none>
扩容副本,新副本的 IP 地址从自动池: auto-nginx-v4-eth0-452e737e5e12(10.244.100.90-10.244.100.95) 中自动分配,并且 IP 池随副本数量自动扩容:
[root@master1 ~]# kubectl scale deploy nginx --replicas 3 # scale pods
deployment.apps/nginx scaled
[root@master1 ~]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-644659db67-szgcg 1/1 Running 0 1m 10.244.100.90 worker5 <none> <none>
nginx-644659db67-98rcg 1/1 Running 0 1m 10.244.100.92 master1 <none> <none>
nginx-644659db67-brqdg 1/1 Running 0 10s 10.244.100.94 master1 <none> <none>
[root@master1 ~]# kubectl get sp
NAME VERSION SUBNET ALLOCATED-IP-COUNT TOTAL-IP-COUNT DEFAULT DISABLE
auto-nginx-v4-eth0-452e737e5e12 4 10.244.0.0/16 3 6 false false
手动指定 IP 池¶
在某些场景下,用户希望直接应用 IP 从一个固定的 IP 范围中分配,而不是由 Spiderpool 随机分配,下面是将展示此功能:
创建 IP 池:
cat << EOF | kubectl apply -f -
apiVersion: spiderpool.spidernet.io/v2beta1
kind: SpiderIPPool
metadata:
name: nginx-v4-ippool
spec:
ipVersion: 4
subnet: 10.244.0.0/16
ips:
- 10.244.120.10-10.244.120.20
spec.subnet 表示该 IP 池属于哪一个子网
spec.ips 固定 IP 地址范围,范围为 10.244.120.10-10.244.120.20,共计 10 个 IP
通过注解 ipam.spidernet.io/ippool 手动指定 IP 池:nginx-v4-ippool,创建应用:nginx-m:
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-m
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
annotations:
ipam.spidernet.io/ippool: '{"ipv4":["nginx-v4-ippool"]}'
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
Spiderpool 从 nginx-v4-ippool 池中分配两个 IP 并绑定到应用。Pod 无论重启或是扩容,仍然从该池中分配 IP ,达到固定 IP 的效果:
[root@master1 ~]# kubectl get po -o wide | grep nginx-m
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-m-7c879df6bc-26dcq 1/1 Running 0 23s 10.244.120.12 worker5 <none> <none>
nginx-m-7c879df6bc-nwdtp 1/1 Running 0 23s 10.244.120.14 master1 <none> <none>
[root@master1 ~]# kubectl get sp
NAME VERSION SUBNET ALLOCATED-IP-COUNT TOTAL-IP-COUNT DEFAULT DISABLE
auto-nginx-v4-eth0-452e737e5e12 4 10.244.0.0/16 3 6 false false
nginx-v4-ippool 4 10.244.0.0/16 2 11 false false
结论¶
经过测试: 集群外客户端可直接通过 Nginx Pod 的 IP 正常访问,集群内部通讯 Nginx Pod 跨节点也都通信正常 (包括跨 Calico 子网)。 在 Calico underlay 场景下,我们可借助 Spiderpool 轻松帮助我们实现 Deployment 等类型应用固定 IP 的需求,这也为该场景下提供了一个新的选择。
更多功能介绍参考 Spiderpool 官方文档。
下载 DCE 5.0 安装 DCE 5.0 申请社区免费体验