IBM Cloud Docs
为应用程序构建映像

为应用程序构建映像

Docker 映像是使用 Red Hat® OpenShift® on IBM Cloud® 所创建的每一个容器的基础。

映像是通过 Dockerfile 创建的,该文件包含构建映像的指令。 Dockerfile 可能会在其单独存储的指令中引用构建工件,例如应用程序、应用程序配置及其依赖项。

构建映像

您可以通过多种方式构建映像,包括以下 IBM Cloud 服务。

IBM Cloud Code Engine
Code Engine 支持从 Dockerfile 和 Cloud Native Buildpack 构建映像,并自动将映像推送到 IBM Cloud® Container Registry。 有关更多信息,请参阅 规划构建
Tekton 管道
Continuous Delivery 服务包含多个 Tekton 任务,您可以在管道中引用这些任务来构建映像。 有关更多信息,请参阅 Tekton 管道

从内部注册表中的现有映像流部署容器

您可以从集群管理员在 Red Hat OpenShift 集群的内部注册表中设置的现有 映像流 部署应用程序。 例如,集群管理员可能已 设置映像流以从外部专用注册表导入映像,例如 IBM Cloud Container Registry。

将映像流与 CLI 配合使用

  1. 访问 Red Hat OpenShift 集群

  2. 列出项目中的可用映像流。 如果您知道映像流的项目,名称和标记,那么可以在其他项目中使用本地映像流,而无需设置映像拉取流凭证。

    oc get is -n <project>
    
  3. 从映像流创建应用程序。

    oc new-app --image-stream="<project>/<imagestream>:<tag>"
    

使用 Red Hat OpenShift Web 控制台中的映像流

  1. Red Hat OpenShift Web 控制台,切换到 开发者 透视图,然后单击 + 添加
  2. 在“添加”窗格菜单栏中,选择要在其中创建应用程序的 项目 default,然后单击 容器映像
  3. 映像 部分中,选择 来自内部注册表的映像名称
  4. 选择先前创建的图像流的 default Project, <image> ImageStreams,和 <tag> Tag.
  5. 查看其余应用程序详细信息,然后单击 创建

将容器从 IBM Cloud Container Registry 映像部署到 default Red Hat OpenShift 项目

可以通过 IBM 提供的公共映像将容器部署到集群,也可以通过存储在 IBM Cloud Container Registry 名称空间中的专用映像来部署。 有关集群如何访问注册表映像的更多信息,请参阅了解如何授权集群从 IBM Cloud Container Registry 中拉取映像

开始之前:

  1. 在 IBM Cloud Container Registry 中设置名称空间,并将映像推送到此名称空间

  2. 创建集群

  3. 访问 Red Hat OpenShift 集群

  4. 创建名为 <deployment>.yaml 的部署配置文件。

  5. 在 IBM Cloud Container Registry 的项目中定义部署和要使用的映像。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: <deployment>
    spec:
      replicas: <number_of_replicas>
      selector:
        matchLabels:
          app: <app_name>
      template:
        metadata:
          labels:
            app: <app_name>
        spec:
          containers:
          - name: <app_name>
            image: <region>.icr.io/<project>/<image>:<tag>
    
    <deployment>
    给你的部署起个名字。
    <number_of_replicas>
    输入部署创建的副本 pod 数。
    app: <app_name>
    使用应用程序的名称作为容器的标签。
    name: <app_name>
    为容器提供名称,例如 app 标签的名称。
    image: <region>.icr.io/project>/image>:tag>
    将映像 URL 变量替换为映像的信息:
    region>:注册域的区域 IBM Cloud Container Registry API 端点。 要列出您登录到的区域的域,请运行 ibmcloud cr api
    namespace>: 注册表名称空间。 要获取名称空间信息,请运行 ibmcloud cr namespace-list
    image>:tag>: 您想用于容器的图像和标记。 要列出注册表名称空间中可用的映像,请运行 ibmcloud cr images
  6. 在集群中创建部署。

    oc apply -f <deployment>.yaml
    

从加密映像部署容器

使用 Image Key Synchronizer 集群附加组件将容器从加密映像部署到集群。

