(Kubernetes + Minikube) 无法从本地注册表获取 docker 图像
(Kubernetes + Minikube) can't get docker image from local registry
我在我的机器上安装了 docker,还有 minikube,里面有 docker,所以我可能在不同的虚拟机上有两个 docker 实例 运行ning
我构建一个图像并标记它,然后将它推送到本地注册表,它成功推送,我也可以从注册表中提取它,而且当我 运行 卷曲以获取标记列表时,我得到了结果,在这里是我做的
1- docker build -t 127.0.0.1:5000/eliza/console:0.0.1 .
2- docker run -d -p 5000:5000 --name registry registry:2
3- docker tag a3703d02a199 127.0.0.1:5000/eliza/console:0.0.1
4- docker push 127.0.0.1:5000/eliza/console:0.0.1
5- curl -X GET http://127.0.0.1:5000/v2/eliza/console/tags/list
以上所有步骤都没有问题。
我的问题是当我 运行 minikube 并尝试在其中的本地注册表中访问此图像时
所以当我 运行 下一个命令时
1- sudo minikube start --insecure-registry 127.0.0.1:5000
2- eval $(minikube docker-env)
3- minikube ssh
4- curl -X GET http://127.0.0.1:5000/v2/eliza/console/tags/list
在最后一步(第 4 点)它给了我下一条消息
curl: (7) Failed to connect to 127.0.0.1 port 5000: Connection refused
所以我可以从我的机器而不是从 minikube 访问图像注册表,当我在 minikube 上使用 Kubernetes 部署此图像并由于无法连接而导致部署失败时,这对我来说当然是个问题 http://127.0.0.1:5000
你能帮我配置 minikube 以查看我的本地注册表,这样我的问题就会得到解决,然后我就可以使用 kubernetes 成功地将映像部署到 minikube 了吗?
更新
我正在使用这个 yaml 文件(我将其命名为 ConsolePre.yaml)来使用 kubernetes
部署我的镜像
apiVersion: v1
kind: Service
metadata:
name: tripbru-console
labels:
app: tripbru-console
spec:
ports:
- port: 9080
targetPort: 9080
nodePort: 30181
selector:
app: tripbru-console
tier: frontend
type: NodePort
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: tripbru-console
labels:
app: tripbru-console
spec:
strategy:
type: Recreate
template:
metadata:
labels:
app: tripbru-console
tier: frontend
spec:
containers:
- image: docker.local:5000/eliza/console:0.0.1
name: tripbru-console
ports:
- containerPort: 9080
name: tripbru-console
并且当我 运行 下一个应用更改的命令时
sudo kubectl apply -f /PATH_TO_YAML_FILE/ConsolePre.yaml
结果是
NAME READY STATUS RESTARTS AGE
po/tripbru-console-1655054400-x3g87 0/1 ErrImagePull 0 1m
当我运行描述命令时
sudo kubectl describe pod tripbru-console-1655054400-x3g87
我在描述结果中找到了下一条消息
Error response from daemon: {"message":"Get
https://docker.local:5000/v1/_ping: dial tcp: lookup docker.local on
10.0.2.3:53: read udp 10.0.2.15:57792-\u003e10.0.2.3:53: i/o timeout"}
我在 minikube /etc/hosts 中配置了 docker.local xxx.xxx.xx.4 所以我不知道从哪里 10.0.2.3:53和 10.0.2.15:57792 来自.
那么我该如何解决这个问题。
谢谢:)
您可以发出此命令将您的 docker CLI 指向 minikube:eval $(minikube docker-env) 然后您可以在那里构建您的图像或从任何地方导出它们并导入。
问题出在你想在任何地方使用 127.0.0.1
的想法。这是错误的。
所以如果你的机器IP是192.168.0.101。然后下面的作品
1- docker build -t 127.0.0.1:5000/eliza/console:0.0.1 .
2- docker run -d -p 5000:5000 --name registry registry:2
3- docker tag a3703d02a199 127.0.0.1:5000/eliza/console:0.0.1
4- docker push 127.0.0.1:5000/eliza/console:0.0.1
5- curl -X GET http://127.0.0.1:5000/v2/eliza/console/tags/list
因为docker 运行 将注册表映射到 127.0.0.1:5000 和 192.168.0.101:5000。现在在你的机器上只有这个 127.0.0.1
可以工作。现在当你使用
3- minikube ssh
你进入了 minikube 机器,它没有注册表 运行ning 在 127.0.0.1:5000。所以错误。使用计算机 IP 无法在此计算机内部访问注册表。
我通常解决这个问题的方法是在本地和其他虚拟机内部使用主机名。
所以在你的机器上创建一个条目 /etc/hosts
docker.local 127.0.0.1
并将您的命令更改为
1- docker build -t docker.local:5000/eliza/console:0.0.1 .
2- docker run -d -p 5000:5000 --name registry registry:2
3- docker tag a3703d02a199 docker.local:5000/eliza/console:0.0.1
4- docker push docker.local:5000/eliza/console:0.0.1
5- curl -X GET http://docker.local:5000/v2/eliza/console/tags/list
然后当您使用 minikube ssh
时,在 /etc/hosts
中输入 docker.local
docker.local 192.168.0.101
然后curl -X GET http://docker.local:5000/v2/eliza/console/tags/list
编辑-1
对于 TLS 问题,您需要在 minikube
中停止 docker 服务
systemctl stop docker
然后编辑 /etc/systemd/system/docker.service.d/10-machine.conf
并更改
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
到
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 --insecure-registry docker.local:5000 --insecure-registry 192.168.1.4:5000
然后重新加载守护进程并启动 docker 服务
systemctl daemon-reload
systemctl start docker
之后尝试拉
docker pull docker.local:5000/eliza/console:0.0.1
并且该命令应该有效
如何从 Docker 容器中访问主机 mac 上的进程 运行?
这是 docker 地区的一个热门问题。看这里。
还有其他方法,例如,对于 mac 上的 Docker,docker.for.mac.localhost
DNS 名称将解析为主机 machine
来自https://docs.docker.com/docker-for-mac/networking/#i-cannot-ping-my-containers
The Mac has a changing IP address (or none if you have no network
access). From 17.06 onwards our recommendation is to connect to the
special Mac-only DNS name docker.for.mac.localhost which will resolve
to the internal IP address used by the host.
假设这个 minikube 的主要目的是用于本地测试,有一种更简单的方法来部署您的 docker 容器(这甚至不需要本地 docker 注册表)
方法 2:将您的 docker CLI 指向您的 minikube 中的 Docker 守护进程 运行,然后在那里执行 docker 构建命令。
这里首先要了解的是,当您在 machine 中安装 docker 时,它有 2 个部分,1) 一个 docker cli,您可以通过它与 docker 守护进程 2) 一个 docker 守护进程。在这个方法中,我们将本地 docker cli 指向 minikube 的 docker 守护进程并执行 docker build
.
此处引用相关部分
When using a single VM of Kubernetes, it's really handy to reuse the
minikube's built-in Docker daemon; as this means you don't have to
build a docker registry on your host machine and push the image into
it - you can just build inside the same docker daemon as minikube
which speeds up local experiments. Just make sure you tag your Docker
image with something other than 'latest' and use that tag while you
pull the image. Otherwise, if you do not specify version of your
image, it will be assumed as :latest, with pull image policy of Always
correspondingly, which may eventually result in ErrImagePull as you
may not have any versions of your Docker image out there in the
default docker registry (usually DockerHub) yet.
为了能够在您的 mac/linux 主机上使用 docker 守护程序,请在您的 shell:
中使用 docker-env 命令
eval $(minikube docker-env)
您现在应该可以在主机 mac/linux 的命令行上使用 docker machine 与 minikube VM 内的 docker 守护进程对话:
执行 docker 容器列表命令:docker ps
。它甚至应该显示与 kubernetes 系统相关的容器(因为现在你的 cli 指向一个 docker 守护进程,你的 minikube 是 运行)。
现在构建您的 docker 图像。然后它将在 minikube 中为您提供。
Minikube 在 docker 容器中运行,因此您应该将其视为一台单独的机器。现在,在这台运行 Kubernetes 的机器中,请注意,了解我们拥有 Minikube 环境和 Kubernetes 环境很重要。理解这一点很重要,因为从 Minikube 连接到本地注册表与从 Kubernetes(驻留在 Minikube 上)连接到本地注册表是不一样的。这里的区别:
enter image description here
创建Job/Deployment/Statefulset时,创建是由minikube完成的,因此它不知道docker中是否有任何服务连接到我们的本地注册表。奇怪的是,我们的“注册表”服务确实在 pods 内工作,也就是说,一旦创建了我们的作业/部署/Statefulset,您就可以毫无问题地访问我们的“注册表”服务。
那么这一切的解决方案是什么?
Minikube 可以通过 192.168.49.1:5000 轻松连接到我们的本地注册表。
如果您希望使用本地注册表中的图像创建作业/部署/状态集,则只需将 192.168.49.1:5000 添加到您的图像中即可。
enter image description here
另一方面,如果您希望能够从 pods 中访问您的本地注册表,您将需要一个服务和一个端点。
注意事项:
请记住,允许 minikube 通过以下方式访问本地注册表非常重要:
minikube start --insecure-registries 192.168.49.1:5000
minikube 很少使用 192.168.49.1 以外的其他 ip,以防万一最好检查一下:
minikube ssh 'grep host.minikube.internal / etc / hosts | cut -f1 '
这一切都假设您在 docker 中创建了一个注册表并公开了端口 5000。
我在我的机器上安装了 docker,还有 minikube,里面有 docker,所以我可能在不同的虚拟机上有两个 docker 实例 运行ning
我构建一个图像并标记它,然后将它推送到本地注册表,它成功推送,我也可以从注册表中提取它,而且当我 运行 卷曲以获取标记列表时,我得到了结果,在这里是我做的
1- docker build -t 127.0.0.1:5000/eliza/console:0.0.1 .
2- docker run -d -p 5000:5000 --name registry registry:2
3- docker tag a3703d02a199 127.0.0.1:5000/eliza/console:0.0.1
4- docker push 127.0.0.1:5000/eliza/console:0.0.1
5- curl -X GET http://127.0.0.1:5000/v2/eliza/console/tags/list
以上所有步骤都没有问题。
我的问题是当我 运行 minikube 并尝试在其中的本地注册表中访问此图像时
所以当我 运行 下一个命令时
1- sudo minikube start --insecure-registry 127.0.0.1:5000
2- eval $(minikube docker-env)
3- minikube ssh
4- curl -X GET http://127.0.0.1:5000/v2/eliza/console/tags/list
在最后一步(第 4 点)它给了我下一条消息
curl: (7) Failed to connect to 127.0.0.1 port 5000: Connection refused
所以我可以从我的机器而不是从 minikube 访问图像注册表,当我在 minikube 上使用 Kubernetes 部署此图像并由于无法连接而导致部署失败时,这对我来说当然是个问题 http://127.0.0.1:5000
你能帮我配置 minikube 以查看我的本地注册表,这样我的问题就会得到解决,然后我就可以使用 kubernetes 成功地将映像部署到 minikube 了吗?
更新
我正在使用这个 yaml 文件(我将其命名为 ConsolePre.yaml)来使用 kubernetes
部署我的镜像apiVersion: v1
kind: Service
metadata:
name: tripbru-console
labels:
app: tripbru-console
spec:
ports:
- port: 9080
targetPort: 9080
nodePort: 30181
selector:
app: tripbru-console
tier: frontend
type: NodePort
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: tripbru-console
labels:
app: tripbru-console
spec:
strategy:
type: Recreate
template:
metadata:
labels:
app: tripbru-console
tier: frontend
spec:
containers:
- image: docker.local:5000/eliza/console:0.0.1
name: tripbru-console
ports:
- containerPort: 9080
name: tripbru-console
并且当我 运行 下一个应用更改的命令时
sudo kubectl apply -f /PATH_TO_YAML_FILE/ConsolePre.yaml
结果是
NAME READY STATUS RESTARTS AGE
po/tripbru-console-1655054400-x3g87 0/1 ErrImagePull 0 1m
当我运行描述命令时
sudo kubectl describe pod tripbru-console-1655054400-x3g87
我在描述结果中找到了下一条消息
Error response from daemon: {"message":"Get https://docker.local:5000/v1/_ping: dial tcp: lookup docker.local on 10.0.2.3:53: read udp 10.0.2.15:57792-\u003e10.0.2.3:53: i/o timeout"}
我在 minikube /etc/hosts 中配置了 docker.local xxx.xxx.xx.4 所以我不知道从哪里 10.0.2.3:53和 10.0.2.15:57792 来自.
那么我该如何解决这个问题。
谢谢:)
您可以发出此命令将您的 docker CLI 指向 minikube:eval $(minikube docker-env) 然后您可以在那里构建您的图像或从任何地方导出它们并导入。
问题出在你想在任何地方使用 127.0.0.1
的想法。这是错误的。
所以如果你的机器IP是192.168.0.101。然后下面的作品
1- docker build -t 127.0.0.1:5000/eliza/console:0.0.1 .
2- docker run -d -p 5000:5000 --name registry registry:2
3- docker tag a3703d02a199 127.0.0.1:5000/eliza/console:0.0.1
4- docker push 127.0.0.1:5000/eliza/console:0.0.1
5- curl -X GET http://127.0.0.1:5000/v2/eliza/console/tags/list
因为docker 运行 将注册表映射到 127.0.0.1:5000 和 192.168.0.101:5000。现在在你的机器上只有这个 127.0.0.1
可以工作。现在当你使用
3- minikube ssh
你进入了 minikube 机器,它没有注册表 运行ning 在 127.0.0.1:5000。所以错误。使用计算机 IP 无法在此计算机内部访问注册表。
我通常解决这个问题的方法是在本地和其他虚拟机内部使用主机名。
所以在你的机器上创建一个条目 /etc/hosts
docker.local 127.0.0.1
并将您的命令更改为
1- docker build -t docker.local:5000/eliza/console:0.0.1 .
2- docker run -d -p 5000:5000 --name registry registry:2
3- docker tag a3703d02a199 docker.local:5000/eliza/console:0.0.1
4- docker push docker.local:5000/eliza/console:0.0.1
5- curl -X GET http://docker.local:5000/v2/eliza/console/tags/list
然后当您使用 minikube ssh
时,在 /etc/hosts
docker.local
docker.local 192.168.0.101
然后curl -X GET http://docker.local:5000/v2/eliza/console/tags/list
编辑-1
对于 TLS 问题,您需要在 minikube
中停止 docker 服务systemctl stop docker
然后编辑 /etc/systemd/system/docker.service.d/10-machine.conf
并更改
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
到
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 --insecure-registry docker.local:5000 --insecure-registry 192.168.1.4:5000
然后重新加载守护进程并启动 docker 服务
systemctl daemon-reload
systemctl start docker
之后尝试拉
docker pull docker.local:5000/eliza/console:0.0.1
并且该命令应该有效
如何从 Docker 容器中访问主机 mac 上的进程 运行?
这是 docker 地区的一个热门问题。看这里。
还有其他方法,例如,对于 mac 上的 Docker,docker.for.mac.localhost
DNS 名称将解析为主机 machine
来自https://docs.docker.com/docker-for-mac/networking/#i-cannot-ping-my-containers
The Mac has a changing IP address (or none if you have no network access). From 17.06 onwards our recommendation is to connect to the special Mac-only DNS name docker.for.mac.localhost which will resolve to the internal IP address used by the host.
假设这个 minikube 的主要目的是用于本地测试,有一种更简单的方法来部署您的 docker 容器(这甚至不需要本地 docker 注册表)
方法 2:将您的 docker CLI 指向您的 minikube 中的 Docker 守护进程 运行,然后在那里执行 docker 构建命令。
这里首先要了解的是,当您在 machine 中安装 docker 时,它有 2 个部分,1) 一个 docker cli,您可以通过它与 docker 守护进程 2) 一个 docker 守护进程。在这个方法中,我们将本地 docker cli 指向 minikube 的 docker 守护进程并执行 docker build
.
此处引用相关部分
When using a single VM of Kubernetes, it's really handy to reuse the minikube's built-in Docker daemon; as this means you don't have to build a docker registry on your host machine and push the image into it - you can just build inside the same docker daemon as minikube which speeds up local experiments. Just make sure you tag your Docker image with something other than 'latest' and use that tag while you pull the image. Otherwise, if you do not specify version of your image, it will be assumed as :latest, with pull image policy of Always correspondingly, which may eventually result in ErrImagePull as you may not have any versions of your Docker image out there in the default docker registry (usually DockerHub) yet.
为了能够在您的 mac/linux 主机上使用 docker 守护程序,请在您的 shell:
中使用 docker-env 命令eval $(minikube docker-env)
您现在应该可以在主机 mac/linux 的命令行上使用 docker machine 与 minikube VM 内的 docker 守护进程对话:
执行 docker 容器列表命令:docker ps
。它甚至应该显示与 kubernetes 系统相关的容器(因为现在你的 cli 指向一个 docker 守护进程,你的 minikube 是 运行)。
现在构建您的 docker 图像。然后它将在 minikube 中为您提供。
Minikube 在 docker 容器中运行,因此您应该将其视为一台单独的机器。现在,在这台运行 Kubernetes 的机器中,请注意,了解我们拥有 Minikube 环境和 Kubernetes 环境很重要。理解这一点很重要,因为从 Minikube 连接到本地注册表与从 Kubernetes(驻留在 Minikube 上)连接到本地注册表是不一样的。这里的区别: enter image description here
创建Job/Deployment/Statefulset时,创建是由minikube完成的,因此它不知道docker中是否有任何服务连接到我们的本地注册表。奇怪的是,我们的“注册表”服务确实在 pods 内工作,也就是说,一旦创建了我们的作业/部署/Statefulset,您就可以毫无问题地访问我们的“注册表”服务。 那么这一切的解决方案是什么? Minikube 可以通过 192.168.49.1:5000 轻松连接到我们的本地注册表。 如果您希望使用本地注册表中的图像创建作业/部署/状态集,则只需将 192.168.49.1:5000 添加到您的图像中即可。 enter image description here 另一方面,如果您希望能够从 pods 中访问您的本地注册表,您将需要一个服务和一个端点。
注意事项: 请记住,允许 minikube 通过以下方式访问本地注册表非常重要:
minikube start --insecure-registries 192.168.49.1:5000
minikube 很少使用 192.168.49.1 以外的其他 ip,以防万一最好检查一下:
minikube ssh 'grep host.minikube.internal / etc / hosts | cut -f1 '
这一切都假设您在 docker 中创建了一个注册表并公开了端口 5000。