推送镜像

比较将镜像推送到 minikube 集群的 8 种方法。

词汇表

Pull 意味着直接从远程注册表下载容器镜像。

Push 意味着直接上传容器镜像到远程注册表。

Load 将可用作归档的镜像加载到集群中。

Save 将镜像保存为归档。

Build 采用“构建上下文”(目录)并从中创建新镜像。

Tag 意味着分配一个名称和标签。

不同方法的比较表

将镜像推送到 minikube 的最佳方法取决于您构建集群时使用的容器运行时(默认是 docker)。以下比较表可以帮助您选择。

方法 支持的运行时 性能 Load Build
docker-env 命令 docker & containerd
cache 命令 全部 一般
podman-env 命令 仅限 cri-o
registry 插件 全部 一般
minikube ssh 全部 最佳 是* 是*
ctr/buildctl 命令 仅限 containerd
image load 命令 全部 一般
image build 命令 全部 一般
  • 注 1:minikube 上的默认容器运行时是 docker
  • 注 2:none 驱动程序(裸金属)不需要将镜像推送到集群,因为系统上的任何镜像都已可供 Kubernetes 集群使用。
  • 注 3:在使用 ssh 运行命令时,要加载或构建的文件必须已存在于节点上(而不仅仅是客户端主机上)。

1. 直接推送到集群内的 Docker 守护进程 (docker-env)

这类似于 podman-env,但仅适用于 Docker 运行时。当使用容器或 VM 驱动程序(除 none 之外的所有驱动程序)时,您可以重用 minikube 集群内的 Docker 守护进程。这意味着您不必在主机上构建镜像并将其推送到 Docker 注册表。您只需在与 minikube 相同的 Docker 守护进程内构建,这可以加快本地实验的速度。

要将您的终端指向使用 minikube 集群内的 Docker 守护进程,请运行此命令

eval $(minikube docker-env)
eval $(minikube docker-env)

PowerShell

& minikube -p minikube docker-env --shell powershell | Invoke-Expression

cmd

@FOR /f "tokens=*" %i IN ('minikube -p minikube docker-env --shell cmd') DO @%i

现在,您在此当前终端中运行的任何 ‘docker’ 命令都将针对 minikube 集群内的 Docker 运行。

因此,如果您执行以下命令,它将显示 minikube VM 或容器内部的 minikube 中的容器。

docker ps

现在您可以在 minikube 内的 Docker 上进行‘构建’,Kubernetes 集群可以立即访问它。

docker build -t my_image .

要验证您的终端是否正在使用 minikube 的 docker-env,您可以检查环境变量 MINIKUBE_ACTIVE_DOCKERD 的值是否反映了集群名称。

提示 1:请记住在您的 yaml 文件中关闭 imagePullPolicy:Always(使用 imagePullPolicy:IfNotPresentimagePullPolicy:Never)。否则 Kubernetes 将不会使用您本地构建的镜像,而是会从网络拉取。

提示 2:评估 docker-env 仅对当前终端有效。关闭终端后,您将恢复使用您自己系统的 Docker 守护进程。

提示 3:在基于容器的驱动程序(如 Docker 或 Podman)中,您每次重启 minikube 集群时都需要重新执行 docker-env。

有关 docker-env 的更多信息


2. 使用 ‘cache’ 命令推送镜像。

从您的主机,您可以直接将 Docker 镜像推送到 minikube。该镜像将被缓存并自动拉取到该机器上创建的所有未来 minikube 集群中。

minikube cache add alpine:latest

add 命令会将请求的镜像存储到 $MINIKUBE_HOME/cache/images,并自动将其加载到 minikube 集群的容器运行时环境中。

提示 1:如果您的镜像在缓存后发生更改,您需要执行‘cache reload’。

minikube 在每次启动时都会刷新缓存镜像。但是,要按需重新加载所有缓存的镜像,请运行此命令

minikube cache reload

提示 2:如果您有多个集群,cache 命令会将镜像加载到所有集群中。

要显示已添加到缓存的镜像

minikube cache list

此列表不包括 minikube 内置的系统镜像。

minikube cache delete <image name>

有关更多信息,请参阅


3. 直接推送到集群内的 CRI-O。 (podman-env)

这类似于 docker-env,但仅适用于 CRI-O 运行时。要直接推送到 CRI-O,请在您的 shell 中使用 podman-env 命令配置主机上的 podman 客户端。

eval $(minikube podman-env)

您现在应该能够从主机上的命令行使用 podman 客户端,它将与 minikube 虚拟机内的 podman 服务进行通信。

podman-remote help

现在您可以在 minikube 内的存储上进行‘构建’,Kubernetes 集群可以立即访问它。

podman-remote build -t my_image .

注意:在 Linux 上,远程客户端称为“podman-remote”,而本地程序称为“podman”。

这类似于 docker-env,但仅适用于 CRI-O 运行时。要直接推送到 CRI-O,请在您的 shell 中使用 podman-env 命令配置主机上的 Podman 客户端。

eval $(minikube podman-env)

您现在应该能够从主机上的命令行使用 Podman 客户端,它将与 minikube 虚拟机内的 Podman 服务进行通信。

podman help

现在您可以在 minikube 内的存储上进行‘构建’,Kubernetes 集群可以立即访问它。

podman build -t my_image .

注意:在 macOS 上,远程客户端称为“podman”,因为没有本地“podman”程序可用。

