我正在使用DevSpace工具将几个服务部署到我的本地集群(minikube
)。一旦有人对其中一个服务进行了更改,并将映像推送到我们的私有仓库,我需要这些更改在我的本地可用。我现在做的是完全删除minikube
集群,并开始一个新的。在这种情况下,所有具有相同标签的图像都只是更新为最新版本,而不是缓存的版本。
但我相信有一些更优雅的方法来克服这个问题。因此,在重新部署服务之前,我需要以某种方式从本地集群中清理/删除/删除过时的映像。
有人能指出他们存储在哪里,我如何查看和删除他们?谢谢。
这里是DevSpace维护者。你需要的是两件事:
- 每次运行
devspace dev
时强制重新创建您的pod的东西。所以,如果你使用的是Deployment或statfulset,你可以添加一些类似标签的东西,例如包含DevSpace内置时间戳变量作为值到你的pod模板。 - pod规范中的
imagePullPolicy: Always
,以确保Kubernetes总是为每个新创建的pod提取最新的映像。否则Kubernetes会使用已经缓存的图片。
在您的devspace.yaml
文件(如果您正在使用组件图部署)中,这可能看起来像这样:
deployments:
- name: my-component
helm:
componentChart: true
values:
labels:
timestamp: $!{DEVSPACE_TIMESTAMP} # here is 1.
containers:
- image: "YOUR_IMAGE:latest" # specify any tag here that you want
imagePullPolicy: Always # here is 2.
$!{DEVSPACE_TIMESTAMP}
=$!{}
强制将这个变量的值作为字符串(因为k8s只允许字符串值作为标签),DEVSPACE_TIMESTAMP
是DevSpace中预定义变量的名称。更多详细信息请访问:https://devspace.sh/cli/docs/configuration/variables/basics#predefined-variables
您可以执行滚动更新,而不是删除所有映像并重新创建集群(这假设您正在使用部署,您应该这样做)。
kubectl set image deployments/<deployment-name>=<repository-name>/<image-name>:<image-tag>
这也是假设,您正在使用正确的标签版本控制。
或者,如果您使用带有latest
标记的图像,您可以将ImagePullPolicy
更改为Always
,然后使用
删除必要的podkubectl delete pod <pod-name> <pod2-name> ...
当新的pod被创建时,新的映像将被拉出。
如果你仍然想删除未使用的docker镜像,你可以使用
docker image prune -a
这将删除所有没有至少一个容器的图像。
您可以尝试以下命令
删除未标记图像:
docker image rm $(docker images | grep "^<none>" | awk "{print $3}")
移除所有停止的容器:
docker container rm $(docker ps -a -q)
(或)
您需要停止并禁用localkube服务:
systemctl disable localkube.service
systemctl stop localkube.service
之后你可以停止和移除容器。
docker system prune -a
删除所有的图像
阻塞/命令式方法
这是我在构建脚本中使用的另一种方法。
主要优点是该命令是同步的,因此您可以将其包含在构建脚本中,而不需要集群每次都下载映像,以便在重新构建期间偶尔进行更新。
一些设置
# an example of building a new image and uploading it for reload in k8s
# in the question, this is already done
docker build -t jamesandariese/my-cool-image:latest .
docker push jamesandariese/my-cool-image:latest
奇迹发生在这里
# reload image in k8s, ignoring cached image
kubectl run
--image=jamesandariese/my-cool-image:latest
--image-pull-policy=Always
--restart=Never
--rm=true
-i download-image --command -- true
if [ $? -eq 0 ];then
1>&2 echo "all pods launched with this image tag will now use the updated image"
else
1>&2 echo "FAILED TO REFRESH IMAGE. See error from kubectl"
fi
此方法基于以下几个事实:
minikube在单个k8s节点上运行(也可以在其他单节点集群上运行,如k3s)
运行一个带有image-to-update和image pull策略的新pod总是导致新图像被下载
将命令重写为true并附加(通过-i),我们得到一个退出代码,该退出代码与我们是否成功更新了图像
一旦kubectl
成功退出,在minikube中更新映像。
注意:这可以通过DaemonSet
和kubectl wait
在整个集群中完成,但是当你有一个完整的集群时,你的SDLC应该更少地关注如何编写一个脚本来做到这一点,更多地关注如何正确标记事物,所以它们并不总是:latest
或:prod
。这种转变对于允许可预测的回滚和在集群中同时运行多个版本非常重要。