天天看點

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