IPPool(地址池)也是calico里的一个资源对象,从地址池中分配地址给pod。
https://docs.projectcalico.org/v3.11/reference/resources/ippool
样例:
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: my.ippool-1
spec:
cidr: 10.1.0.0/16
ipipMode: CrossSubnet
natOutgoing: true
disabled: false
nodeSelector: all()
IPPool配置项:
cidr
: 地址范围
blockSize
: 块大小,按需分配给主机,用于汇总路由。只能在创建ippool的时候设置。
ipipMode
: ipip隧道模式,不能与vxlanMode同时使用, 有三个值。
Always
: 始终使用IPIP隧道。CrossSubnet
: 只有在跨子网的时候才使用IPIP隧道。Never
: 不使用IPIP。
vxlanMode
: vxlan隧道模式,不能与ipipMode同时使用。有三个值,跟ipipMode的一样。Always
: 始终使用VXLAN隧道。CrossSubnet
: 只有在跨子网的时候才使用VXLAN隧道。Never
: 不使用VXLAN。
natOutgoing
: 启用后,由本地址池分配的容器发往外网的数据包会做伪装(MASQUERADE)。 true, false。
disabled
: 设置为true时,calico IPAM将不会分配本地址池里的地址。
nodeSelector
: 节点标签选择器,calico IPAM只为匹配的节点分配地址。默认: all()。
一、配置pod访问外网SNAT
https://docs.projectcalico.org/v3.11/networking/workloads-outside-cluster
默认就是允许的,IPPool的natOutgoing
参数。 启用后将为pod访问外网做SNAT。如果pod只能通过SNAT访问外网,关闭以后,pod将无法访问外网。 也是通过iptables规则实现的。calico生成的规则在kube-proxy之前,所以kube-proxy那个SNAT规则用不上。
就是这条规则, false以后就没有了。
Chain cali-nat-outgoing (1 references)
num pkts bytes target prot opt in out source destination
1 3 216 MASQUERADE all -- * * 0.0.0.0/0 0.0.0.0/0 /* cali:Dw4T8UWPnCLxRJiI */ match-set cali40masq-ipam-pools src ! match-set cali40all-ipam-pools dst
修改也很简单,首先把在使用的ippool的配置导出来。
calicoctl get ippool -o yaml > ippool.yaml
apiVersion: projectcalico.org/v3
items:
- apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
creationTimestamp: "2020-03-10T11:29:34Z"
name: default-ipv4-ippool
resourceVersion: "740608"
uid: 9c43b0ea-33f4-4fb4-b964-6b635748e10a
spec:
blockSize: 26
cidr: 10.6.0.0/16
ipipMode: Never
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
kind: IPPoolList
metadata:
resourceVersion: "743895"
把natOutgoint
改为false
后应用:
[root@k8s-master ~]# calicoctl apply -f ippool.yaml
Successfully applied 1 'IPPool' resource(s)
再看iptables就没有这条规则了。
Chain cali-nat-outgoing (1 references)
num pkts bytes target prot opt in out source destination
二、隧道封装
https://docs.projectcalico.org/v3.11/networking/vxlan-ipip
确定MTU大小
https://docs.projectcalico.org/v3.11/networking/mtu
因为会封装额外的头部信息,所以MTU需要与物理MTU小。 IPIP会封装20字节头部,VXLAN会封装50字节头部。 所以,如果物理MTU是1500,IPIP环境需要设置MTU为1480, VXLAN环境需要设置为1450。
修改MTU需要更改configmap里的veth_mtu
设置。 然后重启calico-node
。
新安装的calico默认MTU是1440, 两个封装类型都可以用。 我这里因为修改过了,所以改一下。
17: cali64a9a8c99ea@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc noqueue state UP mode DEFAULT group default
link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 0
18: cali14aa1c2585d@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc noqueue state UP mode DEFAULT group default
link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 1
可以看到我这里的MTU是9000。 为了两个类型都可以测试,直接修改为1450。
[root@k8s-master ~]# kubectl get configmap -n kube-system
NAME DATA AGE
calico-config 8 2d19h
extension-apiserver-authentication 1 6d5h
[root@k8s-master ~]# kubectl edit configmap/calico-config -n kube-system
把这个改成1450以后保存。
重启calico-node
[root@k8s-master ~]# kubectl get daemonset -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
calico-node 3 3 3 3 3 beta.kubernetes.io/os=linux 3h41m
[root@k8s-master ~]# kubectl rollout restart daemonset/calico-node -n kube-system
daemonset.apps/calico-node restarted
[root@k8s-master ~]#
注意,已存在的pod的网卡mtu是不会变的。
修改为IPIP模式。
注意,修改模式可能会导致正在进行的连接中断。
修改IPPool配置ipipMode: Always
。
应用:
[root@k8s-master ~]# calicoctl apply -f ippool.yaml
Successfully applied 1 'IPPool' resource(s)
应用完成以后,多了一个ipip类型的tunl0网卡。类型可以通过ip link list type ipip
来确定。
20: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
inet 10.6.36.73/32 brd 10.6.36.73 scope global tunl0
valid_lft forever preferred_lft forever
容器里也多出来一个,不知道干嘛用的,而且mtu就是1480,经过后面的一些修改还是1480, 固定不变。
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
路由也变了:
修改为VXLAN模式
修改ippool配置并应用。
可能需要重新导出一份ippool配置来修改。那个resourceVersion可能有限制。
应用以后多出来一个vxlan类型的vxlan
网卡。
20: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
21: vxlan.calico: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1410 qdisc noqueue state UNKNOWN group default
link/ether 66:8c:73:5a:90:99 brd ff:ff:ff:ff:ff:ff
inet 10.6.36.74/32 brd 10.6.36.74 scope global vxlan.calico
valid_lft forever preferred_lft forever
inet6 fe80::648c:73ff:fe5a:9099/64 scope link
valid_lft forever preferred_lft forever
查看路由
10.6.107.192/26 via 10.6.107.197 dev vxlan.calico onlink
10.6.169.128/26 via 10.6.169.140 dev vxlan.calico onlink
发现上面vxlan的网卡mtu有点不对, 看来他并不是从configmap里那个参数拿的。可能需要修改FelixConfiguration
资源对象。
修改MTU
[root@k8s-master ~]# calicoctl get FelixConfiguration
NAME
default
node.k8s-node1
node.k8s-node2
node.k8s-node3
修改default。
导出配置并修改:
apiVersion: projectcalico.org/v3
kind: FelixConfiguration
metadata:
creationTimestamp: "2020-03-10T11:29:34Z"
name: default
resourceVersion: "747102"
uid: ff25ed78-3689-44cd-99bc-bfbb7f43a0fe
spec:
XDPRefreshInterval: null
ipipEnabled: true
ipipMTU: 1480
vxlanMTU: 1450
logSeverityScreen: Info
reportingInterval: 0s
vxlanEnabled: true
ipipMTU与vxlanMTU都指定了。
应用以后,vxlan的网卡mtu就变了。
20: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
21: vxlan.calico: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/ether 66:8c:73:5a:90:99 brd ff:ff:ff:ff:ff:ff
再次切换到ipip, 发现ipip的网卡mtu还是原来的,估计这个是使用的configmap里指定的那个参数。
FelixConfiguration
其他的参数就不研究了。
大家有兴趣的话,官网:
https://docs.projectcalico.org/v3.11/reference/resources/felixconfig
简单看了一下,里面确实说明了,ipipMTU不是从FelixConfiguration
里配置的, vxlanMTU是。
其他一些注意事项
- calico可以自动判断kube-proxy使用的iptables还是ipvs。 Calico还使用NodePorts将流量路由到集群,但是如果NodePort的默认范围修改了,不是30000:32767, 需要在
FelixConfiguration
里修改一下KubeNodePortRange
选项。
https://docs.projectcalico.org/v3.11/networking/use-ipvs
https://docs.projectcalico.org/v3.11/reference/felix/configuration