天天看点

kubernetes deployment 使用镜像摘要发布新版本

默认情况下使用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