×

为什么要使用镜像流

镜像流及其关联的标签提供了一种抽象,用于从 AWS 上的 Red Hat OpenShift 服务内部引用容器镜像。镜像流及其标签允许您查看可用的镜像,并确保即使存储库中的镜像发生更改,您也在使用所需的特定镜像。

镜像流不包含实际的镜像数据,而是呈现相关镜像的单个虚拟视图,类似于镜像存储库。

您可以配置构建和部署以监视镜像流,以便在添加新镜像时收到通知,并分别通过执行构建或部署来做出反应。

例如,如果部署使用某个镜像,并且创建了该镜像的新版本,则可以自动执行部署以获取该镜像的新版本。

但是,如果部署或构建使用的镜像流标签未更新,那么即使容器镜像注册表中的容器镜像已更新,构建或部署也会继续使用以前的(大概已知的良好)镜像。

源镜像可以存储在以下任何位置:

  • AWS 上的 Red Hat OpenShift 服务集成的注册表。

  • 外部注册表,例如 registry.redhat.io 或 quay.io。

  • AWS 上的 Red Hat OpenShift 服务集群中的其他镜像流。

当您定义引用镜像流标签的对象(例如构建或部署配置)时,您指向的是镜像流标签,而不是存储库。当您构建或部署应用程序时,AWS 上的 Red Hat OpenShift 服务会使用镜像流标签查询存储库以找到镜像的关联 ID,并使用该确切的镜像。

镜像流元数据与其他集群信息一起存储在 etcd 实例中。

使用镜像流具有几个显著优势:

  • 您可以标记、回滚标签并快速处理镜像,而无需使用命令行重新推送。

  • 当将新镜像推送到注册表时,您可以触发构建和部署。此外,AWS 上的 Red Hat OpenShift 服务具有针对其他资源(例如 Kubernetes 对象)的通用触发器。

  • 您可以标记定期重新导入的标签。如果源镜像已更改,则会拾取该更改并将其反映在镜像流中,这将根据构建或部署配置触发构建或部署流程。

  • 您可以使用细粒度的访问控制共享镜像,并快速在团队之间分发镜像。

  • 如果源镜像发生更改,镜像流标签仍然指向镜像的已知良好版本,确保您的应用程序不会意外中断。

  • 您可以通过镜像流对象的权限配置围绕谁可以查看和使用镜像的安全策略。

  • 缺乏在集群级别读取或列出镜像权限的用户仍然可以使用镜像流检索项目中标记的镜像。

配置镜像流

ImageStream 对象文件包含以下元素。

镜像流对象定义
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
  annotations:
    openshift.io/generated-by: OpenShiftNewApp
  labels:
    app: ruby-sample-build
    template: application-template-stibuild
  name: origin-ruby-sample (1)
  namespace: test
spec: {}
status:
  dockerImageRepository: 172.30.56.218:5000/test/origin-ruby-sample (2)
  tags:
  - items:
    - created: 2017-09-02T10:15:09Z
      dockerImageReference: 172.30.56.218:5000/test/origin-ruby-sample@sha256:47463d94eb5c049b2d23b03a9530bf944f8f967a0fe79147dd6b9135bf7dd13d (3)
      generation: 2
      image: sha256:909de62d1f609a717ec433cc25ca5cf00941545c83a01fb31527771e1fab3fc5 (4)
    - created: 2017-09-01T13:40:11Z
      dockerImageReference: 172.30.56.218:5000/test/origin-ruby-sample@sha256:909de62d1f609a717ec433cc25ca5cf00941545c83a01fb31527771e1fab3fc5
      generation: 1
      image: sha256:47463d94eb5c049b2d23b03a9530bf944f8f967a0fe79147dd6b9135bf7dd13d
    tag: latest (5)
1 镜像流的名称。
2 可以将新镜像推送到其中以添加或更新此镜像流中的镜像的 Docker 存储库路径。
3 此镜像流标签当前引用的 SHA 标识符。引用此镜像流标签的资源使用此标识符。
4 此镜像流标签以前引用的 SHA 标识符。可用于回滚到较旧的镜像。
5 镜像流标签名称。

镜像流镜像

镜像流镜像指向镜像流内部的特定镜像 ID。

镜像流镜像允许您检索特定镜像流中已标记镜像的元数据。

在您将镜像导入或标记到镜像流中时,Red Hat OpenShift Service on AWS 会自动创建镜像流镜像对象。您无需在用于创建镜像流的任何镜像流定义中显式定义镜像流镜像对象。

