设置映像注册表

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

选择映像注册表解决方案

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

内部 Red Hat OpenShift Container Registry (OCR)

您的集群已配置了内部 Red Hat OpenShift Container Registry,以便 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,您可以通过与 IBM Cloud 的IAM和计费系统的集成,管理多个集群的镜像。 将 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 存储区中存储的任何数据。 创建集群后,您无法从集群中删除或分离 IBM Cloud Object Storage 存储桶。 如果您计划创建一个不使用 COS 支持的内部注册表的集群(例如,用于 IBM 金融服务云环境 ),则在创建集群时必须省略 COS 实例。 如需了解更多信息,请参阅 《 不使用 Object Storage 存储桶创建VPC集群 》。
经典集群,VPC 集群或 Satellite 集群
您可以选择设置内部注册表以将数据存储在运行内部注册表 pod 的工作程序节点的 emptyDir 中。 请记住,此数据不是持久数据,如果重新启动 pod 或工作程序节点,那么将删除存储的数据并且不可恢复。 如果您定期从大型映像构建容器,那么可以将这些映像存储在 emptyDir 本地以提高性能。

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

虚拟私有云

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

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

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

为群集注册表配置 COS 桶

您可以为群集的内部镜像注册表手动配置 IBM Cloud Object Storage 桶。 这在需要设置或重新配置注册表存储后台时非常有用。

准备工作

配置 COS 桶

  1. 为群集和 Object Storage 实例设置环境变量。

    export CLUSTER_NAME=<cluster_name>
    export COS_INSTANCE_ID=<cos_instance_id>
    export CLUSTER_ID=$(ibmcloud ks cluster get --cluster $CLUSTER_NAME --json | jq -r .id)
    
  2. 检查当前图像注册表操作员配置。

    oc get configs.imageregistry.operator.openshift.io/cluster -o yaml
    
  3. 将操作器暂时设置为 Removed 模式。 如果注册表已经激活,请禁用它以避免冲突。

    oc patch configs.imageregistry.operator.openshift.io/cluster \
    --type=merge -p '{"spec":{"managementState":"Removed"}}'
    
  4. 检查注册表是否使用 emptyDir,这意味着没有配置 COS 桶。

    storage:
      emptyDir: {}
      managementState: Managed
    
  5. 为群集创建 Object Storage 桶。 将 <region> 替换为您首选的区域,如 us-southeu-de

    RANDOM_SUFFIX=$(LC_ALL=C tr -dc 'a-z0-9' </dev/urandom | head -c 6)
    COS_BUCKET_NAME="roks-${CLUSTER_ID}-${RANDOM_SUFFIX}"
    ibmcloud cos bucket-create \
      --bucket "$COS_BUCKET_NAME" \
      --ibm-service-instance-id "$COS_INSTANCE_ID" \
      --class standard \
      --region <region>
    
  6. 从注册表配置中删除 emptyDir 字段。

    oc patch configs.imageregistry.operator.openshift.io/cluster \
      --type=json \
      -p '[{"op": "remove", "path": "/spec/storage/emptyDir"}]'
    
  7. 配置注册表以使用 S3 存储 ( Object Storage )。 更新 regionregionEndpoint 值,使其与水桶的区域相匹配。

    oc patch configs.imageregistry.operator.openshift.io/cluster --type=merge -p "$(cat <<EOF
    {
    "spec": {
      "managementState": "Unmanaged",
        "storage": {
          "s3": {
            "bucket": "$COS_BUCKET_NAME",
            "region": "<region>-standard",
            "regionEndpoint": "https://s3.direct.<region>.cloud-object-storage.appdomain.cloud",
            "trustedCA": {
              "name": ""
            },
            "virtualHostedStyle": false
          }
        }
      }
    }
    EOF
    )"
    

    例如,如果您的水桶在 eu-de 中,请使用 region: "eu-de-standard"regionEndpoint: "https://s3.direct.eu-de.cloud-object-storage.appdomain.cloud"

  8. 验证图像注册表操作员配置。

    oc get configs.imageregistry.operator.openshift.io/cluster -o yaml
    
  9. 为 COS 实例创建服务凭据密钥,并提取 HMAC 凭据。

    ibmcloud resource service-key-create roks-$CLUSTER_ID-key \
    --instance-id "$COS_INSTANCE_ID" \
    -p '{"HMAC": true}' \
    -o json > service-key.json
    # Extract values with jq
    ACCESS_KEY=$(jq -r '.credentials.cos_hmac_keys.access_key_id' service-key.json)
    SECRET_KEY=$(jq -r '.credentials.cos_hmac_keys.secret_access_key' service-key.json)
    # Create credentials file
    cat <<EOF > creds.txt
    [default]
    aws_access_key_id = $ACCESS_KEY
    aws_secret_access_key = $SECRET_KEY
    EOF
    

    这会创建一个包含 Object Storage 凭据的 creds.txt 文件。

    凭证文件示例

    [default]
    aws_access_key_id = f1ab5fcf7XXXXXXXXXb2a14e046
    aws_secret_access_key = 4c78ddfa763XXXXXXX23d1cc9350d1
    
  10. 如果 image-registry-private-configuration-user 保密文件不存在,则创建该文件。

    oc create secret generic image-registry-private-configuration-user -n openshift-image-registry
    
  11. 用访问凭证更新密文。

    oc patch secret image-registry-private-configuration-user \
    -n openshift-image-registry \
    --type merge \
    -p "{
        \"data\": {
        \"REGISTRY_STORAGE_S3_ACCESSKEY\": \"$(echo -n "$ACCESS_KEY" | base64)\",
        \"REGISTRY_STORAGE_S3_SECRETKEY\": \"$(echo -n "$SECRET_KEY" | base64)\"
        }
    }"
    
  12. 如果 image-registry-private-configuration 保密文件不存在,则创建该文件。

    oc create secret generic image-registry-private-configuration -n openshift-image-registry
    
  13. 使用完整的 Object Storage 凭据文件更新主图像注册表秘密。

    CREDENTIALS_B64=$(base64 -i creds.txt | tr -d '\n')
    oc patch secret image-registry-private-configuration \
    -n openshift-image-registry \
    --type merge \
    -p "{\"data\": {\"credentials\": \"${CREDENTIALS_B64}\"}}"
    
  14. 将图像注册表操作员设置为 Managed 模式。

    oc patch configs.imageregistry.operator.openshift.io/cluster \
    --type=merge -p '{"spec":{"managementState":"Managed"}}'
    
  15. 重新启动图像注册表部署。

    oc rollout restart deployment image-registry -n openshift-image-registry
    
  16. 验证注册表是否处于健康状态。

    oc get clusteroperator image-registry
    

