Docker for Mac - Kubernetes - 引用本地镜像

55

我正在使用支持Kubernetes的Docker for Mac,并且我很难创建引用本地构建镜像的Kubernetes部署。

docker images的输出:

REPOSITORY  TAG     IMAGE 
test        latest  2c3bdb36a5ed

我的deployment.yaml文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld-deployment
spec:
  selector:
    matchLabels:
      app: helloworld
  replicas: 1
  template:
    metadata:
      labels:
        app: helloworld
    spec:
      containers:
      - name: aaa
        image: test:latest
        ports:
        - containerPort: 8080

当我运行kubectl apply -f deplyment.yaml命令时,将创建Pods,但是:

Translated:

运行kubectl apply -f deplyment.yaml命令后,会创建Pods,但存在问题:

helloworld-deployment-764b8b85d8-2c4kl   0/1       ImagePullBackOff   0          
helloworld-deployment-764b8b85d8-rzq7l   0/1       ImagePullBackOff   0

kubectl describe 命令应用于其中一个 pod,返回如下结果:

  Normal   Scheduled              20s               default-scheduler            Successfully assigned helloworld-deployment-79f66d97c6-7tj2x to docker-for-desktop
  Normal   SuccessfulMountVolume  19s               kubelet, docker-for-desktop  MountVolume.SetUp succeeded for volume "default-token-72f44"
  Normal   BackOff                16s               kubelet, docker-for-desktop  Back-off pulling image "test:latest"
  Warning  Failed                 16s               kubelet, docker-for-desktop  Error: ImagePullBackOff
  Normal   Pulling                4s (x2 over 19s)  kubelet, docker-for-desktop  pulling image "test:latest"
  Warning  Failed                 2s (x2 over 17s)  kubelet, docker-for-desktop  Failed to pull image "test:latest": rpc error: code = Unknown desc = Error response from daemon: pull access denied for test, repository does not exist or may require 'docker login'
  Warning  Failed                 2s (x2 over 17s)  kubelet, docker-for-desktop  Error: ErrImagePull
有趣的是,如果我尝试运行托管在DockerHub上的一些图像,那么一切都很好。 我还尝试使用skaffold,它也非常好用...
我看到一些关于minikube的类似问题,解决方案是使用minikube docker守护程序构建映像,以便可以从Kubernetes集群引用它们。
我希望避免设置本地仓库,那么如何让它与Docker的Kubernetes配合工作?

可能这个可以帮助:https://blog.hasura.io/sharing-a-local-registry-for-minikube-37c7240d0615 - Vishal Biyani
1
@VishalBiyani 谢谢,但我想避免设置 localhost:5000 仓库 - 它可以工作,但每次创建新版本的应用程序时都需要推送到它。Skaffold似乎为此问题找到了一些解决方案... - user62058
3
请尽可能使用图像的标记版本,而不是最新版本。 - Prateek Jain
@techtrainer,你似乎是对的。只要我提供一个有效的标记版本,一切都能正常工作。你知道为什么吗?我只是想在本地开发中使用Docker Edge Kubernetes,并认为使用“latest”是个好主意。 - user62058
4
原因很简单,没有人知道最新版本是什么。所以,Docker必须上线并检查最新版本的价值。一旦您打上标签,它就可以看到本地存在已带标签的镜像版本,并在网上进行检查。 - Prateek Jain
3个回答

111

不知道为什么 "imagePullPolicy: Never" 起作用了,但它确实起作用了。 - Ravindranath Akila
10
根据https://kubernetes.io/docs/concepts/containers/images/#updating-images所述,使用“latest”标签将始终强制进行拉取,就好像设置了imagePullPolicy: always一样,而默认值为IfNotPresent。设置imagePullPolicy: IfNotPresent也可以正常工作。 - Qiulang
1
命令行等效命令:kubectl run local-image-test --image=local-image --image-pull-policy=Never - Daniel
我不是专家,但我认为这个方法可行,因为如果没有这个设置,它首先尝试从公共注册表中拉取图像。显然找不到,因为它只在本地构建。所以基本上,通过告诉它永远不要去寻找新的镜像来拉取,它将被迫使用本地已有的内容。Qiulang 是对的,imagePullPolicy: IfNotPresent是一个更精确的选项,也可以工作。顺便说一句:我遇到了同样的问题,我使用的是带版本标记的标签,而不是最新的标签。 - alewitt

15

在IT技术中,使用标签版本的镜像比latest更好。如果您将Docker镜像运送到生产环境中,应该忽略最新的标签,并且不要使用它,也不要被它所吸引。很容易看到它并认为您的部署脚本应该只拉取“latest”,而您的构建过程会确保其有效性。


4
你说得对。我的想法是仅在Docker Edge上与Kubernetes进行本地开发时使用“latest”标签。开发工作流程如下:1. 修改应用程序代码;2. 运行docker build(这样每次都会创建具有latest标签的镜像);3. 运行kubectl apply -f deployment.yaml。这样,我就不需要每次更改应用程序时都创建一个新标签,并且(更糟糕的是)在我的deployment.yaml中引用该“新标签”。这就是为了简化我的开发工作流程的全部想法。 - user62058
如果这个解决方案对您有用,请接受答案,@user62058。 - Prateek Jain

2
除了techtrainer的评论和回答外,我想提供一些如何操作的示例。
一般规则是,您必须使用图像的标签版本,而不是latest。对于Docker标签,您越具体,越好。要具体化以避免使用错误的图像。如果您不希望同事或其他Docker用户下载图像并不知道它们有多新,请考虑这一点。请具体化以避免此类问题。
docker tag IMAGE ID image/TAG:version.d.m.y

为了更好地管理您的图片,您应该有一些智能的命名约定。我倾向于使用图像的阶段、版本和创建日期来命名。例如:

docker tag 113a43faa138 ubuntu/prod:v1.8.6.2018

这意味着生产阶段,版本1,创建于2018年6月8日。

就是这样。您的版本已经可用,并且命名更容易理解,方便您和其他用户使用此图像。


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