镜像流镜像由镜像流名称和存储库中的镜像 ID 组成,以@符号分隔。

<image-stream-name>@<image-id>

要引用ImageStream对象示例中的镜像,镜像流镜像如下所示。

origin-ruby-sample@sha256:47463d94eb5c049b2d23b03a9530bf944f8f967a0fe79147dd6b9135bf7dd13d

镜像流标签

镜像流标签是指向镜像流中镜像的命名指针。它缩写为istag。镜像流标签用于引用或检索给定镜像流和标签的镜像。

镜像流标签可以引用任何本地或外部管理的镜像。它包含镜像历史记录,以所有镜像曾经指向的堆栈形式表示。每当在特定镜像流标签下标记新的或现有的镜像时,它都会放置在历史堆栈的第一个位置。先前占据顶部位置的镜像位于第二个位置。这允许轻松回滚以使标签再次指向历史镜像。

以下镜像流标签来自ImageStream对象。

镜像流标签在其历史记录中包含两个镜像。
kind: ImageStream
apiVersion: image.openshift.io/v1
metadata:
  name: my-image-stream
# ...
  tags:
  - items:
    - created: 2017-09-02T10:15:09Z
      dockerImageReference: 172.30.56.218:5000/test/origin-ruby-sample@sha256:47463d94eb5c049b2d23b03a9530bf944f8f967a0fe79147dd6b9135bf7dd13d
      generation: 2
      image: sha256:909de62d1f609a717ec433cc25ca5cf00941545c83a01fb31527771e1fab3fc5
    - created: 2017-09-01T13:40:11Z
      dockerImageReference: 172.30.56.218:5000/test/origin-ruby-sample@sha256:909de62d1f609a717ec433cc25ca5cf00941545c83a01fb31527771e1fab3fc5
      generation: 1
      image: sha256:47463d94eb5c049b2d23b03a9530bf944f8f967a0fe79147dd6b9135bf7dd13d
    tag: latest
# ...

镜像流标签可以是永久标签或跟踪标签。

  • 永久标签是特定版本的标签,指向特定版本的镜像,例如 Python 3.5。

  • 跟踪标签是参考标签,它跟踪另一个镜像流标签,并且可以更新以更改它们跟踪的镜像,就像符号链接一样。这些新级别不能保证向后兼容。

    例如,Red Hat OpenShift Service on AWS 附带的latest镜像流标签是跟踪标签。这意味着当新级别可用时,latest镜像流标签的使用者会更新到镜像提供的框架的最新级别。指向v3.10latest镜像流标签可以随时更改为v3.11。重要的是要注意,这些latest镜像流标签的行为与 Docker latest标签不同。在这种情况下,latest镜像流标签不指向 Docker 存储库中的最新镜像。它指向另一个镜像流标签,该标签可能不是镜像的最新版本。例如,如果latest镜像流标签指向镜像的v3.10,当发布3.11版本时,latest标签不会自动更新为v3.11,并且保留在v3.10,直到手动更新为指向v3.11镜像流标签。

    跟踪标签仅限于单个镜像流,不能引用其他镜像流。

您可以根据自己的需要创建自己的镜像流标签。

镜像流标签由镜像流名称和标签组成,用冒号分隔。

<imagestream name>:<tag>

例如,要引用前面ImageStream对象示例中的sha256:47463d94eb5c049b2d23b03a9530bf944f8f967a0fe79147dd6b9135bf7dd13d镜像,镜像流标签将是:

origin-ruby-sample:latest

镜像流变更触发器

镜像流触发器允许在新的上游镜像版本可用时自动调用您的构建和部署。

例如,当修改镜像流标签时,可以自动启动构建和部署。这是通过监控特定镜像流标签并在检测到更改时通知构建或部署来实现的。

使用镜像流

以下部分描述如何使用镜像流和镜像流标签。

不要在默认项目中运行工作负载或共享对默认项目的访问权限。默认项目保留用于运行核心集群组件。

以下默认项目被认为是高度特权的:defaultkube-publickube-systemopenshiftopenshift-infraopenshift-node以及其他系统创建的且openshift.io/run-level标签设置为01的项目。依赖于准入插件的功能(例如 Pod 安全准入、安全上下文约束、集群资源配额和镜像引用解析)在高度特权的项目中不起作用。

获取有关镜像流的信息

您可以获取有关镜像流的一般信息以及有关其指向的所有标签的详细信息。

