IBM Cloud Docs
设置映像注册表

设置映像注册表

Red Hat® OpenShift® on IBM Cloud® 集群包含内部注册表,用于在本地构建、部署和管理容器映像。 要使专用注册表能够管理和控制对整个企业中映像的访问权,您还可以将集群设置为使用 IBM Cloud® Container Registry。

选择映像注册表解决方案

您的容器镜像必须存储在集群可访问的容器注册表中,以便将应用程序部署到集群中。 您可以选择使用集群 Red Hat OpenShift 的内置注册表、仅限特定用户访问的私有注册表,或公共注册表。 查看下表以选择适合您用例的最佳选项。

内部 Red Hat OpenShiftContainer Registry (OCR)

您的集群已配置为内部模式 Container RegistryRed Hat OpenShift,以便 Red Hat OpenShift 能够在集群内部自动构建、部署和管理应用程序生命周期。 图像存储在集群创建时分配的后端 IBM Cloud 经典文件存储设备中。 如果需要更多存储空间,可以调整该设备的大小。 用例:

  • Red Hat OpenShift-原生映像流、构建及应用部署流程(按集群为单位)。
  • 映像可以在集群中的所有项目之间共享,其中访问权通过 RBAC 角色进行控制。
  • 将内部注册表与其他 Red Hat 产品集成,CloudForms 以实现漏洞扫描等扩展功能。
  • 用于通过路由公开内部注册表的选项,以便用户可以通过公用网络从注册表中拉取映像。
  • 用于设置内部注册表以从专用注册表 (例如 IBM Cloud Container Registry) 拉取映像推送映像 的选项。

有关更多信息,请参阅使用内部注册表

专用注册表

专用注册表是保护映像免受未经授权的用户的良好选择。 专用注册表必须由集群管理员设置,以确保访问权、存储配额、映像信任和其他功能按预期工作。 缺省情况下,Red Hat OpenShift 集群 通过 default 项目中的映像拉取私钥与专用 IBM Cloud Container Registry 集成。IBM Cloud Container Registry 是一个高可用性的多租户专用注册表,用于存储您自己的映像。 您还可以从全局 icr.io 注册表中拉取 IBM 提供的映像,并从授权注册表中获取经许可的软件。 通过 IBM Cloud Container Registry,您可以管理多个集群的图像,并集成 IAM 和 IBM Cloud 计费功能。 将 IBM Cloud Container Registry 与内部注册表配合使用的优点:

  • 通过内部注册表进行本地映像高速缓存以实现更快的构建。
  • 其他项目中的部署可以看到映像流,因此您不必将拉取私钥复制到每个项目。
  • 跨多个集群共享映像,而无需将映像推送到多个注册表。
  • 自动扫描映像漏洞。
  • 通过 IBM Cloud IAM 策略单独的区域注册表来控制访问权。
  • 保留映像,而无需占用集群或连接的存储设备中的存储空间。 您还可以设置策略来管理映像数量,以防止映像占用的空间太多。
  • VPC 基础结构: 使用专用注册表服务端点,以便仅使用专用云服务端点的集群仍可访问注册表。
  • 设置存储和映像拉取流量配额,以更好地控制映像的存储、使用和计费。
  • 授权注册表中拉取获得许可的 IBM 内容。

首先,请参阅以下主题:

公共注册表

公共注册表(如 Docker Hub)是跨团队、公司、集群或云服务提供商共享图像的一种方式。 一些公共注册表还可能会提供专用注册表组件。 用例:

  • 在公用网络上推送和拉取映像。
  • 跨云服务提供商的容器快速测试。
  • 不需要企业级功能,例如漏洞扫描或访问管理。

有关更多信息,请参阅公共注册表的文档,例如 QuayDocker Hub。

将图像存储在内部注册表中

Red Hat OpenShift 集群默认具有内部注册表。 内部注册表中的映像已备份,但具体情况因集群 Red Hat OpenShift on IBM Cloud 的基础设施提供商而异。

经典集群
缺省情况下,使用使用 File Storage for Classic 作为支持存储器的内部注册表来设置 Red Hat OpenShift 集群。 删除集群时,还将删除内部注册表及其映像。 若需持久化镜像,可考虑使用私有注册表( IBM Cloud Container Registry 如)、将镜像备份至持久化存储( Object Storage 如),或创建独立 Red Hat OpenShift 的容器注册表(OCR)集群。 有关更多信息,请参阅 Red Hat OpenShift 文档
VPC 集群
Red Hat OpenShift 集群的内部注册表将映像备份到帐户中的 IBM Cloud Object Storage 实例中自动创建的存储区。 即使删除集群,也会保留 Object Storage 存储区中存储的任何数据。
经典集群,VPC 集群或 Satellite 集群
您可以选择设置内部注册表以将数据存储在运行内部注册表 pod 的工作程序节点的 emptyDir 中。 请记住,此数据不是持久数据,如果重新启动 pod 或工作程序节点,那么将删除存储的数据并且不可恢复。 如果您定期从大型映像构建容器,那么可以将这些映像存储在 emptyDir 本地以提高性能。

将内部映像注册表备份到 IBM Cloud Object Storage

虚拟私有云

您 Red Hat OpenShift 集群内部注册表中的图像会自动备份到一个 IBM Cloud Object Storage 存储桶中。 即使删除集群,也会保留 Object Storage 存储区中存储的任何数据。

但是,如果在创建集群时存储区未能创建,那么必须手动创建存储区并将集群设置为使用该存储区。 同时,内部注册表使用 emptyDir Kubernetes 卷,该卷将容器映像存储在工作程序节点的辅助磁盘上。 emptyDir 卷不会被视为持久高可用性存储器,如果删除使用该映像的 pod,那么将自动删除该映像。

要为内部注册表手动创建存储区,请参阅 集群创建有关云对象存储区的错误

在经典集群中的内部注册表中存储映像

默认情况下,集群 Red Hat OpenShift 的内部注册表使用 File Storage for ClassicIBM Cloud 卷来存储注册表镜像。 可以查看存储卷的缺省大小,或者更新卷大小。

查看卷详细信息

要查看卷详细信息(包括存储类和大小),可以描述持久卷声明。

oc describe pvc -n openshift-image-registry image-registry-storage

更改卷详细信息

如果注册表需要更多千兆字节的存储空间来存储映像,那么可以调整文件存储器卷的大小。 有关更多信息,请参阅更改现有存储设备的大小和 IOPS。 调整 IBM Cloud 基础架构帐户中的卷大小时,不会更新连接的 PVC 描述。 相反,您可以登录使用 registry-backingopenshift-image-registry PVC的Pod来验证卷是否已调整大小。

将映像存储在工作程序节点空目录中

如果您定期从大型映像构建容器,那么可以将内部注册表映像本地存储在工作程序节点 (例如裸机工作程序节点) 的 emptyDir 中,以提高性能。

