在 K3s 节点上安装并使用 nerdctl

💡 原文中文,约5000字,阅读约需12分钟。
📝

内容提要

在 K3s 节点安装 nerdctl:下载精简二进制解压至 /usr/local/bin,配置 /etc/nerdctl/nerdctl.toml 指向 K3s 的 containerd socket(/run/k3s/containerd/containerd.sock)和 k8s.io 命名空间,即可查看管理 K3s 容器镜像。若需 nerdctl run 独立容器,须另装 CNI 插件并配置桥接网络;构建镜像需安装 BuildKit。

🔎

延伸解读

为何选择 nerdctl 而非 ctr 或 crictl

K3s 节点上已有 ctr 和 crictl,但 ctr 与 Docker CLI 不兼容且功能有限,crictl 面向 Kubernetes 运维。nerdctl 提供 Docker 兼容的命令行体验,支持 run、build、compose 等操作,更适合日常容器管理。因此,在 K3s 节点上安装 nerdctl 可以弥补现有工具的不足,提升操作效率。

配置关键:指向 K3s 的 containerd socket

K3s 的 containerd socket 位于 /run/k3s/containerd/containerd.sock,而非标准路径。nerdctl 默认连接标准路径,因此必须通过 /etc/nerdctl/nerdctl.toml 配置文件修改 address 和 namespace 为 k8s.io,才能正确管理 K3s 的容器和镜像。这是安装后能否正常使用的关键步骤。

独立容器网络:CNI 插件的按需安装

若仅查看 K3s 已有容器和镜像,无需额外 CNI。但若要用 nerdctl run 启动独立容器,则必须安装 CNI 插件并配置桥接网络(如 10.88.0.0/16)。该网络仅供 nerdctl 管理的独立容器使用,不影响 K3s 自身网络。安装 CNI 后,需注意使用默认命名空间运行独立容器。

构建镜像与本地镜像使用

nerdctl build 需要 BuildKit daemon 支持,需额外安装并配置 systemd 服务,指向 K3s 的 containerd socket。构建时可将镜像打 tag 到 k8s.io 命名空间,并在 Pod spec 中设置 imagePullPolicy: Never,即可直接使用本地镜像,避免从远程仓库拉取,适合离线或开发环境。

❓

Q&A

K3s 节点上如何安装 nerdctl?

下载 nerdctl 精简二进制包,解压到 /usr/local/bin 即可。例如:curl -LO https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz,然后 sudo tar Cxzvf /usr/local/bin nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz nerdctl。

如何配置 nerdctl 以连接 K3s 的 containerd?

创建 /etc/nerdctl/nerdctl.toml 文件,设置 address = "/run/k3s/containerd/containerd.sock" 和 namespace = "k8s.io"。

nerdctl 和 ctr、crictl 有什么区别?

ctr 是 containerd 内置调试工具,与 Docker CLI 不兼容;crictl 是 CRI 调试工具,面向 Kubernetes 运维;nerdctl 是 Docker 兼容 CLI,支持 run/build/compose,推荐日常使用。

在 K3s 节点上使用 nerdctl run 启动独立容器需要什么额外配置?

需要安装 CNI 插件并配置桥接网络。下载 CNI 插件解压到 /opt/cni/bin,并创建 /etc/cni/net.d/10-nerdctl-bridge.conflist 网络配置。

如何使用 nerdctl 构建镜像?

需要安装 BuildKit。下载 BuildKit 并解压到 /usr/local,创建 systemd 服务并启动,然后使用 nerdctl build 命令构建镜像。

如何让 K3s 使用 nerdctl 构建的本地镜像?

使用 nerdctl 在 k8s.io 命名空间构建镜像,例如 sudo nerdctl --namespace k8s.io build -t myapp:local .,然后在 Pod spec 中设置 imagePullPolicy: Never。

🏷️

标签

➡️

继续阅读