从cni shell脚本看传入哪些参数

作者: admin 分类: docker 发布时间: 2018-05-10 14:51 ė 6 没有评论

# cd $GOPATH/src
# git clone https://github.com/containernetworking/cni.git
# cd cni/scripts
# export CNI_PATH=/opt/cni/bin/
# export NETCONFPATH=/etc/cni/net.d
# ./docker-run.sh –rm busybox ifconfig | grep -Pi “(eth0|lo|inet addr)”

docker-run.sh

#!/bin/bash

# Run a docker container with network namespace set up by the
# CNI plugins.

# Example usage: ./docker-run.sh --rm busybox /sbin/ifconfig

#获取容器ID
contid=$(docker run -d --net=none busybox:latest /bin/sleep 10000000)
#获取容器进行pid
pid=$(docker inspect -f '{{ .State.Pid }}' $contid)
#容器的网络命名空间路径
netnspath=/proc/$pid/ns/net

#引入exec-plugins.sh脚本 传入容器ID和
./exec-plugins.sh add $contid $netnspath

function cleanup() {
        ./exec-plugins.sh del $contid $netnspath
        docker rm -f $contid >/dev/null
}
trap cleanup EXIT
#启动容器

docker run --net=container:$contid $@

exec-plugins.sh

#!/usr/bin/env bash
export CNI_PATH=/opt/cni/bin/  
# export NETCONFPATH=/etc/cni/net.d
if [[ ${DEBUG} -gt 0 ]]; then set -x; fi

NETCONFPATH=${NETCONFPATH-/etc/cni/net.d}

