专栏首页腾讯云TStack专栏9021年了,你还不知道CNI?

9021年了,你还不知道CNI?

|作者简介

John lin

目前專注於 Kubernetes CNI 插件開發,並透過 Open vSwitch 設計容器網路於多物理節點上的虛擬網路架構

之前的文章内有提到过CNI插件 

进来看看,宝岛小哥哥的CNI插件~

Container Networking Inteferface (以下简称 CNI)是一个由 CoreOS 所提出的一个容器网路规范并开发了一个专案 containernetworking/cni ,他的核心目标是针对容器提出一个解决方案将网路功能插件化(模组化)

当启用一个 CNI 插件,运作流程是在创建容器时,调用这个 CNI 插件并为这个容器配置网路设定,最后再启动容器内的 Process ,最后当容器结束前 CNI 插件会将网路功能终止再清除设定。

目前这个网路模型已经广泛的受到社群的认可,例如知名的容器集群管理平台 Kubernetes 即是支援这种 CNI 容器网路规范,目前依不同需求,或不同社群及偏好可以在 Kubernetes 上选用不同插件像是 Calico, Weave, SRIOV, Ciliuim, Canal 和 Flannel ,而上述的插件都是遵循 CNI 容器网路规范,所开发而来。

|CNI 基本使用方法

既然提到容器,我们可以回到容器的最基本核心概念,Linux Network Namespace 它提供了一个独立的网路环境,包括网卡、路由、iptables 规则等都与其他的 Network Namespace 隔离。而最基础操作 Network Namespace 方法可以透过 netns 来创建或删除。对于想了解 netns 如何使用的朋友,不妨参考 手把手打造彷 mininet 网路 的 Step2。

接着我们要做的步骤大致如下:

  1. 创建 Network Namespace
  2. 建立一个 network configuration
  3. 运行 CNI Plugins 喂入 network configuration(本例将使用 linux bridge 的 plugin)
  4. 测试网路互通性

在 Ubuntu 64bit 系统上实验,在开始之前,我们先将 CNI 插件备齐

$ mkdir myCNI
$ cd myCNI
$ curl -O -L https://github.com/containernetworking/cni/releases/download/v0.5.2/cni-amd64-v0.5.2.tgz
$ tar -xzvf cni-amd64-v0.5.2.tgz
$ ls
bridge  cni-amd64-v0.5.2.tgz  cnitool  dhcp  flannel  host-local  ipvlan  loopback  macvlan  noop  ptp  tuning

这裡面的 network plugin binary 分别有不同的网路功能,我们将在这篇用到 bridge 及 host-local

Step1. 取得 root 权限后,透过 netns创建两个 network namespace

$ ip netns add ns1
$ ip netns add ns2

Step2. 建立一个 network configuration

cat > mybridge.conf <<"EOF"
{
    "name": "mybridge",
    "type": "bridge",
    "bridge": "kbr0",
    "isGateway": true,
    "isDefaultGateway": true,
    "ipMasq": true,
    "ipam": {
      "type": "host-local",
      "subnet": "10.244.0.0/16",
      "routes": [
         { "dst": "0.0.0.0/0" }
      ],
      "gateway": "10.244.1.1"
    }
}
EOF

这个 configuration 十分重要,它除了定义 bridge 上的设定,也定义了容器接上 bridge 所配发的 IP 及所属的子网域。稍微指出几个比较特别的栏位:

  1. type : 是用来指定其对应的 binary 档桉名称
  2. ipam : 又作 IP Allocation 是用来分配容器IP及切割子网域,注意到里面又有一个 type 呼叫 host-local

Step3. 运行 CNI Plugins 喂入 network configuration

  1. CNI_COMMAND 指定 action (目前CNI套件有 ADD 及 DEL 两个command);
  2. CNI_CONTAINERID 给予 namespace name;
  3. CNI_NETNS mount 路径;
  4. CNI_IFNAME 创建容器内部 interface 名称
  5. CNI_PATH 告诉 CNI plugin 的所在位置(目前刚好在myCNI目录裡面所以用 pwd)