请记住,此数据不是持久数据,如果重新启动 pod 或工作程序节点,那么将删除存储的数据并且不可恢复。

  1. 访问 Red Hat OpenShift 集群
  2. 更新映像注册表操作程序 configmap 以将存储器设置为使用工作程序节点的 emptyDir。 请注意,更新 configmap 以使用 emptyDir 不会 除去映像注册表的原始 PVC。
    oc patch configs.imageregistry.operator.openshift.io/cluster --type merge --patch '{"spec":{"storage":{"emptyDir":{}}}}'
    
  3. 如果 映像注册表操作员管理状态 设置为 Unmanaged,例如在 Satellite 集群中,请将管理状态更新为 Managed。 现在,操作程序将更新内部注册表 pod。
    oc patch configs.imageregistry.operator.openshift.io/cluster --type merge -p '{"spec":{"managementState":"Managed"}}'
    
  4. 获取内部注册表 pod 的详细信息,以便您可以验证更新。
    1. 检查 image-registry pod 是否正在运行,以及 pod 是否在集群中的每个工作程序节点上运行。

      oc get pods -n openshift-image-registry
      

      示例输出

      NAME                                               READY   STATUS    RESTARTS   AGE
      cluster-image-registry-operator-695bf78ffc-zvkhd   2/2     Running   0          33m
      image-registry-6774598589-65cnx                    1/1     Running   0          112s
      node-ca-gg66r                                      1/1     Running   0          113s
      node-ca-n8jpq                                      1/1     Running   0          113s
      node-ca-p2d7j                                      1/1     Running   0          113s
      
    2. 获取运行 image-registry pod 的 Node 的公共 IP 地址。

      oc describe pod -n openshift-image-registry <image-registry-pod> | grep Node
      

      示例输出

      Node:               169.xx.xxx.xxx/169.xx.xxx.xxx
      

      如果工作程序节点 IP 地址是专用的,请运行 ibmcloud oc worker ls -c <cluster> | grep <private_IP> 并记下相应的公共 IP 地址。

    3. 获取 pod YAML 中 metadata.uid 部分中 image-registry pod 的 UID (而不是 metadata.ownerReferences.uid 部分中副本集的 UID)。

      oc get pod -n openshift-image-registry <image-registry-pod> -o yaml
      

      示例输出

      apiVersion: v1
      kind: Pod
      metadata:
          uid: e8d7718d-b0bd-47e2-9aaa-05f3a608fd9b
      ...
      
  5. 验证内部注册表是否将数据存储到工作程序节点的 emptyDir
    1. 使用先前检索的工作程序节点 直接从集群访问注册表。 遵循步骤将测试映像推送到内部注册表。

      要完成文档 Red Hat OpenShift 中的这些步骤,您需要使用 podman 命令行工具。 缺省情况下,工作程序节点可能没有此 CLI 工具。 请参阅 Podman 安装指南以了解可用的RHEL版本。

    2. 浏览至保存到 emptyDir 的内部注册表 pod 文件夹。 对于 <pod_uid>,请使用先前检索的 pod UID

      cd var/lib/kubelet/pods/<pod_uid>/volumes/kubernetes.io~empty-dir/registry-storage/docker/registry/v2/repositories/openshift
      
    3. 验证映像是否在存储库目录中。

      ls
      

      示例输出

      <myimage>  nginx  ...
      

除去内部映像注册表

虚拟私有云

图像注册表操作员部署仅存在于工具包管理的 Red Hat OpenShift on IBM Cloud 集群中。 HyperShift 托管集群在控制平面中运行镜像注册表操作员。

如果您不想使用内部映像注册表,那么可以完成以下步骤以将其除去。

  1. 保存内部注册表配置的副本。
    oc get configs.imageregistry.operator.openshift.io cluster -o yaml > configs.yaml
    
  2. 运行以下补丁命令以将映像注册表的管理状态更改为 Removed
    kubectl patch configs.imageregistry.operator.openshift.io cluster -p '{"spec":{"managementState":"Removed"}}' --type='merge'
    
  3. 更改管理状态后,将从集群中的 openshift-image-registry 名称空间中除去映像注册表服务和部署。 您可以运行以下命令来验证是否已除去这些命令。 请注意,仅会除去映像注册表部署和服务。 将保留映像注册表操作程序部署和服务。
    oc get deployment -n openshift-image-registry
    
    oc get svc -n openshift-image-registry
    

为内部注册表设置安全的外部路径

默认情况下,您的 Red Hat OpenShift 集群拥有一个内部注册表,可通过具有内部IP地址的服务访问。 如果要使内部注册表在公用网络上可用,可以设置安全的重新加密路径。 例如,可以将集群的内部注册表设置为充当其他项目或集群中的部署的公共注册表。

开始之前:

