容器跨主机通信之Calico

1,Difficulties with traditional overlay networks

https://www.projectcalico.org/learn/

Traditional virtual infrastructures have offered a LAN-like (Layer 2) experience to users configuring multiple workloads.  This may require several layers of virtual LANs, bridging and tunnelling to make Layer 2 networking work across multiple physical hosts.  This presents a range of problems.


  • Scale challenges above few hundred servers / thousands of workloads.
  • Difficult to troubleshoot due to packet encapsulation.
  • On/off-ramp device (or virtual router hop) required to access non-virtualized devices.
  • Every node in the network is state-heavy (e.g. VLANs, tunnels).
  • Virtual NAT device required to connect a workload to a public “floating IP”.
  • High availability / load balancing across links requires additional LB function and/or app-specific logic.
  • Geographically distributed data centers require inter-DC tunnels.
  • CCNA or equivalent required to understand end-to-end networking




关于Calico的原理:

Calico把每个操作系统的 协议栈 认为是一个 路由器 ,然后把所有的 容器 认为是连在这个路由器上的 网络终端 ,在路由器之间跑标准的路由协议——BGP的协议,然后让它们自己去学习这个网络拓扑该如何转发。所以Calico方案其实是一个纯三层的方案,也就是说让每台机器的协议栈的三层去确保两个容器,跨主机容器之间的三层连通性。



对于控制平面,它每个节点上会运行两个主要的程序,一个是Felix,它会监听ECTD中心的存储,从它获取事件,比如说用户在这台机器上加了一个IP,或者是分配了一个容器等。接着会在这台机器上创建出一个容器,并将其网卡、IP、MAC都设置好,然后在内核的路由表里面写一条,注明这个IP应该到这张网卡。绿色部分是一个标准的路由程序,它会从内核里面获取哪一些IP的路由发生了变化,然后通过标准BGP的路由协议扩散到整个其他的宿主机上,让外界都知道这个IP在这里,你们路由的时候得到这里来。

由于Calico是一种纯三层的实现,因此可以避免与二层方案相关的数据包封装的操作,中间没有任何的NAT,没有任何的overlay,所以它的转发效率可能是所有方案中最高的,因为它的包直接走原生TCP/IP的协议栈,它的隔离也因为这个栈而变得好做。因为TCP/IP的协议栈提供了一整套的防火墙的规则,所以它可以通过IPTABLES的规则达到比较复杂的隔离逻辑。



2,Calico 简介

Calico是一个纯三层的协议,为OpenStack虚机和Docker容器提供多主机间通信。Calico不使用重叠网络比如flannel和libnetwork重叠网络驱动,它是一个纯三层的方法,使用虚拟路由代替虚拟交换,每一台虚拟路由通过BGP协议传播可达信息(路由)到剩余数据中心。

https://www.projectcalico.org/

Calico不使用重叠网络比如flannel和libnetwork重叠网络驱动,它是一个纯三层的方法,使用虚拟路由代替虚拟交换,每一台虚拟路由通过BGP协议传播可达信息(路由)到剩余数据中心。

Calico在每一个计算节点利用Linux Kernel实现了一个高效的vRouter来负责数据转发,而每个vRouter通过BGP协议负责把自己上运行的workload的路由信息像整个Calico网络内传播——小规模部署可以直接互联,大规模下可通过指定的BGP route reflector来完成。

这样保证最终所有的workload之间的数据流量都是通过IP路由的方式完成互联的。



Calico节点组网可以直接利用数据中心的网络结构(无论是L2或者L3),不需要额外的NAT,隧道或者Overlay Network。


如上图所示,这样保证这个方案的简单可控,而且没有封包解包,节约CPU计算资源的同时,提高了整个网络的性能。


Calico有2种方式:

2.1 IPIP

从字面来理解,就是把一个IP数据包又套在一个IP包里。是把 IP 层封装到 IP 层的一个 tunnel,看起来似乎是浪费,实则不然。它的作用其实基本上就相当于一个基于IP层的网桥!我们知道,普通的网桥是基于mac层的,根本不需 IP,而这个 ipip 则是通过两端的路由做一个 tunnel,把两个本来不通的网络通过点对点连接起来。ipip 的源代码在内核 net/ipv4/ipip.c 中可以找到。



more about ip in ip:  https://en.wikipedia.org/wiki/IP_in_IP


2.2 BGP

边界网关协议(Border Gateway Protocol, BGP)是互联网上一个核心的去中心化自治路由协议。它通过维护IP路由表或‘前缀’表来实现自治系统(AS)之间的可达性,属于矢量路由协议。BGP不使用传统的内部网关协议(IGP)的指标,而使用基于路径、网络策略或规则集来决定路由。因此,它更适合被称为矢量性协议,而不是路由协议。

BGP,通俗的讲就是讲接入到机房的多条线路(如电信、联通、移动等)融合为一体,实现多线单IP,BGP 机房的优点:服务器只需要设置一个IP地址,最佳访问路由是由网络上的骨干路由器根据路由跳数与其它技术指标来确定的,不会占用服务器的任何系统。


3,部署Calico on Docker

VM1: 129.107.126.193
VM2: 129.107.126.220


(1) , install etcd and execute it

on VM1, 
etcd    --name uta-vm1 \
        --initial-advertise-peer-urls http://$IP1:2380 \
        --listen-peer-urls http://$IP1:2380 \
        --listen-client-urls http://$IP1:2379,http://127.0.0.1:2379 \
        --advertise-client-urls http://$IP1:2379 \
        --initial-cluster-token etcd-cluster \
        --initial-cluster uta-vm1=http://$IP1:2380,uta-vm2=http://$IP2:2380  \
        --initial-cluster-state new

