如何在Minikube中使用本地Docker镜像?

637

我有几个 Docker 镜像,想要在 minikube 中使用。我不想先上传并下载相同的镜像,而是直接使用本地镜像。如何做到这一点?

我尝试过的方法:
1. 我尝试运行以下命令(分别运行,两次删除 minikube 实例并重新开始)

kubectl run hdfs --image=fluxcapacitor/hdfs:latest --port=8989
kubectl run hdfs --image=fluxcapacitor/hdfs:latest --port=8989 imagePullPolicy=Never

输出:

NAME                    READY     STATUS              RESTARTS   AGE
hdfs-2425930030-q0sdl   0/1       ContainerCreating   0          10m

它只是卡在某个状态上,但从未达到就绪状态。


2. 我尝试创建一个注册表,然后将图像放入其中,但那也没有起作用。 我可能做错了那个步骤,但我找不到正确的说明来完成此任务。

请提供使用本地docker映像的说明以在本地kubernetes实例中使用。
操作系统:ubuntu 16.04
Docker:Docker版本1.13.1,构建编号092cba3
Kubernetes:

Client Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.3", GitCommit:"029c3a408176b55c30846f0faedf56aae5992e9b", GitTreeState:"clean", BuildDate:"2017-02-15T06:40:50Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.2", GitCommit:"08e099554f3c31f6e6f07b448ab3ed78d0520507", GitTreeState:"clean", BuildDate:"1970-01-01T00:00:00Z", GoVersion:"go1.7.1", Compiler:"gc", Platform:"linux/amd64"}

如果有人能帮我使用docker-compose解决这个问题,那就太棒了。

编辑:

eval $(minikube docker-env)中加载的镜像:

REPOSITORY                                            TAG                 IMAGE ID            CREATED             SIZE
fluxcapacitor/jupyterhub                              latest              e5175fb26522        4 weeks ago         9.59 GB
fluxcapacitor/zeppelin                                latest              fe4bc823e57d        4 weeks ago         4.12 GB
fluxcapacitor/prediction-pmml                         latest              cae5b2d9835b        4 weeks ago         973 MB
fluxcapacitor/scheduler-airflow                       latest              95adfd56f656        4 weeks ago         8.89 GB
fluxcapacitor/loadtest                                latest              6a777ab6167c        5 weeks ago         899 MB
fluxcapacitor/hdfs                                    latest              00fa0ed0064b        6 weeks ago         1.16 GB
fluxcapacitor/sql-mysql                               latest              804137671a8c        7 weeks ago         679 MB
fluxcapacitor/metastore-1.2.1                         latest              ea7ce8c5048f        7 weeks ago         1.35 GB
fluxcapacitor/cassandra                               latest              3cb5ff117283        7 weeks ago         953 MB
fluxcapacitor/apachespark-worker-2.0.1                latest              14ee3e4e337c        7 weeks ago         3.74 GB
fluxcapacitor/apachespark-master-2.0.1                latest              fe60b42d54e5        7 weeks ago         3.72 GB
fluxcapacitor/package-java-openjdk-1.8                latest              1db08965289d        7 weeks ago         841 MB
gcr.io/google_containers/kubernetes-dashboard-amd64   v1.5.1              1180413103fd        7 weeks ago         104 MB
fluxcapacitor/stream-kafka-0.10                       latest              f67750239f4d        2 months ago        1.14 GB
fluxcapacitor/pipeline                                latest              f6afd6c5745b        2 months ago        11.2 GB
gcr.io/google-containers/kube-addon-manager           v6.1                59e1315aa5ff        3 months ago        59.4 MB
gcr.io/google_containers/kubedns-amd64                1.9                 26cf1ed9b144        3 months ago        47 MB
gcr.io/google_containers/kube-dnsmasq-amd64           1.4                 3ec65756a89b        5 months ago        5.13 MB
gcr.io/google_containers/exechealthz-amd64            1.2                 93a43bfb39bf        5 months ago        8.37 MB
gcr.io/google_containers/pause-amd64           