在运行 Red Hat OpenShift 4.5 或更高版本的集群中,CRI-O 容器运行时支持使用加密容器映像。 加密容器映像是包含加密层内容的 Open Container Initiative (OCI) 映像。 您可以为特定集群启用映像加密,而不是保护个别开发者 (例如,使用映像拉取私钥从注册表拉取映像的开发者) 的映像。 通过这种方式,您可以确保仅在具有映像解密密钥的特定集群中运行已加密的映像。

要使用加密映像来运行应用程序,必须与集群中的工作程序节点上的容器运行时共享用于解密该映像的密钥。 在集群中启用 Image Key Synchronizer 附加组件时,将在 image-key-synchronizer 项目中部署同步器守护程序集。 然后,您可以创建包含该项目中的映像解密密钥的 Kubernetes 私钥。 该附加组件将密钥添加到工作程序节点上的特定目录,容器运行时可以在该工作程序节点上访问这些密钥并使用这些密钥对容器映像进行解密。 请注意,Image Key Synchronizer 附加组件还支持首先 由存储在 IBM® Key Protect 实例 中的根密钥打包的专用密钥。

准备工作

  1. 下载并安装以下开放式源代码工具的 CLI 客户机:

  2. 访问 Red Hat OpenShift 集群

  3. 可选: 为映像加密创建公用密钥和专用密钥对时,可以直接在私钥中提供专用密钥,或者首先使用 Key Protect 根密钥或密钥管理服务 (KMS) 来打包专用密钥。 要准备打包专用密钥,请执行以下操作:

    1. 安装 Key Protect CLI 插件

    2. 创建 Key Protect 服务实例

    3. 创建 Key Protect 根密钥

    4. 获取 Key Protect 实例的以下值:

    5. 创建名为 keyprotect-config 的 Kubernetes 私钥,其中包含检索到的值。 Image Key Synchronizer 附加组件使用此私钥中的环境变量向 Key Protect 实例进行认证。

      apiVersion: v1
      kind: Secret
      metadata:
        name: keyprotect-config
        namespace: image-key-synchronizer
      type: Opaque
      stringData:
        config.json: |
            {
                "keyprotect-url":"<service_endpoint>",
                "instance-id": "<service_instance_ID>",
                "apikey": "<service_instance_ID_API_key>"
            }
      

