While working with Kubernetes locally, you may want to run some locally built Docker images in Kubernetes. This may not work out-of-the-box, because minikube uses its own local Docker registry that’s not connected to the one on your local machine.
在本地使用Kubernetes时,您可能需要在Kubernetes中运行一些本地构建的Docker映像。 这可能无法立即使用,因为minikube使用了自己的本地Docker注册表,该注册表未连接到本地计算机上的Docker注册表。
In this article, I’ll show how easy it is to run locally built images in Kubernetes, without publishing them to a global registry. For this article, I suppose you already have kubectl and minikube installed locally. This article is targeted at the Linux environment.
在本文中,我将展示在Kubernetes中运行本地构建的映像而不将其发布到全局注册表中是多么容易。 对于本文,我想您已经在本地安装了kubectl和minikube。 本文针对Linux环境。
I start with creating the following trivial
Dockerfile
that runs busybox and outputs “Hello World”:
我首先创建以下琐碎的
Dockerfile
,该文件运行busybox并输出“ Hello World”:
FROM busyboxCMD [“echo”, “Hello World!”]
I now build it:
我现在建立它:
> docker build . -t forketyfork/hello-world
I can now run a container from this image and see that it works as expected:
我现在可以从该图像运行一个容器,并看到它按预期工作:
> docker run forketyfork/hello-world
Hello World!
Next, I create the
helloworld.yml
configuration file to run this container as a Kubernetes job:
接下来,我创建
helloworld.yml
配置文件以将该容器作为Kubernetes作业运行:
apiVersion: batch/v1
kind: Job
metadata:
name: hello-world
spec:
template:
metadata:
name: hello-world-pod
spec:
containers:
- name: hello-world
image: forketyfork/hello-world
restartPolicy: Never
Notice that I’ve specified the name of the image I just built and set the
restartPolicy
to
Never
so that it would only run once and terminate.
请注意,我已经指定了刚刚构建的映像的名称,并将
restartPolicy
设置为
Never
以便它只能运行一次并终止。
I now try to create a job out of this configuration file using
kubectl
:
我现在尝试使用
kubectl
在此配置文件
kubectl
创建作业:
> kubectl create -f helloworld.yml
Let’s check if it worked, using the
kubectl get pods
command:
让我们使用
kubectl get pods
命令检查它是否有效:
> kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world-lfrzh 0/1 ErrImagePull 0 6s
It didn’t work, and the pod failed with the
ErrImagePull
status. The reason is Kubernetes tries to pull the image specified in
helloworld.yml
, but this image is neither in the
minikube
docker registry nor in the public Docker registry.
它不起作用,并且吊舱以
ErrImagePull
状态失败。 原因是Kubernetes尝试提取
helloworld.yml
指定的映像,但是该映像既不在
minikube
注册表中,也不在公共Docker注册表中。
I don’t want to pull this image from a public registry since it’s only available locally. I fix this by setting the
imagePullPolicy
for the image to
Never
:
我不想从公共注册表中提取此图像,因为它仅在本地可用。 我通过设置解决这个问题
imagePullPolicy
的图像
Never
:
apiVersion: batch/v1
kind: Job
metadata:
name: hello-world
spec:
template:
metadata:
name: hello-world-pod
spec:
containers:
- name: hello-world
image: forketyfork/hello-world
imagePullPolicy: Never
restartPolicy: Never
Let’s remove the job and create it once again:
让我们删除作业并再次创建它:
> kubectl delete -f helloworld.yml
job.batch "hello-world" deleted> kubectl create -f helloworld.yml
job.batch/hello-world created> kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world-r4g9g 0/1 ErrImageNeverPull 0 6s
I now observe another error —
ErrImageNeverPull
. This means that the minikube node uses its own Docker repository that’s not connected to the Docker registry on the local machine, so without pulling, it doesn’t know where to get the image from.
现在,我观察到另一个错误
ErrImageNeverPull
。 这意味着minikube节点使用其自己的Docker存储库,该存储库未连接到本地计算机上的Docker注册表,因此,如果不进行提取,它将不知道从何处获取映像。
To fix this, I use the
minikube docker-env
command that outputs environment variables needed to point the local Docker daemon to the minikube internal Docker registry:
为了解决这个问题,我使用
minikube docker-env
命令,该命令输出将本地Docker守护程序指向minikube内部Docker注册表所需的环境变量:
> minikube docker-env
export DOCKER_TLS_VERIFY=”1"
export DOCKER_HOST=”tcp://172.17.0.2:2376"
export DOCKER_CERT_PATH=”/home/user/.minikube/certs”
export MINIKUBE_ACTIVE_DOCKERD=”minikube”# To point your shell to minikube’s docker-daemon, run:
# eval $(minikube -p minikube docker-env)
To apply these variables, I use the proposed command:
要应用这些变量,我使用建议的命令:
> eval $(minikube -p minikube docker-env)
I now need to build the image once again, so that it’s installed in the minikube registry, instead of the local one:
现在,我需要再次构建映像,以便将其安装在minikube注册表中,而不是本地映像中:
> docker build . -t forketyfork/hello-world
And recreate the job once again:
并再次重新创建作业:
> kubectl delete -f helloworld.yml
> kubectl create -f helloworld.yml
Now
kubectl get pods
shows that the
hello-world
pod has completed successfully:
现在,
kubectl get pods
显示
hello-world
pod已成功完成:
> kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world-f5hzz 0/1 Completed 0 4s
The logs of the pod show that it did what’s expected:
吊舱的日志显示它完成了预期的工作:
> kubectl logs hello-world-f5hzz
Hello World!
One thing to note is that the command
eval $(minikube -p minikube docker-env)
has to be run in every new terminal window before you build an image. An alternative would be to put it into your
.profile
file.
需要注意的一件事是,在构建映像之前,必须在每个新的终端窗口中运行命令
eval $(minikube -p minikube docker-env)
。 另一种选择是将其放入您的
.profile
文件中。
翻译自: https://medium.com/swlh/how-to-run-locally-built-docker-images-in-kubernetes-b28fbc32cc1d