on VM2 do the same thing, using different IP


启动 docker

on VM1

$ sudo docker daemon --cluster-store=etcd://129.107.126.193:2379



(2) install calicoctl

$ wget https://github.com/projectcalico/calicoctl/releases/download/v1.1.0/calicoctl
$ chmod +x calicoctl 
$ sudo mv calicoctl /usr/local/bin/


$ calicoctl -h
Usage:
  calicoctl [options] [...]

    create    Create a resource by filename or stdin.
    replace   Replace a resource by filename or stdin.
    apply     Apply a resource by filename or stdin.  This creates a resource
              if it does not exist, and replaces a resource if it does exists.
    delete    Delete a resource identified by file, stdin or resource type and
              name.
    get       Get a resource identified by file, stdin or resource type and
              name.
    config    Manage system-wide and low-level node configuration options.
    ipam      IP address management.
    node      Calico node management.
    version   Display the version of calicoctl.

Options:
  -h --help               Show this screen.
  -l --log-level=  Set the log level (one of panic, fatal, error,
                          warn, info, debug) [default: panic]


3,

$ vim calicoctl.cfg


写入如下内容,这是在VM1上面:



apiVersion: v1
kind: calicoApiConfig
metadata:
spec:
  datastoreType: etcdv2
  etcdEndpoints: http://129.107.126.193:2379,http://129.107.126.220:2379

在VM2上面:

apiVersion: v1
kind: calicoApiConfig
metadata:
spec:
  datastoreType: etcdv2
  etcdEndpoints: http://129.107.126.193:2379,http://129.107.126.220:2379


运行下面的命令在节点1/2来启动calico-node

$ sudo calicoctl node run --ip=129.107.126.193  --config=./calicoctl.cfg
$ sudo calicoctl node run --ip=129.107.126.220  --config=./calicoctl.cfg

运行后在两个主机用docker ps可以看到正在运行calico-node的container:

$ sudo docker ps 
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS                            PORTS               NAMES
02204717e058        quay.io/calico/node:latest   "start_runit"            16 seconds ago      Restarting (1) 5 seconds ago                           calico-node


通过下面命令查看节点状态信息:

$ sudo calicoctl node status
Calico process is running.

IPv4 BGP status
+-----------------+-------------------+-------+----------+-------------+
|  PEER ADDRESS   |     PEER TYPE     | STATE |  SINCE   |    INFO     |
+-----------------+-------------------+-------+----------+-------------+
| 129.107.126.193 | node-to-node mesh | up    | 00:08:19 | Established |
+-----------------+-------------------+-------+----------+-------------+

IPv6 BGP status
No IPv6 peers found.


更多关于bgp配置:
http://docs.projectcalico.org/v2.0/usage/configuration/bgp

ipip enabled配置:
http://docs.projectcalico.org/master/reference/calicoctl/resources/ippool


4,下面为我们的calico网络添加可用的ip pool

$ vim ipPool.yaml

apiVersion: v1
kind: ipPool
metadata:
  cidr: 10.1.1.0/24
spec:
  ipip:
    enabled: false
  nat-outgoing: true
  disabled: false


$ sudo calicoctl create -f ipPool.yaml
Successfully created 1 'ipPool' resource(s)


$ sudo calicoctl get ipPool
CIDR
10.1.1.0/24
192.168.0.0/16
fd80:24e2:f998:72d6::/64


do the samething on VM2



5,在上面创建的ip pool(10.1.1.0/24)里创建子网络

on VM1:

$ sudo docker network create --driver calico --ipam-driver calico-ipam  --subnet 10.1.1.0/24  calico-net1
3e526b46f068781650dc4ced04c15c77fbf46b215fb95d10f938a12a37d13acc



可以看到我们刚建立的网络calico-net1

$ sudo docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
e899b1958786        bridge              bridge              local
3e526b46f068         calico-net1         calico              global
58566d3ecc75        docker_gwbridge     bridge              local
26362372b64b        host                host                local
17c7751410e7        myoverlay-1         overlay             global
a72c2bebcc6a        none                null                local
169a60dd6c80        weave               weavemesh           local

因为etcd的原因,在VM2上面 sudo docker network ls,也能看到网络calico-net1。



7, create container in the network calico-net1

on VM1:
$ sudo docker run -t -i  --net calico-net1  --name calico-c1  ubuntu:16.10 /bin/bash

on VM2:
$ sudo docker run -t -i  --net calico-net1  --name calico-c2  ubuntu:16.10 /bin/bash


in container
# apt update -y

# apt install wget iputils-ping fish gcc openssh-client net-tools g++ make vim git autoconf automake libtool -y

ping each other.



done

同一网络内的容器是能相互通信的;不同网络内的容器相互是不通的。不同节点上属于同一网络的容器也是能相互通信的,这样就实现了容器的跨主机互连。



4, 性能

Calico官方给出的Calico与物理网络、OVS的性能对比:
http://www.projectcalico.org/calico-dataplane-performance/


我自己的测试结果与这个文章中的结果的差别有些大,虽然确实Calico在网络本身较好的情况下TCP有着绝对优势,但是它的UDP性能并不算很突出,在非ipip模式时能保持一点领先,但是在ipip模式时候,与Flannel基本等同,甚至更差。


你可能感兴趣的:(container)