CNI(Container Networking Interface) 容器网络接口
cnitool
cnitool是一个执行CNI配置的简单程序。它将在已创建的网络命名空间中添加或删除接口。
环境变量:
- NETCONFPATH:默认从
/etc/cni/net.d
下所有以*.conf
和*.json
结尾的文件中获取环境变量 - CNI_PATH:CNI插件路径
简单的示例
安装
go get github.com/containernetworking/cni
go install github.com/containernetworking/cni/cnitool
git clone https://github.com/containernetworking/plugins.git
cd plugins
./build_linux.sh
创建cni网络
echo '{"cniVersion":"0.4.0","name":"myptp","type":"ptp","ipMasq":true,"ipam":{"type":"host-local","subnet":"172.16.29.0/24","routes":[{"dst":"0.0.0.0/0"}]}}' | tee /etc/cni/net.d/10-myptp.conf
绑定cni
# 创建ns
sudo ip netns add testing
# 把容器添加到cni网络中
sudo CNI_PATH=./bin cnitool add myptp /var/run/netns/testing
# 检查
sudo CNI_PATH=./bin cnitool check myptp /var/run/netns/testing
# 测试
sudo ip -n testing addr
sudo ip netns exec testing ping -c 1 4.2.2.2
# 清理
sudo CNI_PATH=./bin cnitool del myptp /var/run/netns/testing
sudo ip netns del testing
IPAM插件
ip地址分配插件
-
dhcp
: 在宿主机上运行一个守护进程,代表容器发出dhcp请求 -
host-local
: 维护已分配ip的本地数据库 -
static
: 为容器分配静态IPv4/IPv6地址
Main插件
接口的创建插件
-
bridge
:创建一个桥接,将主机和容器添加到其中 -
ipvlan
:在容器中添加ipvlan接口 -
macvlan
:创建一个新的MAC地址,将所有流量转发到容器 -
ptp
:创建一对veth虚拟接口 -
host-device
:将已经存在的设备移动到容器中 -
vlan
:创建vlan接口
Windows的接口
-
win-bridge
:创建一个桥接,将主机和容器添加到其中 -
win-overlay
:为容器创建overlay接口
ptp
https://www.cni.dev/plugins/current/main/ptp/
ptp
插件通过使用veth虚拟设备在容器和主机之间创建点对点链接。host-local IPAM
插件可以用来给容器分配ip。容器接口的流量将通过主机接口路由。
集群多cni部署:手工配置ptp-cni
有些时候因为网络环境的特殊性,并不能实现每个节点都在相同的网络环境下,我们可以通过独立部署cni的方式实现集群内的互通。
ptp节点信息
prifcy-k8s-xx1.hz.163.org 7.34.xx.xx1 pod:10.178.128.0/24
prifcy-k8s-xx2.hz.163.org 7.34.xx.xx2 pod:10.178.129.0/24
k8s集群中禁止原有cni调度
tolerations: # 配置了污点容忍
- operator: Exists
spec:
affinity:
nodeAffinity: # 添加节点亲和性
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node.netease.com/ptp
operator: DoesNotExist # 使用不存在
检查cni插件
$ ls /opt/cni/bin
bandwidth bridge dhcp firewall flannel host-device host-local ipvlan loopback macvlan portmap ptp sbr scud-cni-bgp static tuning vlan
$ less /etc/default/kubelet-extra
--kubeconfig=/etc/kubernetes/kubelet.conf \
--cni-bin-dir=/opt/cni/bin \
--cni-conf-dir=/etc/cni/net.d \
--config=/var/lib/kubelet/config.yaml \
--network-plugin=cni \
配置kubelet-nci,编写/etc/cni/net.d/ptp.conflist,两个节点区分一下subnet
{
"cniVersion":"0.3.1",
"name":"ptp-network",
"plugins":[
{
"name": "ptpnet",
"type": "ptp",
"ipam": {
"type": "host-local",
"subnet": "10.178.128.0/24",
"routes": [
{
"dst": "0.0.0.0/0"
}
]
},
"mtu": 1450,
"ipMasq": false
}
]
}
重启kubelet: systemctl restart kubelet.service
,查看pod已经可以正常分配ip了
skiff-agent-c2pln 1/1 Running 3 62s 10.178.128.6 prifcy-k8s-ptp-xx1.hz.163.org
skiff-agent-pbrsk 1/1 Running 3 62s 10.178.129.6 prifcy-k8s-ptp-xx2.hz.163.org
现在需要保证集群内pod网络互通
# ptp节点上启动tunl0
ip link set tunl0 up
# 2台ptp节点上也要添加对应的路由,保证ptp节点之间互通
ip route add 10.178.129.0/24 via 7.34.73.xx1 dev tunl0 onlink
ip route add 10.178.128.0/24 via 7.34.73.xx2 dev tunl0 onlink
# 贵州集群正常cni节点添加路由,节点上本身就启动了tunl0
ip route add 10.178.128.0/24 via 7.34.73.xx1 dev tunl0 onlink
ip route add 10.178.129.0/24 via 7.34.73.xx2 dev tunl0 onlink
# 完成后就可以在正常节点上ping通ptp的网段了
ping -c1 10.178.129.3
ptp的pod可以访问外网
iptables -t nat -A POSTROUTING -s 10.178.128.0/24 -d 10.48.160.0/22 -j RETURN # pod网段
iptables -t nat -A POSTROUTING -s 10.178.128.0/24 -d 10.48.164.0/26 -j RETURN # node网段
iptables -t nat -A POSTROUTING -s 10.178.128.0/24 -j MASQUERADE