v0.11.0
flannel 是常用的网络打通的工具。
在github搜索flannel。
网址: https://github.com/coreos/flannel
一、介绍
flannel可以单独启动, 也可以k8s启动, 在k8s启动可以直接从K8S获取网段信息,单独启动需要在etcd里添加flannel配置。这里是单独启动的。
flannel网络模式
https://github.com/coreos/flannel/blob/master/Documentation/backends.md
其中vxlan比较常用,自动创建vxlan隧道, 有一定网络损耗。
如果是在相同网段的物理局域网,可以使用host-gw,通过给给节点创建路由规则,每多一个节点就多创建一条规则,就是路由规则多点, 没有网络损耗。
配置网段
https://github.com/coreos/flannel/blob/master/Documentation/configuration.md
{
"Network": "10.0.0.0/8",
"SubnetLen": 20,
"SubnetMin": "10.10.0.0",
"SubnetMax": "10.99.0.0",
"Backend": {
"Type": "udp",
"Port": 7890
}
}
Network : 就是flannel可以使用,可以分配的所有ip。
SubnetLen: 让docker使用的掩码。默认24。
如果没有下面那两个参数限制最大最小, 可分配网段的范围就是:
10.0.0.0/20 - 10.255.240.0/20
2的12次方个可用网段。
SubnetMin: 最小网段。 默认为网段最小的一个。
SubnetMax: 最大网段。 这个最小最大就是可以分配给节点docker使用的网段范围。 默认为网段最大的一个。
上面这个例子可不是10-99, 而是:
1010.0000 - 1100011.0000
。
后面那个减去前面那个等于:101 1001 0000,1424
1424 + 1, 有1425个网段可以使用。
然后每个网段4096个地址,4094个可以使用。
Backend 就是flannel的网络模式, 例子里是udp。
常用的就Network以及Backend。
以上面的参数启动flannel,只是把Type改成了vxlan, 去掉了port。 所生成的文件,重点就是网段部分:
[root@k8s-node1 etcd]# cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.0.0.0/8
FLANNEL_SUBNET=10.12.16.1/20
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
[root@k8s-node1 etcd]# cat /run/flannel/docker_opts.env
DOCKER_OPT_BIP="--bip=10.12.16.1/20"
DOCKER_OPT_IPMASQ="--ip-masq=false"
DOCKER_OPT_MTU="--mtu=1450"
DOCKER_OPTS=" --bip=10.12.16.1/20 --ip-masq=false --mtu=1450"
二、给flannel创建证书。
因为集群里的etcd是双向认证的, 所以flannel想要连接etcd需要证书。
etcd不会验证证书的Common Name, 所以不需要生成san扩展的证书。
使用集群CA生成证书就可以。
[root@k8s-ca data]# ./openssl.sh build flannel
Generating RSA private key, 2048 bit long modulus
.....+++
.......+++
。。。。。。。。。。。。。
我这里是使用自己的脚本生成的。
https://www.yxingxing.net/articles/2019/10/25/1571997217121.html
三、安装flannel
1、下载
https://www.yxingxing.net/articles/2019/10/25/1571997217121.html
2、目录结构
[root@k8s-node1 flannel]# tree
.
├── bin
│ ├── flanneld
│ └── mk-docker-opts.sh
└── ssl
├── cacert.pem
├── flannel.crt
└── flannel.key
2 directories, 5 files
3、在etcd创建网络配置。
使用etcdctl添加配置。
注意etcdctl要工作在v2模式,在v2里添加配置, 因为flannel不支持v3的etcd。
[root@k8s-node1 etcd]# bin/etcdctl --endpoints "https://172.100.102.71:2379,https://172.100.102.72:2379,https://172.100.102.73:2379" --cert-file ssl/etcd.crt --key-file ssl/etcd.key --ca-file ssl/cacert.pem set /coreos.com/network/config '
{
"Network": "10.1.0.0/16",
"SubnetLen": 24,
"SubnetMin": "10.1.10.0",
"SubnetMax": "10.1.90.0",
"Backend": {
"Type": "vxlan"
}
}'
# 输出
{
"Network": "10.1.0.0/16",
"SubnetLen": 24,
"SubnetMin": "10.1.10.0",
"SubnetMax": "10.1.90.0",
"Backend": {
"Type": "vxlan"
}
}
[root@k8s-node1 etcd]#
上面有81个网段,每个网段253个可用ip。
如果节点需要启动很多pod, 大于253,节点不多,可以改一下SubnetLen, 比如改成23, 可用ip就成510个,可用网段是39个。 就是ip掩码计算,长时间没有算这东西,也不知道算的对不对。
这里只是说明参数的使用,
大多数情况下SubnetLen, SubnetMin, SubnetMax 都会省略, 使用默认值。 如:
{"Network": "10.1.0.0/16", "Backend": {"Type": "vxlan" } }
4、创建Unit
vim /lib/systemd/system/flannel.service
[Unit]
Description=Etcd server
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/local/flannel/bin/flanneld \
-etcd-cafile /usr/local/flannel/ssl/cacert.pem \
-etcd-certfile /usr/local/flannel/ssl/flannel.crt \
-etcd-keyfile /usr/local/flannel/ssl/flannel.key \
-etcd-endpoints "https://172.100.102.71:2379,https://172.100.102.72:2379,https://172.100.102.73:2379" \
-ip-masq \
-healthz-port 300
ExecStartPost=/usr/local/flannel/bin/mk-docker-opts.sh -d /var/run/flannel/docker_opts.env
[Install]
RequiredBy=docker.service
WantedBy=multi-user.target
那4个etcd参数是用来连接etcd的。
-ip-masq是用来生成iptables的SNAT规则。用于容器里的地址可以访问外网。
在flannel这里要加上这个参数,如果这里不加,docker的启动参数就要加上,但是docker生成的iptables规则没有考虑不同主机pod之间的通信,因为不同的主机pod的网段是不同的, 所以就导致访问其他主机pod也会SNAT。在下面还有flannel的iptables,可以对比一下。
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 10.1.0.0/16 0.0.0.0/0
启动以后会在/var/run/flannel下面生成docker网络相关的启动参数, 可以在docker的Unit文件以变量文件加载。
5、启动flannel, 并修改docker启动参数。
[root@k8s-node1 etcd]# systemctl start flannel
启动以后会生成一个类型为vxlan的flannel网卡。类型这样看不出来,需要ip link list type vxlan
来查看。
[root@k8s-node1 etcd]# ip addr show dev flannel.1
5: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default
link/ether ca:a6:ef:90:97:e7 brd ff:ff:ff:ff:ff:ff
inet 10.1.44.0/32 scope global flannel.1
valid_lft forever preferred_lft forever
inet6 fe80::c8a6:efff:fe90:97e7/64 scope link
valid_lft forever preferred_lft forever
[root@k8s-node1 etcd]#
之后访问其他节点容器的地址都是会通过flannel网卡的vxlan隧道发出去, 因为这里现在只有一个节点,路由看不出来, 下面截了其他测试集群的信息:
[root@k8s-node1 bin]# ip route list
default via 172.100.101.1 dev eth0 proto static metric 100
10.1.15.0/24 via 10.1.15.0 dev flannel.1 onlink
10.1.37.0/24 via 10.1.37.0 dev flannel.1 onlink
10.1.51.0/24 via 10.1.51.0 dev flannel.1 onlink
10.1.53.0/24 via 10.1.53.0 dev flannel.1 onlink
10.1.65.0/24 via 10.1.65.0 dev flannel.1 onlink
10.1.68.0/24 via 10.1.68.0 dev flannel.1 onlink
10.1.72.0/24 via 10.1.72.0 dev flannel.1 onlink
10.1.81.0/24 via 10.1.81.0 dev flannel.1 onlink
10.1.90.0/24 dev docker0 proto kernel scope link src 10.1.90.1
172.100.101.0/24 dev eth0 proto kernel scope link src 172.100.101.193 metric 100
[root@k8s-node1 bin]#
下面是docker的,flannel启动以后会生成一个文件,就是subnet.env, 还有一个是由flannel的mk-docker-opts.sh脚本生成的可以直接让docker使用的docker_opts.env文件。
[root@k8s-node1 etcd]# cat /var/run/flannel/docker_opts.env
DOCKER_OPT_BIP="--bip=10.1.44.1/24"
DOCKER_OPT_IPMASQ="--ip-masq=false"
DOCKER_OPT_MTU="--mtu=1450"
DOCKER_OPTS=" --bip=10.1.44.1/24 --ip-masq=false --mtu=1450"
[root@k8s-node1 etcd]# cat /var/run/flannel/subnet.env
FLANNEL_NETWORK=10.1.0.0/16
FLANNEL_SUBNET=10.1.44.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
[root@k8s-node1 etcd]#
这里因为flannel启动的时候加上了--ip-masq,所以在生成的docker参数里ip-masq就是false了。 mtu为1450是因为使用的是vxlan, 如果使用host-gw就是1500了。
这个就是--ip-masq加的规则。
Chain POSTROUTING (policy ACCEPT 2 packets, 120 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 RETURN all -- * * 10.1.0.0/16 10.1.0.0/16
2 0 0 MASQUERADE all -- * * 10.1.0.0/16 !224.0.0.0/4
3 0 0 RETURN all -- * * !10.1.0.0/16 10.1.44.0/24
4 0 0 MASQUERADE all -- * * !10.1.0.0/16 10.1.0.0/16
改一下docker的启动参数。可以看到现在docker0的地址。
[root@k8s-node1 etcd]# ip addr show dev docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:de:8a:a3:35 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
[root@k8s-node1 etcd]#
添加读取flannel生成的文件。并在启动参数里使用。
EnvironmentFile=/var/run/flannel/docker_opts.env
vim /lib/systemd/system/docker.service
重启docker
[root@k8s-node1 etcd]# systemctl daemon-reload
[root@k8s-node1 etcd]# systemctl restart docker
[root@k8s-node1 etcd]# ip addr show dev docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:de:8a:a3:35 brd ff:ff:ff:ff:ff:ff
inet 10.1.44.1/24 brd 10.1.44.255 scope global docker0
valid_lft forever preferred_lft forever
[root@k8s-node1 etcd]#
在etcd里可以查看到节点的信息
[root@k8s-node1 etcd]# bin/etcdctl --endpoints "https://172.100.102.71:2379,https://172.100.102.72:2379,https://172.100.102.73:2379" --cert-file ssl/etcd.crt --key-file ssl/etcd.key --ca-file ssl/cacert.pem ls /coreos.com/network
/coreos.com/network/config
/coreos.com/network/subnets
[root@k8s-node1 etcd]# bin/etcdctl --endpoints "https://172.100.102.71:2379,https://172.100.102.72:2379,https://172.100.102.73:2379" --cert-file ssl/etcd.crt --key-file ssl/etcd.key --ca-file ssl/cacert.pem ls /coreos.com/network/subnets
/coreos.com/network/subnets/10.1.44.0-24
[root@k8s-node1 etcd]# bin/etcdctl --endpoints "https://172.100.102.71:2379,https://172.100.102.72:2379,https://172.100.102.73:2379" --cert-file ssl/etcd.crt --key-file ssl/etcd.key --ca-file ssl/cacert.pem get /coreos.com/network/subnets/10.1.44.0-24
{"PublicIP":"172.100.102.71","BackendType":"vxlan","BackendData":{"VtepMAC":"ca:a6:ef:90:97:e7"}}
[root@k8s-node1 etcd]#