默认情况下使用deployment发布新版本发布是要使用新的镜像tag
先演示一下常规部署:
准备Dockerfile
FROM nginx
ENV app_version=v1
传镜像到私库里面
docker login -u <USER> -p <PASSWORD> docker-registry.default.svc:5000
docker build -t=docker-registry.default.svc:5000/default/nginx:v1 .
docker push docker-registry.default.svc:5000/default/nginx:v1
准备deployment配置 nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: docker-registry.default.svc:5000/default/nginx:v1
ports:
- containerPort: 80
securityContext:
privileged: true
导入配置
kubectl create -f nginx.yaml
更新应用
Dockerfile
FROM nginx
ENV app_version=v2
docker login -u <USER> -p <PASSWORD> docker-registry.default.svc:5000
docker build -t=docker-registry.default.svc:5000/default/nginx:v2 .
docker push docker-registry.default.svc:5000/default/nginx:v2
更新deployment镜像
kubectl set image deployment/nginx nginx=docker-registry.default.svc:5000/default/nginx:v2
kubectl rollout status deployment/nginx -n default -w
Waiting for deployment "nginx" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
deployment "nginx" successfully rolled out
看一下deployment的版本,发现已经有两个版本了
kubectl rollout history deployment/nginx -n default
deployments "nginx"
REVISION CHANGE-CAUSE
1 <none>
2 <none>
使用镜像摘要发布:
有时候我们不想去维护镜像的tag版本,这时候可以使用镜像仓库的digest(摘要)
FROM nginx
ENV app_version=v1
docker build -t=docker-registry.default.svc:5000/default/nginx .
docker push docker-registry.default.svc:5000/default/nginx
那怎么获取摘要呢?
docker images docker-registry.default.svc:5000/default/nginx --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
docker-registry.default.svc:5000/default/nginx latest sha256:ec870e6c5c55a6ddc99b295ae175b49044bd58d9cf0d6d0b238543c14b017c3d dc2a69015e29 10 minutes ago 127 MB
值得注意的是如果只是在本地build镜像而没有docker push过DIGEST字段是不存在的
可以一键获取镜像的digest
docker inspect docker-registry.default.svc:5000/default/nginx |jq -r '.[]|.RepoDigests|.[]'
docker-registry.default.svc:5000/default/nginx@sha256:ec870e6c5c55a6ddc99b295ae175b49044bd58d9cf0d6d0b238543c14b017c3d
kubectl set image deployment/nginx nginx=docker-registry.default.svc:5000/default/nginx@sha256:ec870e6c5c55a6ddc99b295ae175b49044bd58d9cf0d6d0b238543c14b017c3d
可以观察一下docker registry 的数据
ls /data/docker-registry/docker/registry/v2/repositories/default/nginx/_manifests/revisions/sha256/
ec870e6c5c55a6ddc99b295ae175b49044bd58d9cf0d6d0b238543c14b017c3d
这时候我们传一下新内容的镜像,可以发现docker registry的摘要是不会被覆盖的
FROM nginx
ENV app_version=v2
docker build -t=docker-registry.default.svc:5000/default/nginx .
docker push docker-registry.default.svc:5000/default/nginx
ls /data/docker-registry/docker/registry/v2/repositories/default/nginx/_manifests/revisions/sha256/
d910d71ccd4594c586bed1d0b711c106718abe4f51e9495037778e8bc450c542 ec870e6c5c55a6ddc99b295ae175b49044bd58d9cf0d6d0b238543c14b017c3d
docker images docker-registry.default.svc:5000/default/nginx --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
docker-registry.default.svc:5000/default/nginx latest sha256:d910d71ccd4594c586bed1d0b711c106718abe4f51e9495037778e8bc450c542 c11d1be93c4d 4 minutes ago 127 MB
docker-registry.default.svc:5000/default/nginx <none> sha256:ec870e6c5c55a6ddc99b295ae175b49044bd58d9cf0d6d0b238543c14b017c3d dc2a69015e29 23 minutes ago 127 MB
结论:
docker pull不会删除以前的镜像,可以使用digest区分历史版本,docker守护进程也不会自动回收未使用的镜像除非使用docker image prune。docker push也是同理,docker registry 的历史版本也是需要手动清理
使用tag的好处是tag名称通常是友好的可辨别的。使用digest的好处是digest是只读的,可以保证镜像不会在不知情的情况下更新,虽然digest sha256值并不友好,但是版本管理我们通常依赖deployment的history
具体可以参考:https://success.docker.com/article/images-tagging-vs-digests