排除 COS 注册表配置故障

如果在 Object Storage 注册表配置中遇到问题,请尝试以下故障排除步骤。

  1. 请检查 image-registry pod是否正在运行。

    oc project openshift-image-registry
    oc get pods
    

    示例输出

    NAME                              READY   STATUS    RESTARTS   AGE
    image-registry-7d8b57c98f-m92t7   1/1     Running   0          3h53m
    node-ca-62p88                     1/1     Running   0          5h12m
    node-ca-6s8vx                     1/1     Running   0          5h17m
    node-ca-b5jwl                     1/1     Running   0          4h56m
    node-ca-chl7k                     1/1     Running   0          5h17m
    node-ca-l6tlb                     1/1     Running   0          4h55m
    node-ca-q4vw8                     1/1     Running   0          4h55m
    
  2. 检查群组操作员 image-registry 的状态。

    oc describe clusteroperator image-registry
    
  3. 如有需要,请暂时删除 S3 后端配置,并恢复到 emptyDir,以解除对操作员的锁定。

    oc patch configs.imageregistry.operator.openshift.io/cluster --type=merge -p '{
    "spec": {
        "managementState": "Managed",
        "storage": {
          "emptyDir": {}
        }
    }
    }'
    
  4. 检查 openshift-image-registry 命名空间中的 pod。

    oc get pods -n openshift-image-registry
    
  5. 检查已部署的配置环境变量。

    oc get pod -n openshift-image-registry -l docker-registry=default -o jsonpath='{.items[0].spec.containers[0].env}' | jq
    

