一.前置概念
Docker 与 Kubernetes 共用同一个 containerd 进程 时,只要满足以下 3 个条件,就不会冲突:
检查点 | 要求 | 原因 |
---|---|---|
cgroup-driver | kubelet 与 containerd 必须同为 systemd |
二者不一致会导致 Pod 无法调度 |
Unix socket | kubelet 指向 /run/containerd/containerd.sock ;Docker 也复用该 socket |
不抢占,不重复启动 containerd |
端口/目录 | 无重叠 |
特性 | cri-dockerd |
containerd (内置 CRI) |
---|---|---|
本质 | 一个适配器或垫片 | 一个完整的容器运行时,原生实现了 CRI 接口 |
目的 | 为了在 dockershim 被移除后,让用户还能继续使用 Docker Engine作为 Kubernetes 的底层运行时。 |
作为 Kubernetes 默认的、推荐的容器运行时。 |
架构 | 多一层翻译,复杂度更高。kubelet -> cri-dockerd -> dockerd -> containerd -> runc |
架构更简洁。kubelet -> containerd (CRI) -> runc |
推荐度 | 不推荐。仅作为旧集群迁移的临时过渡方案。 | 强烈推荐。是所有新集群的标准选择。 |
未来 | 是旧技术的延伸,会逐步淘汰。 | 是现在和未来的标准。 |
你有两种主要的实现路径,其核心区别如下表所示:
特性 | 方案 A:安装 Docker 作为独立工具(推荐) | 方案 B:使用 cri-dockerd 让 K8s 接管 Docker |
---|---|---|
本质 | Docker 作为独立的工具,用于构建镜像、运行容器等 | 让 Kubernetes 使用 Docker 作为其底层容器运行时 |
K8s 运行时 | 保持不变,仍是 containerd | 需要变更,从 containerd 改为 Docker (通过 cri-dockerd) |
管理方式 | 容器和镜像由 Docker 和 containerd 分别管理 | 容器和镜像由 Kubernetes 通过 Docker 统一管理 |
复杂度 | 低,简单安装配置即可 | 高,需安装配置 cri-dockerd 并调整 K8s 组件配置 |
稳定性风险 | 低,不影响现有 K8s 集群 | 中,更改运行时可能引入风险 |
适用场景 | 需使用 Docker 命令构建镜像、测试容器 | 确实需要让 K8s 使用 Docker 来创建和管理容 |
二.安装docker
1.解决containerd冲突,安装docker
**注意:安装的docker版本需要支持k8s里面的containerd版本,docker不额外安装containerd,使用同一个containerd
# 确保已安装 yum-utils,它提供了 yumdownloader 命令
sudo yum install yum-utils -y
# 添加仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yumdownloader --resolve --destdir=/tmp docker-ce-24.0.* docker-ce-cli-24.0.* docker-compose-plugin
命令说明:
--resolve:自动解析并下载所有依赖的包。这个参数非常重要,否则你只下载指定的包,安装时会因为缺少依赖而失败47。
--destdir=/tmp:指定将下载的 RPM 包存放于 /tmp 目录。你可以根据需要修改为其他路径。
2.手动强制安装(忽略依赖)
cd /tmp
sudo rpm -Uvh --nodeps docker-ce-24.0.* docker-ce-cli-24.0.*
3.配置
mkdir -p /etc/docker
vim /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"storage-driver": "overlay2"
}
// 强制 cgroup 驱动为 systemd,与 kubelet 保持一致
// 使用性能较好的overlay2存储驱动
4.启动
# 启动并设为开机自启
systemctl daemon-reload
systemctl enable --now docker
docker version
5.安装docker-compose
sudo rpm -ivh docker-compose-plugin*
-i install(安装)
-v verbose(显示详细过程)
-h hash(进度条)
6.使用的命令查看的容器服务不同,原因containerd的名称空间隔离
(1)虽然物理上是同一个 containerd 进程,Docker 与 Kubernetes 各自把容器放在 不同的 containerd 命名空间:
Docker 默认使用
moby
Kubernetes CRI 使用
k8s.io
工具 | 命名空间 | 能看到谁的容器 |
---|---|---|
docker ps / docker images |
moby |
仅 Docker 手动启动的容器 |
crictl ps / crictl images |
k8s.io |
仅 Kubernetes Pod 容器 |
nerdctl -n k8s.io ps |
k8s.io |
Pod 容器 |
# 看看 containerd 里有哪些命名空间
sudo ctr ns ls
(2)把 Docker 镜像搬到 k8s.io
# 把本地 Docker 镜像导出
docker save nginx:latest | sudo ctr -n k8s.io images import -
(3)containerd操作命令
7.使用自己的harbor
(1)containerd默认拉取镜像的地址配置
# 如果没有这个文件
[root@master ~]# containerd config default >/etc/containerd/config.toml
[root@master ~]# vim /etc/containerd/config.toml
sandbox_image = "harbor:443/k8s/pause:3.9"
#这行配置指定了 containerd 用于创建 Pod 沙箱(sandbox)的镜像。在 Kubernetes 中,每个 Pod 都需要一个基础的沙箱镜像来启动,这个镜像通常是一个轻量级的、只包含基本功能的镜像,用于作为容器运行的基础环境。pause 镜像就是这样一个镜像,它通常用于在 Pod 内部创建一个容器,作为该 Pod 所有其他容器的“父容器”
这意味着 containerd 将从你的 Harbor 仓库中拉取这个特定的 pause 镜像版本。
SystemdCgroup = true
# 配置镜像仓库
末尾插入:
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://192.168.88.240:443"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor:443"]
endpoint = ["https://192.168.88.240:443"]
[plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.88.240:443".tls]
insecure_skip_verify = true
#这部分配置允许 containerd 在与 192.168.88.240:443 通信时跳过 TLS 证书验证。
[root@master ~]# systemctl enable --now kubelet containerd
docker pull <Harbor地址>/<项目名>/<镜像名>:<标签>
8.nerdctl命令使用和安装
(1)下载地址
curl -L https://github.com/containerd/nerdctl/releases/download/v1.7.7/nerdctl-full-1.7.7-linux-amd64.tar.gz -o nerdctl-full.tar.gz
(2)将下载的文件解压到 /usr/local
目录
sudo tar Cxzvf /usr/local nerdctl-full.tar.gz
nerdctl --version
(3)命令使用
(2)nerdctl
- 开发者之友
场景: 你需要在装了 Containerd 的机器上像用 Docker 一样构建、拉取、运行镜像。
重要提示:
(1)要操作 K8s 的镜像(在 k8s.io
命名空间),必须加 -n
参数:
(2)拉取镜像必须写完整镜像仓库地址
命 令 |
描述 | 示例 |
---|---|---|
run |
运行一个容器 (最常用) | sudo nerdctl run -d --name nginx -p 80:80 nginx:alpine |
ps |
查看容器列表 | sudo nerdctl ps -a |
images |
查看镜像列表 | sudo nerdctl images |
pull |
拉取镜像 | sudo nerdctl pull nginx:alpine |
exec |
进入容器 | sudo nerdctl exec -it nginx sh |
build |
构建镜像 (需要 BuildKit) | sudo nerdctl build -t my-app:1.0 . |
network |
管理网络 | sudo nerdctl network ls |
compose |
运行 Docker Compose | sudo nerdctl compose up -d |
名称空间 | nerdctl namespace ls |
(3)配置harbor仓库跳过证书认证
# 1. 创建证书配置目录(目录名必须与镜像仓库地址完全一致)
sudo mkdir -p /etc/containerd/certs.d/harbor:443
# 2. 创建 hosts.toml 配置文件
sudo tee /etc/containerd/certs.d/harbor:443/hosts.toml > /dev/null <<EOF
server = "https://harbor:443"
[host."https://harbor:443"]
capabilities = ["pull", "push", "resolve"]
skip_verify = true
EOF
# 3. 重启 containerd
sudo systemctl restart containerd