这类似于 docker-env,但仅适用于 CRI-O 运行时。要直接推送到 CRI-O,请在您的 shell 中使用 podman-env 命令配置主机上的 Podman 客户端。

PowerShell

& minikube -p minikube podman-env --shell powershell | Invoke-Expression

cmd

@FOR /f "tokens=*" %i IN ('minikube -p minikube podman-env --shell cmd') DO @%i

您现在应该能够从主机上的命令行使用 Podman 客户端,它将与 minikube 虚拟机内的 Podman 服务进行通信。

现在您可以在 minikube 内的存储上进行‘构建’,Kubernetes 集群可以立即访问它。

podman help
podman build -t my_image .

注意:在 Windows 上,远程客户端称为“podman”,因为没有本地“podman”程序可用。

请记住关闭 imagePullPolicy:Always(使用 imagePullPolicy:IfNotPresentimagePullPolicy:Never),否则 Kubernetes 将不会使用您本地构建的镜像。


4. 使用 Registry 插件推送到集群内

为了说明目的,我们将假设 minikube VM 具有 192.168.39.0/24 子网中的一个 IP。如果您尚未根据 网络指南 覆盖这些子网,您可以在 这里 找到特定操作系统和驱动程序组合使用的默认子网,但这可能会发生变化。在适用的情况下,请将 192.168.39.0/24 替换为适合您环境的值。

确保 Docker 已配置为使用 192.168.39.0/24 作为不安全注册表。有关说明,请参阅 此处

确保 192.168.39.0/24 在 minikube 中被启用为不安全注册表。有关说明,请参阅 此处

启用 minikube registry 插件

minikube addons enable registry

构建 Docker 镜像并适当地标记它

docker build --tag $(minikube ip):5000/test-img .

将 Docker 镜像推送到 minikube 注册表

docker push $(minikube ip):5000/test-img

5. 使用 SSH 在 minikube 内部构建镜像

使用 minikube ssh 在 minikube 节点内运行命令,并在那里直接运行构建命令。您在那里运行的任何命令都将针对 Kubernetes 集群正在使用的相同守护进程/存储运行。

对于 Docker,请使用

docker build

有关 docker build 命令的更多信息,请阅读 Docker 文档 (docker.com)。

对于 CRI-O,请使用

sudo podman build

有关 podman build 命令的更多信息,请阅读 Podman 文档 (podman.io)。

对于 Containerd,请使用

sudo ctr images import
sudo buildctl build

有关 ctr images 命令的更多信息,请阅读 containerd 文档 (containerd.io)

有关 buildctl build 命令的更多信息,请阅读 Buildkit 文档 (mobyproject.org)。

要退出 minikube ssh 并返回到您的终端,请输入

exit

6. 直接推送到集群内的 containerd (buildkitd)

这类似于 docker-env 和 podman-env,但仅适用于 Containerd 运行时。

目前需要手动启动守护进程并设置隧道。

ctr 指令

要访问 containerd,您需要以 root 用户登录。这需要将 ssh 密钥添加到 /root/authorized_keys

docker@minikube:~$ sudo mkdir /root/.ssh
docker@minikube:~$ sudo chmod 700 /root/.ssh
docker@minikube:~$ sudo cp .ssh/authorized_keys /root/.ssh/authorized_keys
docker@minikube:~$ sudo chmod 600 /root/.ssh

请注意 ssh 命令所需的标志。

minikube --alsologtostderr ssh --native-ssh=false

将 containerd 套接字从机器隧道连接到主机。(*使用上面的 ssh 标志(最重要的是 -p 端口和 root@host)*)

ssh -nNT -L ./containerd.sock:/run/containerd/containerd.sock ... &

现在您可以运行命令来连接此 unix 套接字,该套接字通过 ssh 隧道连接。

ctr --address ./containerd.sock help

“k8s.io”命名空间中的镜像可供 Kubernetes 集群访问。

buildctl 指令

启动 BuildKit 守护进程,使用 containerd 后端。

docker@minikube:~$ sudo -b buildkitd --oci-worker=false --containerd-worker=true --containerd-worker-namespace=k8s.io

使 BuildKit 套接字对普通用户可用。

docker@minikube:~$ sudo groupadd buildkit
docker@minikube:~$ sudo chgrp -R buildkit /run/buildkit
docker@minikube:~$ sudo usermod -aG buildkit $USER
docker@minikube:~$ exit

请注意 ssh 命令所需的标志。

minikube --alsologtostderr ssh --native-ssh=false

将 BuildKit 套接字从机器隧道连接到主机。(*使用上面的 ssh 标志(最重要的是 -p 端口和 user@host)*)

ssh -nNT -L ./buildkitd.sock:/run/buildkit/buildkitd.sock ... &

之后,应该可以使用 buildctl 了。

buildctl --addr unix://buildkitd.sock build \
    --frontend=dockerfile.v0 \
    --local context=. \
    --local dockerfile=. \
    --output type=image,name=registry.k8s.io/username/imagename:latest

现在您可以在 minikube 内的存储上进行‘构建’。Kubernetes 集群可以立即访问它。


7. 直接加载到集群内的容器运行时

minikube 客户端将直接与集群中的容器运行时通信,并在那里运行加载命令——针对相同的存储。

minikube image load my_image

有关更多信息,请参阅


8. 构建镜像到集群内的容器运行时

minikube 客户端将直接与集群中的容器运行时通信,并在那里运行构建命令——针对相同的存储。

minikube image build -t my_image .

有关更多信息,请参阅