要部署使用加密映像的容器:

  1. 启用 Image Key Synchronizer 附加组件。

    ibmcloud oc cluster addon enable image-key-synchronizer -c <cluster_name_or_ID>
    
  2. 验证是否已在集群中的 image-key-synchronizer 项目中成功创建 addon-image-key-synchronizer 守护程序集。

    oc get ds addon-image-key-synchronizer -n image-key-synchronizer
    
  3. 使用 openssl 生成专用和公用 RSA 密钥对。

    openssl genrsa -out myprivatekey.pem
    openssl rsa -in myprivatekey.pem -pubout -out mypubkey.pem
    
  4. 直接在私钥中提供专用密钥,或者首先使用来自密钥管理服务 (KMS) 的根密钥 (例如 Key Protect) 来打包专用密钥。 在 image-key-synchronizer 项目中创建私钥后,Image Key Synchronizer 附加组件会自动将专用密钥复制到工作程序节点上的 /etc/crio/keys/synced 目录。

    • 直接提供专用密钥: 将专用密钥保存为 image-key-synchronizer 项目中的 Kubernetes 私钥。
      oc create -n image-key-synchronizer secret generic --type=key --from-file=myprivatekey.pem <secret_name>
      
    • 要使用 Key Protect 根密钥来打包专用密钥:
      1. 在 base64中对专用密钥进行编码,然后复制输出。

        cat myprivatekey.pem | base64
        
      2. 使用 Key Protect CLI 插件将 base64-encoded 专用密钥与根密钥合并。 在输出中,复制打包的专用密钥的密文。

        ibmcloud kp key wrap <root_key_ID> -p <base64_encoded_private_key>
        
      3. 将打包的专用密钥另存为 image-key-synchronizer 项目中的 Kubernetes 私钥。

        apiVersion: v1
        kind: Secret
        type: kp-key
        metadata:
          name: <secret_name>
          namespace: image-key-synchronizer
        stringData:
          rootkeyid: "<root_key_ID>"
          ciphertext: "<wrapped_private_key_cipertext>"
        
      4. 创建私钥。

        oc apply -n image-key-synchronizer -f <secret_name>.yaml
        
  5. 使用 docker 以本地拉取 OCI 映像。 将 <source_image> 替换为图片的存储库,将 <tag> 替换为要使用的图片的标记,如 latest

    docker pull <source_image>:<tag>
    
  6. 使用 skopeo 对本地映像进行加密。 此命令将复制先前拉取的 OCI 映像,使用公用密钥对映像进行加密,并将已加密的映像保存到另一个本地文件中。 请考虑对已加密的映像 <source_image>_encrypted 进行命名,以方便识别。

    skopeo copy --encryption-key jwe:./mypubkey.pem <source_image>:<tag> <source_image>_encrypted:<tag>
    
  7. 可选: 要在本地验证映像是否已加密,您可以尝试使用不正确的密钥对映像进行解密。

    1. 生成新的私人密钥

      openssl genrsa --out wrongkey.pem 1024
      
    2. 尝试使用此新密钥来解密映像。 解密命令失败,因为指定了不正确的专用密钥。

      skopeo copy --decryption-key ./wrongkey.pem <source_image>_encrypted:<tag> <source_image>_decrypted:<tag>
      
  8. 可选: 将加密映像推送到支持加密 OCI 映像的 IBM Cloud Container Registry

  9. 在应用程序部署中指定加密映像。 例如,如果已将加密映像推送到 IBM Cloud Container Registry,那么可以遵循 将容器从 IBM Cloud Container Registry 映像部署到 default Red Hat OpenShift 项目 中的示例。 在集群中创建部署时,容器运行时使用 /etc/crio/keys/synced 目录中的专用解密密钥在运行映像之前对其进行解密。

  10. 对于要加密的任何后续映像,可以使用相同的公用密钥通过 Skopeo对映像进行加密,或者重复这些步骤以使用不同的公用和专用密钥对。

如果您稍后决定禁用该附加组件,那么将除去 addon-image-key-synchronizer 守护程序集,但不会除去 image-key-synchronizer 项目以及在该项目中创建的任何私钥,并且容器运行时仍可以使用这些私钥来运行加密映像。 如果您还要从工作程序节点中除去密钥,那么必须先从 image-key-synchronizer 项目中删除相应的私钥,然后再禁用该附加组件。

有关每个 Image Key Synchronizer 附加组件版本的更改列表,请参阅 IBM Cloud Image Key Synchronizer 附加组件更改日志

在 pod 部署中引用映像拉取私钥

如果集群管理员未 将映像拉取私钥存储在 Kubernetes 服务帐户 中,那么所有未指定服务帐户的部署都无法使用映像拉取私钥来部署容器。 而是可以在 pod 部署中定义映像拉取私钥。 在 pod 部署中引用图像拉取密钥时,图像拉取密钥仅对该 pod 有效,不能在 Red Hat OpenShift 项目中的 pod 之间共享。

准备工作

在 Pod 部署中引用图像拉取密钥、

  1. 创建名为 mypod.yaml 的 pod 配置文件。

  2. 定义要用于访问 IBM Cloud Container Registry 中映像的 pod 和映像拉取私钥。

    要访问私人图像、

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
        - name: <container_name>
          image: <region>.icr.io/<namespace_name>/<image_name>:<tag>
      imagePullSecrets:
        - name: <secret_name>
    

    访问 IBM Cloud 公共图像、

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
        - name: <container_name>
          image: icr.io/<image_name>:<tag>
      imagePullSecrets:
        - name: <secret_name>
    
    container_name>
    要部署到集群的容器的名称。 namespace_name>: 存储映像的注册表命名空间。 要列出可用名称空间,请运行 ibmcloud cr namespace-listimage_name>: 要使用的映像的名称。 要列出 IBM Cloud 帐户中的可用映像,请运行 ibmcloud cr image-listtag>: 要使用的映像的版本。 如果没有指定标记,则默认使用最新标记的图像。 <secret_name>: 先前创建的映像拉取私钥的名称。
  3. 保存更改。

  4. 在集群中创建部署。

    oc apply -f mypod.yaml
    

