Docker 私有系統資料庫作為 kubernetes pod - 已刪除的圖像自動重新創建
我將 docker 私有系統資料庫 v2.7.0 作為具有服務和持久卷的 kubernetes pod 執行,這要歸功於 Varun Kumar G 教程,這是我設置中唯一成功的方法,讓 kubernetes 從我的私有 docker 系統資料庫中提取我的3 個節點 - 本地 - 帶有 ubuntu 20.04 lts kvms 的集群。
問題在於從 kubernetes pod docker registry v2.7.0 中刪除圖像(必須使用以前的版本,因為最新的 v2.7.1 不適用於 htpasswd)。此外,我已經閱讀了很多類似的主題,例如this、this和this。
使用 docker registry v2.7.1作為 docker 容器執行,我可以毫無問題地刪除圖像,
但是使用 docker registry v2.7.0作為 kubernetes pod執行,通常的刪除步驟導致無法再次推送已刪除的映像,即使在成功刪除 blob 並手動刪除
/var/lib/registry/docker/registry/v2/repositories/
.下面是系統資料庫 pod yaml
apiVersion: v1 kind: Pod metadata: name: dockreg-pod labels: app: mregistry spec: containers: - name: registry image: registry:2.7.0 imagePullPolicy: IfNotPresent volumeMounts: - name: repo-vol mountPath: "/var/lib/registry" - name: certs-vol mountPath: "/certs" readOnly: true - name: auth-vol mountPath: "/auth" readOnly: true env: - name: REGISTRY_AUTH value: "htpasswd" - name: REGISTRY_AUTH_HTPASSWD_REALM value: "Registry Realm" - name: REGISTRY_AUTH_HTPASSWD_PATH value: "/auth/htpasswd" - name: REGISTRY_HTTP_TLS_CERTIFICATE value: "/certs/tls.crt" - name: REGISTRY_HTTP_TLS_KEY value: "/certs/tls.key" - name: REGISTRY_STORAGE_DELETE_ENABLED value: "true" volumes: - name: repo-vol persistentVolumeClaim: claimName: repo-pvc - name: certs-vol secret: secretName: certs-secret - name: auth-vol secret: secretName: auth-secret restartPolicy: Always nodeName: spring
以下是持久卷 yaml
apiVersion: v1 kind: PersistentVolume metadata: name: repo-pv labels: type: prstore spec: capacity: storage: 7Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: fsType: ext4 path: /root/repo nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - spring --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: repo-pvc labels: type: prstore spec: selector: matchLabels: type: prstore volumeMode: Filesystem storageClassName: local-storage accessModes: - ReadWriteOnce resources: requests: storage: 7Gi
假設我在一個全新的系統資料庫 pod 上推送一個圖像,並且預先清除了持久性儲存。
root@sea:scripts# docker push dockreg:5000/mubu4:v4 The push refers to repository [dockreg:5000/mubu4] 9f54eef41275: Pushed v4: digest: sha256:7bd0d9a9821815dccb5c53c18cea04591ec633e2e529c5cdd39681169589c17f size: 529
刪除圖像似乎按預期工作,直到我再次嘗試推送已刪除的圖像,此時我遇到了可怕的
Layer already exists
錯誤。正如您可能在上面看到的,我在系統資料庫 pod 環境中包含以下內容,
- name: REGISTRY_STORAGE_DELETE_ENABLED value: "true"
否則我會
unsupported
從呼叫中得到一個錯誤curl -X DELETE
,即使在添加之後delete: enabled: true
在
/etc/docker/registry/config.yml
吊艙內,version: 0.1 log: fields: service: registry storage: cache: blobdescriptor: inmemory filesystem: rootdirectory: /var/lib/registry delete: enabled: true http: addr: :5000 headers: X-Content-Type-Options: [nosniff] health: storagedriver: enabled: true interval: 10s threshold: 3
這似乎對我的案例沒有影響。
以下是刪除步驟。
curl -u alexander:sofianos \ > -vsk -H "Accept: \ > application/vnd.docker.distribution.manifest.v2+json" \ > -X DELETE \ > https://dockreg:5000/v2/mubu4/manifests/sha256:\ > 7bd0d9a9821815dccb5c53c18cea04591ec633e2e529c5cdd39681169589c17f
上面列印了以下內容
> DELETE /v2/mubu4/manifests/sha256:7bd0d9a9821815dccb5c53c18cea04591ec633e2e529c5cdd39681169589c17f HTTP/2 > Host: dockreg:5000 > authorization: Basic YWxleGFuZGVyOnNvZmlhbm9z > user-agent: curl/7.68.0 > accept: application/vnd.docker.distribution.manifest.v2+json > * Connection state changed (MAX_CONCURRENT_STREAMS == 250)! < HTTP/2 202 < docker-distribution-api-version: registry/2.0 < x-content-type-options: nosniff < content-length: 0 < date: Sat, 30 Oct 2021 13:25:53 GMT < * Connection #0 to host dockreg left intact
這似乎是有序的。
下面,從系統資料庫 pod 中刪除 blob
root@sea:scripts# kubectl exec -it dockreg-pod -- sh / # bin/registry garbage-collect /etc/docker/registry/config.yml mubu4 0 blobs marked, 3 blobs and 0 manifests eligible for deletion blob eligible for deletion: sha256:7b1a6ab2e44dbac178598dabe7cff59bd67233dba0b27e4fbd1f9d4b3c877a54 INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/7b/7b1a6ab2e44dbac178598dabe7cff59bd67233dba0b27e4fbd1f9d4b3c877a54 go.version=go1.11.2 instance.id=82a101ee-47f4-4f4f-bc79-76d774b0924b service=registry blob eligible for deletion: sha256:7bd0d9a9821815dccb5c53c18cea04591ec633e2e529c5cdd39681169589c17f INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/7b/7bd0d9a9821815dccb5c53c18cea04591ec633e2e529c5cdd39681169589c17f go.version=go1.11.2 instance.id=82a101ee-47f4-4f4f-bc79-76d774b0924b service=registry blob eligible for deletion: sha256:ecb35fc8715f5ab1d9053ecb2f2d9ebbec4a59c0a0615d98de53bc29f7285085 INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/ec/ecb35fc8715f5ab1d9053ecb2f2d9ebbec4a59c0a0615d98de53bc29f7285085 go.version=go1.11.2 instance.id=82a101ee-47f4-4f4f-bc79-76d774b0924b service=registry
最後,手動刪除儲存庫映像
/ # rm -rf /var/lib/registry/docker/registry/v2/repositories/mubu4
在我的持久儲存上,系統資料庫現在看起來像這樣
root@spring:repo# tree . └── docker └── registry └── v2 ├── blobs │ └── sha256 │ ├── 7b │ └── ec └── repositories 8 directories, 0 files
但是當我再次嘗試推送已刪除的圖像時,我得到了
root@sea:scripts# docker push dockreg:5000/mubu4:v4 The push refers to repository [dockreg:5000/mubu4] 9f54eef41275: Layer already exists v4: digest: sha256:7bd0d9a9821815dccb5c53c18cea04591ec633e2e529c5cdd39681169589c17f size: 529
在我的系統資料庫中,我之前刪除的 mubu4 圖像文件夾已通過上述推送命令神秘地重新創建。
root@spring:repo# tree . └── docker └── registry └── v2 ├── blobs │ └── sha256 │ ├── 7b │ └── ec └── repositories └── mubu4 └── _manifests ├── revisions │ └── sha256 │ └── 7bd0d9a9821815dccb5c53c18cea04591ec633e2e529c5cdd39681169589c17f │ └── link └── tags └── v4 ├── current │ └── link └── index └── sha256 └── 7bd0d9a9821815dccb5c53c18cea04591ec633e2e529c5cdd39681169589c17f └── link 19 directories, 3 files
我還嘗試用
root@spring:repo# rm -rf *
無濟於事。之後嘗試推送已刪除的圖像,仍然輸出完全相同的
Layer already exists
錯誤,並且系統資料庫樹再次自動重新創建,看起來與上述樹輸出中的完全相同。問題是我還能嘗試什麼來完成這項工作,和/或替代地,
從上面的測試可以看出,在 docker registry kubernetes pod 中,還有其他文件保存著已刪除鏡像似乎沒有被刪除的配置,這些文件通過 docker push 呼叫啟動已刪除鏡像的重新創建。除了樹我應該往哪裡看
/var/lib/registry/docker/registry/v2/
所以我可以刪除對已刪除圖像的所有引用?
似乎至少在此處和此處描述的系統資料庫版本 2.7.0 中存在記憶體問題。
建議在上述執行緒中完全禁用記憶體或每次重新啟動容器。
因為我將 docker 系統資料庫用作 kubernetes pod,所以更改了預設系統資料庫配置文件,即。
/etc/docker/registry/config.yml
沒有任何效果,因為 kubernetes 系統資料庫 pod yaml 優先,這意味著必須在 pod yaml 中將配置設置為環境變數,REGISTRY_variable
下劃線表示縮進級別,如docs中所述。所以解決方案是添加
- name: REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR value: ""
到 pod yaml 中的容器環境,以便完全禁用記憶體,否則如果系統資料庫作為 docker 容器執行,我們可以在以下內容中使用
config.yml
:storage: cache: blobdescriptor: ""
另一種方法是在每次刪除圖像時重新啟動 pod:
kubectl exec <pod_name> -c <container_name> -- reboot
或者如果它是一個 docker 容器
docker restart <registry_container>