推送镜像

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

术语表

拉取 (Pull) 指直接从远程注册表下载容器镜像。

推送 (Push) 指直接将容器镜像上传到远程注册表。

加载 (Load) 指将可用作归档文件的镜像加载到集群中使其可用。

保存 (Save) 指将镜像保存为归档文件。

构建 (Build) 指获取一个“构建上下文”(目录)并从中在集群中创建一个新镜像。

标记 (Tag) 指分配名称和标签。

不同方法的比较表

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

方法 支持的运行时 性能 加载 构建
docker-env 命令 docker 和 containerd
cache 命令 所有 中等
podman-env 命令 仅限 cri-o
注册表插件 所有 中等
minikube ssh 所有 最佳 是* 是*
ctr/buildctl 命令 仅限 containerd
image load 命令 所有 中等
image build 命令 所有 中等
  • 注1:minikube上默认的容器运行时是docker
  • 注2:none驱动(裸机)不需要将镜像推送到集群,因为您系统上的任何镜像都已对Kubernetes集群可用。
  • 注3:当使用ssh运行命令时,要加载或构建的文件必须已在节点上可用(而不仅仅是在客户端主机上)。

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

这类似于podman-env,但仅适用于Docker运行时。当使用容器或虚拟机驱动(除了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内部、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. 使用注册表插件推送到集群内

为了说明目的,我们假设minikube虚拟机拥有192.168.39.0/24子网中的一个IP。如果您没有按照网络指南覆盖这些子网,您可以在此处找到minikube针对特定操作系统和驱动组合使用的默认子网,该子网可能会发生变化。在适用的任何地方,请将192.168.39.0/24替换为适用于您环境的相应值。

确保docker已配置为将192.168.39.0/24用作不安全的注册表。请参阅此处获取说明。

确保在minikube中将192.168.39.0/24启用为不安全的注册表。请参阅此处获取说明。

启用minikube注册表插件

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

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

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 .

更多信息请参阅