步骤
  • 要获取有关镜像流的一般信息以及有关其指向的所有标签的详细信息,请输入以下命令:

    $ oc describe is/<image-name>

    例如:

    $ oc describe is/python
    示例输出:
    Name:			python
    Namespace:		default
    Created:		About a minute ago
    Labels:			<none>
    Annotations:		openshift.io/image.dockerRepositoryCheck=2017-10-02T17:05:11Z
    Docker Pull Spec:	docker-registry.default.svc:5000/default/python
    Image Lookup:		local=false
    Unique Images:		1
    Tags:			1
    
    3.5
      tagged from centos/python-35-centos7
    
      * centos/python-35-centos7@sha256:49c18358df82f4577386404991c51a9559f243e0b1bdc366df25
          About a minute ago
  • 要获取有关特定镜像流标签的所有可用信息,请输入以下命令:

    $ oc describe istag/<image-stream>:<tag-name>

    例如:

    $ oc describe istag/python:latest
    示例输出:
    Image Name:	sha256:49c18358df82f4577386404991c51a9559f243e0b1bdc366df25
    Docker Image:	centos/python-35-centos7@sha256:49c18358df82f4577386404991c51a9559f243e0b1bdc366df25
    Name:		sha256:49c18358df82f4577386404991c51a9559f243e0b1bdc366df25
    Created:	2 minutes ago
    Image Size:	251.2 MB (first layer 2.898 MB, last binary layer 72.26 MB)
    Image Created:	2 weeks ago
    Author:		<none>
    Arch:		amd64
    Entrypoint:	container-entrypoint
    Command:	/bin/sh -c $STI_SCRIPTS_PATH/usage
    Working Dir:	/opt/app-root/src
    User:		1001
    Exposes Ports:	8080/tcp
    Docker Labels:	build-date=20170801

    输出的信息比显示的更多。

  • 输入以下命令可发现镜像流标签支持的架构或操作系统:

    $ oc get istag <image-stream-tag> -ojsonpath="{range .image.dockerImageManifests[*]}{.os}/{.architecture}{'\n'}{end}"

    例如:

    $ oc get istag busybox:latest -ojsonpath="{range .image.dockerImageManifests[*]}{.os}/{.architecture}{'\n'}{end}"
    示例输出:
    linux/amd64
    linux/arm
    linux/arm64
    linux/386
    linux/mips64le
    linux/ppc64le
    linux/riscv64
    linux/s390x

向镜像流添加标签

您可以向镜像流添加其他标签。

步骤
  • 使用oc tag命令添加指向现有标签之一的标签。

    $ oc tag <image-name:tag1> <image-name:tag2>

    例如:

    $ oc tag python:3.5 python:latest
    示例输出:
    Tag python:latest set to python@sha256:49c18358df82f4577386404991c51a9559f243e0b1bdc366df25.
  • 确认镜像流有两个标签,一个3.5指向外部容器镜像,另一个标签latest指向相同的镜像,因为它基于第一个标签创建。

    $ oc describe is/python
    示例输出:
    Name:			python
    Namespace:		default
    Created:		5 minutes ago
    Labels:			<none>
    Annotations:		openshift.io/image.dockerRepositoryCheck=2017-10-02T17:05:11Z
    Docker Pull Spec:	docker-registry.default.svc:5000/default/python
    Image Lookup:		local=false
    Unique Images:		1
    Tags:			2
    
    latest
      tagged from python@sha256:49c18358df82f4577386404991c51a9559f243e0b1bdc366df25
    
      * centos/python-35-centos7@sha256:49c18358df82f4577386404991c51a9559f243e0b1bdc366df25
          About a minute ago
    
    3.5
      tagged from centos/python-35-centos7
    
      * centos/python-35-centos7@sha256:49c18358df82f4577386404991c51a9559f243e0b1bdc366df25
          5 minutes ago

为外部镜像添加标签

您可以为外部镜像添加标签。

步骤
  • 使用oc tag命令进行所有与标签相关的操作,添加指向内部或外部镜像的标签。

    $ oc tag <repository/image> <image-name:tag>

    例如,此命令将docker.io/python:3.6.0镜像映射到python镜像流中的3.6标签。

    $ oc tag docker.io/python:3.6.0 python:3.6
    示例输出:
    Tag python:3.6 set to docker.io/python:3.6.0.

    如果外部镜像是安全的,则必须创建一个包含访问该注册表凭据的密钥。

更新镜像流标签

您可以更新标签以反映镜像流中的另一个标签。

步骤
  • 更新标签

    $ oc tag <image-name:tag> <image-name:latest>

    例如,以下命令将latest标签更新为反映镜像流中的3.6标签:

    $ oc tag python:3.6 python:latest
    示例输出:
    Tag python:latest set to python@sha256:438208801c4806548460b27bd1fbcb7bb188273d13871ab43f.

