新手使用Containerd时的几点须知

相信大家在2020年岁末都被Kubernetes即将抛弃Docker的消息刷屏了。事实上作为接替Docker运行时的Containerd在早在Kubernetes1.7时就能直接与Kubelet集成使用,只是大部分时候我们因熟悉Docker,...

相信大家在2020年岁末都被Kubernetes即将抛弃Docker的消息刷屏了。事实上作为接替Docker运行时的Containerd在早在Kubernetes1.7时就能直接与Kubelet集成使用,只是大部分时候我们因熟悉Docker,在部署集群时采用了默认的dockershim。不过社区也说了,在1.20之后的版本的kubelet会放弃对dockershim部分的支持

attachments-2022-07-V2j9WRVS62cc31b930062,png

作为普通小白,我们在更换Containerd后,以往的一些习惯和配置也不得不改变和适配。那么本篇也是最近小白逐渐替换Containerd后的一些总结。


1. Containerd安装与Kubelet集成

安装前的准备

cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf

overlay

br_netfilter

EOF


sudo modprobe overlay

sudo modprobe br_netfilter


# 设置必需的 sysctl 参数,这些参数在重新启动后仍然存在。

cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf

net.bridge.bridge-nf-call-iptables  = 1

net.ipv4.ip_forward                 = 1

net.bridge.bridge-nf-call-ip6tables = 1

EOF


sudo sysctl --system

安装containerd

# 安装 Docker 的官方 GPG 密钥

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key --keyring /etc/apt/trusted.gpg.d/docker.gpg add -


# 新增 Docker apt 仓库。

sudo add-apt-repository \

    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \

    $(lsb_release -cs) \

    stable"

    

# 安装containerd包

sudo apt-get update && sudo apt-get install -y containerd.io

生成containerd默认配置

sudo mkdir -p /etc/containerd

sudo containerd config default > /etc/containerd/config.toml

修改kubelet配置

在配置文件/var/lib/kubelet/kubeadm-flags.env的KUBELET_KUBEADM_ARGS追加以下部分

KUBELET_KUBEADM_ARGS="--container-runtime=remote --runtime-request-timeout=15m --container-runtime-endpoint=unix:///run/containerd/containerd.sock --image-service-endpoint=unix:///run/containerd/containerd.sock


重启containerd和kubelet服务

systemctl restart containerd kubelet复


Containerd常见操作

更换Containerd后,以往我们常用的docker命令也不再使用,取而代之的分别是crictl和ctr两个命令客户端。


crictl是遵循CRI接口规范的一个命令行工具,通常用它来检查和管理kubelet节点上的容器运行时和镜像

ctr是containerd的一个客户端工具,

使用crictl命令之前,需要先配置/etc/crictl.yaml如下:


runtime-endpoint: unix:///run/containerd/containerd.sock

image-endpoint: unix:///run/containerd/containerd.sock

timeout: 10

debug: false


接下来就是crictl的的常见命令,其中能完全替代docker命令的参照下列表格

-----------------------------------

attachments-2022-07-fBRZWnjN62cc33676c95b,png

这里需注意的是,由于Containerd也有namespaces的概念,对于上层编排系统的支持,主要区分了3个命名空间分别是k8s.io、moby和default,以上我们用crictl操作的均在k8s.io命名空间完成如查看镜像列表就需要加上-n参数


ctr -n k8s.io images list


 Containerd与(虚拟)显卡设备

在Docker中,通常用nvidia-docker来调用nvidia-container-runtime来实现容器的GPU设备挂载。在更换成Containerd后,我们就不再需要nvidia-docker这个客户端,而是直接在containerd运行时的plugin中直接调用nvidia-container-runtime


除了需要正常安装containerd和nvidia、cuda驱动外,还需要安装nvidia-container-runtime


curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \

  sudo apt-key add -

distribution=$(. /etc/os-release;echo $ID$VERSION_ID)

curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \

  sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list

sudo apt update

sudo apt install nvidia-container-runtime -y


最后在containerd添加nvidia运行时配置


/etc/containerd/config.toml


    [plugins."io.containerd.grpc.v1.cri".containerd]

      snapshotter = "overlayfs"

-     default_runtime_name = "runc"

+     default_runtime_name = "nvidia"

      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]

        # This section is added by system, we can just ignore it.

        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]

          runtime_type = "io.containerd.runc.v2"

          runtime_engine = ""

          runtime_root = ""

          privileged_without_host_devices = false

          base_runtime_spec = ""

+       [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia]

+         runtime_type = "io.containerd.runc.v2"

+         runtime_engine = ""

+         runtime_root = ""

+         privileged_without_host_devices = false

+         base_runtime_spec = ""

+         [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options]

+           BinaryName = "nvidia-container-runtime"


此外如果你和小白一样用了腾讯的tke-gpu-manager来虚拟化GPU设备的话,还需要将gpu-manager升级到1.1.0版本以上。然后修改启动参数即可解决


containers:- env:

  - name: EXTRA_FLAGSvalue: --container-runtime-endpoint=/var/run/containerd/containerd.sock


最后我们用一个pod来验证GPU是否能正常识别到即可


apiVersion: v1

kind: Pod

metadata:

  name: vcuda

spec:

  restartPolicy: Never

  containers:

  - image: nvidia/cuda:10.1-runtime-ubuntu16.04

    name: nvidia

    command:

    - "/usr/local/nvidia/bin/nvidia-smi"

    - "pmon"

    - "-d"

    - "10"

    resources:

      requests:

        tencent.com/vcuda-core: 50

        tencent.com/vcuda-memory: 4

      limits:

        tencent.com/vcuda-core: 50

        tencent.com/vcuda-memory: 4


4. Containerd控制台日志

在Docker时代,kubernetes的容器控制日志默认格式为json,在更换为Containerd后,容器的控制台输出变为text格式,如下


# docker的json格式日志

{"log":"[INFO] plugin/reload: Running configuration MD5 = 4665410bf21c8b272fcfd562c482cb82\n","stream":"stdout","time":"2020-01-10T17:22:50.838559221Z"}


#contaienrd的text格式日志

2020-01-10T18:10:40.01576219Z stdout F [INFO] plugin/reload: Running configuration MD5 = 4665410bf21c8b272fcfd562c482cb82


大多情况情况下这会导致我们默认的日志采集客户端以前用json格式解析器报错而无法继续采集日志,所以当我们把Containerd上线后还需要修改日志采集端的配置。

以fluentd为样例,我们需要引入multi_format来解析两种格式的容器日志


<source>

  @id fluentd-containers.log

  @type tail

  path /var/log/containers/*.log

  pos_file /var/log/es-containers.log.pos

  tag raw.kubernetes.*

  read_from_head true

  <parse>@type multi_format<pattern>  format json  time_key time  time_format %Y-%m-%dT%H:%M:%S.%NZ</pattern>#这部分用来正则匹配CRI容器日志格式<pattern>  format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/  time_format %Y-%m-%dT%H:%M:%S.%N%:z</pattern>

  </parse></source>

总结

K8S的Worker节点逐渐的往轻量化转移,除了Containerd之外还有k8s的亲儿子cri-o,不过相比Containerd已经过大规模生产环境验证的产品来讲,当下Containerd仍然是最佳的容器运行时管理工具。


  • 发表于 2022-07-11 22:21
  • 阅读 ( 33 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
shitian
shitian

662 篇文章

作家榜 »

  1. shitian 662 文章
  2. 石天 437 文章
  3. 每天惠23 33 文章
  4. 小A 29 文章