要使用内部注册表,请设置用于访问此注册表的公共路径。 然后,创建包含用于访问此注册表的凭证的映像拉取私钥,以便其他项目中的部署可以从此注册表中拉取映像。

  1. 从项目 openshift-image-registry 中,确保该 image-registry 服务在内部注册表中存在。

    oc get svc -n openshift-image-registry
    

    示例输出

    NAME                      TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
    image-registry            ClusterIP      172.21.xxx.xxx    <none>          5000/TCP                     36d
    image-registry-operator   ClusterIP      None             <none>          60000/TCP                     36d
    
  2. 为使用 reencrypt TLS终止的服务 image-registry 创建一条安全路由。 通过重新加密,路由器会使用一个证书终止 TLS 连接,然后使用其他证书来重新加密与内部注册表的连接。 通过这种方法,将加密用户和内部注册表之间的连接的完整路径。 若要使用您自己的自定义域名,请包含 选项 --hostname

    oc create route reencrypt --service=image-registry -n openshift-image-registry
    
  3. 检索分配给 image-registry 该路由的主机名( HOST/PORT )和端口( PORT )。

    oc get route image-registry -n openshift-image-registry
    

    示例输出

    NAME              HOST/PORT                                                                                                  PATH      SERVICES          PORT       TERMINATION   WILDCARD
    image-registry   image-registry-openshift-image-registry.<cluster_name>-<ID_string>.<region>.containers.appdomain.cloud             image-registry   5000-tcp   reencrypt     None
    
  4. 编辑路由以将 负载均衡策略设置为 source,使相同的客户端IP地址到达相同的服务器,如同直通路由配置那样。 可以通过在 metadata.annotations 部分中添加注释 haproxy.router.openshift.io/balance: source 来设置该策略。 您可以通过应用程序 Red Hat OpenShift 控制台或在命令行中运行以下命令来编辑配置文件。

    oc edit route image-registry -n openshift-image-registry
    

    添加注释。

    apiVersion: route.openshift.io/v1
    kind: Route
    metadata:
    annotations:
        haproxy.router.openshift.io/balance: source
    ...
    
  5. 如果企业网络策略阻止通过代理或防火墙从本地系统访问公共端点,那么 允许访问您在以下步骤中为内部注册表创建的路由子域

  6. 使用与主机名相同的路径登录到内部注册表。

    docker login -u $(oc whoami) -p $(oc whoami -t) image-registry-openshift-image-registry.<cluster_name>-<ID_string>.<region>.containers.appdomain.cloud
    
  7. 既然您已登录,现在可尝试将样本 hello-world 应用程序推送到内部注册表。

    1. 从 DockerHub 中拉取 hello-world 映像,或在本地计算机上构建映像。

      docker pull hello-world
      
    2. 使用内部注册表的主机名、要将映像部署到的项目以及映像名称和标记来标记本地映像。

      docker tag hello-world:latest image-registry-openshift-image-registry.<cluster_name>-<ID_string>.<region>.containers.appdomain.cloud/<project>/<image_name>:<tag>
      
    3. 将映像推送到集群的内部注册表。

      docker push image-registry-openshift-image-registry.<cluster_name>-<ID_string>.<region>.containers.appdomain.cloud/<project>/<image_name>:<tag>
      
    4. 验证图像是否已添加到图像 Red Hat OpenShift 流中。

      oc get imagestream
      

      示例输出

      NAME          DOCKER REPO                                                            TAGS      UPDATED
      hello-world   image-registry-openshift-image-registry.svc:5000/default/hello-world   latest    7 hours ago
      
  8. 要支持项目中的部署从内部注册表中拉取映像,请在项目中创建映像拉取私钥,以保存用于访问内部注册表的凭证。 然后,将映像拉取私钥添加到每个项目的缺省服务帐户。

    1. 列出缺省服务帐户使用的映像拉取私钥,并记下以 default-dockercfg 开头的私钥。

      oc describe sa default
      

      示例输出

      ...
      Image pull secrets:
      all-icr-io
      default-dockercfg-mpcn4
      ...
      
    2. 从配置文件的 data 字段中获取已编码的私钥信息。

      oc get secret <default-dockercfg-name> -o yaml
      

      示例输出

      apiVersion: v1
      data:
        .dockercfg: ey...=
      
    3. data 字段的值进行解码。

      echo "<ey...=>" | base64 -D
      

      示例输出

      {"172.21.xxx.xxx:5000":{"username":"serviceaccount","password":"eyJ...
      
    4. 为内部注册表创建新的映像拉取私钥。

      • secret_name 为您的图像拉取密钥命名,例如 internal-registry.
      • --namespace 请输入要创建镜像拉取密钥的项目,例如 default
      • --docker-server 请将内部服务IP地址(172.21.xxx.xxx:5000)替换为主机名,并添加路由 image-registry 及端口(image-registry-openshift-image-registry.<cluster_name>-<ID_string>.<region>.containers.appdomain.cloud:5000)。
      • --docker-username 复制上张图片中的 "username" 拉取密钥,例如 serviceaccount
      • --docker-password 复制上图中的 "password" 拉取密钥。
      • --docker-email: 如有,请输入您的 Docker 电子邮箱地址。 如果没有,请输入一个虚构的电子邮件地址,例如 a@b.c。 此电子邮件对于创建 Kubernetes 私钥是必需的,但在创建后不会再使用此电子邮件。
      oc create secret docker-registry internal-registry --namespace default --docker-server image-registry-openshift-image-registry.<cluster_name>-<ID_string>.<region>.containers.appdomain.cloud:5000 --docker-username serviceaccount --docker-password <eyJ...> --docker-email a@b.c
      
    5. 将映像拉取私钥添加到项目的 default 服务帐户。

      oc patch -n <namespace_name> serviceaccount/default --type='json' -p='[{"op":"add","path":"/imagePullSecrets/-","value":{"name":"<image_pull_secret_name>"}}]'
      
    6. 针对要从内部注册表中拉取映像的每个项目,重复上述步骤。

既然您已为内部注册表设置了可访问的路径,接下来就可以登录到注册表,将映像推送到注册表以及从注册表中拉取映像。 有关更多信息,请参阅 Red Hat OpenShift 文档

将映像从 IBM Cloud Container Registry 导入内部注册表映像流

默认情况下,您的 Red Hat OpenShift on IBM Cloud 集群配置为从项目 default 中的远程私有 icr.ioIBM Cloud Container Registry 域拉取镜像。 您可以通过将镜像标记为 镜像流,将其从 导入到 集群 Red Hat OpenShiftIBM Cloud Container Registry 的内部注册表中。 通过此设置,您可以使用内部注册表的本地高速缓存从映像部署应用程序,这可使应用程序部署构建速度更快。 此外,其他项目的部署可以引用该镜像流,这样您就不必在每个项目 IBM Cloud Container Registry 中创建镜像拉取密钥凭证。

若您在 IBM Cloud Container Registry 中更新映像,该映像不会自动拉取至您 Red Hat OpenShift 集群的内部注册表。 而是 配置定期导入,或者重复这些步骤来标记映像。 根据您在部署中使用的映像拉取策略,您可能还需要重新启动部署。

想要了解有关构建,映像流和内部注册表如何协同工作的更多信息? 阅读 文档 Red Hat OpenShift,或查看 这篇关于管理容器镜像的博客

  1. 访问 Red Hat OpenShift 集群

  2. 切换到 default 项目以将映像拉入映像流。 已使用凭证设置 default 项目以访问 icr.io 注册表。

    oc project default
    
  3. 列出 IBM Cloud Container Registry中的可用映像。 请注意要拉入 Red Hat OpenShift 集群内部注册表的映像的 存储库标记

    ibmcloud cr images
    
  4. 标记映像,以将其作为映像流从 IBM Cloud Container Registry 名称空间拉入内部注册表。 有关更多信息,请参阅 Red Hat OpenShift 文档 或运行 oc tag --help

    oc tag <region>.icr.io/<namespace>/<image>:<tag> default/<image>:<tag> --reference-policy=local [--scheduled]
    
    • <region>.icr.io/<namespace>/<image>:<tag>:使用先前检索到的存储库标记信息完成 IBM Cloud Container Registry 区域、命名空间、图像和要提取的图像的标记名称。
    • default/<image>:<tag>: 输入从 IBM Cloud Container Registry 标记的映像创建的内部映像流的信息。 在 default 项目中创建此映像流,如果未指定项目,那么该项目也是创建映像流的项目。 <image>:<tag> 的值通常与先前检索的值相匹配。
    • --reference-policy=local: 将此值设置为 local,以便将来自 IBM Cloud Container Registry 的映像副本导入到内部注册表的本地高速缓存中,并将其作为映像流提供给集群的项目。 如果不包含此值,那么当您在部署中使用映像流时,该映像流将返回到 IBM Cloud Container Registry,因此需要项目中的凭证。
    • --scheduled: 设置此可选选项以设置将映像从 IBM Cloud Container Registry 定期导入到内部注册表中。 默认频率为15分钟。 有关更多信息,请参阅 Red Hat OpenShift 文档
  5. 验证是否已创建映像流。

    oc get imagestreams
    
  6. 验证映像流是否已成功从 IBM Cloud Container Registry中拉取映像。 在输出中,检查 最新标记自 映像是否与 * <region>.icr.io/<namespace>/<image>@<digest> 映像匹配。

    oc describe is/<imagestream>
    

    示例输出

    NAME:            <imagestream>
    Namespace:        default
    Created:        2 days ago
    Labels:            <none>
    Annotations:        openshift.io/image.dockerRepositoryCheck=2020-03-31T09:41:36Z
    Image Repository:    image-registry.openshift-image-registry.svc:5000/default/ant1
    Image Lookup:        local=false
    Unique Images:        1
    Tags:                1
    
    latest
        tagged from <region>.icr.io/<namespace>/<image>:<tag>
    
        * <region>.icr.io/<namespace>/<image>@<digest>
            2 days ago
    

现在,开发者可以 在应用程序部署中使用映像流。 映像已成功从内部注册表中本地拉取的映像进行构建。 您不需要将项目中的映像拉取私钥设置为 IBM Cloud Container Registry,因为映像流是集群的本地映像流。

在内部注册表中设置构建以将映像推送到 IBM Cloud Container Registry

在 Red Hat OpenShift on IBM Cloud 集群中 创建构建时,您可以配置内部注册表,将镜像推送到外部存储库。IBM Cloud Container Registry 默认情况下,集群 default 项目中的镜像拉取密钥仅具有从拉取镜像的读取 IBM Cloud Container Registry 权限。 要推送映像,必须添加具有写访问权的私钥。

  1. 访问 Red Hat OpenShift 集群

  2. 切换到该项目 default

    oc project default
    
  3. 遵循设置 IBM Cloud IAM API 密钥的步骤 具有 ReaderWriter 服务访问角色,可从 icr.io 注册表中提取映像并将其推送到注册表。

    请记住,有权访问项目的任何用户都可以使用此私钥将映像推送到专用注册表。 您可能想要设置 日志记录和监视 工具,以便可以观察谁在集群中执行哪些操作。

  4. 对要将映像推送到的每个 icr.io 区域重复上一步。

  5. 将私钥添加到构建服务帐户,并引用构建配置文件中的私钥。 有关更多信息,请参阅 Red Hat OpenShift 文档

    1. 通过将刚刚创建的私钥链接到集群中使用的所有构建的 builder 角色,将该私钥添加到构建服务帐户。

      oc secrets link builder <secret_name>
      
    2. 列出构建配置,并记下要授予对 IBM Cloud Container Registry的推送和拉取访问权的配置。

      oc get bc
      
    3. 设置构建配置的映像推送私钥,以使用您刚刚通过 Writer 服务访问权 IBM Cloud Container Registry创建的私钥。

      oc set build-secret --push bc/<build_config_name> <secret_name>
      
    4. 设置要从要从中拉取初始构建映像的注册表拉取的构建配置的映像拉取私钥。 例如,如果源映像位于 IBM Cloud Container Registry 存储库中,那么您可以使用刚刚通过 Reader 服务访问 IBM Cloud Container Registry 创建的私钥。

      oc set build-secret --pull bc/<build_config_name> <secret_name>
      
  6. 更新构建服务帐户和构建配置文件以推送到 IBM Cloud Container Registry之后,请重新启动构建。

    oc start-build <build_name>
    
  7. 获取构建 pod 的名称,例如 <build>-2-build

    oc get pods
    
  8. 检查构建的日志,并记下推送映像的位置。

    oc logs <build_pod>
    

    成功的映像推送日志的示例。

    ...
    Successfully pushed <region>.icr.io/<namespace>/<build_name>@sha256:<hash>
    Push successful
    
  9. 请检查专用注册表中的映像,以确认是否已创建该映像。

    ibmcloud cr image list
    

    示例输出

    Repository                                Tag       Digest     Namespace     Created         Size     Security status   
    <region>.icr.io/<namespace>/<build_name>  latest    <digest>   <namespace>   2 minutes ago   182 MB   33 Issues  
    

现在,您的 Red Hat OpenShift 构建可以将映像从 IBM Cloud Container Registry拉取并推送到映像。

使用 IBM Cloud Container Registry

默认情况下,您的 Red Hat OpenShift on IBM Cloud 集群配置为从项目 default 中的远程私有 icr.ioIBM Cloud Container Registry 域拉取镜像。 若需在其他项目中使用 IBM Cloud Container Registry 存储于中的镜像,可将镜像通过镜像流拉取至内部注册表,或为每个项目中的全局及区域注册表创建镜像拉取密钥。

要将映像导入到内部注册表中: 请参阅 将映像从 IBM Cloud Container Registry 导入到内部注册表映像流中

直接从外部 IBM Cloud Container Registry 中拉取映像: 请参阅以下主题。

了解如何授权集群从私有注册表拉取镜像

为了从注册表中拉取映像,Red Hat OpenShift on IBM Cloud 集群会使用一种特殊类型的 Kubernetes 私钥,即 imagePullSecret。 此映像拉取私钥存储了用于访问容器注册表的凭证。

容器注册表可以是:

  • 您自己的 IBM Cloud Container Registry中的专用名称空间。
  • IBM Cloud Container Registry 中属于其他 IBM Cloud 帐户的专用名称空间。
  • 任何其他专用注册表,例如 Docker。

但是,缺省情况下,集群设置为仅从 IBM Cloud Container Registry中的帐户名称空间拉取映像,并将容器从这些映像部署到集群中的 default Red Hat OpenShift 项目。 如果需要在集群的其他项目中或从其他容器注册表中拉取映像,那么必须设置自己的映像拉取私钥。

缺省映像拉取私钥设置

通常,您的 Red Hat OpenShift on IBM Cloud 集群仅设置为从 Red Hat OpenShiftdefault 项目中的所有 icr.ioIBM Cloud Container Registry 域拉取镜像。 请查阅以下常问问题解答,了解如何从其他 Red Hat OpenShift 项目或账户拉取镜像、限制拉取权限,或为何您的集群可能缺少默认镜像拉取密钥。

我的集群如何配置才能从项目 Red Hat OpenShiftdefault 中拉取镜像?
创建集群时,集群会具有 IBM Cloud IAM 服务标识,此标识已被授予对 IBM Cloud Container Registry 的 IAM 读取者服务访问角色策略。 在存储于集群的映像拉取私钥中的非到期 API 密钥中,会模拟服务标识凭证。 图像提取密钥已添加至命名 Kubernetesdefault 空间,并纳入该项目 Red Hat OpenShift 服务 default 账户的密钥列表。 通过使用映像拉取私钥,部署可以从 全局和区域 IBM Cloud Container Registry 拉取映像 (只读访问),以在 default Red Hat OpenShift 项目中部署容器。
  • 全局注册表安全地存储 IBM提供的公共映像。 您可以在部署中引用这些公共映像,而不是对存储在每个区域注册表中的映像具有不同的引用。
  • 区域注册表用于安全地存储您自己的专用 Docker 映像。
如果我在 default Red Hat OpenShift 项目中没有映像拉取私钥怎么办?
您可以通过 登录到集群 并运行 oc get secrets -n default | grep "icr-io" 来检查映像拉取私钥。 如果未列出 icr 私钥,那么创建集群的人员可能没有对 IAM 中的 IBM Cloud Container Registry 的必需许可权。 请参阅《 更新现有集群以使用 API 密钥镜像拉取密钥 》。
能否限制从特定区域注册库的拉取访问?
可以,可以编辑服务标识的现有 IAM 策略,以将读取者服务访问角色限制为只能访问该区域注册表或注册表资源(例如,名称空间)。 必须为 IBM Cloud 启用 IBM Cloud Container Registry IAM 策略后,才能定制注册表 IAM 策略。

想要让您的注册表凭据更加安全?请让集群管理员在集群中 启用密钥管理服务提供商,以加密集群中的 Kubernetes 机密信息——例如存储注册表凭据的镜像拉取密钥。

我能否在除 default 以外的 Red Hat OpenShift 项目中拉取映像?
缺省情况下不能。 通过使用默认集群配置,您可以将存储在命名 IBM Cloud Container Registry 空间中的任意镜像部署为容器,并将其部署到集群的项目 Red Hat OpenShiftdefault 中。 若需在其他 Red Hat OpenShift 项目或账户 IBM Cloud 中使用这些图像 ,您可选择复制或创建专属的图像提取密钥
我可以从其他 IBM Cloud 账户提取图片吗?
可以,在要使用的 IBM Cloud 帐户中创建 API 密钥。 然后,在要从 IBM Cloud 帐户中提取映像的每个集群的每个项目中,创建保存 API 密钥的私钥。 如需了解更多信息 ,请参考此示例,该示例使用了经过授权的服务ID API密钥

要使用非 IBM Cloud 注册表(如 Docker),请参阅访问存储在其他专用注册表中的映像

API密钥是否需要对应服务ID? 如果我的账户达到服务ID的上限会怎样?
缺省集群设置会创建服务标识,用于将 IBM Cloud IAM API 密钥凭证存储在映像拉取私钥中。 但是,您还可以为单个用户创建 API 密钥,并将这些凭证存储在一个映像拉取私钥中。 若达到 服务ID的IAM配额限制,集群将无法创建服务ID和镜像拉取密钥,默认情况下无法从注册 icr.io 域拉取镜像。 您必须创建自己的映像拉取私钥,但创建时须使用单个用户(例如功能标识,而不是 IBM Cloud IAM 服务标识)的 API 密钥。
我看到区域注册表域和所有注册表域的映像拉取私钥。 我使用哪一个?
先前,Red Hat OpenShift on IBM Cloud 为每个区域公共 icr.io 注册表域创建了单独的映像拉取私钥。 现在,所有区域的所有公共和专用 icr.io 注册表域都存储在集群的 default Kubernetes 项目中自动创建的单个 all-icr-io 映像拉取私钥中。

对于集群中其他 Kubernetes 名称空间中用于从专用注册表拉取容器映像的工作负载,现在只能将 all-icr-io 映像拉取私钥复制到该 Kubernetes 项目。 然后,在服务帐户或部署中指定 all-icr-io 私钥。 您无需再复制与映像的区域注册表匹配的映像拉取私钥。 此外,请记住,对于不需要认证的公共注册表,您不需要映像拉取私钥。

在 Red Hat OpenShift 另一个项目中复制或创建图像提取密钥后,我是否就完成了?
还没完。 容器必须有权使用所创建的私钥来拉取映像。 可以将映像拉取私钥添加到该名称空间的服务帐户,或者在每个部署中引用此私钥。 有关指示信息,请参阅使用映像拉取私钥部署容器

icr.io 注册表的专用网络连接

当您设置账户 IBM Cloud 以使用服务端点时,可通过私有网络连接向推送镜像,并从拉取镜像 IBM Cloud Container Registry。

我需要执行哪些操作来设置集群以使用与 icr.io 注册表的专用连接?

  1. 为 IBM Cloud 基础架构帐户启用 虚拟路由器功能(VRF),以便您可以使用 IBM Cloud Container Registry 私有云服务端点。 要启用 VRF,请参阅 启用 VRF。 要检查是否已启用 VRF,请使用 ibmcloud account show 命令。
  2. 启用 IBM Cloud 帐户以使用服务端点

IBM Cloud Container Registry 自动使用私有云服务端点。 您无需为 Red Hat OpenShift on IBM Cloud 集群启用私有云服务端点。

更新现有集群以使用 API 密钥映像拉取私钥

新的 Red Hat OpenShift on IBM Cloud 集群将API密钥存储在 镜像拉取密钥 中,用于授权访问 IBM Cloud Container Registry。 使用这些映像拉取私钥时,可以通过存储在 icr.io 注册表域中的映像来部署容器。 如果未使用私钥创建集群,那么可以将映像拉取私钥添加到集群。

准备工作

  1. 访问 Red Hat OpenShift 集群

  2. 确保您具有以下许可权: IBM Cloud IAM 操作员或管理员 平台访问角色 Red Hat OpenShift on IBM Cloud。 账户所有者可通过执行以下命令授予您该角色。

    ibmcloud iam user-policy-create EMAIL --service-name containers-kubernetes --roles "Administrator,Operator"
    
  3. IBM Cloud IAM 管理员平台访问角色,IBM Cloud Container Registry 适用于所有区域和资源组。 该策略无法限定在特定区域或资源组内生效。 账户所有者可通过执行以下命令授予您该角色。

    验证密钥是否创建成功

    ibmcloud iam user-policy-create <your_user_email> --service-name container-registry --roles Administrator
    
  4. 如果帐户 限制服务标识创建,请在控制台 (API 或 CLI 中的 iam-identity ) 中将 服务标识创建者 角色添加到 Identity and Access Management

  5. 如果帐户 限制 API 密钥创建,请在控制台 (API 或 CLI 中的 iam-identity ) 中将 用户 API 密钥创建者 角色添加到 Identity and Access Management

更新映像拉取私钥

在 namespace defaultKubernetes 中更新集群映像拉取密钥。

  1. 获取集群标识。

    ibmcloud oc cluster ls
    
  2. 运行以下命令以创建集群的服务标识,并为该服务标识分配 IBM Cloud Container Registry的 IAM 读者 服务访问角色。 此命令还会创建 API 密钥以模拟服务标识凭证,并将 API 密钥存储在集群中的 Kubernetes 映像拉取私钥中。 图像拉取密钥位于项目 Red Hat OpenShiftdefault 中。

    ibmcloud oc cluster pull-secret apply --cluster <cluster_name_or_ID>
    

    运行此命令时,IAM 凭证和映像拉取私钥的创建操作将启动,并且可能需要一些时间才能完成。 在创建镜像拉取密钥之前,您无法部署从域 icr.ioIBM Cloud Container Registry 中拉取镜像的容器。

  3. 验证是否在集群中创建了映像拉取私钥。

    oc get secrets | grep icr-io
    

    示例输出

    all-icr-io           kubernetes.io/dockerconfigjson        1         16d
    
  4. 更新 容器部署 以从 icr.io 域名中提取映像。

  5. 可选:如果您有防火墙,请确保对于使用的域,允许出站网络流量流至注册表子网

  6. 使用下列其中一个选项来完成设置。

使用图像提取密钥访问外部私有注册表中的图像

在集群中设置专属镜像拉取密钥,即可将容器部署到除项目外的 Red Hat OpenShift 其他项目,使用存储在其他 IBM Cloud 账户中的 default 镜像,或使用存储在外部私有注册表中的镜像。 此外,您还可以创建自己的映像拉取私钥来应用 IAM 访问策略,以将许可权作用对象限制为特定注册表映像名称空间或操作(例如,pushpull)。

创建映像拉取私钥后,容器必须使用该私钥才有权从注册表中拉取映像。 您可以将镜像拉取密钥添加到项目的服务账户中,或在每次部署时引用该密钥。 有关指示信息,请参阅使用映像拉取私钥部署容器

镜像拉取密钥仅对创建它们的项目 Red Hat OpenShift 有效。 对要部署容器的每个名称空间,重复这些步骤。

开始之前:

  1. 在 IBM Cloud Container Registry 中设置名称空间,并将映像推送到此名称空间
  2. 创建集群
  3. 访问 Red Hat OpenShift 集群

要使用您自己的映像拉取私钥,请从以下选项中进行选择:

若您已在项目中创建了用于部署的镜像拉取密钥,请参阅 《 使用创建的镜像拉取 imagePullSecret 密钥部署容器 》。

复制现有映像拉取私钥

您可以将镜像拉取密钥(例如为 Red Hat OpenShiftdefault 项目自动创建的密钥)复制到集群中的其他项目。 若需为该项目使用不同的 IBM Cloud IAM API 密钥凭证(例如限制对特定项目的访问权限,或从 IBM Cloud 其他账户拉取镜像), 改为创建镜像拉取密钥。

  1. 列出集群中可用的 Red Hat OpenShift 项目,或创建一个项目以供使用。

    oc get projects
    

    示例输出

    default          Active
    ibm-cert-store   Active
    ibm-system       Active
    kube-public      Active
    kube-system      Active
    

    创建项目

    oc new-project <project_name>
    
  2. 列出项目 defaultRed Hat OpenShift 中现有的图像 IBM Cloud Container Registry 拉取密钥。

    oc get secrets -n default | grep icr-io
    

    示例输出

    all-icr-io          kubernetes.io/dockerconfigjson        1         16d
    
  3. default 项目中的 all-icr-io 图像拉取密钥复制到您选择的项目中。 新的图像提取密钥命名为 <project_name>-icr-<region>-io

    oc get secret all-icr-io -n default -o yaml | sed 's/default/<new-project>/g' | oc create -n <new-project> -f -   
    
  4. 验证私钥是否已成功创建。

    oc get secrets -n <project_name> | grep icr-io
    
  5. 要部署容器,请向每个部署或项目的服务帐户 添加映像拉取私钥,以便项目中的任何部署都可以从注册表拉取映像。

使用不同的 IAM API 密钥凭证创建映像拉取私钥

可以将 IBM Cloud IAM 访问策略分配给用户或服务标识,以将许可权作用对象限制为特定注册表映像名称空间或操作(例如,pushpull)。 然后,创建 API 密钥并将这些注册表凭证存储在集群的映像拉取私钥中。

例如,要访问其他 IBM Cloud 帐户中的映像,请创建 API 密钥,用于存储该帐户中用户或服务标识的 IBM Cloud Container Registry 凭证。 然后,在集群账户中,为每个集群和集群项目将 API 密钥凭据保存为图像拉取密钥。

以下步骤创建 API 密钥,用于存储 IBM Cloud IAM 服务标识的凭证。 您可能希望为具有对 IBM Cloud 的 IBM Cloud Container Registry IAM 服务访问策略的用户标识创建 API 密钥,而不使用服务标识。 但是,请确保用户是功能标识,或者有计划来应对用户离开的情况,以便集群始终可以访问注册表。

  1. 列出集群中可用的 Red Hat OpenShift 项目,或创建一个项目,以便从注册表镜像中部署容器。

    oc get projects
    

    示例输出

    default          Active
    ibm-cert-store   Active
    ibm-system       Active
    kube-public      Active
    kube-system      Active
    

    创建项目

    oc new-project <project_name>
    
  2. 为集群创建 IBM Cloud IAM 服务标识,此标识用于映像拉取私钥中的 IAM 策略和 API 密钥凭证。 请务必为服务 ID 添加描述性名称,以便日后能轻松检索该服务 ID,例如包含集群名称和项目名称。

    ibmcloud iam service-id-create <cluster_name>-<project>-id --description "Service ID for IBM Cloud Container Registry in Red Hat OpenShift on IBM Cloud cluster <cluster_name> project <project>"
    
  3. 为集群服务标识创建定制 IBM Cloud IAM 策略,以授予对 IBM Cloud Container Registry 的访问权。

    ibmcloud iam service-policy-create <cluster_service_ID> --roles <service_access_role> --service-name container-registry [--region <IAM_region>] [--resource-type namespace --resource <registry_namespace>]
    
    cluster_service_ID
    必需。 请替换为之前为您的 Kubernetes 集群创建的服务 <cluster_name>-<kube_namespace>-id ID。
    --service-name container-registry
    必需。 输入 container-registry,以便 IAM 策略可用于 IBM Cloud Container Registry。
    --roles <service_access_role>
    必需。 输入您希望为其 IBM Cloud Container Registry 限定服务ID访问权限 的服务访问角色。 可能的值为 Reader(读取者)、Writer(写入者)和 Manager(管理者)。
    --region <IAM_region>
    可选。 如果要将访问策略的作用域限定为特定 IAM 区域,请以逗号分隔列表格式输入各区域。 可能的值为 global本地注册表区域
    --resource-type namespace --resource <registry_namespace>
    可选。 若需限制访问权限仅限于特定 IBM Cloud Container Registry 命名空间 中的图像,请 namespace 在资源类型处输入,并指定 <registry_namespace>。 要列出注册表名称空间,请运行 ibmcloud cr namespaces
  4. 为服务标识创建 API 密钥。 将API密钥命名为与您的服务ID相似的名称,并包含您之前创建的服务ID <cluster_name>-<kube_namespace>-id. 请确保为 API 密钥提供描述,以帮助您日后检索该密钥。

    ibmcloud iam service-api-key-create <cluster_name>-<project>-key <cluster_name>-<project>-id --description "API key for service ID <service_id> in Red Hat OpenShift on IBM Cloud cluster <cluster_name> project <project>"
    
  5. 从上一个命令的输出中检索 API 密钥值。

    Please preserve the API key! It can't be retrieved after it's created.
    
    Name          <cluster_name>-<kube_namespace>-key   
    Description   key_for_registry_for_serviceid_for_kubernetes_cluster_multizone_namespace_test   
    Bound To      crn:v1:bluemix:public:iam-identity::a/1bb222bb2b33333ddd3d3333ee4ee444::serviceid:ServiceId-ff55555f-5fff-6666-g6g6-777777h7h7hh   
    Created At    2019-02-01T19:06+0000   
    API Key       i-8i88ii8jjjj9jjj99kkkkkkkkk_k9-llllll11mmm1   
    Locked        false   
    UUID          ApiKey-222nn2n2-o3o3-3o3o-4p44-oo444o44o4o4   
    
  6. 创建一个镜像拉取密钥,用于在集群项目中存储 API 密钥凭据。 对要从中拉取映像的每个 icr.io 域的每个集群的每个项目重复此步骤。

    oc --namespace <project> create secret docker-registry <secret_name> --docker-server=<registry_URL> --docker-username=iamapikey --docker-password=<api_key_value> --docker-email=<docker_email>
    
    --namespace <project>
    必需。 指定您用于服务ID名称的集群项目 Red Hat OpenShift。
    <secret_name>
    必需。 输入映像拉取私钥的名称。
    --docker-server <registry_URL>
    必需。 设置在其中设置注册表名称空间的映像注册表的 URL。 有关可用域,请参阅 本地区域
    --docker-username iamapikey
    必需。 输入用户名以登录您的私人注册表。 如果使用 IBM Cloud Container Registry,请输入 iamapikey
    --docker-password <token_value>
    必需。 输入您先前 API Key 检索到的值。
    --docker-email <docker-email>
    必需。 如果您有 Docker 电子邮件地址,请输入该地址。 如果没有,请输入一个虚构的电子邮件地址,例如 a@b.c。 此电子邮件对于创建 Kubernetes 私钥是必需的,但在创建后不会再使用此电子邮件。
  7. 验证私钥是否已成功创建。 将 <project> 替换为 中创建图像 project 拉取密钥的位置。

    oc get secrets --namespace <project>
    
  8. 将镜像拉取密钥添加到服务 Kubernetes 账户中,以便在部署容器时,项目中的任何Pod都能使用该镜像拉取密钥

访问存储在其他专用注册表中的映像

如果您已经拥有专用注册表,那么必须将相应的注册表凭证存储在 Kubernetes 映像拉取私钥中,并在配置文件中引用此私钥。

开始之前:

  1. 创建集群
  2. 访问 Red Hat OpenShift 集群

要创建映像拉取私钥,请执行以下操作:

  1. 创建 Kubernetes 私钥以用于存储专用注册表凭证。

    oc --namespace <project> create secret docker-registry <secret_name>  --docker-server=<registry_URL> --docker-username=<docker_username> --docker-password=<docker_password> --docker-email=<docker_email>
    
    --namespace <project>
    必需。 您希望使用该密钥并部署容器的集群 Red Hat OpenShift 项目。 要列出集群中的可用项目,请运行 oc get projects
    <secret_name>
    必需。 要用于映像拉取私钥的名称。
    --docker-server <registry_URL>
    必需。 要在其中存储专用映像的注册表的 URL。
    --docker-username <docker_username>
    必需。 用于登录您的私人注册表的用户名。
    --docker-password <token_value>
    必需。 用于登录到专用注册表的密码,例如令牌值。
    --docker-email <docker-email>
    必需。 如果您有 Docker 电子邮件地址,请输入该地址。 若您没有邮箱地址,请输入一个虚构的邮箱地址,例如 a@b.c. 此电子邮件对于创建 Kubernetes 私钥是必需的,但在创建后不会再使用此电子邮件。
  2. 验证私钥是否已成功创建。 将 <project> 替换为在其中创建映像拉取私钥的项目的名称。

    oc get secrets --namespace <project>
    
  3. 创建引用映像拉取私钥的 pod

使用映像拉取私钥来部署容器

您可以在 pod 部署中定义镜像拉取密钥,或将镜像拉取密钥存储在 Kubernetes 服务账户中,以便项目中所有未指定服务 Kubernetes 账户的部署都能使用该密钥。

要规划如何在集群中使用映像拉取私钥,请在以下选项之间进行选择。

  • 在 Pod 部署中引用镜像拉取密钥:若不希望默认授予项目中所有 Pod 对注册表的访问权限,请使用此选项。 开发者可以 在每个必须访问注册表的 pod 部署中包含映像拉取私钥
  • 将镜像拉取密钥存储在服务 Kubernetes 账户中:选择此选项可为所选 Red Hat OpenShift 项目中的所有部署授予访问注册表中镜像的权限。 要将映像拉取私钥存储在 Kubernetes 服务帐户中,请使用 以下步骤

将图像拉取密钥存储在所选项目的服务 Kubernetes 账户中

每个 Red Hat OpenShift 项目都有一个名为 Kubernetes 的服务 default 账户。 在项目中,您可以将映像拉取私钥添加到此服务帐户,以授予 pod 从注册表拉取映像的访问权。 未指定服务账户的部署将自动使用该 Red Hat OpenShift 项目的默认 default 服务账户。

  1. 检查 default 服务帐户是否已存在映像拉取私钥。

    oc describe serviceaccount default -n <project_name>
    

    <none> 在“图像拉取密钥”条目中显示时,表示不存在图像拉取密钥。

  2. 将映像拉取私钥添加到 default 服务帐户。

    • 示例命令:在未定义镜像拉取密钥时添加镜像拉取密钥。

      oc patch -n <project_name> serviceaccount/default -p '{"imagePullSecrets":[{"name": "<image_pull_secret_name>"}]}'
      
    • 示例命令:当镜像拉取密钥已定义时添加镜像拉取密钥。

      oc patch -n <project_name> serviceaccount/default --type='json' -p='[{"op":"add","path":"/imagePullSecrets/-","value":{"name":"<image_pull_secret_name>"}}]'
      
  3. 验证映像拉取私钥是否已添加到 default 服务帐户。

    oc describe serviceaccount default -n <project_name>
    

    示例输出

    Name:                default
    Namespace:           <namespace_name>
    Labels:              <none>
    Annotations:         <none>
    Image pull secrets:  <image_pull_secret_name>
    Mountable secrets:   default-token-sh2dx
    Tokens:              default-token-sh2dx
    Events:              <none>
    

    如果 映像拉取私钥 显示 <secret> (not found),请通过运行 oc get secrets -n project 来验证映像拉取私钥是否存在于与服务帐户相同的项目中。

  4. 创建名为 mypod.yaml 的 pod 配置文件,以从注册表中的 映像 部署容器。

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
        - name: mypod-container
          image: <region>.icr.io/<project>/<image>:<tag>
    
  5. 通过应用 mypod.yaml 配置文件在集群中创建 pod。

    oc apply -f mypod.yaml
    

设置集群以拉取授权软件

您可以设置 Red Hat OpenShift on IBM Cloud 集群以拉取授权软件,授权软件是受保护的容器映像的集合,这些映像包装在由 IBM 许可您使用的 Helm chart 中。 授权软件存储在特殊的 IBM Cloud Container Registry cp.icr.io 域中。 要访问此域,您必须创建一个带有集群授权密钥的镜像拉取密钥,并将此镜像拉取密钥添加到您希望部署此授权软件的每个项目的服务 Kubernetes 账户中。

开始之前: 访问 Red Hat OpenShift 集群

  1. 获取授权软件库的权利密钥。

    1. 登录 MyIBM.com 网站,滚动至容器软件库部分。 单击查看库
    2. 访问容器软件 > 权利密钥页面中,单击复制密钥。 此密钥授权访问容器软件库中的所有授权软件。
  2. 在您要部署授权容器的项目中,创建一个镜像拉取密钥,以便访问授权 cp.icr.io 注册表。 使用先前检索到的 权利密钥 作为 --docker-password 值。 有关更多信息,请参阅访问存储在其他专用注册表中的映像

    oc create secret docker-registry entitled-cp-icr-io --docker-server=cp.icr.io --docker-username=cp --docker-password=<entitlement_key> --docker-email=<docker_email> -n <project>
    
  3. 将镜像拉取密钥添加到命名空间的服务账户中,以便项目中的任何容器都能使用该授权密钥拉取授权镜像。 有关更多信息,请参阅使用映像拉取私钥部署容器

    oc patch -n <project> serviceaccount/default --type='json' -p='[{"op":"add","path":"/imagePullSecrets/-","value":{"name":"entitled-cp-icr-io"}}]'
    
  4. 在项目中创建一个Pod,该Pod从授权注册表中的镜像构建容器。

    oc run <pod_name> --image=cp.icr.io/<image_name> -n <project> --generator=run-pod/v1
    
  5. 通过验证 pod 是否处于 Running 状态,检查是否能够基于授权映像成功构建容器。

    oc get pod <pod_name> -n <project>
    

想知道接下来要做什么吗? 您可以设置授权 Helm chart 存储库,其中存储了包含授权软件的 Helm chart。 如果已在集群中安装 Helm,请运行 helm repo add entitled https://raw.githubusercontent.com/IBM/charts/master/repo/entitled

将专用注册表添加到全局拉取私钥

RHEL 工作节点

在只使用 RHEL 工作节点的群集中,可以设置一个全局映像提取秘密,群集中的每个工作节点都可以使用该秘密从私有注册表中提取映像。

缺省情况下,Red Hat OpenShift on IBM Cloud 集群具有以下注册表的全局映像拉取私钥,因此可以部署缺省 Red Hat OpenShift 组件。

  • cloud.openshift.com
  • quay.io
  • registry.connect.redhat.com
  • registry.redhat.io

请勿将全局拉取密钥替换为不具备默认 Red Hat 注册表凭据的拉取密钥。 如果这样做,集群中默认安装 Red Hat OpenShift 的组件(例如) OperatorHub, 可能会失败,因为它们无法从这些注册表中获取镜像。

开始之前:

要添加专用注册表,请在 openshift-config 项目中编辑全局 pull-secret

  1. 创建用于保存用于访问专用注册表的凭证的私钥值,并将解码后的私钥值存储在 JSON 文件中。 创建私钥值时,凭证将自动编码为 base64。 通过使用 --dry-run 选项,将仅创建私钥值,并且不会在集群中创建任何私钥对象。 然后,解码后的私钥值将存储在 JSON 文件中,以便稍后在全局拉取私钥中使用。

    oc create secret docker-registry <secret_name> --docker-server=<registry_URL> --docker-username=<docker_username> --docker-password=<docker_password> --docker-email=<docker_email> --dry-run=true --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode > myregistryconfigjson
    
    --namespace <project>
    必需。 您希望使用该密钥并部署容器的集群 Red Hat OpenShift 项目。 要列出集群中的可用项目,请运行 oc get ns
    <secret_name>
    必需。 要用于映像拉取私钥的名称。
    --docker-server <registry_URL>
    必需。 要在其中存储专用映像的注册表的 URL。
    --docker-username <docker_username>
    必需。 用于登录您的私人注册表的用户名。
    --docker-password <token_value>
    必需。 用于登录到专用注册表的密码,例如令牌值。
    --docker-email <docker-email>
    必需。 如果您有 Docker 电子邮件地址,请输入该地址。 若您没有邮箱地址,请输入一个虚构的邮箱地址,例如 a@b.c. 此电子邮件对于创建 Kubernetes 私钥是必需的,但在创建后不会再使用此电子邮件。
    --dry-run=true
    包含此选项以仅创建私钥值,而不创建私钥对象并将其存储在集群中。
    --output="jsonpath={.data.\.dockerconfigjson}"
    仅从 Kubernetes 私钥的数据部分获取 .dockerconfigjson 值。
    | base64 --decode > myregistryconfigjson
    将解码后的密钥数据下载到本地 myregistryconfigjson 文件。
  2. 检索缺省全局拉取私钥的解码私钥值,并将该值存储在 dockerconfigjson 文件中。

    oc get secret pull-secret -n openshift-config --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode > dockerconfigjson
    
  3. 将下载的专用注册表拉取私钥 myregistryconfigjson 文件与缺省全局拉取私钥 dockerconfigjson 文件组合在一起。

    jq -s '.[0] * .[1]' dockerconfigjson myregistryconfigjson > dockerconfigjson-merged
    
  4. 使用组合的 dockerconfigjson-merged 文件更新全局拉取私钥。

    oc set data secret/pull-secret -n openshift-config --from-file=.dockerconfigjson=dockerconfigjson-merged
    
  5. 验证全局拉取私钥是否已更新。 检查专用注册表和每个缺省 Red Hat 注册表是否在以下命令的输出中。

    oc get secret pull-secret -n openshift-config --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
    

    示例输出

    {
        "auths": {
            "cloud.openshift.com": {
                "auth": "<encoded_string>",
                "email": "email@example.com"
            },
            "quay.io": {
                "auth": "<encoded_string>",
                "email": "email@example.com"
            },
            "registry.connect.redhat.com": {
                "auth": "<encoded_string>",
                "email": "email@example.com"
            },
            "registry.redhat.io": {
                "auth": "<encoded_string>",
                "email": "email@example.com"
            },
            "<private_registry>": {
                "username": "iamapikey",
                "password": "<encoded_string>",
                "email": "email@example.com",
                "auth": "<encoded_string>"
            }
        }
    }
    
  6. 要选取全局配置更改,请重新装入集群中的所有工作程序节点。

    1. 记下集群中工作程序节点的 标识

      ibmcloud oc worker ls -c <cluster_name_or_ID>
      
    2. 对于经典集群 重新装入每个工作程序节点。 您可以通过包含多个 -w 选项来重新装入多个工作程序节点,但请确保为应用程序同时运行足够多的工作程序节点以避免中断。

      ibmcloud oc worker reload -c <cluster_name_or_ID> -w <workerID_1> -w <workerID_2>
      
    3. 对于 VPC 集群 替换每个工作程序节点。 开始之前,请确保集群具有足够的其他工作程序节点,以便可以重新调度 pod 并继续运行。

      ibmcloud oc worker replace --cluster <cluster_name_or_ID> --worker <worker_node_ID>
      
  7. 在工作程序节点恢复为正常状态后,请验证是否在工作程序节点上更新了全局拉取私钥。

    1. 启动调试 pod 以登录到工作程序节点。 使用先前为 <node_name> 检索的 专用 IP

      oc debug node/<node_name>
      
    2. 将根目录切换到主机,以便您可以查看工作程序节点上的文件。

      chroot /host
      
    3. 验证 Docker 配置文件是否具有与您设置的全局拉取私钥匹配的注册表凭证。

      vi /.docker/config.json
      

更新全局拉取密钥

RHCOS 工作节点 RHEL 工作节点

在使用 RHCOS Worker 或 RHCOS 和 RHEL Worker 组合的群集中,可以完成以下步骤更新 Red Hat OpenShift on IBM Cloud 群集中的全局拉取密钥。

缺省情况下,Red Hat OpenShift on IBM Cloud 集群具有以下注册表的全局映像拉取私钥,因此可以部署缺省 Red Hat OpenShift 组件。

  • cloud.openshift.com
  • quay.io
  • registry.connect.redhat.com
  • registry.redhat.io

请勿将全局拉取密钥替换为不具备默认 Red Hat 注册表凭据的拉取密钥。 如果这样做,集群中默认安装 Red Hat OpenShift 的组件(例如) OperatorHub, 可能会失败,因为它们无法从这些注册表中获取镜像。

  1. 创建一个秘密,其中包含要使用的注册表的凭据。
    oc create secret docker-registry docker-auth-secret \
    --docker-server=REGISTRY \
    --docker-username=USERNAME \
    --docker-password=PASSWORD \
    --namespace kube-system
    
  2. 创建DaemonSet,以便在所有工作节点上应用秘密。
    cat << EOF | oc create -f -
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: update-docker-config
      namespace: kube-system
      labels:
        app: update-docker-config
    spec:
      selector:
        matchLabels:
          name: update-docker-config
      template:
        metadata:
          labels:
            name: update-docker-config
        spec:
          initContainers:
            - command: ["/bin/sh", "-c"]
              args:
                - >
                  echo "Checking if RHEL or RHCOS host";
                  [[ -s /docker-config/.docker/config.json  ]] && CONFIG_PATH=/docker-config/.docker || CONFIG_PATH=/docker-config/root/.docker;
                  echo "Backing up or restoring config.json";
                  [[ -s \$CONFIG_PATH/config.json ]] && cp \$CONFIG_PATH/config.json \$CONFIG_PATH/config.json.bak || cp \$CONFIG_PATH/config.json.bak \$CONFIG_PATH/config.json;
                  echo "Merging secret with config.json";
                  /host/usr/bin/jq -s '.[0] * .[1]' \$CONFIG_PATH/config.json /auth/.dockerconfigjson > \$CONFIG_PATH/config.tmp;
                  mv \$CONFIG_PATH/config.tmp \$CONFIG_PATH/config.json;
                  echo "Sending signal to reload crio config";
                  pidof crio;
                  kill -1 \$(pidof crio)
              image: icr.io/ibm/alpine:latest
              imagePullPolicy: IfNotPresent
              name: updater
              resources: {}
              securityContext:
                privileged: true
              volumeMounts:
                - name: docker-auth-secret
                  mountPath: /auth
                - name: docker
                  mountPath: /docker-config
                - name: bin
                  mountPath: /host/usr/bin
                - name: lib64
                  mountPath: /lib64
          containers:
            - resources:
                requests:
                  cpu: 0.01
              image: icr.io/ibm/alpine:latest
              name: sleepforever
              command: ["/bin/sh", "-c"]
              args:
                - >
                  while true; do
                    sleep 100000;
                  done
          hostPID: true
          volumes:
            - name: docker-auth-secret
              secret:
                secretName: docker-auth-secret
            - name: docker
              hostPath:
                path: /
            - name: bin
              hostPath:
                path: /usr/bin
            - name: lib64
              hostPath:
                path: /lib64
                hostPathType: Directory
    EOF
    
  3. 验证 pod 是否正在运行。
    oc get daemonset -n kube-system update-docker-config
    

更新 IBM Cloud Kubernetes Service containerd 定制注册表配置

通过 Kubernetes V 1.22 或更高版本,可以使用工作程序节点上的 containerd 配置文件来配置从容器注册表中拉取。 您可以使用 daemonset 来更新集群中所有节点的配置,这将防止在工作程序节点重新装入或添加新工作程序时擦除配置。

用于更新 containerd 定制注册表配置的示例 daemonset

使用示例 YAML 文件来定义在所有工作程序节点上运行的 daemonset,以设置或更新 containerd 注册表主机配置并安装到相应的 containerd 注册表路径。

此示例为 dockerhub 设置以下注册表主机配置。 此注册表主机配置已提供并在工作程序供应阶段自动配置。 在部署之后以及在工作程序节点重新装入或重新启动之后,init 容器会在每个工作程序节点上初始化 hosts.toml

server = "https://docker.io"
[host."https://registry-1.docker.io"]
capabilities = ["pull", "resolve"]

示例 YAML 文件

apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
    name: containerd-dockerhub-registry-config
name: containerd-dockerhub-registry-config
namespace: kube-system
spec:
selector:
    matchLabels:
    name: containerd-dockerhub-registry-config
template:
    metadata:
    labels:
        name: containerd-dockerhub-registry-config
    spec:
    initContainers:
    - image: alpine:3.13.6
        name: containerd-dockerhub-registry-config
        command:
        - /bin/sh
        - -c
        - |
            #!/bin/sh
            set -uo pipefail
            cat << EOF > /etc/containerd/certs.d/docker.io/hosts.toml
            server = "https://docker.io"
            [host."https://registry-1.docker.io"]
            capabilities = ["pull", "resolve"]
            EOF
        volumeMounts:
        - mountPath: /etc/containerd/certs.d/docker.io/
        name: dockerhub-registry-config
    containers:
    - name: pause
        image: "us.icr.io/armada-master/pause:3.5"
        imagePullPolicy: IfNotPresent
    volumes:
    - name: dockerhub-registry-config
        hostPath:
        path: /etc/containerd/certs.d/docker.io/

有关更新 containerd 注册表主机配置的更多信息,请参阅 containerd 文档