$ CNI_COMMAND=ADD CNI_CONTAINERID=ns1 CNI_NETNS=/var/run/netns/ns1 CNI_IFNAME=eth3 CNI_PATH=`pwd` ./bridge <mybridge.conf
{
    "ip4": {
        "ip": "10.244.0.1/16",
        "gateway": "10.244.1.1",
        "routes": [
            {
                "dst": "0.0.0.0/0",
                "gw": "10.244.1.1"
            },
            {
                "dst": "0.0.0.0/0",
                "gw": "10.244.1.1"
            }
        ]
    },
    "dns": {}
}
$ CNI_COMMAND=ADD CNI_CONTAINERID=ns2 CNI_NETNS=/var/run/netns/ns2 CNI_IFNAME=eth3 CNI_PATH=`pwd` ./bridge <mybridge.conf
{
    "ip4": {
        "ip": "10.244.0.2/16",
        "gateway": "10.244.1.1",
        "routes": [
            {
                "dst": "0.0.0.0/0",
                "gw": "10.244.1.1"
            },
            {
                "dst": "0.0.0.0/0",
                "gw": "10.244.1.1"
            }
        ]
    },
    "dns": {}
}

Step4. 最后可以由 ip netns exec ${name} ifconfg 来看容器所分配的 IP 进行互通测试。

$ip netns exec ns1 ifconfig
eth3      Link encap:Ethernet  HWaddr 0a:58:0a:f4:00:01
          inet addr:10.244.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::903f:40ff:fea6:adc4/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:23 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1854 (1.8 KB)  TX bytes:648 (648.0 B)
$ip netns exec ns2 ifconfig
eth3      Link encap:Ethernet  HWaddr 0a:58:0a:f4:00:02
          inet addr:10.244.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::10e0:5aff:feca:442a/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:648 (648.0 B)  TX bytes:648 (648.0 B)
$ ip netns exec ns2 ping 10.244.0.1
PING 10.244.0.1 (10.244.0.1) 56(84) bytes of data.
64 bytes from 10.244.0.1: icmp_seq=1 ttl=64 time=0.360 ms
64 bytes from 10.244.0.1: icmp_seq=2 ttl=64 time=0.093 ms
64 bytes from 10.244.0.1: icmp_seq=3 ttl=64 time=0.086 ms

这篇算是个入门的操作简介,让大家更快了解 CNI 的使用,如果有在使用 Docker container 也是可以透过类似相同的手法来操作将 CNI 的 Plugin 接上,只要取得 container ID 及 network namespace 的 mount 路径,即可做到一样的操作方法。

· END ·

本文分享自微信公众号 - 腾讯云TStack(gh_035269c8aa5f)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 「docker实战篇」python的docker-docker系统管理-基础概念(28)

    PS:说了下docker的优越性,vagrant的方式搭建了一个centos7的docker环境。一定要了解集装箱的概念对了解docker很有必要。

    IT故事会
  • Docker清理占用的磁盘空间

    摘要:用了 Docker,好处挺多的,但是有一个不大不小的问题,它会一不小心占用太多磁盘,这就意味着我们必须及时清理。

    用户1437675
  • Weekly | 2019.03.18~2019.03.24

    Docker 从 2013 年首次亮相,至今已 6 年之久,而 Docker 也已一度成为容器技术的代名词,很庆幸能投身 Docker 相关的领域。官方博客[1...

    Jintao Zhang
  • 「docker实战篇」python的docker-docker系统管理-基本命令(29)

    PS:docker的基本命令很重要,但是如果会使用help这个功能官方介绍的更清楚,我这里也是把英文做了翻译。主要还是理解原理。

    IT故事会
  • 「docker实战篇」python的docker- 多设备端并发抓取抖音粉丝数据(23)

    PS:调试过程中,夜神模拟器,appium,python代码插件没有问题的话,程序在运行过程中出现的最多的问题还是xpath定位的问题,对于python的代码其...

    IT故事会
  • 「docker实战篇」python的docker- 抖音视频抓取(中)(25)

    IT故事会
  • 开疆拓土,扬帆起航:云+社区助力长沙开发者社区成立

    2019年4月21日,云+社区联合长沙开发者社区在长沙岳麓区腾讯众创空间成功举办了长沙开发者技术大会暨长沙开发者社区成立大会。

    TVP官方团队
  • CentOS7系统上使用RapidSVN

    由于公司使用的代码管理工具还是 subversion,每次都命令行使用实在有点不方便,于是乎想到了找一个 Linux 平台的可视化 subversion 工具,...

    kongxx
  • Docker实现容器具有固定IP

    在搭建一些集群软件的时候,组件和组件之间需要进行网络通信,这个时候如果每次重启IP都发生变化会很不方便,因此希望能够将容器的IP固定下来,这也是可以实现的,具体...

    大江小浪
  • 这 10 道 Spring Boot 常见面试题你需要了解下

    多年来,随着新功能的增加,spring变得越来越复杂。只需访问https://spring.io/projects页面,我们就会看到可以在我们的应用程序中使用的...

    Java团长

扫码关注云+社区

领取腾讯云代金券