function exec_plugins() {
        i=0
        contid=$2
        netns=$3
        export CNI_COMMAND=$(echo $1 | tr '[:lower:]' '[:upper:]')
        echo $CNI_PATH
        export PATH=$CNI_PATH:$PATH
        export CNI_CONTAINERID=$contid
        export CNI_NETNS=$netns

        for netconf in $(echo $NETCONFPATH/*.conf | sort); do
                name=$(jq -r '.name' <$netconf)
                plugin=$(jq -r '.type' <$netconf)
                export CNI_IFNAME=$(printf eth%d $i)
                #将json文件 输入给插件
                res=$($plugin <$netconf)
                if [ $? -ne 0 ]; then
                        errmsg=$(echo $res | jq -r '.msg')
                        if [ -z "$errmsg" ]; then
                                errmsg=$res
                        fi

                        echo "${name} : error executing $CNI_COMMAND: $errmsg"
                        exit 1
                elif [[ ${DEBUG} -gt 0 ]]; then
                        echo ${res} | jq -r .
                fi

                let "i=i+1"
        done
}

if [ $# -ne 3 ]; then
        echo "Usage: $0 add|del CONTAINER-ID NETNS-PATH"
        echo "  Adds or deletes the container specified by NETNS-PATH to the networks"
        echo "  specified in \$NETCONFPATH directory"
        exit 1
fi

exec_plugins $1 $2 $3

下段文字转载于:https://wiki.shileizcc.com/confluence/display/KUB/Kubernetes+CNI

CNI Plugin 插件详解
CNI Plugin 包括 3 个基本接口的定义:添加(Add Container to Network)、删除(Delete Container from Network)和版本查询(Report Version)。这些接口的具体实现要求插件提供一个可执行的程序,在容器网络添加或删除时进行调用,已完成具体的操作。

添加
将容器添加到某个网络。主要过程为在 Container Runtime 创建容器时,先创建好容器内的网络命名空间(Network Namaspace),然后调用 CNI 插件为该 netns 运行网络配置,最后启动容器内的进程。

添加接口的参数如下:

Version:CNI 版本号。
Container ID:容器 ID。
Network namespace path:容器的网络命名空间路径,例如 /proc/[pid]/ns/net。
Network configuration:网络配置 JSON 文档,用于描述容器待加入的网络。
Extra arguments:其他参数,提供基于容器的 CNI 插件简单配置机制。
Name of the interface inside the container:容器内的网卡名。
返回的信息如下:

Interfaces list:网卡列表,根据 plugin 的实现,可能包括 Sandbox Interface 名称、主机 Interface 名称、每个 Interface 的地址等信息。
IPs assigned to the interface:IPv4 或者 IPv6 地址、网关地址、路由信息等。
DNS information:DNS 相关的信息。
删除
容器销毁时将容器从某个网络中删除。

删除接口参数如下:

version:CNI 版本号。
Container ID:容器 ID。
Network namespace path:容器的网络命名空间路径,例如 /proc/[pid]/ns/net。
Network configuration:网络配置 JSON 文档,用于描述容器待加入的网络。
Extra arguments:其他参数,提供基于容器的 CNI 插件简单配置机制。
Name of the interface inside the container:容器内的网卡名。
版本查询
查询网络插件支持的 CNI 规范版本号。

无参数,返回值为网络插件支持的 CNI 规范版本号,例如:

{
“cniVersion”: “0.3.1”, // the version of the CNI spec in use for this optput
“supportedVersions”: [“0.1.0”, “0.2.0”, “0.3.0”, “0.3.1”] // the list of CNI spec version that this plugin spports
}
CNI 插件能够支持通过环境变量和标准输入传入参数。可执行文件通过 “网络配置参数” 中的 type 字段标识的文件名在环境变量 “CNI_PATH” 设定的路径下进行查找。一旦找到,容器运行时将调用该可执行程序,并传入以下环境变量和网络配置参数,供该插件完成容器网络资源和参数的设置。

环境变量参数如下:

CNI_CONMMAND:接口方法,包括 ADD、DEL 和 VERSION。
CNI_CONTAINERID:容器 ID。
CIN_NETNS:容器的网络命名空间路径,例如 /proc/[pid]/ns/net。
CNI_INNAME:待支持的网络接口名称。
CNI_ARGS:其他参数,为 key = value 格式,对个参数之间用分号分隔,例如 “FOO=BAR; ABC=123″。
CNI_PATH:可执行文件查询路径,可以设置多个。
网络哦遏制参数则由一个 JSON 报文组成,以标准输入(stdin)的方式传递给可执行程序。

网络配置参数如下:

cniVersion(string):CNI 版本号。
name(string):网络名称,应在一个管理域内唯一。
type(string):CNI 插件可执行文件的名称。
args(dictionary):其他参数。
ipMasq(boolean):是否设置 IP Masquerade(需插件支持),适用于主机可作为网关的环境中。
ipam:IP 地址管理的相关配置。
– type(string):IPAM 可执行的文件名。

dns:DNS 服务的相关配置。
– namespace(list of string):名字服务器列表,可以使用 IPv4 和 IPv6 地址。

– domain(string):本地域名,用于短主机名查询。

– search(list of strings):按优先级排序的域名查询列表。

– options(list of strings):传递给 resolver 的选项列表。

下例定义了一个名为 ”dbnet“ 的网络配置参数,IPAM 使用 ”host-local“ 进行设置。

{
“cniVersion”: “0.3.1”,
“name”: “dbnet”,
“type”: “bridge”,
“bridge”: “cni0”,
“ipam”: {
“type”: “host-local”,
“subnet”: “10.1.0.0/16”,
“gateway”: “10.1.0.1”
},
“dns”: {
“nameservers”: [ “10.1.0.1” ]
}
}
IPAM Plugin 插件详解
为了减轻 CNI Plugin 对 IP 地址管理的负担,CNI 规范中设置了一个新的插件专门用于管理容器的 IP 地址(还包括网关、路由等信息),被称为 IPAM Plugin。通常用 CNI Plugin 在运行时自动调用 IPAM Plugin 完成容器 IP 地址的分配。

IPAM Plugin 负责为容器分配 IP 地址、网关、路由和 DNS,典型的实现包括 host-local 和 dhcp。与 CNI Plugin 类似,IPAM 插件也通过可执行程序完成 IP 地址分配的具体操作。IPAM 可执行程序也处理传递给 CNI 插件的环境变量和通过标准输入(stdin)传入的网络配置参数。

如果成功完成了容器 IP 地址的分配,则 IPAM 插件应该通过标准输出(stdout)返回以下 JSON 报文:

{
“cniVersion”: “0.3.1”,
“ips”: [
{
“version”: “<4-or-6>“,
“address”: ““,
“gateway”: “” (optional)
},

],
“routes”: [
{
“dst”: “ip-and-prefix-in-cidr”,
“gw”: “ip-of-next-hop” (optional)
},

],
“dns”: {
“nameservers”: ““, (optional)
“domain”: ““, (optional)
“search”: ““, (optional)
“options”: “” (optional)
}
}
其中包括 ips、routes 和 dns 三段内容。

ips 段:分配给容器 IP 地址(可能包括网关)。
routes 段:路由规则记录。
dns 段:DNS 相关的信息。

源码分析:
http://www.cnblogs.com/YaoDD/p/6410725.html
http://www.cnblogs.com/YaoDD/p/6412836.html

本文出自 小Q,转载时请注明出处及相应链接。

本文永久链接: http://www.linuxqq.com/archives/1839.html

0
更多
Ɣ回顶部