Kubernetes 弃用 Docker 后如何切换到 Containerd

仙人技术

共 6392字,需浏览 13分钟

 ·

2021-05-28 12:35

Kubernetes 从 v1.20 开始弃用 Docker[1],并推荐用户切换到基于容器运行时接口(CRI)[2]的容器引擎,如 containerd、cri-o 等。如果你使用了云服务商提供的托管 Kubernetes 服务,那你不用担心,像 GKE、AKS 等云服务商都已经在新版集群中把默认的运行时切换到 containerd 。

那对于那些自管的集群,又如何把容器运行时从 Docker 切换到 Containerd 呢?

切换容器运行时的方法

首先,标记节点为维护模式,并驱逐其上正在运行的 Pod,避免切换过程中影响应用的正常运行:

kubectl cordon <node-name>
kubectl drain <node-name> --ignore-daemonsets

然后以 root 用户登录到 Node 上面,停止 docker 和 kubelet,并删除 docker:

systemctl stop kubelet
systemctl stop docker
apt purge docker-ce docker-ce-cli

接下来,生成 containerd 配置文件:

mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml

由于国内环境无法访问 GCR,需要修改默认 pause 镜像为国内可以访问的地址,比如替换为 MCR:

...
[plugins."io.containerd.grpc.v1.cri"]
  sandbox_image = "mcr.microsoft.com/oss/kubernetes/pause:1.3.1"
...

接下来,打开 /etc/default/kubelet,修改 kubelet 启动选项,配置容器运行时为 containerd:

KUBELET_FLAGS=... --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock

修改完成后, 重启 containerd 和 kubelet:

systemctl daemon-reload
systemctl restart containerd
systemctl restart kubelet

最后,退出 Node,使用 kubectl 命令验证节点的容器运行时:

# kubectl get node <node-name> -o wide
NAME          STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
<node-name>   Ready    agent   13d   v1.18.2   10.241.0.21   <none>        Ubuntu 18.04.5 LTS   5.4.0-1039  containerd://1.4.3

可以发现,容器运行时已经切换到了 containerd,其版本为 1.4.3。

最后,把节点重新加回集群中:

kubectl uncordon <node-name>

对其他的节点重复以上步骤,就可以把集群的 docker 替换成 containerd。

镜像构建的方法

除了以上的步骤,切换到 containerd 之后,还需要注意 docker.sock 不再可用,也就意味着不能再在容器里面执行 docker 命令来构建镜像了。这里,我推荐几种不需要 docker.sock 也可以构建镜像的方法。

第一个是 Docker Buildx[3],这也是 Kubernetes 社区用于构建多体系结构镜像的方法。比如,你可以执行下面的命令来构建镜像:

docker buildx create --driver kubernetes --driver-opt replicas=3 --use
docker buildx build -t example.com/foo --push .

第二个是 Redhat 开源的 Buildah[4]。Buildah 是 Openshift 默认的镜像构建工具,同时支持 OCI 和 Docker 镜像格式。Buildah 的使用方法类似于 docker build,如:

# 构建镜像
buildah bud -t example.com/foo:latest .
# 查询镜像列表
buildah images

第三个是 Google 开源的 kaniko[5]。Kaniko 不需要 docker daemon 就可以从 Dockerfile 构建镜像。在使用 Kaniko 时要注意,它在构建镜像时需要把构建上下文(context)传入到 kaniko 命令行中,构建上下文可以放到标准输入中,也可以放到 AWS S3、Azure Blob Storage、GCS Bucket 等云存储中。

如下是一个 Kaniko 的使用示例:

echo -e 'FROM alpine \nRUN echo "created from standard input"' > Dockerfile | tar -cf - Dockerfile | gzip -9 | kubectl run kaniko \
--rm --stdin=true \
--image=gcr.io/kaniko-project/executor:latest --restart=Never \
--overrides='{
  "apiVersion": "v1",
  "spec": {
    "containers": [
      {
        "name": "kaniko",
        "image": "gcr.io/kaniko-project/executor:latest",
        "stdin": true,
        "stdinOnce": true,
        "args": [
          "--dockerfile=Dockerfile",
          "--context=tar://stdin",
          "--destination=gcr.io/my-repo/my-image"
        ],
        "volumeMounts": [
          {
            "name": "cabundle",
            "mountPath": "/kaniko/ssl/certs/"
          },
          {
            "name": "docker-config",
            "mountPath": "/kaniko/.docker/"
          }
        ]
      }
    ],
    "volumes": [
      {
        "name": "cabundle",
        "configMap": {
          "name": "cabundle"
        }
      },
      {
        "name": "docker-config",
        "configMap": {
          "name": "docker-config"
        }
      }
    ]
  }
}'

总结

Docker 弃用后,可以把 Kubernetes 容器运行时切换到社区维护并支持 CRI 的容器引擎,如 containerd、cri-o 等。切换之后,也需要注意,原来使用 docker build 构建镜像的应用需要切换到无需 Dockerd 就可以构建镜像的工具,如 docker buildx、buildah、kaniko 等。

参考资料

[1]

Kubernetes 弃用 Docker: https://kubernetes.io/blog/2020/12/02/dont-panic-kubernetes-and-docker/

[2]

容器运行时接口(CRI): https://kubernetes.io/blog/2016/12/container-runtime-interface-cri-in-kubernetes/

[3]

Docker Buildx: https://docs.docker.com/buildx/working-with-buildx/

[4]

Buildah: https://github.com/containers/buildah

[5]

kaniko: https://github.com/GoogleContainerTools/kaniko


浏览 66
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报