美文网首页
辞旧迎新,新手使用Containerd时的几点须知

辞旧迎新,新手使用Containerd时的几点须知

作者: 魔哈Moha | 来源:发表于2021-01-05 09:53 被阅读0次
    docker-gogogo.jpg

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

    image.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
    

    2. 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命令的参照下列表格

    操作 crictl docker
    查看运行容器 crictl ps docker ps
    查看镜像 crictl images docker images
    查看容器日志 crictl logs docker logs
    登陆容器控制台 crictl exec docker exec
    pull镜像 crictl pull docker pull
    容器启动/停止 crictl start/stop docker start/stop
    容器资源情况 crictl stats docker stats

    可以看到crictl对容器生命周期的管理基本已经覆盖,不过在crictl我们不能完成操作也比较多,比如对镜像的管理就不属于它的管理范围。这部分还得依靠ctr来实现,操作方式同样可以参照下表

    操作 ctr docker
    查看镜像 ctr images ls docker images
    镜像导入/导出 ctr images import/exporter docker load/save
    镜像拉取/推送 ctr images pull/push docker pull/push
    镜像tag ctr images tag docker tag

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

    ctr -n k8s.io images list
    

    3. 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_FLAGS
        value: --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仍然是最佳的容器运行时管理工具。


    关注公众号「云原生小白」,获取更多精彩内容

    相关文章

      网友评论

          本文标题:辞旧迎新,新手使用Containerd时的几点须知

          本文链接:https://www.haomeiwen.com/subject/ttjioktx.html