10.6. 修剪镜像

修剪自定义资源可启用自动镜像修剪。管理员可以手工删除因为年龄、状态或超过限值而不再需要的镜像。手动删除镜像的方法有两种:

  • 在集群上以一个 JobCronJob 运行镜像修剪。
  • 运行 oc adm prune images 命令。

先决条件

  • 若要修剪镜像,您必须先以具有访问令牌的用户身份登录到 CLI。用户还必须有集群角色 system:image-pruner 或更高级别的角色(如 cluster-admin)。
  • 公开镜像 registry。

流程

使用以下方法之一可以手工删除因为年龄、状态或超过限值而不再需要的镜像:

  • 通过为 pruner 服务帐户创建 YAML 文件,在集群中以 JobCronJob 形式运行镜像修剪,例如:

    $ oc create -f <filename>.yaml

    输出示例

    kind: List
    apiVersion: v1
    items:
    - apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: pruner
        namespace: openshift-image-registry
    - apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: openshift-image-registry-pruner
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: system:image-pruner
      subjects:
      - kind: ServiceAccount
        name: pruner
        namespace: openshift-image-registry
    - apiVersion: batch/v1beta1
      kind: CronJob
      metadata:
        name: image-pruner
        namespace: openshift-image-registry
      spec:
        schedule: "0 0 * * *"
        concurrencyPolicy: Forbid
        successfulJobsHistoryLimit: 1
        failedJobsHistoryLimit: 3
        jobTemplate:
          spec:
            template:
              spec:
                restartPolicy: OnFailure
                containers:
                - image: "quay.io/openshift/origin-cli:4.1"
                  resources:
                    requests:
                      cpu: 1
                      memory: 1Gi
                  terminationMessagePolicy: FallbackToLogsOnError
                  command:
                  - oc
                  args:
                  - adm
                  - prune
                  - images
                  - --certificate-authority=/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt
                  - --keep-tag-revisions=5
                  - --keep-younger-than=96h
                  - --confirm=true
                  name: image-pruner
                serviceAccountName: pruner

  • 运行 oc adm prune images [<options>] 命令:

    $ oc adm prune images [<options>]

    除非使用了 --prune-registry=false,否则修剪镜像会从集成 registry 中移除数据。

    使用 --namespace 标志修剪镜像时不移除镜像,只移除镜像流。镜像是没有命名空间的资源。因此,将修剪限制到特定的命名空间会导致无法计算其当前使用量。

    默认情况下,集成 registry 会缓存 blob 元数据来减少对存储的请求数量,并提高处理请求的速度。修剪不会更新集成 registry 缓存。在修剪后推送的镜像如果含有修剪的层,它们会被破坏,因为不会推送在缓存中有元数据的已修剪层。因此,您必须重新部署 registry,以便在修剪后清除缓存:

    $ oc rollout restart deployment/image-registry -n openshift-image-registry

    如果集成 registry 使用 Redis 缓存,您必须手动清理数据库。

    如果无法在修剪后重新部署 registry,那么您必须永久禁用缓存。

    oc adm prune images 操作需要 registry 的路由。默认不创建 registry 路由。

    Prune images CLI 配置选项表描述了可供 oc adm prune images <options> 命令使用的选项

    表 10.4. 修剪镜像 CLI 配置选项

    选项描述

    --all

    包括没有推送到 registry 但已通过 pullthrough 镜像的镜像。默认为开启。要将修剪限制为已被推送到集成 registry 的镜像,请传递 --all=false

    --certificate-authority

    与 OpenShift Container Platform 管理的 registry 通信时使用的证书颁发机构文件的路径。默认为来自当前用户配置文件的证书颁发机构数据。如果提供,则发起安全连接。

    --confirm

    指明应该执行修剪,而不是空运行。这需要具有指向集成容器镜像 registry 的有效路由。如果此命令在集群网络外运行,则必须使用 --registry-url 来提供路由。

    --force-insecure

    谨慎使用这个选项。允许与通过 HTTP 托管或具有无效 HTTPS 证书的容器 registry 进行不安全连接。

    --keep-tag-revisions=<N>

    对于每个镜像流,每个标签最多保留 N 个镜像修订(默认值 3)。

    --keep-younger-than=<duration>

    不修剪相对于当前时间年龄不到 <duration> 的镜像。或者,不修剪被相对于当前时间年龄不到 <duration> 的其他对象引用的镜像(默认值 60m)。

    --prune-over-size-limit

    修剪超过同一项目中定义的最小限值的每个镜像。此标志不能与 --keep-tag-revisions--keep-younger-than 结合使用。

    --registry-url

    联系 registry 时使用的地址。此命令尝试使用由受管镜像和镜像流决定的集群内部 URL。如果失败(registry 无法解析或访问),则需要使用此标志提供一个替代路由。可以在 registry 主机名中加上前缀 https://http:// 来强制执行特定的连接协议。

    --prune-registry

    此选项与其他选项指定的条件结合,可以控制是否修剪 registry 中与 OpenShift Container Platform 镜像 API 对象对应的数据。默认情况下,镜像修剪同时处理镜像 API 对象和 registry 中对应的数据。

    当您只关注移除 etcd 内容时(可能要减少镜像对象的数量,但并不关心清理 registry)或要通过硬修剪 registry 来单独进行操作(可能在 registry 的适当维护窗口期间),此选项很有用处。

10.6.1. 镜像修剪条件

您可以对手动修剪的镜像应用条件。

  • 要删除任何由 OpenShift Container Platform 管理的镜像,或删除带有注解 openshift.io/image.managed的镜像:

    • 至少在 --keep-younger-than 分钟前创建 ,且当前没有被引用:

      • 在之前 --keep-younger-than 分钟内创建的 Pod。
      • 在之前 --keep-younger-than 分钟内创建的镜像流。
      • 运行的 pod
      • 待处理的 pod
      • 复制控制器
      • 部署
      • 部署配置
      • 副本集(Replica set)
      • 构建配置
      • Builds
      • stream.status.tags[].items--keep-tag-revisions 个最新项。
    • 超过同一项目中定义的最小限值,且当前没有被引用:

      • 运行的 pod
      • 待处理的 pod
      • 复制控制器
      • 部署
      • 部署配置
      • 副本集(Replica set)
      • 构建配置
      • Builds
  • 不支持从外部 registry 进行修剪。
  • 镜像被修剪后,会从在 status.tags 引用了该镜像的所有镜像流中移除对该镜像的所有引用。
  • 移除不再被任何镜像引用的镜像层。
注意

--prune-over-size-limit 标志无法与 --keep-tag-revisions--keep-younger-than 标志结合使用。这样做会返回不允许操作的信息。

与使用一个命令同时进行两个操作相比,把移除 OpenShift Container Platform 镜像 API 对象的操作和从 registry 中删除镜像数据的操作分开进行(使用 --prune-registry=false 然后再硬修剪 registry),可以缩减时间窗口且更加安全。但是,计时窗口不会完全剔除。

例如,您仍然可以创建引用镜像的 pod,因为修剪会标识该镜像以供修剪。您仍需对在修剪操作期间创建的 API 对象(它可能会引用镜像)加以注意以避免出现引用已删除内容的问题。

重新进行修剪时如果没有使用 --prune-registry 选项,或使用 --prune-registry=true 选项,则不会修剪之前通过 --prune-registry=false 修剪的镜像的镜像 registry 中相关的存储。对于任何使用 --prune-registry=false 修剪的镜像,只能通过硬修剪注册表将其从 registry 存储中删除。