删除镜像流标签

您可以从镜像流中删除旧标签。

步骤
  • 从镜像流中删除旧标签

    $ oc tag -d <image-name:tag>

    例如:

    $ oc tag -d python:3.6
    示例输出:
    Deleted tag default/python:3.6

有关集群示例操作员如何处理已弃用的镜像流标签的更多信息,请参阅从集群示例操作员中删除已弃用的镜像流标签

配置镜像流标签的定期导入

在使用外部容器镜像注册表时,要定期重新导入镜像(例如,获取最新的安全更新),可以使用--scheduled标志。

步骤
  1. 安排导入镜像

    $ oc tag <repository/image> <image-name:tag> --scheduled

    例如:

    $ oc tag docker.io/python:3.6.0 python:3.6 --scheduled
    示例输出:
    Tag python:3.6 set to import docker.io/python:3.6.0 periodically.

    此命令使 Red Hat OpenShift Service on AWS 定期更新此特定镜像流标签。此周期是集群范围的设置,默认为 15 分钟。

  2. 删除定期检查,重新运行上述命令但省略--scheduled标志。这会将其行为重置为默认值。

    $ oc tag <repositiory/image> <image-name:tag>

导入和使用镜像和镜像流

以下部分描述如何导入和使用镜像流。

从私有注册表导入镜像和镜像流

可以将镜像流配置为从需要身份验证的私有镜像注册表导入标签和镜像元数据。如果您将集群示例操作员用于提取内容的注册表更改为除registry.redhat.io以外的其他注册表,则此过程适用。

从非安全或安全注册表导入时,密钥中定义的注册表 URL 必须包含:80端口后缀,否则在尝试从注册表导入时不会使用该密钥。

步骤
  1. 您必须通过输入以下命令创建一个用于存储凭据的secret对象

    $ oc create secret generic <secret_name> --from-file=.dockerconfigjson=<file_absolute_path> --type=kubernetes.io/dockerconfigjson
  2. 配置密钥后,创建新的镜像流或输入oc import-image命令

    $ oc import-image <imagestreamtag> --from=<image> --confirm

    在导入过程中,Red Hat OpenShift Service on AWS 会获取密钥并将其提供给远程方。

允许 Pod 引用来自其他安全注册表的镜像

要从其他私有或安全注册表拉取安全容器,您必须从容器客户端凭据(例如 Docker 或 Podman)创建拉取密钥,并将其添加到您的服务帐户。

Docker 和 Podman 都使用配置文件来存储登录安全或非安全注册表的身份验证详细信息

  • Docker:默认情况下,Docker 使用$HOME/.docker/config.json

  • Podman:默认情况下,Podman 使用$HOME/.config/containers/auth.json

如果您以前登录过安全或非安全注册表,这些文件会存储您的身份验证信息。

如果 Docker 和 Podman 凭据文件以及关联的拉取密钥具有唯一路径(例如,quay.ioquay.io/),则它们可以包含对同一注册表的多个引用。但是,Docker 和 Podman 均不支持针对完全相同的注册表路径的多个条目。

config.json文件示例
{
   "auths":{
      "cloud.openshift.com":{
         "auth":"b3Blb=",
         "email":"[email protected]"
      },
      "quay.io":{
         "auth":"b3Blb=",
         "email":"[email protected]"
      },
      "quay.io/repository-main":{
         "auth":"b3Blb=",
         "email":"[email protected]"
      }
   }
}
拉取密钥示例
apiVersion: v1
data:
  .dockerconfigjson: ewogICAiYXV0aHMiOnsKICAgICAgIm0iOnsKICAgICAgIsKICAgICAgICAgImF1dGgiOiJiM0JsYj0iLAogICAgICAgICAiZW1haWwiOiJ5b3VAZXhhbXBsZS5jb20iCiAgICAgIH0KICAgfQp9Cg==
kind: Secret
metadata:
  creationTimestamp: "2021-09-09T19:10:11Z"
  name: pull-secret
  namespace: default
  resourceVersion: "37676"
  uid: e2851531-01bc-48ba-878c-de96cfe31020
