• OpenvSwitch实现kubernetes依赖的底层网络


    kubernetes网络模型设计的一个基础原则是:每个Pod都拥有一个独立的IP地址,而且假定所有Pod都在一个可以直接连通的、扁平的网络空间中(在GCE里面是现成的网络模型)。在kubernetes中,IP是以Pod为单位进行分配的。一个Pod内部的所有容器共享一个网络堆栈(实际上就是一个网络命名空间,包括它们的IP地址、网络设备、配置等都是共享的)。按照这个网络原则抽象出来的一个Pod一个IP的设计模型也被称作IP-per-Pod模型。在我们搭建k8s集群的过程中,需要自己实现这个网络假设,将不同节点上的Docker容器之间的互相访问先打通,然后运行k8s。目前有许多开源组件支持容器网络模型,比如说Flannel、OpenvSwitch和Calico等。在本文中,我们利用OVS作为实现底层网络(如下图所示),仅实现了不同节点之间的docker0网桥之间的互通,没有搭建基于OVS的完整kubernetes集群。

    OpenvSwitch是一个开源的虚拟交换机软件,OVS的网桥可以直接建立多种通信通道(隧道)如VxLAN,GRE,在k8s、Docker场景下,我们主要是建立L3到L3的隧道。在这里,我们采取VxLAN隧道的方式实现。

    实验拓扑如图所示,在VMware上运行3台ubuntu16.04虚拟机。

    当容器内的应用访问另一个容器的地址时,数据包会通过容器内的默认路由发送给docker0网桥。OVS的网桥是作为docker0网桥的端口存在的,它会将数据发送给OVS网桥。OVS网络已经通过配置建立了和其他OVS网桥的GRE/VxLAN隧道,自然能将数据送达对端的Node,并送往docker0及Pod。接下来进行实际操作。

    1.安装Docker

    sudo apt-get install docker.io

    2.安装OpenvSwitch

    sudo apt-get install openvswitch-switch

    3.为docker0网桥重新分配IP

    为了避免Docker创建的docker0地址产生冲突(因为Docker Daemon启动且给docker0选择子网时只有几个备选列表,很容易产生冲突,我这里装完docker,docker0网桥的地址都是172.17.0.1/16),所以我们要给docker0网桥重新分配IP地址,网上有很多种解决方案,众说纷纭,我这里按照下面的步骤进行。首先,停止docker服务,然后将docker0网桥删除,手动建立一个Linux网桥,然后手动给这个网桥配置IP地址范围。

    sudo service docker stop
    sudo ip link set dev docker0 down
    sudo brctl delbr docker0
    sudo brctl addbr docker0
    sudo ip addr add 172.17.30.1/24 dev docker0
    sudo ip link set dev docker0 up

    查看IP地址信息:

    我这里配置是,master节点的docker0 IP地址为172.17.20.1,node1节点docker0 IP地址为172.17.10.1,node2节点docker0 IP地址为172.17.30.1。

    4 .创建网桥和Vxlan隧道

    建立OpenvSwitch的网桥br0,然后通过ovs-vsctl命令给ovs网桥增加VxLAN端口,添加端口时要将目标连接的NodeIP地址设置为对端的IP地址。(对于大型集群网络,需要做自动化脚本来完成)

    (1) 创建ovs网桥br0

    分别在master,node1,node2节点上执行如下命令:

    sudo ovs-vsctl add-br br0

    (2) 创建Vxlan隧道连接到对端

    首先建立master节点到node2节点之间的隧道:

    在master节点执行:

    sudo ovs-vsctl add-port br0 vxlan1 -- set interface vxlan1 type=vxlan option:remote_ip=10.0.0.76

    其中10.0.0.76是node2的ens33网卡地址。

    在node2上执行:

    sudo ovs-vsctl add-port br0 vxlan1 -- set interface vxlan1 type=vxlan option:remote_ip=10.0.0.70

    其中10.0.0.70是master的ens33网卡地址。

    执行ovs-vsctl show可看到如下结果:

    同理,建立master到node1之间的隧道,

    在master上执行:

    sudo ovs-vsctl add-port br0 vxlan2 -- set interface vxlan2 type=vxlan option:remote_ip=10.0.0.71

    其中10.0.0.71是node1的地址,这里注意使用另外一个端口vxlan2来作为隧道的端口。

    在node1上执行:

    sudo ovs-vsctl add-port br0 vxlan2 -- set interface vxlan2 type=vxlan option:remote_ip=10.0.0.70

    其中,10.0.0.70是master的IP地址。

    执行ovs-vsctl可以看到:

    master节点上的br0有两个端口用来做隧道,vxlan1和vxlan2。对于node1和node2之间则不需要再建立额外的隧道了,后面可以看到二者之间的docker0网桥能够相互ping通。

    5.添加br0到本地docker0

    sudo brctl addif docker0 br0

    这个操作就相当于把两个交换机给连上了,使得容器流量通过OVS流经tunnel。

    6. 启动br0与docker0网桥

    sudo ip link set dev br0 up
    
    sudo ip link set dev docker0 up

    7. 添加路由规则

    由于10.0.0.70与10.0.0.71以及10.0.0.76的docker0网段分别为172.17.20.1/24、172.17.10.1/24和172.17.30.1/24,这几个网段的路由都需经过本机的docker0网桥路由,其中一个24网段是通过OVS的VxLAN隧道到达对端的,因此需要在每个node上添加通过docker0网桥转发172.17.0.0/16段的路由规则:

    sudo ip route add 172.17.0.0/16 dev docker0

    8.清空Docker自带的iptables规则以及Linux规则

    #iptables –t nat –F; iptables –F

    9.各节点上docker0之间的互通测试

    master节点ping node1

     

    master ping node2

    node1 ping master和node2

    node2 ping master和node1 :

    10.wireshark抓包

    监听br0网桥,在br0网桥上并没有VxLAN报文

    在ens33上抓包,发现了VxLAN封装的ping包报文通过,说明VxLAN是在承载网的物理网络上完成的封包过程。

    至此,基于OVS的网络搭建成功。kubernetes还有许多优秀的开源网络组件,大家各有优势和缺点,有时间做一个汇总。

    参考资料:

     《kubernetes权威指南》

  • 相关阅读:
    【HDOJ】2774 Shuffle
    【POJ】2170 Lattice Animals
    【POJ】1084 Square Destroyer
    【POJ】3523 The Morning after Halloween
    【POJ】3134 Power Calculus
    【Latex】如何在Latex中插入伪代码 —— clrscode3e
    【HDOJ】4801 Pocket Cube 的几种解法和优化
    【HDOJ】4080 Stammering Aliens
    【HDOJ】1800 Flying to the Mars
    SQL语法
  • 原文地址:https://www.cnblogs.com/neutronman/p/8124757.html
Copyright © 2020-2023  润新知