cni网络插件

k8s的网络假设

  1. 集群中每个pod 都有独立的ip
  2. 同一个pod中容器共享ip
  3. 集群中pod 可以直接通讯而不需要nat
  4. 可以通过策略控制pod的通信

是什么

  1. flannel 是一个为k8s设计的简单易用的三层网络解决方案
  2. falnnel 不控制container 如何与host 进行通讯,只控制host与host之间如何通讯
  3. flannel 聚焦于网络通讯,网络策略有calico 负责
  4. flannel 以服务的形式运行在每一台主机上,负责从大的网络中租赁子网给每一台主机
  5. flannel 可以使用k8s api 或直接使用etcd来存储网络配置、子网分配及辅助数据。通过监听etcd的变化来调整路由,github 建议使用k8s api 来连接etcd
  6. 容器间数据包被转发通过vxlan、host-gw 及多种云网络
  7. flannel 一旦获得租赁的子网会在/run/flannel/subnet.env 生成环境变量文件。每次flannel 重启都会试图访问/run/flannel/subnet.env 中FLANNEL_SUBNET的值,从而防止在租约到期前更新了网络信息
  8. 可以运行多个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]

  1. 在启动kube-apiserver是需要添加 --allow-privileged=true 。否则在pod 中无法使用sercurityContext.privileged: true
  2. 在启动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

上一篇:kube-flannel.yml


下一篇:k8s V1.18.0版本一键部署脚本