type: Opaque
步骤
  • 从现有的身份验证文件创建密钥

    • 对于使用.docker/config.json的 Docker 客户端,请输入以下命令

      $ oc create secret generic <pull_secret_name> \
          --from-file=.dockerconfigjson=<path/to/.docker/config.json> \
          --type=kubernetes.io/dockerconfigjson
    • 对于使用.config/containers/auth.json的 Podman 客户端,请输入以下命令

      $ oc create secret generic <pull_secret_name> \
           --from-file=<path/to/.config/containers/auth.json> \
           --type=kubernetes.io/podmanconfigjson
  • 如果您还没有安全注册表的 Docker 凭据文件,您可以通过运行以下命令创建密钥:

    $ oc create secret docker-registry <pull_secret_name> \
        --docker-server=<registry_server> \
        --docker-username=<user_name> \
        --docker-password=<password> \
        --docker-email=<email>
  • 要使用密钥拉取 Pod 的镜像,您必须将密钥添加到您的服务帐户。此示例中的服务帐户名称应与 Pod 使用的服务帐户名称匹配。默认服务帐户是default

    $ oc secrets link default <pull_secret_name> --for=pull

使用清单列表

使用oc import-imageoc tag CLI 命令时,您可以通过添加--import-mode标志来导入清单列表的单个子清单或所有清单。

请参考以下命令来创建包含单个子清单或多架构镜像的镜像流。

步骤
  • 通过输入以下命令创建包含多架构镜像并设置导入模式为PreserveOriginal的镜像流:

    $ oc import-image <multiarch-image-stream-tag>  --from=<registry>/<project_name>/<image-name> \
    --import-mode='PreserveOriginal' --reference-policy=local --confirm
    示例输出:
    ---
    Arch:           <none>
    Manifests:      linux/amd64     sha256:6e325b86566fafd3c4683a05a219c30c421fbccbf8d87ab9d20d4ec1131c3451
                    linux/arm64     sha256:d8fad562ffa75b96212c4a6dc81faf327d67714ed85475bf642729703a2b5bf6
                    linux/ppc64le   sha256:7b7e25338e40d8bdeb1b28e37fef5e64f0afd412530b257f5b02b30851f416e1
    ---
  • 或者,输入以下命令使用Legacy导入模式导入镜像,此模式会丢弃清单列表并导入单个子清单:

    $ oc import-image <multiarch-image-stream-tag>  --from=<registry>/<project_name>/<image-name> \
    --import-mode='Legacy' --confirm

    --import-mode=的默认值为Legacy。不包含此值,或未指定LegacyPreserveOriginal,都会导入单个子清单。无效的导入模式将返回以下错误:error: valid ImportMode values are Legacy or PreserveOriginal

限制

使用清单列表具有以下限制

  • 在某些情况下,用户可能希望直接使用子清单。运行oc adm prune imagesCronJob修剪程序时,它们无法检测到何时使用了子清单列表。因此,使用oc adm prune imagesCronJob修剪程序的管理员可能会删除整个清单列表,包括子清单。

    为了避免此限制,您可以改用标签或摘要来使用清单列表。

配置清单列表的定期导入

要定期重新导入清单列表,可以使用--scheduled标志。

步骤
  • 输入以下命令设置镜像流以定期更新清单列表:

    $ oc import-image <multiarch-image-stream-tag>  --from=<registry>/<project_name>/<image-name> \
    --import-mode='PreserveOriginal' --scheduled=true

导入清单列表时配置 SSL/TSL

要导入清单列表时配置 SSL/TSL,可以使用--insecure标志。

步骤
  • 设置--insecure=true,以便导入清单列表时跳过 SSL/TSL 验证。例如:

    $ oc import-image <multiarch-image-stream-tag> --from=<registry>/<project_name>/<image-name> \
    --import-mode='PreserveOriginal' --insecure=true

为 --import-mode 指定架构

您可以通过排除或包含--import-mode=标志来在多架构和单架构之间切换导入的镜像流。

步骤
  • 运行以下命令通过排除--import-mode=标志将镜像流从多架构更新为单架构:

    $ oc import-image <multiarch-image-stream-tag> --from=<registry>/<project_name>/<image-name>
  • 运行以下命令将镜像流从单架构更新为多架构:

    $ oc import-image <multiarch-image-stream-tag>  --from=<registry>/<project_name>/<image-name> \
    --import-mode='PreserveOriginal'

--import-mode 的配置字段

下表描述了--import-mode=标志可用的选项

参数 描述

Legacy

--import-mode的默认选项。指定此选项时,将丢弃清单列表,并导入单个子清单。平台的选择顺序如下:

  1. 标签注释

  2. 控制平面架构

  3. Linux/AMD64

  4. 列表中的第一个清单

PreserveOriginal

指定此选项时,将保留原始清单。对于清单列表,将导入清单列表及其所有子清单。