跳转至

创建和使用网络

概述

容器中会发现里面只有一张网卡而且无法连接到外部网络之中,需要借助于 CNI(Container Network Interface 是一个云计算基础项目来实现Containerd 容器具有网络功能)

CNI 插件下载

# - 1. 从 containernetworking/plugins 的 release 页面下载最新版本
# 解压到 /usr/local/cni-plugins
wget https://github.com/containernetworking/plugins/releases/download/v1.1.0/cni-plugins-linux-amd64-v1.1.0.tgz
mkdir -p /usr/local/cni-plugins
tar xvf cni-plugins-linux-amd64-v1.1.0.tgz -C /usr/local/cni-plugins

# - 2. 从 containernetworking/cni 的 release 页面下载最新版本
# 解压到 /usr/local/cni-{version}
wget https://github.com/containernetworking/cni/archive/refs/tags/v1.1.0.tar.gz
tar -zxvf v1.1.0.tar.gz -C /usr/local/

创建 CNI 网络插件

https://github.com/containernetworking/cni#running-the-plugins

使用 bridge 插件创建一个网卡依赖于下面的配置文件

mkdir -p /etc/cni/net.d

自定义网络配置文件:

cat >/etc/cni/net.d/10-my_net.conf <<EOF
{
    "cniVersion": "0.2.0",
    "name": "my_net",
    "type": "bridge",
    "bridge": "cni0",
    "isGateway": true,
    "ipMasq": true,
    "ipam": {
        "type": "host-local",
        "subnet": "10.22.0.0/16",
        "routes": [
            { "dst": "0.0.0.0/0" }
        ]
    }
}
EOF

回环网卡配置:

cat >/etc/cni/net.d/99-loopback.conf <<EOF
{
    "cniVersion": "0.2.0",
    "name": "lo",
    "type": "loopback"
}
EOF

利用 CNI 网络插件进行激活 cni0 网卡

cd /usr/local/cni-1.1.0/scripts

CNI_PATH=/usr/local/cni-plugins ./priv-net-run.sh echo "Hello World! CNI Plugins."
````

宿主机执行 `ip a` 命令即可看到一个 cni0 的网卡

```plain
[root@devmaster scripts]# ip a
...
4: cni0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 7e:94:56:75:d1:05 brd ff:ff:ff:ff:ff:ff
    inet 10.22.0.1/16 brd 10.22.255.255 scope global cni0
       valid_lft forever preferred_lft forever
    inet6 fe80::7c94:56ff:fe75:d105/64 scope link 
       valid_lft forever preferred_lft forever

使用 CNI 网络插件

使 containerd 容器具备网络功能(使其具备各容器互通、外部网络通信功能)

ctr -n k8s.io run -d docker.io/library/busybox:latest busybox
ctr -n k8s.io task ls

export pid=$(ctr -n k8s.io t ls|grep busybox|awk '{print $2}')
export netnspath=/proc/$pid/ns/net
CNI_PATH=/usr/local/cni-plugins /usr/local/cni-1.1.0/scripts/exec-plugins.sh add $pid $netnspath

随后进入 busybox 容器我们将会发现其新增了一张网卡并可以实现外部网络访问:

ctr -n k8s.io task exec --exec-id $RANDOM -t busybox sh - 

新增的网卡:

/ # ip a
...
2: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether f6:f5:09:9a:a3:e6 brd ff:ff:ff:ff:ff:ff
    inet 10.22.0.3/16 brd 10.22.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::f4f5:9ff:fe9a:a3e6/64 scope link 
       valid_lft forever preferred_lft forever

再创建一个 busybox-1 实现互通

ctr -n k8s.io run -d docker.io/library/busybox:latest busybox-1

export pid=$(ctr -n k8s.io t ls|grep busybox-1|awk '{print $2}')
export netnspath=/proc/$pid/ns/net
CNI_PATH=/usr/local/cni-plugins /usr/local/cni-1.1.0/scripts/exec-plugins.sh add $pid $netnspath

查看创建容器的 pid 进程相关信息

ps ajxf|egrep "containerd-shim-runc|43908|48850"|grep -v grep

得到输出:

[root@devmaster scripts]# ps ajxf|egrep "containerd-shim-runc|43908|48850"|grep -v grep
      1    2775    2775    1108 ?             -1 Sl       0   0:00 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id busybox -address /run/containerd/containerd.sock
      1    2971    2971    1108 ?             -1 Sl       0   0:00 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id busybox-1 -address /run/containerd/containerd.sock

查看创建的 busybox-1 相关信息

ctr -n k8s.io task exec --exec-id $RANDOM -t busybox-1 sh -

查看网卡

/ # ip a
...
2: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 9e:f7:5a:d6:12:5e brd ff:ff:ff:ff:ff:ff
    inet 10.22.0.4/16 brd 10.22.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::9cf7:5aff:fed6:125e/64 scope link 
       valid_lft forever preferred_lft forever

采用 nc -l -v -p 8080 监听在另外的一个容器里面进行通信链接。

busybox-1 中:

nc -l -v -p 8080

busybox 中:

nc -vv 10.22.0.4 8080