containerd 是一个行业标准的容器运行时,强调简单性、健壮性、可移植性;继 Kubernetes、Prometheus、Envoy 和 CoreDNS 之后,于 2019 年 2 月 28 日,containerd 正式成为云原生计算基金会的毕业项目;从 k8s v1.20 开始废弃对 dockershim 的支持,改用 Containerd 作为默认的容器运行时,于 k8s v1.24 正式移除 dockershim 相关实现代码

Containerd 容器网络是通过 pause 容器(或 Infra 容器)实现,其容器镜像为gcr.io/google_containers/pause-amd64:3.6,该容器是实现 Linux 命名空间共享的基础,

建议通过 PC 端访问本文章,以获取更好阅读体验,由于精力有限,该文章的后续更新、完善仅限于站点 运维技术帮 (https://ywjsbang.com) 望理解 !!

部署环境

1、部署环境说明

CentOS Linux release 7.9.2009 (Core)
Linux Kernel 5.4.186-1.el7.elrepo.x86_64
containerd v1.6.2
runc v1.1.1
crictl v1.20.0

2、节点 IP 地址及组件部署说明

节点IP 地址Pod IP 地址部署信息
a4192.168.31.1410.14.0.0/16containerd、crictl、runc
a5192.168.31.1510.15.0.0/16containerd、crictl、runc

Containerd 解压部署

1、下载解压部署

# 下载解压安装,该压缩文件除包含 containerd 外,还额外包含 cni 插件、runc
wget https://github.com/containerd/containerd/releases/download/v1.6.2/cri-containerd-cni-1.6.2-linux-amd64.tar.gz
tar xvf containerd-1.6.2-linux-amd64.tar.gz -C /

# 替换 containerd 中的 runc (可选)
wget https://github.com/opencontainers/runc/releases/download/v1.1.1/runc.amd64
mv runc.amd64 /usr/local/sbin/runc

# 生成 containerd 默认配置文件
mkdir -p /etc/containerd/ && containerd config default > /etc/containerd/config.toml

# 启动
systemctl daemon-reload && systemctl start containerd.service

2、cri-containerd-cni-1.6.2-linux-amd64.tar.gz 解压文件说明

# cni 网络插件
./opt/cni/bin/tuning、vrf、loopback、portmap、ptp、ipvlan、host-device、macvlan、host-local、firewall、bandwidth、sbr、vlan、static、bridge、dhcp
# cni 网络插件网络配置文件
./etc/cni/net.d/10-containerd-net.conflist
# containerd 启动脚本
./etc/systemd/system/containerd.service
./usr/local/bin/containerd-shim
./usr/local/bin/containerd-shim-runc-v1    # 使用了 v2 版本 shim API,该 shim 仍然只支持 cgroup v1
./usr/local/bin/containerd-shim-runc-v2    # 使用了 v2 版本 shim API,同时支持 cgroup v1 和 v2
./usr/local/bin/containerd          # containerd
./usr/local/bin/containerd-stress   # containerd 内置的压测工具
./usr/local/bin/ctr                 # containerd 自身内置的容器管理工具
./usr/local/bin/ctd-decoder
./usr/local/sbin/runc  # 是一个 CLI 工具,用于根据 OCI 规范在 Linux 上生成和运行容器

# 命令行程序 crictl 程序配置
./etc/crictl.yaml
./usr/local/bin/crictl              # 兼容 cri 规范的容器管理工具
./usr/local/bin/critest

各节点 cni 配置

1、使用 cni 插件 bridge, 将当前节点创建的容器桥接到主机网络

// 使用 bridge、portmap 插件提供内网地址、端口映射功能
cat > /etc/cni/net.d/10-containerd-net.conflist << EOF
{
  "cniVersion": "1.0.0",
  "name": "containerd-net",
  "plugins": [
    {
      "type": "bridge",
      "bridge": "cni0",
      "isGateway": true,
      "ipMasq": true,
      "promiscMode": true,
      "ipam": {
        "type": "host-local",
        "ranges": [
          [{
            "subnet": "10.14.0.0/16"
          }]
        ],
        "routes": [
          { "dst": "0.0.0.0/0" }
        ]
      }
    },
    {
      "type": "portmap",
      "capabilities": {"portMappings": true}
    }
  ]
}
EOF
// 容器环回口 lo 配置
cat > /etc/cni/net.d/99-loopback.conf << EOF
{
    "cniVersion": "1.0.0",
    "name": "lo",
    "type": "loopback"
}
EOF

创建、运行测试容器

1、在一个 pod 沙箱中启动两个容器(nginx、debug)示例,pod 沙箱配置信息如下:

# 将镜像 k8s.gcr.io/pause:3.6 导入到指定命名空间 k8s.io 以便 crictl 工具使用
ctr -n k8s.io images import pause_v3.6.tar

# 启动运行一个 pod sandbox, 可在该 pod sandbox 运行一个或多个容器
cat > pod-sandbox.json << EOF
{
    "metadata": {
        "name": "pod-sandbox",
        "uid": "hdishd83djaidwnduwk28bcsb",
        "namespace": "k8s.io",
        "attempt": 3
    },
    "log_directory": "/tmp",
    "dns_config": {
        "servers": ["8.8.8.8","8.8.4.4"]
    },
    "port_mappings":[
        {
            "protocol": 0,
            "container_port": 80,
            "host_port": 80,
            "host_ip": "192.168.31.15"
        }
    ]
}
EOF

2、a4、a5 节点执行如下操作创建测试容器 debug、nginx

# 删除转发默认动作
iptables -D FORWARD -j REJECT --reject-with icmp-host-prohibited
# 创建 pod 沙箱, 及查看 pod id
crictl runp pod-sandbox.json
crictl pods
# 通过 pod id 创建容器 debug
crictl create 6bc6f4352e3b3 debug.json pod-sandbox.json
crictl start 2369dff38e2db
# 通过 pod id 创建容器 nginx
crictl create 6bc6f4352e3b3 nginx.json pod-sandbox.json
crictl start a92939273b7de
# 手动添加不同节点内的 pod 网段路由
route add -net 10.15.0.0/16 gw 192.168.31.15
# 查看启动的容器
crictl ps
# > CONTAINER           IMAGE                                CREATED             STATE               NAME                ATTEMPT             POD ID
# > a92939273b7de       nginx:latest                         18 seconds ago      Running             nginx               0                   6bc6f4352e3b3
# > 2369dff38e2db       harbor.it123.me/library/debug:v1.2   27 minutes ago      Running             debug               0                   6bc6f4352e3b3

Containerd-stress

1、利用 Containerd 内置压测工具 containerd-stress 测试 containerd 守护进程每秒创建、启动、删除容器的性能

containerd-stress -c 10 -i docker.io/library/alpine:latest --runtime io.containerd.runc.v2
# > INFO[0000] pulling docker.io/library/alpine:latest
# > INFO[0002] starting stress test run...
# > INFO[0063] worker 0 finished
# > INFO[0063] worker 3 finished
# > INFO[0063] worker 1 finished
# > INFO[0063] worker 7 finished
# > INFO[0063] worker 8 finished
# > INFO[0063] worker 9 finished
# > INFO[0063] worker 6 finished
# > INFO[0063] worker 5 finished
# > INFO[0063] worker 4 finished
# > INFO[0063] worker 2 finished
# > INFO[0063] ending test run in 60.399 seconds
# > INFO[0063] create/start/delete 987 containers in 60.399 seconds (16.341 c/sec) or (0.061 sec/c)  failures=0

压测结果说明: 60 秒内完成 987 个容器的创建、启动、删除等操作,平均每秒 16.34 个,经监测、系统磁盘写 io 操作数达到上限!!

iperf3 流量压测

1、节点间 iperf3 流量压测

# a5 节点执行
firewall-cmd --add-port=5201/tcp
iperf3 -s
# 从 a4 节点发起压测
iperf3 -c 192.168.31.15 -n 100G -b 30G
# > Connecting to host 192.168.31.15, port 5201
# > [  4] local 10.14.0.4 port 39974 connected to 192.168.31.15 port 5201
# > [ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
# > [  4]   0.00-1.00   sec  1.69 GBytes  19.5 Gbits/sec  191   2.01 MBytes
# > [  4]   1.00-2.00   sec  1.95 GBytes  19.7 Gbits/sec    0   2.01 MBytes
# > ...
# > ...
# > [  4]  46.00-47.00  sec  2.27 GBytes  19.5 Gbits/sec    0   2.90 MBytes
# > [  4]  47.00-48.00  sec  2.26 GBytes  19.4 Gbits/sec    0   2.90 MBytes
# > [  4]  48.00-48.15  sec   344 MBytes  19.4 Gbits/sec    0   2.90 MBytes
# > - - - - - - - - - - - - - - - - - - - - - - - - -
# > [ ID] Interval           Transfer     Bandwidth       Retr
# > [  4]   0.00-48.15  sec   100 GBytes  19.5 Gbits/sec  451             sender
# > [  4]   0.00-48.15  sec   100 GBytes  19.5 Gbits/sec                  receiver
# > iperf Done.

2、节点容器间 iperf3 流量压测

# 从 a4 节点容器发起压测
crictl exec -it 2369dff38e2db sh
iperf3 -c 10.15.0.3 -n 100G -b 30G
# > Connecting to host 10.15.0.3, port 5201
# > [  4] local 10.14.0.4 port 52846 connected to 10.15.0.3 port 5201
# > [ ID] Interval           Transfer     Bandwidth       Retr  Cwnd
# > [  4]   0.00-1.00   sec  1.60 GBytes  15.7 Gbits/sec  204   1.98 MBytes
# > [  4]   1.00-2.00   sec  1.71 GBytes  16.7 Gbits/sec    0   2.00 MBytes
# > [  4]   2.00-3.00   sec  1.97 GBytes  16.9 Gbits/sec    0   2.01 MBytes
# > [  4]   3.00-4.00   sec  2.02 GBytes  17.3 Gbits/sec   34   2.01 MBytes
# > ...
# > ...
# > [  4]  45.00-46.00  sec  2.29 GBytes  19.7 Gbits/sec    0   2.02 MBytes
# > [  4]  46.00-47.00  sec  2.42 GBytes  18.8 Gbits/sec    0   2.02 MBytes
# > [  4]  47.00-47.20  sec   492 MBytes  20.8 Gbits/sec    0   2.02 MBytes
# > - - - - - - - - - - - - - - - - - - - - - - - - -
# > [ ID] Interval           Transfer     Bandwidth       Retr
# > [  4]   0.00-47.20  sec   100 GBytes  18.2 Gbits/sec  298             sender
# > [  4]   0.00-47.20  sec   100 GBytes  18.2 Gbits/sec                  receiver
# > iperf Done.

3、结论
节点间流量压测平均带宽 19.5 Gbits/sec,节点容器间压测平均带宽 18.2 Gbits/sec,容器化后其流量平均损耗为 (19.5 - 18.2)/19.5 = 6.7%

http 流量压测

1、节点间压测

autocannon http://192.168.31.15
# > Running 10s test @ http://192.168.31.15
# > 10 connections
# > ┌─────────┬──────┬──────┬───────┬───────┬─────────┬─────────┬───────┐
# > │ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%   │ Avg     │ Stdev   │ Max   │
# > ├─────────┼──────┼──────┼───────┼───────┼─────────┼─────────┼───────┤
# > │ Latency │ 0 ms │ 4 ms │ 12 ms │ 13 ms │ 4.51 ms │ 3.29 ms │ 24 ms │
# > └─────────┴──────┴──────┴───────┴───────┴─────────┴─────────┴───────┘
# > ┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
# > │ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg     │ Stdev   │ Min     │
# > ├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
# > │ Req/Sec   │ 12967   │ 12967   │ 21535   │ 22575   │ 20583.6 │ 2720.26 │ 12967   │
# > ├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
# > │ Bytes/Sec │ 11.1 MB │ 11.1 MB │ 18.4 MB │ 19.3 MB │ 17.6 MB │ 2.32 MB │ 11.1 MB │
# > └───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

2、节点容器间压测

autocannon http://10.15.0.3
# > Running 10s test @ http://10.15.0.3
# > 10 connections
# > ┌─────────┬──────┬──────┬───────┬───────┬─────────┬─────────┬───────┐
# > │ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%   │ Avg     │ Stdev   │ Max   │
# > ├─────────┼──────┼──────┼───────┼───────┼─────────┼─────────┼───────┤
# > │ Latency │ 0 ms │ 4 ms │ 13 ms │ 13 ms │ 4.77 ms │ 3.41 ms │ 20 ms │
# > └─────────┴──────┴──────┴───────┴───────┴─────────┴─────────┴───────┘
# > ┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
# > │ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg     │ Stdev   │ Min     │
# > ├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
# > │ Req/Sec   │ 8107    │ 8107    │ 19343   │ 22879   │ 18842   │ 3964.17 │ 8106    │
# > ├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
# > │ Bytes/Sec │ 6.92 MB │ 6.92 MB │ 16.5 MB │ 19.5 MB │ 16.1 MB │ 3.38 MB │ 6.91 MB │
# > └───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

3、结论
平均延迟: 节点间 web 流量压测平均延迟 4.51ms,容器间平均压测 4.77ms, 容器化后平均损耗为 (4.77 - 4.51)/4.51 = 5.8%
平均每秒请求数: 节点间每秒平均请求数 20583,节点容器间为 18842,其平均损耗为 (20583 - 18842)/20583 = 8.5%

重要提醒: 由于笔者时间、视野、认知有限,本文难免出现错误、疏漏等问题,期待各位读者朋友、业界大佬指正交流, 共同进步 !!

参考

https://github.com/opencontainers/runc/releases
https://github.com/containernetworking/plugins
https://github.com/containernetworking/cni
https://www.cni.dev/docs/
https://github.com/kubernetes-sigs/cri-tools
https://github.com/kubernetes-sigs/cri-tools/tree/master/docs/examples

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