19.7. 硬修剪 registry
OpenShift Container Registry 可能会积累未被 OpenShift Container Platform 集群的 etcd 引用的 Blob。因此,基本镜像修剪过程对它们无法操作。它们称为孤立的 Blob。
以下情形中可能会出现孤立的 Blob:
-
使用
oc delete image <sha256:image-id>
命令手动删除镜像,该命令仅从 etcd 中移除镜像,而不从 registry 存储中移除。 - docker 守护进程失败发起了推送到 registry,这会造成只上传一些 Blob,但不上传其镜像清单(这作为最后一个组件上传)。所有唯一镜像 Blob 变成孤立的 Blob。
- OpenShift Container Platform 因为配额限制而拒绝某一镜像。
- 标准镜像修剪器删除镜像清单,但在删除相关 Blob 前中断。
- registry 修剪器中有一个程序错误,无法移除预定的 Blob,从而导致引用它们的镜像对象被移除,并且 Blob 变成孤立的 Blob。
硬修剪 registry,这是独立于基本镜像修剪的过程,允许您删除孤立的 Blob。如果 OpenShift Container registry 的存储空间不足,并且您认为有孤立的 Blob,则应该执行硬修剪。
这应该是罕见的操作,只有在有证据表明创建了大量新的孤立项时才需要。否则,您可以定期执行标准镜像修剪,例如一天一次(取决于要创建的镜像数量)。
从 registry 中硬修剪孤立的 Blob:
- 登录 :以具有访问令牌的用户身份使用 CLI 登录。
运行基本镜像修剪 :基本镜像修剪会移除了不再需要的额外镜像。硬修剪不移除自己的镜像,只移除保存在 registry 存储中的 Blob。因此,您应该在硬修剪之前运行此操作。
如需了解步骤,请参阅修剪镜像。
将 registry 切换为只读模式 :如果 registry 不以只读模式运行,任何在修剪的同时发生的推送将会:
- 失败,并导致出现新的孤立项;或者
- 成功,尽管镜像不可拉取(因为删除了一些引用的 Blob)。
只有 registry 切回到读写模式后,推送才会成功。因此,必须仔细地调度硬修剪。
将 registry 切换成只读模式:
设置以下环境变量:
$ oc set env -n default \ dc/docker-registry \ 'REGISTRY_STORAGE_MAINTENANCE_READONLY={"enabled":true}'
默认情况下,上一步骤完成后,registry 应自动重新部署;等待重新部署完成后再继续。然而,如果您禁用了这些触发器,则必须手动重新部署 registry,以便获取新的环境变量:
$ oc rollout -n default \ latest dc/docker-registry
添加 system:image-pruner 角色 :用来运行 registry 实例的服务帐户需要额外的权限才能列出某些资源。
获取服务帐户名称:
$ service_account=$(oc get -n default \ -o jsonpath=$'system:serviceaccount:{.metadata.namespace}:{.spec.template.spec.serviceAccountName}\n' \ dc/docker-registry)
将 system:image-pruner 集群角色添加到服务帐户:
$ oc adm policy add-cluster-role-to-user \ system:image-pruner \ ${service_account}
(可选)在空运行模式下运行修剪器 :若要查看会移除多少 Blob,请以空运行模式运行硬修剪器。不会实际进行任何更改:
$ oc -n default \ exec -i -t "$(oc -n default get pods -l deploymentconfig=docker-registry \ -o jsonpath=$'{.items[0].metadata.name}\n')" \ -- /usr/bin/dockerregistry -prune=check
另外,若要获得修剪候选者的准确路径,可提高日志级别:
$ oc -n default \ exec "$(oc -n default get pods -l deploymentconfig=docker-registry \ -o jsonpath=$'{.items[0].metadata.name}\n')" \ -- /bin/sh \ -c 'REGISTRY_LOG_LEVEL=info /usr/bin/dockerregistry -prune=check'
已截断的输出示例
$ oc exec docker-registry-3-vhndw \ -- /bin/sh -c 'REGISTRY_LOG_LEVEL=info /usr/bin/dockerregistry -prune=check' time="2017-06-22T11:50:25.066156047Z" level=info msg="start prune (dry-run mode)" distribution_version="v2.4.1+unknown" kubernetes_version=v1.6.1+$Format:%h$ openshift_version=unknown time="2017-06-22T11:50:25.092257421Z" level=info msg="Would delete blob: sha256:00043a2a5e384f6b59ab17e2c3d3a3d0a7de01b2cabeb606243e468acc663fa5" go.version=go1.7.5 instance.id=b097121c-a864-4e0c-ad6c-cc25f8fdf5a6 time="2017-06-22T11:50:25.092395621Z" level=info msg="Would delete blob: sha256:0022d49612807cb348cabc562c072ef34d756adfe0100a61952cbcb87ee6578a" go.version=go1.7.5 instance.id=b097121c-a864-4e0c-ad6c-cc25f8fdf5a6 time="2017-06-22T11:50:25.092492183Z" level=info msg="Would delete blob: sha256:0029dd4228961086707e53b881e25eba0564fa80033fbbb2e27847a28d16a37c" go.version=go1.7.5 instance.id=b097121c-a864-4e0c-ad6c-cc25f8fdf5a6 time="2017-06-22T11:50:26.673946639Z" level=info msg="Would delete blob: sha256:ff7664dfc213d6cc60fd5c5f5bb00a7bf4a687e18e1df12d349a1d07b2cf7663" go.version=go1.7.5 instance.id=b097121c-a864-4e0c-ad6c-cc25f8fdf5a6 time="2017-06-22T11:50:26.674024531Z" level=info msg="Would delete blob: sha256:ff7a933178ccd931f4b5f40f9f19a65be5eeeec207e4fad2a5bafd28afbef57e" go.version=go1.7.5 instance.id=b097121c-a864-4e0c-ad6c-cc25f8fdf5a6 time="2017-06-22T11:50:26.674675469Z" level=info msg="Would delete blob: sha256:ff9b8956794b426cc80bb49a604a0b24a1553aae96b930c6919a6675db3d5e06" go.version=go1.7.5 instance.id=b097121c-a864-4e0c-ad6c-cc25f8fdf5a6 ... Would delete 13374 blobs Would free up 2.835 GiB of disk space Use -prune=delete to actually delete the data
运行硬修剪 :在 docker-registry pod 的一个正在运行的实例中执行以下命令进行硬修剪:
$ oc -n default \ exec -i -t "$(oc -n default get pods -l deploymentconfig=docker-registry -o jsonpath=$'{.items[0].metadata.name}\n')" \ -- /usr/bin/dockerregistry -prune=delete
输出示例
$ oc exec docker-registry-3-vhndw \ -- /usr/bin/dockerregistry -prune=delete Deleted 13374 blobs Freed up 2.835 GiB of disk space
将 registry 切回到读写模式 :在修剪完成后,可以执行以下命令将 registry 切回到读写模式:
$ oc set env -n default dc/docker-registry REGISTRY_STORAGE_MAINTENANCE_READONLY-