将映像推送到 IBM Cloud Container Registry

在集群管理员 使用 IBM Cloud Container Registry 设置映像注册表后,您可以通过向名称空间添加映像来安全地存储 Docker 映像并与其他用户共享这些映像。

例如,您可以从任何私人或公共注册源获取图像,然后对其进行标记,以便以后在 IBM Cloud Container Registry 中使用。 或者,您可以将使用的 Docker 映像推送到名称空间,以便其他用户可以访问该映像。 要开始使用,请参阅 向名称空间添加映像

使用 Vulnerability Advisor 管理 IBM Cloud Container Registry 中映像的安全性

Vulnerability Advisor 检查由、第三方提供或添加到组织的 命名空间的容器映像的安全状态。IBM IBM Cloud Container Registry

将映像添加到名称空间时,Vulnerability Advisor 会自动对该映像进行扫描,以检测安全问题和潜在漏洞。 如果发现安全问题,系统会提供指示信息,以帮助修复所报告的漏洞。 要开始使用,请参阅 使用 Vulnerability Advisor

为容器映像设置可信内容

可以基于已签名并存储在 IBM Cloud Container Registry 中的可信映像来构建容器,并阻止未签名或易受攻击的映像中的部署。

  1. 对可信内容的映像签名。 设置映像的信任后,可以管理可信内容和可以将映像推送到注册表的签署者。
  2. 要实施策略以便只能使用已签名的映像在集群中构建容器,请 安装开放式源代码 Portieris 项目
  3. 集群用户可以部署通过可信映像构建的应用程序。
    1. 部署到 default Kubernetes 名称空间
    2. 部署到其他 Kubernetes 名称空间,或从其他 IBM Cloud 区域或帐户进行部署

在群集中启用图像安全强制执行

在集群中启用映像安全性实施时,将安装开放式源代码 Portieris Kubernetes 项目。 然后,您可以创建映像策略,防止不符合策略的 pod(如未签名的映像)在群集中运行。

有关更多信息,请参阅 Portieris 文档

突变图像: 缺省情况下,Portieris 使用 MutatingAdmissionWebhook 许可控制器来突变图像,以通过摘要而不是标记来引用该图像。 但是,您可能有一些部署技术会拒绝已突变的映像。 如果是这样,那么可以使用 图像突变选项策略 来更改缺省行为。

启用或禁用映像安全性实施

您可以从 CLI 或控制台为集群启用或禁用映像安全性实施。 对于较早版本,请参阅 Portieris 文档

使用 CLI 启用或禁用映像安全性实施

请参阅以下命令。

从控制台启用或禁用映像安全性实施

  1. 控制面板中选择您的仪表盘。
  2. 找到图像安全设置区域,点击启用禁用

缺省映像策略

启用映像安全实施时,Red Hat OpenShift on IBM Cloud 会自动在集群中创建某些映像策略。 禁用该功能时,将除去底层 ClusterImagePolicy CRD,这将除去所有缺省映像策略以及您创建的任何定制映像策略。

  • 名称为 ibm-signed-image-enforcement 的映像策略将项目中运行的映像限制为仅 Red Hat OpenShift on IBM Cloud 映像。 请勿修改这些映像策略。 您所作的任何更改都将在几分钟内被覆盖。
  • 其他映像策略 (例如 defaultdefault-allow-all) 允许不受其他映像策略限制的映像。 您可以修改这些映像策略并保留更改,但不重命名映像策略。 如果重命名策略,那么将创建更多具有缺省名称和设置的策略。

要查看集群中的映像策略,

准备工作

访问 Red Hat OpenShift 集群

  1. 列出全局应用于集群的映像策略。 有关示例配置,请参阅 Portieris 策略文档

    oc get ClusterImagePolicy
    
  2. 列出应用于集群中特定名称空间的映像策略。 有关示例配置,请参阅 Portieris 策略文档

    oc get ImagePolicy --all-namespaces