为什么最后一行的最后四列没有数值? - undefined
好的,OP已经离开了这个地方:"上次出现是在6年前"。 - undefined
33个回答

764
根据手册的描述,您可以使用eval $(minikube docker-env)从Minikube中重用Docker守护程序。
因此,要使用图像而无需上传它,您可以按照以下步骤进行操作:
  1. 使用eval $(minikube docker-env)设置环境变量
  2. 使用Minikube的Docker守护程序构建图像(例如,docker build -t my-image .
  3. 将图像设置为Pod规范中的构建标签(例如,my-image
  4. imagePullPolicy设置为Never,否则Kubernetes将尝试下载图像。
重要提示:您必须在每个要使用的终端上运行eval $(minikube docker-env),因为它只为当前的shell会话设置环境变量。

11
在关闭当前终端之前,非常重要的一点是记得运行eval $(minikube docker-env),然后再尝试重新构建镜像...之前我花费了6个小时与一个无法在minikube中更新的镜像作斗争...看起来像是某个包没有更新...但实际上只是minikube所引用的镜像没有更新。 - Mike
73
如果您想要从minikube中返回或退出环境,请执行以下命令:eval $(minikube docker-env -u) - Budi Mulyo
8
如何使用kubectl将“imagePullPolicy”设置为“Never”? - laxman
40
现在,您还可以使用“minikube cache add imagename:tag”将映像推送到minikube中,确保同时包括标签。文档 - miha
34
“minikube cache” 将在未来版本中被弃用,请切换到 “minikube image load” - 我刚从终端获取了这个信息。 - Mattia Paterna
显示剩余11条评论

303
根据svenwltr的解决方案,对我有效的方法是:
# Start minikube
minikube start

# Set docker env
eval $(minikube docker-env)             # Unix shells
minikube docker-env | Invoke-Expression # PowerShell

# Build image
docker build -t foo:0.0.1 .

# Run in Minikube
kubectl run hello-foo --image=foo:0.0.1 --image-pull-policy=Never

# Check that it's running
kubectl get pods

9
您可以在此处找到关于imagePullPolicy的命令行的yml版本:https://kubernetes.io/docs/concepts/containers/images/ - granadaCoder
2
在Windows上,eval $(minikube docker-env) 对我来说不起作用。 在PowerShell中,minikube docker-env | Invoke-Expression 似乎可以工作。在其他终端中,需要读取 minikube docker-env 返回的最后一行。例如,在 IntelliJ(在 Windows 上)中,它是 @FOR /f "tokens=*" %i IN ('minikube -p minikube docker-env') DO @%i。在构建 Docker 镜像之前,您必须始终在任何新的终端/会话中执行此操作。 - chriscross
在执行 eval $(minikube docker-env) 时,我遇到了以下错误:“'none' driver does not support 'minikube docker-env' command”似乎这个问题也被记录在了 Github 上:https://github.com/kubernetes/minikube/issues/2443 - Anonymous Creator

273

有一个简单而有效的方法,可以直接将您的本地Docker镜像推送到minikube,这将节省在minikube中重新构建图像的时间。

minikube image load <image name>

(minikube cache add <image name> - 旧的废弃方法,仅供参考)

更多细节请参见此处

有关将映像推送到minikube的所有可能方法均在此处提及:https://minikube.sigs.k8s.io/docs/handbook/pushing/


33
这个答案应该排名更高,它是更为最新的解决方案。 - keser
2
我想知道为什么它这么慢。有时会被取消。可能是内存不够。 - Gherman
答案部分顶部有排序选项卡,您可能选择了一个不熟悉的选项卡,最好选择的是“趋势”。 - Krushna
有没有一种方法可以强制 pod 在我重复上传新镜像到 minikube 时选择新镜像?每次我使用相同的名称/标签上传新的镜像版本时,pod 都会继续使用旧镜像,直到我在 minikube 中显式删除该镜像并重新加载它。 - abcdn
2
对于任何阅读此答案的人:如果没有 imagePullPolicy: Never,它将无法正常工作。如果您查看日志,您会发现即使已知该镜像(minikube image ls),minikube 仍然尝试拉取该镜像。 - GrumpyRodriguez

169

注意:

  • 这个答案并不限于minikube!

  • 如果想在minikube的Docker上创建注册表,则先运行eval $(minikube docker-env)(使docker在主机终端中可用)
    否则,请通过minikube ssh进入虚拟机,然后按照以下步骤进行操作

  • 根据您的操作系统,minikube将自动将homepath挂载到VM上。

  • 如Eli所述,您需要将本地注册表添加为不安全以使用http(如果使用本地主机名则可能不适用,但如果使用本地主机,则会适用)
    在生产环境中不要使用http,要努力保护安全。


使用本地注册表:

docker run -d -p 5000:5000 --restart=always --name local-registry registry:2

现在请正确地标记您的图像:

docker tag ubuntu localhost:5000/ubuntu

请注意,localhost应更改为运行注册表容器的机器的DNS名称。

现在将您的镜像推送到本地注册表:

docker push localhost:5000/ubuntu

你应该能够将其拉回来:

docker pull localhost:5000/ubuntu

现在将你的yaml文件更改为使用本地注册表。

考虑在适当的位置挂载卷,以使镜像在注册表上持久化。


4
请将您的yaml文件更改为使用本地注册表。你能稍微解释一下吗?我已经推送到了本地注册表(很酷的技巧),但是我仍然无法让minikube连接它,问题依旧。 - Zach Estela
3
请将yaml文件中的镜像名称更改为<registryIP>:5000/ubuntu,@ZachEstela。 - Farhad Farahi
1
@FarhadFarahi 如果我把我的笔记本电脑交给你,你会如何找到它?我只是想知道。我按照Docker教程的步骤来运行Windows版Docker。 - Daan
2
@FarhadFarahi:请在您的答案中添加,您需要将本地注册表添加为不安全,以便使用http: https://docs.docker.com/registry/insecure/(如果使用localhost则可能不适用,但如果使用本地主机名则适用)。 - Eli Algranti
1
根据我的minikube仪表板,无法拉取图像“localhost:5000/src_interface:latest”,这似乎不起作用。kubectl如何访问端口5000? - Shardj
显示剩余5条评论

26

根据Farhad的回答这个回答的补充,以下是设置本地注册表的步骤。

在本地机器上进行设置

在本地机器上设置主机名:编辑/etc/hosts文件,添加以下行:

docker.local 127.0.0.1

现在开始一个本地注册表(删除-d以运行非守护程序模式):
docker run -d -p 5000:5000 --restart=always --name registry registry:2

现在请正确标记您的图片:
docker tag ubuntu docker.local:5000/ubuntu

现在将您的镜像推送到本地仓库:
docker push docker.local:5000/ubuntu

验证图像是否已推送:
curl -X GET http://docker.local:5000/v2/ubuntu/tags/list

在Minikube上进行设置
使用以下命令在Minikube上进行SSH连接:minikube ssh
编辑/etc/hosts文件,添加以下内容:
docker.local <your host machine's IP address>

验证访问权限:
curl -X GET http://docker.local:5000/v2/ubuntu/tags/list

现在如果你试图拉取,可能会遇到一个http访问错误。
启用不安全访问:
如果你计划始终使用Minikube与本地设置一起使用,那么创建一个Minikube实例以默认使用不安全的注册表(在现有集群上不起作用)。
minikube start --insecure-registry="docker.local:5000"

如果不是这样,请按照以下步骤操作:
systemctl stop docker

编辑Docker服务文件:从systemctl status docker获取路径。
可能是:

/etc/systemd/system/docker.service.d/10-machine.conf 或 /usr/lib/systemd/system/docker.service

追加此文本(将192.168.1.4替换为您的IP地址)
--insecure-registry docker.local:5000 --insecure-registry 192.168.1.4:5000

到这一行
ExecStart=/usr/bin/docker daemon -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --tlsverify --tlscacert /etc/docker/ca.pem --tlscert /etc/docker/server.pem --tlskey /etc/docker/server-key.pem --label provider=virtualbox --insecure-registry 10.0.0.0/24

而且:

systemctl daemon-reload
systemctl start docker

尝试拉一下:
docker pull docker.local:5000/ubuntu

现在将您的YAML文件更改为使用本地注册表。
containers:
  - name: ampl-django
       image: dockerhub/ubuntu

containers:
  - name: ampl-django
    image: docker.local:5000/nymbleup

不要在生产环境中使用http。努力确保安全。

什么是“Docker服务文件”?它是“Docker服务文件”吗?还是其他什么东西? - undefined

17

较新版本的minikube允许您通过运行以下命令从本地docker实例加载镜像:

 minikube image rm image <imagename>:<version>  
 minikube image load <imagename>:<version> --daemon

加载命令可能会显示错误,但图像仍会加载到您的minikube实例中。


这似乎是一个很好的答案...你有任何来源吗? - Dan Ortega
2
刚在这里找到参考资料:https://minikube.sigs.k8s.io/docs/handbook/pushing/#7-loading-directly-to-in-cluster-container-runtime ... 实际上并不需要使用 --daemon 选项。 - Dan Ortega
需要多久时间?已经运行了20分钟,用于645MB的图像。 - Nilesh

15

关于'minikube'需要记住的一件事情是,minikube的主机不同于您的本地主机,因此,我意识到为了在minikube中使用本地镜像进行测试,您必须先在本地构建您的Docker镜像或从本地拉取它,然后使用下面的命令将其添加到minikube上下文中,而这个上下文实际上就是另一个Linux实例。

 minikube cache add <image>:<tag>

然而,在您的Kubernetes部署YAML中不要忘记设置imagePullPolicy:Never,这将确保使用本地添加的映像而不是尝试从注册表远程拉取它。

更新minikube cache会在即将推出的版本中被弃用,请切换至minikube image load


7
尽管这段代码可能回答了问题,但是提供关于为什么和/或如何回答问题的额外背景信息可以提高其长期价值。 - n1colas.m

13

一种方法是本地构建图像,然后执行以下操作:

docker save imageNameGoesHere | pv | (eval $(minikube docker-env) && docker load)

minikube docker-env 可能在不同的用户/ sudo下运行时不能返回正确的信息。相反,您可以运行 sudo -u yourUsername minikube docker-env

它应该返回类似以下内容:

export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/home/chris/.minikube/certs"
export DOCKER_API_VERSION="1.23"
# Run this command to configure your shell:
# eval $(minikube docker-env)

正确的命令是 docker save imageNameGoesHere > pv | (eval $(minikube docker-env) && docker load) - salvador
2
docker save imageNameGoesHere | (eval $(minikube docker-env) && docker load) 对我有效。 - lhaferkamp

12
除了接受的答案之外,你还可以使用以下命令实现你最初想要的目标(使用run命令创建一个部署):
kubectl run hdfs --image=fluxcapacitor/hdfs:latest --port=8989 --generator=run-pod/v1

我在Kubernetes-dev论坛上找到了关于生成器的信息:
如果你使用kubectl run命令,它会为你生成一个清单,默认情况下将imagePullPolicy设置为Always。你可以使用以下命令来获取imagePullPolicy为IfNotPresent的清单,这对于minikube是有效的:
kubectl run --image= --generator=run-pod/v1
Dan Lorenc

https://groups.google.com/forum/#!topic/kubernetes-dev/YfvWuFr_XOM


10
如果有人在设置Minikube环境后想要回到本地环境,请使用以下命令。
eval $(docker-machine env -u)

已经发布为 https://dev59.com/IFgQ5IYBdhLWcg3wkEzm#JbejEYcBWogLw_1bgDSd 的内容。 - Kalle Richter
4
请执行以下命令以为minikube取消docker环境变量设置:eval $(minikube docker-env -u) - miracle_the_V

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接