k8s的网络假设
- 集群中每个pod 都有独立的ip
- 同一个pod中容器共享ip
- 集群中pod 可以直接通讯而不需要nat
- 可以通过策略控制pod的通信
是什么
- flannel 是一个为k8s设计的简单易用的三层网络解决方案
- falnnel 不控制container 如何与host 进行通讯,只控制host与host之间如何通讯
- flannel 聚焦于网络通讯,网络策略有calico 负责
- flannel 以服务的形式运行在每一台主机上,负责从大的网络中租赁子网给每一台主机
- flannel 可以使用k8s api 或直接使用etcd来存储网络配置、子网分配及辅助数据。通过监听etcd的变化来调整路由,github 建议使用k8s api 来连接etcd
- 容器间数据包被转发通过vxlan、host-gw 及多种云网络
- flannel 一旦获得租赁的子网会在
/run/flannel/subnet.env
生成环境变量文件。每次flannel 重启都会试图访问/run/flannel/subnet.env
中FLANNEL_SUBNET的值,从而防止在租约到期前更新了网络信息 - 可以运行多个flanneld 通过
flanneld -subnet-file /vxlan.env -etcd-prefix=/vxlan/network
配置文件
[info]
如果
--kube-subnet-mgr true
则flannel 从/etc/kube-flannel/net-conf.json
读取启动配置
如果--kube-subnet-mgr false
则flannel 从etcd
读取启动配置。其中key 为/coreos.com/network/config
,可以使用--etcd-prefix
来修改该key
配置文件事例
{
"Network": "10.244.0.0/16", # 必须的key
"SubnetLen": "/24",
"SubnetMin": "10.244.21.0/24",
"SubnetMax": "10.244.22.0/24",
"Backend": {
"Type": "udp",
"Port": 7890
}
}
Backends
flannel 支持多种类型的配置,这个设置一旦设定,在集群运行状态不应该做修改
-
VXLAN
-
host-gw 通常不能使用在云环境,要求host 运行在相同的二层网络
-
UDP suggested for debugging
-
AWS, GCE, and AliVPC 处于试验阶段,存在风险
-
ipip
-
ipsec
vxlan 使用linxu内核的vxlan 技术进行封包
"Backend":{
"Type": "vxlan",
# vxlan的标识符 linux 使用 1, windows 使用大于或等于4096的值
"VNI": 1,
# 当通讯的主机在同一子网中时基于host-gw 的方式通讯,vxlan 仅用于不同网段的主机通讯
"DirectRouting": false
}
host-gw
"Backend":{
"Type": "host-gw"
}
upd
"Backend":{
"Type": "udp",
# udp 的端口 Linux 使用 8472 windows 使用4789
"Port": 8472
}
ali-vpc
"Backend":{
"Type": "ali-vpc",
# 可以使用环境变量 ACCESS_KEY_ID
"AccessKeyID": "",
# 可以使用环境变量 ACCESS_KEY_SECRET
"AccessKeySecret": ""
}
tencent-vpc
"Backend":{
"Type": "tencent-vpc",
# 可以使用环境变量 ACCESS_KEY_ID
"AccessKeyID": "",
# 可以使用环境变量 ACCESS_KEY_SECRET
"AccessKeySecret": ""
}
ipip
使用内核的ipip 来封装包
ipip 是一种最简单的隧道
他的开销最低,单只能封装基于IPV4的单播数据,因此不支持 OSPF
RIP
等基于组播的协议
"Backend": {
"Type": "ipip",
# 当通讯的主机在同一子网中时基于host-gw 的方式通讯,ipip 仅用于不同网段的主机通讯
"DirectRouting": false
}
ipsec
使用内核的ipsec 进行封包
使用IKEv2进程,通过预共享秘钥的来实现秘钥的交换,保证秘钥在周期性改变
"Backend": {
"Type": "ipsec",
# 预共享秘钥,最少96个字符,可以使用这个命令生成 dd if=/dev/urandom count=48 bs=1 status=none | xxd -p -c 48 xxd通过yum install vim-common 安装
"PSK": ""
# 当通讯的主机在同一子网中时基于host-gw 的方式通讯,ipip 仅用于不同网段的主机通讯
"DirectRouting": false,
# 使用udp 封包,默认false
"UDPEncap": false,
# 秘钥交换的算法
"ESPProposal": "aes128gcm16-sha256-prfsha256-ecp256"
}
启动命令
flannel
--publish-ip="10.4.7.21"
用于通讯的ip--etcd-endpoints=https://10.4.7.12:2379,https://10.4.7.21:2379
指定etcd,使用都好隔开--etcd-prefix=/coreos.com/network
指定 etdctl 中key--etcd-keyfile=""
与etcd 通讯的key--etcd-certfile=""
与etcd 通讯的crt--etcd-cafile=""
与etcd 通讯的ca--kube-subnet-mgr
指定使用k8sapi 而不是独立的etcd--iface=""
指定通讯的网卡名字 eth0--subnet-file=/run/flannel/subnet.env
指定变量文件包括subnet 和 MTU。MTU 有flannel 自动设定不能修改--net-config-path=/etc/kube-flannel/net-conf.json
指定启动配置文件--ip-masq=false
发往pod 集群外的网络进行nat,这里假设iptables POSTROUTING 的默认策略为ACCEPT--healthz-port=0
指定健康检查的端口,0 表示禁用
任何指令都可以通过环境变量的形式传递规则如下:
使用FLANNELD_
代替指令开头的--
其他-
转换成_
所有小写字母转大写
举例:--etcd-endpoints=http://10.0.0.2:2379
is equivalent to FLANNELD_ETCD_ENDPOINTS=http://10.0.0.2:2379
安装部署
[info]
- 在启动kube-apiserver是需要添加
--allow-privileged=true
。否则在pod 中无法使用sercurityContext.privileged: true- 在启动kubelet 是需要指定
--allocate-node-cidrs=true
--cluster-cidr="172.7.0.0/16"
。否则会提示crashLoopBackOff
,容器日志提示Error registering network: faild to acquire less: node "node-01" pod cidr not assigned
部署
https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/k8s-manifests/kube-flannel-legacy.yml
https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/k8s-manifests/kube-flannel-rbac.yml
网络策略canl
wget https://docs.projectcalico.org/manifests/canal.yaml --no-check-certificate