有关配置注册表的更多信息,请参阅 设置和配置注册表

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

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

查看卷详细信息

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

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

更改卷详细信息

如果注册表需要更多千兆字节的存储空间来存储映像,那么可以调整文件存储器卷的大小。 有关更多信息,请参阅更改现有存储设备的大小和 IOPS。 调整 IBM Cloud 基础架构帐户中的卷大小时,不会更新连接的 PVC 描述。 相反,您可以登录到使用 registry-backing PVC 的 openshift-image-registry 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
        ```
        示例输出
    
        ```sh {: screen}
        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
        ```
    1. 获取运行 `image-registry` pod 的 **Node** 的公共 IP 地址。
    
    ```sh {: pre}
        oc describe pod -n openshift-image-registry <image-registry-pod> | grep Node
        ```
        示例输出
    
        ```sh {: screen}
        Node:               169.xx.xxx.xxx/169.xx.xxx.xxx
        ```
        如果工作程序节点 IP 地址是专用的,请运行 `ibmcloud oc worker ls -c <cluster> | grep <private_IP>` 并记下相应的公共 IP 地址。
        {: tip}
    
    1. 获取 pod YAML 中 `metadata.uid` 部分中 `image-registry` pod 的 **UID** (而不是 `metadata.ownerReferences.uid` 部分中副本集的 UID)。
    
    ```sh {: pre}
        oc get pod -n openshift-image-registry <image-registry-pod> -o yaml
        ```
        示例输出
    
        ```yaml {: screen}
        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
        ```
    1. 验证映像是否在存储库目录中。
    ```sh {: pre}
        ls
        ```
        示例输出
        ```sh {: screen}
        <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. image-registry 服务创建一条安全路由,该路由使用 reencrypt TLS 作为终结点。 通过重新加密,路由器会使用一个证书终止 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
        ```
    1. 使用内部注册表的主机名、要将映像部署到的项目以及映像名称和标记来标记本地映像。
    
    ```sh {: pre}
        docker tag hello-world:latest image-registry-openshift-image-registry.<cluster_name>-<ID_string>.<region>.containers.appdomain.cloud/<project>/<image_name>:<tag>
        ```
    1. 将映像推送到集群的内部注册表。
    
    ```sh {: pre}
        docker push image-registry-openshift-image-registry.<cluster_name>-<ID_string>.<region>.containers.appdomain.cloud/<project>/<image_name>:<tag>
        ```
    4. 请确认该镜像已添加到 Red Hat OpenShift 镜像流中。
    
    ```sh {: pre}
        oc get imagestream
        ```
        示例输出
    
        ```sh {: screen}
        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
        ```
        示例输出
    
        ```sh {: screen}
        ...
        Image pull secrets:
        all-icr-io
        default-dockercfg-mpcn4
        ...
        ```
    1. 从配置文件的 `data` 字段中获取已编码的私钥信息。
    
    ```sh {: pre}
        oc get secret <default-dockercfg-name> -o yaml
        ```
        示例输出
    
        ```yaml {: screen}
        apiVersion: v1
        data:
          .dockercfg: ey...=
        ```
    1. 对 `data` 字段的值进行解码。
    
    ```sh {: pre}
        echo "<ey...=>" | base64 -D
        ```
        示例输出
    
        ```sh {: screen}
        {"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 私钥是必需的,但在创建后不会再使用此电子邮件。
    
    ```sh {: pre}
        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 服务帐户。
    
    ```sh {: pre}
        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>
        ```
    1. 列出构建配置,并记下要授予对 IBM Cloud Container Registry的推送和拉取访问权的配置。
    
    ```sh {: pre}
        oc get bc
        ```
    1. 设置构建配置的映像推送私钥,以使用您刚刚通过 `Writer` 服务访问权 IBM Cloud Container Registry创建的私钥。
    
    ```sh {: pre}
        oc set build-secret --push bc/<build_config_name> <secret_name>
        ```
    4. 设置要从要从中拉取初始构建映像的注册表拉取的构建配置的映像拉取私钥。 例如,如果源映像位于 IBM Cloud Container Registry 存储库中,那么您可以使用刚刚通过 `Reader` 服务访问 IBM Cloud Container Registry 创建的私钥。
    
    ```sh {: pre}
        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 项目或账户拉取镜像、限制拉取权限,或为何您的集群可能缺少默认镜像拉取密钥。

我的集群应如何配置才能从 default Red Hat OpenShift 项目中拉取镜像?
创建集群时,集群会具有 IBM Cloud IAM 服务标识,此标识已被授予对 IBM Cloud Container Registry 的 IAM 读取者服务访问角色策略。 在存储于集群的映像拉取私钥中的非到期 API 密钥中,会模拟服务标识凭证。 镜像拉取密钥已添加到 default Kubernetes 命名空间中,并已添加到 default 服务账户中,该账户属于此 Red Hat OpenShift 项目。 通过使用映像拉取私钥,部署可以从 全局和区域 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 命名空间中的任何镜像所对应的容器,部署到集群中的 default Red Hat OpenShift 项目中。 若要在其他 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 IBM Cloud Container Registry 的 IAM 管理员平台访问角色,适用于所有区域和资源组。 该策略无法限定在特定区域或资源组范围内。 账户所有者可以通过运行以下命令向您授予该角色。

    验证密钥是否已成功创建

    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

更新映像拉取私钥

更新位于 default Kubernetes 命名空间中的集群镜像拉取密钥。

  1. 获取集群标识。

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

    ibmcloud oc cluster pull-secret apply --cluster CLUSTER_NAME_OR_ID
    

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

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

    oc get secrets | grep icr-io
    

    示例输出

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

  5. 可选:如果您启用了防火墙,请确保为所使用的域名添加 允许发往注册表子网的出站网络流量 规则。

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

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

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

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

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

开始之前:

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

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

如果您已在项目中创建了图像拉取密钥,并希望在部署中使用它,请参阅 《使用已创建的 imagePullSecret 部署容器》

复制现有映像拉取私钥

您可以将一个图像拉取密钥(例如为 default Red Hat OpenShift 项目自动生成的密钥)复制到集群中的其他项目中。 如果您希望为该项目使用不同的 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. 列出 default Red 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 添加一个便于日后检索的描述,例如同时包含集群名称和项目名称。

    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 项目都有一个名为 default 的 Kubernetes 服务帐户。 在项目中,您可以将映像拉取私钥添加到此服务帐户,以授予 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>"}]}'
        ```
    - 当已定义镜像拉取密钥时,用于添加镜像拉取密钥的示例命令。
    
    ```sh {: pre}
        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>
        ```
    1. **对于经典集群** 重新装入每个工作程序节点。 您可以通过包含多个 `-w` 选项来重新装入多个工作程序节点,但请确保为应用程序同时运行足够多的工作程序节点以避免中断。
    
    ```sh {: pre}
        ibmcloud oc worker reload -c <cluster_name_or_ID> -w <workerID_1> -w <workerID_2>
        ```
    1. **对于 VPC 集群** 替换每个工作程序节点。 开始之前,请确保集群具有足够的其他工作程序节点,以便可以重新调度 pod 并继续运行。
    
    ```sh {: pre}
        ibmcloud oc worker replace --cluster <cluster_name_or_ID> --worker <worker_node_ID>
        ```
    
    
  7. 在工作程序节点恢复为正常状态后,请验证是否在工作程序节点上更新了全局拉取私钥。

    1. 启动调试 pod 以登录到工作程序节点。 使用先前为 <node_name> 检索的 专用 IP
        oc debug node/<node_name>
        ```
    1. 将根目录切换到主机,以便您可以查看工作程序节点上的文件。
    
    ```sh {: pre}
        chroot /host
        ```
    1. 验证 Docker 配置文件是否具有与您设置的全局拉取私钥匹配的注册表凭证。
    
    ```sh {: pre}
        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,以便在所有工作节点上应用秘密。
    ocp_release_pull_secret_image=$(oc get ds -n openshift-dns node-resolver -o jsonpath='{.spec.template.spec.containers[0].image}')
    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: ${ocp_release_pull_secret_image}
              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: ${ocp_release_pull_secret_image}
              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 文档