文章目录
- 一、前言
- 二、学会查看 ippool 整个yaml文件中,各个属性什么意思
- 2.1 ippool整个yaml文件属性解释
- 2.2 calico底层网络通信(相同Node和不同Node)
- 2.3 小结
- 三、实践应用:kubernetes设置指定IP的场景及方法
- 3.1 基本语法(通过annotations指定)
- 基本语法1:每个pod指定IP池
- 基本语法2:每个pod指定静态IP地址
- 基本语法3:每个pod申请浮动IP
- 基本语法4:基于node节点指定IP池
- 基本语法5:基于命名空间指定IP池
- 3.2 实践应用
- 应用一:为pod指定IP地址池
- 步骤1:创建IP地址池
- 步骤2:创建应用测试
- 小结
- 应用二:Pod设置静态IP/固定IP(设置的IP地址必须包含在已存在的IPPool中)
- 应用三:删除或禁用已存在的IPPool
- 禁用IPPool
- 删除IPPool
- 应用四:根据节点指定IP池
- 步骤1:给节点打上标签
- 步骤2:创建IPPool
- 步骤3:创建应用测试
- 应用五:基于namespace指定IP池
- 步骤1:查看当前存在的IP池
- 步骤2:创建新的IP池
- 步骤3:创建新的namespace,并指定IP池
- 步骤4:创建应用测试
- 小结
- 四、尾声
一、前言
Kubernetes中,除了daemonSet和运行在主节点的静态Pod(例如 apiserver controller-manager scheduler etcd),直接使用宿主机IP作为Pod之外,其他的,deployment statefulset job/cronjob replicaSet 控制器管理的Pod,都是需要使用虚拟IP的。这些Pod运行所需要的虚拟IP,都是cni网络插件生成的,如果使用的cni网络插件是Calico的,这些虚拟IP是一个crd自定义的 kind: IPPool 的资源生成的。
这篇文章就来看一下Calico中这个IPPool是怎样为Pod生成虚拟IP的。
本文把握两个知识点
第一,学会查看 ippool 整个yaml文件中,各个属性什么意思;(本文第二部分)
第二,对于各种业务需求,如果使用 IPPool 来完成。(本文第三部分)
二、学会查看 ippool 整个yaml文件中,各个属性什么意思
Pod一般不建议设置静态IP地址,若想要实现设置静态IP,可以参考下面的方法。像亚马逊、阿里云等厂家是支持静态IP的,但如果是自己的私有云,可以参考下面的方法。这里使用的是calico网络方案,其他的网络方案,好像并不支持,更详细的操作,可以看看calico的官方文档。
2.1 ippool整个yaml文件属性解释
IP Pool资源定义
IPPool资源yaml定义
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
name: default-ipv4-ippool
spec:
blockSize: 26
cidr: 192.168.0.0/16
ipipMode: Always
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
disabled: false
如果使用calicoctl定义,则将apiVersion更改为apiVersion: projectcalico.org/v3
字段说明
metadata:
spec:
要想看每个属性的默认值,就查看集群那个ippool
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
annotations:
projectcalico.org/metadata: '{"uid":"7a74f733-5d33-47f9-8b13-5a379f6e290f","creationTimestamp":"2023-03-08T16:15:22Z"}'
creationTimestamp: "2023-03-08T16:15:22Z"
generation: 1
name: default-ipv4-ippool
resourceVersion: "737"
uid: 21d4daf2-82a3-4c06-bbba-ea99c674005a
spec:
blockSize: 26
cidr: 192.168.0.0/16
ipipMode: Always
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
blockSize 业务含义就是 块大小,默认的块大小是 64 。
32位的默认是 26位,32-26=6 位 ,2的6次方就是64,就是块大小
分块的目的是为了分机器node,每个机器node就分配一个块,证明如下:
2.2 calico底层网络通信(相同Node和不同Node)
IPv4 26和IPv6 122的默认块大小为64个地址的块。这允许将地址按组分配给在同一主机上运行的工作负载。通过对地址进行分组,主机之间以及与其他BGP对等方之间交换的路由更少。如果主机在一个块中分配所有地址,则将为其分配一个附加块。如果没有更多可用的块,则主机可以从分配给其他主机的块中获取地址。为借用的地址添加了特定的路由,这会影响路由表的大小。
情况一:将 myapp-pod 部署在主机 m 上,查看路由解释全过程(优先匹配长的,而不是匹配在前面的)
步骤1:对于具体IP,子网掩码长度24, 在机器m上,192.168.159.8/24、192.168.159.9/24、192.168.159.10/24、192.168.159.11/24、192.168.159.13/24、192.168.159.21/24、192.168.159.22/24、192.168.159.23/24 ,直接使用 calicoXxx 网卡,0.0.0.0 表示在 m 机器上自行处理
步骤2:当访问 192.168.55.64/26、192.168.159.0/26 的时候,m节点可以直接机器上处理(Gatway列为0.0.0.0),w1节点需要通过 tunl0 网卡跳转到 155 机器(Gateway列指出)
步骤3:当访问 192.168.190.64/26 的时候,w1节点可以直接机器上处理(Gatway列为0.0.0.0),m节点需要通过 tunl0 网卡跳转到 151 机器(Gateway列指出)
步骤4:当访问 192.168.100/24 的时候,两个机器都可以通过自己的 ens33 网卡,本机器 0.0.0.0 上处理 (因为这个 192.168.100/24 是通过 ipaddr+mask 配置指定的)
步骤5:当访问 172.17/16 的时候,两个机器都可以通过自己的 docker0 网卡,本机器 0.0.0.0 上处理
步骤6:当访问 0.0.0.0/0 任意地址 的时候,两个机器都可以通过自己的 ens33 网卡,本机器 0.0.0.0 上处理(因为这是通过 linux gateway 配置指定的)
[root@m ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.100.2 0.0.0.0 UG 100 0 0 ens33
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.55.64 0.0.0.0 255.255.255.192 U 0 0 0 *
192.168.100.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
192.168.159.0 0.0.0.0 255.255.255.192 U 0 0 0 *
192.168.159.8 0.0.0.0 255.255.255.255 UH 0 0 0 cali396dfe27aad
192.168.159.9 0.0.0.0 255.255.255.255 UH 0 0 0 calic32badc86da
192.168.159.10 0.0.0.0 255.255.255.255 UH 0 0 0 cali48e10e29d97
192.168.159.11 0.0.0.0 255.255.255.255 UH 0 0 0 cali0054af02df5
192.168.159.13 0.0.0.0 255.255.255.255 UH 0 0 0 cali22552fba529
192.168.159.21 0.0.0.0 255.255.255.255 UH 0 0 0 cali6ab633ce8cf
192.168.159.22 0.0.0.0 255.255.255.255 UH 0 0 0 cali505bb5c3e0a
192.168.159.23 0.0.0.0 255.255.255.255 UH 0 0 0 cali0027cc35f35
192.168.190.64 192.168.100.151 255.255.255.192 UG 0 0 0 tunl0
[root@w1 ~]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default gateway 0.0.0.0 UG 100 0 0 ens33
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.55.64 192.168.100.155 255.255.255.192 UG 0 0 0 tunl0
192.168.100.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
192.168.159.0 192.168.100.155 255.255.255.192 UG 0 0 0 tunl0
192.168.190.64 0.0.0.0 255.255.255.192 U 0 0 0 *
情况二:将 myapp-pod 部署在主机 w1 上,查看路由:
步骤1:对于具体IP,子网掩码长度24, 在机器m上,192.168.159.8/24、192.168.159.9/24、192.168.159.10/24、192.168.159.11/24、192.168.159.13/24、192.168.159.21/24、192.168.159.22/24,直接使用 calicoXxx 网卡,0.0.0.0 表示在 m 机器上自行处理
步骤2:当访问 192.168.55.64/26、192.168.159.0/26 的时候,m节点可以直接机器上处理(Gatway列为0.0.0.0),w1节点需要通过 tunl0 网卡跳转到 155 机器(Gateway列指出)
步骤3:当访问 192.168.190.64/26 的时候,w1节点可以直接机器上处理(Gatway列为0.0.0.0),m节点需要通过 tunl0 网卡跳转到 151 机器(Gateway列指出)
步骤4:当访问 192.168.100/24 的时候,两个机器都可以通过自己的 ens33 网卡,本机器 0.0.0.0 上处理 (因为这个 192.168.100/24 是通过 ipaddr+mask 配置指定的)
步骤5:当访问 172.17/16 的时候,两个机器都可以通过自己的 docker0 网卡,本机器 0.0.0.0 上处理
步骤6:当访问 0.0.0.0/0 任意地址 的时候,两个机器都可以通过自己的 ens33 网卡,本机器 0.0.0.0 上处理(因为这是通过 linux gateway 配置指定的)
[root@m fixip]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.100.2 0.0.0.0 UG 100 0 0 ens33
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.55.64 0.0.0.0 255.255.255.192 U 0 0 0 *
192.168.100.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
192.168.159.0 0.0.0.0 255.255.255.192 U 0 0 0 *
192.168.159.8 0.0.0.0 255.255.255.255 UH 0 0 0 cali396dfe27aad
192.168.159.9 0.0.0.0 255.255.255.255 UH 0 0 0 calic32badc86da
192.168.159.10 0.0.0.0 255.255.255.255 UH 0 0 0 cali48e10e29d97
192.168.159.11 0.0.0.0 255.255.255.255 UH 0 0 0 cali0054af02df5
192.168.159.13 0.0.0.0 255.255.255.255 UH 0 0 0 cali22552fba529
192.168.159.21 0.0.0.0 255.255.255.255 UH 0 0 0 cali6ab633ce8cf
192.168.159.22 0.0.0.0 255.255.255.255 UH 0 0 0 cali505bb5c3e0a
192.168.190.64 192.168.100.151 255.255.255.192 UG 0 0 0 tunl0
[root@w1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.100.2 0.0.0.0 UG 100 0 0 ens33
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.55.64 192.168.100.155 255.255.255.192 UG 0 0 0 tunl0
192.168.100.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
192.168.159.0 192.168.100.155 255.255.255.192 UG 0 0 0 tunl0
192.168.190.64 0.0.0.0 255.255.255.192 U 0 0 0 *
192.168.190.74 0.0.0.0 255.255.255.255 UH 0 0 0 cali0027cc35f35
将块大小从默认值增加(例如,使用24IPv4为每个块提供256个地址)意味着每个主机更少的块,并且可能会减少路由。但是,请尝试确保池中至少有与主机一样多的块。【即确保 blockCount > HostCount ,否则会报错】
从默认值减小块大小(例如,使用28IPv4为每个块提供16个地址)意味着每个主机有更多块,因此可能有更多路由。如果它允许块在主机之间更公平地分布,那么这将是有益的。
关于cidr和blockSize设置
比如你新增一个IPPool,cidr设置为192.169.0.0/29,在没有设置blockSize情况下,默认是/26的blockSize,这样是不允许的,192.169.0.0/29可用地址为8个,而默认blockSize为26将会把IP段分为64块,没有足够的IP,所以是无效的,所以blockSize应该等于大于子网掩码。
新创建的IPPool,可以在原有的IPPool中某一子网,比如
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
name: test-ipv4-ippool
spec:
blockSize: 29
cidr: 192.168.0.0/29
ipipMode: Always
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
2.3 小结
这里搞懂了两件事:
第一,ippool yaml文件的各个属性的含义
第二,整个 k8s 集群的网络路由,每个Pod都会有一个calico网卡,同一机器的Pod之间通信直接使用 calico网卡,不同机器的Pod之间通信要通过 tul0 网卡路由
如果开发中遇到问题,同一机器的Pod之间可以通信,不同机器的Pod之间无法通信,要么是tul0网卡缺失或错误,要么是路由route缺失或错误
三、实践应用:kubernetes设置指定IP的场景及方法
如果将这些方法中的一种以上用于IP地址分配,则它们将具有以下优先级,其中1为最高优先级:
1、Kubernetes批注 (annotations)
2、CNI配置
3、IP池节点选择器
本文主要通过annotations指定。
3.1 基本语法(通过annotations指定)
基本语法1:每个pod指定IP池
cni.projectcalico.org/ipv4pools:
annotations:
"cni.projectcalico.org/ipv4pools": "[\"default-ipv4-ippool\"]"
cni.projectcalico.org/ipv6pools:
annotations:
"cni.projectcalico.org/ipv6pools": "[\"2001:db8::1/120\"]"
基本语法2:每个pod指定静态IP地址
cni.projectcalico.org/ipAddrs:
annotations:
"cni.projectcalico.org/ipAddrs": "[\"192.168.0.1\"]"
cni.projectcalico.org/ipAddrsNoIpam:
annotations:
"cni.projectcalico.org/ipAddrsNoIpam": "[\"10.0.0.1\"]"
说明:cni.projectcalico.org/ipAddrsNoIpam:绕过IPAM分配给Pod的IPv4和/或IPv6地址的列表。任何IP冲突和路由都必须手动或由其他系统来处理。Calico仅在其IP地址属于Calico IP池内时才将路由分配到Pod。如果分配的IP地址不在Calico IP池中,则必须确保通过另一种机制来处理到该IP地址的路由。
基本语法3:每个pod申请浮动IP
annotations:
"cni.projectcalico.org/floatingIPs": "[\"10.0.0.1\"]"
基本语法4:基于node节点指定IP池
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: rack-1-ippool
spec:
cidr: 192.168.1.0/24
ipipMode: Always
natOutgoing: true
nodeSelector: rack == "1"
基本语法5:基于命名空间指定IP池
# kubectl annotate namespace test-ippool "cni.projectcalico.org/ipv4pools"='["test-ipv4-ippool"]'
namespace/test-ippool annotated
将 ippool 和节点绑定,这样分配到这个节点的所有的pod,就都应用到这个 ippool
将 ippool 和 ns 绑定,这样分配到这个 ns 的所有的pod,就都应用到这个 ippool
3.2 实践应用
应用一:为pod指定IP地址池
步骤1:创建IP地址池
# cat> ippool.yaml <<EOF
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
name: test1-ipv4-ippool
spec:
blockSize: 29
cidr: 192.169.0.0/29
ipipMode: Always
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
EOF
# kubectl apply -f ippool.yaml
# kubectl exec -it -n kube-system calicoctl -- calicoctl ipam show
+----------+----------------+-----------+------------+--------------+
| GROUPING | CIDR | IPS TOTAL | IPS IN USE | IPS FREE |
+----------+----------------+-----------+------------+--------------+
| IP Pool | 192.168.0.0/16 | 65536 | 6 (0%) | 65530 (100%) |
| IP Pool | 170.252.0.0/29 | 8 | 0 (0%) | 8 (100%) |
| IP Pool | 192.169.0.0/29 | 8 | 0 (0%) | 8 (100%) | # 新创建的IPPool
+----------+----------------+-----------+------------+--------------+
步骤2:创建应用测试
spec.template.metadata.annotations指定了使用的IPPool
# cat >tomcat.yaml<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: tomcat
template:
metadata:
annotations:
"cni.projectcalico.org/ipv4pools": "[\"test1-ipv4-ippool\"]"
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: tomcat:7.0.70
ports:
- containerPort: 8080
protocol: TCP
apiVersion: v1
kind: Service
metadata:
name: tomcat
namespace: default
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 32080
selector:
app: tomcat
# kubectl apply -f tomcat.yaml
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
tomcat-7c9bc7f455-ccsvx 1/1 Running 0 127m 192.169.0.1 k8node1 <none> <none>
tomcat-7c9bc7f455-nb4wr 1/1 Running 0 127m 192.169.0.3 k8node2 <none> <none>
tomcat-7c9bc7f455-s4r9q 1/1 Running 0 127m 192.169.0.2 k8node1 <none>
小结
小结:
(1) 新建 ippool
(2) pod 通过annotations指定使用 ippool,这个 deployment 下的Pod 的 ip 都在 192.169.0.0/29 范围内
应用二:Pod设置静态IP/固定IP(设置的IP地址必须包含在已存在的IPPool中)
虽然官方说名 cni.projectcalico.org/ipAddrs:后面是IPv4或IPv6列表,实际并不支持,仅可以设置一个IP地址。所以Pod副本数超过1个是不行的。
# cat >tomcat.yaml<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: tomcat
template:
metadata:
annotations:
"cni.projectcalico.org/ipAddrs": "[\"192.168.3.100\"]"
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: tomcat:7.0.70
ports:
- containerPort: 8080
protocol: TCP
apiVersion: v1
kind: Service
metadata:
name: tomcat
namespace: default
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 32080
selector:
app: tomcat
# kubectl apply -f tomcat.yaml
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
tomcat-94f77b7db-vq7zl 1/1 Running 0 5s 192.168.3.100 k8node2 <none> <none>
小结:
pod 通过annotations指定使用 ippool,这个 pod 的 ip 是指定的 192.168.3.100 。
注意:使用这种方式,这个 deployment 只能有一个 replicas 副本,就是只能有一个 pod ,只能指定一个 ip ,否则就会报错 more than one xxx (kubectl describe pod pod-name -n ns-name)
应用三:删除或禁用已存在的IPPool
理由:如果不禁用或删除,创建的Pod也有可能分配到其他IPPool中的地址段
# kubectl exec -it -n kube-system calicoctl -- calicoctl get ippool -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED SELECTOR
default-ipv4-ippool 192.168.0.0/16 true Always Never false all()
禁用IPPool
# kubectl get ippools.crd.projectcalico.org default-ipv4-ippool -oyaml >default-ipv4-ippool.yaml
# 修改default-ipv4-ippool.yaml,添加disabled: true
# vim default-ipv4-ippool.yaml
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
generation: 1
name: default-ipv4-ippool
spec:
blockSize: 26
cidr: 192.168.0.0/16
disabled: true
ipipMode: Always
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
# kubectl apply -f default-ipv4-ippool.yaml
ippool.crd.projectcalico.org/default-ipv4-ippool configured
[root@k8master src]# kubectl exec -it -n kube-system calicoctl -- calicoctl get ippool -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED SELECTOR
default-ipv4-ippool 192.168.0.0/16 true Always Never true all()
删除IPPool
# kubectl exec -it -n kube-system calicoctl -- calicoctl delete default-ipv4-ippool
小结:ippool 不仅可以新建,也可以被禁用(存在但不使用)和删除(直接变为不存在),这样做的目的是如果不禁用或删除,创建的Pod也有可能分配到其他IPPool中的地址段
应用四:根据节点指定IP池
步骤1:给节点打上标签
# kubectl label nodes k8node1 rack=0
node/k8node1 labeled
# kubectl label nodes k8node2 rack=1
node/k8node2 labeled
将 k8node1 节点打上标签 rack=0
将 k8node2 节点打上标签 rack=1
步骤2:创建IPPool
cat >ippool.yaml<<EOF
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
name: rack0-ippool
spec:
blockSize: 26
cidr: 170.16.0.0/16
ipipMode: Always
natOutgoing: true
nodeSelector: rack == "0" # 选择具有 rack=0 标签的节点
vxlanMode: Never
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata: name: rack1-ippool
spec:
blockSize: 26
cidr: 170.17.0.0/16
ipipMode: Always
natOutgoing: true
nodeSelector: rack == "1" # 选择具有 rack=1 标签的节点
vxlanMode: NeverEOF
# kubectl apply -f ippool.yaml
# kubectl exec -it -n kube-system calicoctl -- calicoctl get ippool -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED SELECTOR
default-ipv4-ippool 192.168.0.0/16 true Always Never true all()
rack0-ippool 170.16.0.0/16 true Always Never false rack == "0"
rack1-ippool 170.17.0.0/16 true Always Never false rack == "1"
步骤3:创建应用测试
cat >tomcat.yaml<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat
namespace: default
spec:
replicas: 4
selector:
matchLabels:
app: tomcat
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: tomcat:7.0.70
ports:
- containerPort: 8080
protocol: TCP
apiVersion: v1
kind: Service
metadata:
name: tomcat
namespace: default
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 32080
selector:
app: tomcatEOF
# kubectl apply -f tomcat.yaml
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
tomcat-f556bbb4d-56bd4 1/1 Running 0 8s 170.16.0.194 k8node1 <none> <none>
tomcat-f556bbb4d-5nzkb 1/1 Running 0 8s 170.17.184.131 k8node2 <none> <none>
tomcat-f556bbb4d-pn86t 1/1 Running 0 8s 170.16.0.193 k8node1 <none> <none>
tomcat-f556bbb4d-wvf7c 1/1 Running 0 8s 170.17.184.130 k8node2 <none> <none>
凡是分配到 k8node1 节点上的pod,ip 为 170.16.0.0/16 范围内,比如 170.16.0.194 和 170.16.0.193
凡是分配到 k8node2 节点上的pod,ip 为 170.17.0.0/16 范围内,比如 170.17.184.130 和 170.17.184.131
应用五:基于namespace指定IP池
步骤1:查看当前存在的IP池
# kubectl exec -it -n kube-system calicoctl -- calicoctl get ippools
NAME CIDR SELECTOR
default-ipv4-ippool 192.168.0.0/16 all()
# kubectl get ippools.crd.projectcalico.org
NAME AGE
default-ipv4-ippool 18h
步骤2:创建新的IP池
# cat> ippool.yaml <<EOF
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
name: test-ipv4-ippool
spec:
cidr: 170.252.0.0/29
ipipMode: Always
natOutgoing: true
nodeSelector: all()
vxlanMode: NeverEOF
# kubectl apply -f ippool.yaml
# kubectl exec -it -n kube-system
calicoctl -- calicoctl get ippools
NAME CIDR SELECTOR
default-ipv4-ippool 192.168.0.0/16 all()
test-ipv4-ippool 170.252.0.0/29 all() # 这个 ippool 是新创建的
步骤3:创建新的namespace,并指定IP池
# kubectl create ns test-ippool
namespace/test-ippool created
# kubectl annotate namespace test-ippool "cni.projectcalico.org/ipv4pools"='["test-ipv4-ippool"]'
namespace/test-ippool annotated
# kubectl describe ns test-ippool
Name: test-ippoolLabels: <none>
Annotations: cni.projectcalico.org/ipv4pools: ["test-ipv4-ippool"]
Status: ActiveNo resource quota.No resource limits.
步骤4:创建应用测试
注意namespace设置test-ippool
# cat >tomcat.yaml<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat
namespace: test-ippool
spec:
replicas: 3
selector:
matchLabels:
app: tomcat
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: tomcat:7.0.70
ports:
- containerPort: 8080
protocol: TCP
apiVersion: v1
kind: Service
metadata:
name: tomcat
namespace: test-ippool
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 32080
selector:
app: tomcat
# kubectl apply -f tomcat.yaml
# kubectl get pod -n test-ippool -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
tomcat-f556bbb4d-fjdwn 1/1 Running 0 105s 170.252.0.5 k8node1 <none> <none>
tomcat-f556bbb4d-sbcrr 1/1 Running 0 17m 170.252.0.3 k8node2 <none> <none>
tomcat-f556bbb4d-zjw87 1/1 Running 0 105s 170.252.0.6 k8node1 <none> <none>
小结
小结:
(1) 创建 ippool
(2) 创建命名空间
(3) ippool 和 ns 绑定
(4) 在这个 ns 下新建 deployment-service,这个ns下的pod,其 ip在 170.252.0.0/29 范围内
四、尾声
总结一下本文学到的,如下:
第一,学会查看 ippool 整个yaml文件中,各个属性什么意思:整个 k8s 集群的网络路由,每个Pod都会有一个calico网卡,同一机器的Pod之间通信直接使用 calico网卡,不同机器的Pod之间通信要通过 tul0 网卡路由。如果开发中遇到问题,同一机器的Pod之间可以通信,不同机器的Pod之间无法通信,要么是tul0网卡缺失或错误,要么是路由route缺失或错误
第二,对于各种业务需求,如果使用 IPPool 来完成:给Pod指定IP池、给Pod指定静态IP、将 ippool 绑定到 ns 上、将 ippool 绑定到 node 上
Calico的组成:一个deploy calico-kube-controller和一个daemonSet calico-node
Calico的功能:
(1) 作为一个 CNI 网络插件,像 Flannel 一样,需要完成Pod之间的网络通信,包括两种情况,在相同Node上的Pod、在不同Node上的Pod
(2) 相对于Flannel,提供了两个高级功能,网络策略NetworkPolicy和固定IP(通过IPPool)实现
这篇文章,我们学习了作为一个 CNI 网络插件,像 Flannel 一样,需要完成Pod之间的网络通信,包括两种情况,在相同Node上的Pod、在不同Node上的Pod,以及如果通过 IPPool 来给Pod配置固定IP,这个IPPool不是k8s的资源是,而是calico的自定义crd资源。
注意:K8S的资源通过 kubectl get api-resources 来查看
参考文档:pod设置静态IP以及设置IP范围