天天看点

如何在kubernetes中运行本地构建的docker映像

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