×

Red Hat为Red Hat容器注册表中的镜像提供签名。这些签名可以在使用机器配置操作符 (MCO) 将其拉取到OpenShift Container Platform 4集群时自动验证。

Quay.io 提供构成OpenShift Container Platform的大部分镜像,并且只有发行版镜像已签名。发行版镜像是指经批准的OpenShift Container Platform镜像,提供一定程度的保护,以防范供应链攻击。但是,OpenShift Container Platform的一些扩展(例如日志记录、监控和服务网格)是从Operator Lifecycle Manager (OLM)提供的Operator。这些镜像来自Red Hat生态系统目录容器镜像注册表。

要验证Red Hat注册表和您的基础架构之间这些镜像的完整性,请启用签名验证。

启用Red Hat容器注册表的签名验证

为Red Hat容器注册表启用容器签名验证需要编写一个签名验证策略文件,该文件指定用于验证来自这些注册表的镜像的密钥。对于RHEL8节点,注册表默认情况下已在/etc/containers/registries.d中定义。

步骤
  1. 创建一个Butane配置文件,51-worker-rh-registry-trust.bu,其中包含工作节点所需的配置。

    有关Butane的信息,请参阅“使用Butane创建机器配置”。

    variant: openshift
    version: 4.17.0
    metadata:
      name: 51-worker-rh-registry-trust
      labels:
        machineconfiguration.openshift.io/role: worker
    storage:
      files:
      - path: /etc/containers/policy.json
        mode: 0644
        overwrite: true
        contents:
          inline: |
            {
              "default": [
                {
                  "type": "insecureAcceptAnything"
                }
              ],
              "transports": {
                "docker": {
                  "registry.access.redhat.com": [
                    {
                      "type": "signedBy",
                      "keyType": "GPGKeys",
                      "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
                    }
                  ],
                  "registry.redhat.io": [
                    {
                      "type": "signedBy",
                      "keyType": "GPGKeys",
                      "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
                    }
                  ]
                },
                "docker-daemon": {
                  "": [
                    {
                      "type": "insecureAcceptAnything"
                    }
                  ]
                }
              }
            }
  2. 使用Butane生成一个机器配置YAML文件,51-worker-rh-registry-trust.yaml,其中包含要写入工作节点磁盘的文件。

    $ butane 51-worker-rh-registry-trust.bu -o 51-worker-rh-registry-trust.yaml
  3. 应用创建的机器配置。

    $ oc apply -f 51-worker-rh-registry-trust.yaml
  4. 检查工作机器配置池是否已使用新的机器配置推出。

    1. 检查是否创建了新的机器配置。

      $ oc get mc
      示例输出
      NAME                                               GENERATEDBYCONTROLLER                      IGNITIONVERSION   AGE
      00-master                                          a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      00-worker                                          a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      01-master-container-runtime                        a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      01-master-kubelet                                  a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      01-worker-container-runtime                        a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      01-worker-kubelet                                  a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      51-master-rh-registry-trust                                                                   3.2.0             13s
      51-worker-rh-registry-trust                                                                   3.2.0             53s (1)
      99-master-generated-crio-seccomp-use-default                                                  3.2.0             25m
      99-master-generated-registries                     a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      99-master-ssh                                                                                 3.2.0             28m
      99-worker-generated-crio-seccomp-use-default                                                  3.2.0             25m
      99-worker-generated-registries                     a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             25m
      99-worker-ssh                                                                                 3.2.0             28m
      rendered-master-af1e7ff78da0a9c851bab4be2777773b   a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             8s
      rendered-master-cd51fd0c47e91812bfef2765c52ec7e6   a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             24m
      rendered-worker-2b52f75684fbc711bd1652dd86fd0b82   a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             24m
      rendered-worker-be3b3bce4f4aa52a62902304bac9da3c   a2178ad522c49ee330b0033bb5cb5ea132060b0a   3.2.0             48s (2)
      
      1 新的机器配置
      2 新的渲染机器配置
    2. 检查工作机器配置池是否正在使用新的机器配置更新。

      $ oc get mcp
      示例输出
      NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
      master   rendered-master-af1e7ff78da0a9c851bab4be2777773b   True      False      False      3              3                   3                     0                      30m
      worker   rendered-worker-be3b3bce4f4aa52a62902304bac9da3c   False     True       False      3              0                   0                     0                      30m (1)
      
      1 UPDATING字段为True时,机器配置池正在使用新的机器配置进行更新。当该字段变为False时,工作机器配置池已更新为新的机器配置。
  5. 如果您的集群使用任何RHEL7工作节点,当工作机器配置池更新时,请在这些节点的/etc/containers/registries.d目录中创建YAML文件,这些文件指定给定注册服务器的分离签名的位置。以下示例仅适用于registry.access.redhat.comregistry.redhat.io中托管的镜像。

    1. 启动到每个RHEL7工作节点的调试会话。

      $ oc debug node/<node_name>
    2. 将根目录更改为/host

      sh-4.2# chroot /host
    3. 创建一个包含以下内容的/etc/containers/registries.d/registry.redhat.io.yaml文件。

      docker:
           registry.redhat.io:
               sigstore: https://registry.redhat.io/containers/sigstore
    4. 创建一个包含以下内容的/etc/containers/registries.d/registry.access.redhat.com.yaml文件。

      docker:
           registry.access.redhat.com:
               sigstore: https://access.redhat.com/webassets/docker/content/sigstore
    5. 退出调试会话。

验证签名验证配置

应用机器配置到集群后,机器配置控制器会检测新的MachineConfig对象并生成新的rendered-worker-<hash>版本。

先决条件
  • 您已使用机器配置文件启用签名验证。

步骤
  1. 在命令行上,运行以下命令以显示关于所需工作节点的信息。

    $ oc describe machineconfigpool/worker
    初始工作节点监控的示例输出。
    Name:         worker
    Namespace:
    Labels:       machineconfiguration.openshift.io/mco-built-in=
    Annotations:  <none>
    API Version:  machineconfiguration.openshift.io/v1
    Kind:         MachineConfigPool
    Metadata:
      Creation Timestamp:  2019-12-19T02:02:12Z
      Generation:          3
      Resource Version:    16229
      Self Link:           /apis/machineconfiguration.openshift.io/v1/machineconfigpools/worker
      UID:                 92697796-2203-11ea-b48c-fa163e3940e5
    Spec:
      Configuration:
        Name:  rendered-worker-f6819366eb455a401c42f8d96ab25c02
        Source:
          API Version:  machineconfiguration.openshift.io/v1
          Kind:         MachineConfig
          Name:         00-worker
          API Version:  machineconfiguration.openshift.io/v1
          Kind:         MachineConfig
          Name:         01-worker-container-runtime
          API Version:  machineconfiguration.openshift.io/v1
          Kind:         MachineConfig
          Name:         01-worker-kubelet
          API Version:  machineconfiguration.openshift.io/v1
          Kind:         MachineConfig
          Name:         51-worker-rh-registry-trust
          API Version:  machineconfiguration.openshift.io/v1
          Kind:         MachineConfig
          Name:         99-worker-92697796-2203-11ea-b48c-fa163e3940e5-registries
          API Version:  machineconfiguration.openshift.io/v1
          Kind:         MachineConfig
          Name:         99-worker-ssh
      Machine Config Selector:
        Match Labels:
          machineconfiguration.openshift.io/role:  worker
      Node Selector:
        Match Labels:
          node-role.kubernetes.io/worker:
      Paused:                              false
    Status:
      Conditions:
        Last Transition Time:  2019-12-19T02:03:27Z
        Message:
        Reason:
        Status:                False
        Type:                  RenderDegraded
        Last Transition Time:  2019-12-19T02:03:43Z
        Message:
        Reason:
        Status:                False
        Type:                  NodeDegraded
        Last Transition Time:  2019-12-19T02:03:43Z
        Message:
        Reason:
        Status:                False
        Type:                  Degraded
        Last Transition Time:  2019-12-19T02:28:23Z
        Message:
        Reason:
        Status:                False
        Type:                  Updated
        Last Transition Time:  2019-12-19T02:28:23Z
        Message:               All nodes are updating to rendered-worker-f6819366eb455a401c42f8d96ab25c02
        Reason:
        Status:                True
        Type:                  Updating
      Configuration:
        Name:  rendered-worker-d9b3f4ffcfd65c30dcf591a0e8cf9b2e
        Source:
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   00-worker
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   01-worker-container-runtime
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   01-worker-kubelet
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   99-worker-92697796-2203-11ea-b48c-fa163e3940e5-registries
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   99-worker-ssh
      Degraded Machine Count:     0
      Machine Count:              1
      Observed Generation:        3
      Ready Machine Count:        0
      Unavailable Machine Count:  1
      Updated Machine Count:      0
    Events:                       <none>
  2. 再次运行oc describe命令。

    $ oc describe machineconfigpool/worker
    工作节点更新后的示例输出。
    ...
        Last Transition Time:  2019-12-19T04:53:09Z
        Message:               All nodes are updated with rendered-worker-f6819366eb455a401c42f8d96ab25c02
        Reason:
        Status:                True
        Type:                  Updated
        Last Transition Time:  2019-12-19T04:53:09Z
        Message:
        Reason:
        Status:                False
        Type:                  Updating
      Configuration:
        Name:  rendered-worker-f6819366eb455a401c42f8d96ab25c02
        Source:
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   00-worker
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   01-worker-container-runtime
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   01-worker-kubelet
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   51-worker-rh-registry-trust
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   99-worker-92697796-2203-11ea-b48c-fa163e3940e5-registries
          API Version:            machineconfiguration.openshift.io/v1
          Kind:                   MachineConfig
          Name:                   99-worker-ssh
      Degraded Machine Count:     0
      Machine Count:              3
      Observed Generation:        4
      Ready Machine Count:        3
      Unavailable Machine Count:  0
      Updated Machine Count:      3
    ...

    Observed Generation参数显示基于控制器生成的配置的代数增加计数。即使控制器未能处理规范并生成修订版,此控制器也会更新此值。Configuration Source值指向51-worker-rh-registry-trust配置。

  3. 使用以下命令确认policy.json文件是否存在。

    $ oc debug node/<node> -- chroot /host cat /etc/containers/policy.json
    示例输出。
    Starting pod/<node>-debug ...
    To use host binaries, run `chroot /host`
    {
      "default": [
        {
          "type": "insecureAcceptAnything"
        }
      ],
      "transports": {
        "docker": {
          "registry.access.redhat.com": [
            {
              "type": "signedBy",
              "keyType": "GPGKeys",
              "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
            }
          ],
          "registry.redhat.io": [
            {
              "type": "signedBy",
              "keyType": "GPGKeys",
              "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
            }
          ]
        },
        "docker-daemon": {
          "": [
            {
              "type": "insecureAcceptAnything"
            }
          ]
        }
      }
    }
  4. 使用以下命令确认registry.redhat.io.yaml文件是否存在。

    $ oc debug node/<node> -- chroot /host cat /etc/containers/registries.d/registry.redhat.io.yaml
    示例输出。
    Starting pod/<node>-debug ...
    To use host binaries, run `chroot /host`
    docker:
         registry.redhat.io:
             sigstore: https://registry.redhat.io/containers/sigstore
  5. 使用以下命令确认registry.access.redhat.com.yaml文件是否存在。

    $ oc debug node/<node> -- chroot /host cat /etc/containers/registries.d/registry.access.redhat.com.yaml
    示例输出。
    Starting pod/<node>-debug ...
    To use host binaries, run `chroot /host`
    docker:
         registry.access.redhat.com:
             sigstore: https://access.redhat.com/webassets/docker/content/sigstore

了解缺少可验证签名的容器镜像的验证

每个OpenShift Container Platform发行版镜像都是不可变的,并使用Red Hat生产密钥签名。在OpenShift Container Platform更新或安装期间,发行版镜像可能会部署不具有可验证签名的容器镜像。每个签名的发行版镜像摘要都是不可变的。发行版镜像中的每个引用都是对另一个镜像的不可变摘要的引用,因此可以信任其内容。换句话说,发行版镜像上的签名验证所有发行版内容。

例如,缺少可验证签名的镜像引用包含在签名的OpenShift Container Platform发行版镜像中。

发行版信息示例输出。
$ oc adm release info  quay.io/openshift-release-dev/ ocp-release@sha256:2309578b68c5666dad62aed696f1f9d778ae1a089ee461060ba7b9514b7ca417 -o pullspec (1)
quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9aafb914d5d7d0dec4edd800d02f811d7383a7d49e500af548eab5d00c1bffdb (2)
1 签名的发行版镜像SHA。
2 包含在发行版中且缺少可验证签名的容器镜像。

更新期间的自动验证

签名验证是自动进行的。OpenShift Cluster Version Operator (CVO) 在OpenShift Container Platform更新期间验证发行版镜像上的签名。这是一个内部流程。如果自动验证失败,则OpenShift Container Platform安装或更新将失败。

也可以使用skopeo命令行实用程序手动进行签名验证。

其他资源

使用skopeo验证Red Hat容器镜像的签名

您可以通过从OCP发行版镜像站点提取这些签名来验证包含在OpenShift Container Platform发行版镜像中的容器镜像的签名。由于镜像站点上的签名不是Podman或CRI-O易于理解的格式,您可以使用skopeo standalone-verify命令来验证您的发行版镜像是否由Red Hat签名。

先决条件
  • 您已安装skopeo命令行实用程序。

步骤
  1. 通过运行以下命令获取发行版的完整SHA。

    $ oc adm release info <release_version>  \ (1)
    1 将<release_version>替换为您的发行版号,例如4.14.3
    示例输出片段。
    ---
    Pull From: quay.io/openshift-release-dev/ocp-release@sha256:e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55
    ---
  2. 通过运行以下命令下载Red Hat发行版密钥。

    $ curl -o pub.key https://access.redhat.com/security/data/fd431d51.txt
  3. 通过运行以下命令获取要验证的特定发行版的签名文件。

    $ curl -o signature-1 https://mirror.openshift.com/pub/openshift-v4/signatures/openshift-release-dev/ocp-release/sha256%<sha_from_version>/signature-1 \ (1)
    1 <sha_from_version>替换为与发行版SHA匹配的镜像站点完整链接中的SHA值。例如,4.12.23发行版的签名链接是https://mirror.openshift.com/pub/openshift-v4/signatures/openshift-release-dev/ocp-release/sha256%e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55/signature-1,SHA值为e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55
  4. 通过运行以下命令获取发行版镜像的清单。

    $ skopeo inspect --raw docker://<quay_link_to_release> > manifest.json \ (1)
    1 <quay_link_to_release>替换为oc adm release info命令的输出。例如,quay.io/openshift-release-dev/ocp-release@sha256:e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55
  5. 使用skopeo验证签名。

    $ skopeo standalone-verify manifest.json quay.io/openshift-release-dev/ocp-release:<release_number>-<arch> any signature-1 --public-key-file pub.key

    其中

    <release_number>

    指定发行版号,例如4.14.3

    <arch>

    指定体系结构,例如x86_64

    示例输出。
    Signature verified using fingerprint 567E347AD0044ADE55BA8A5F199E2F91FD431D51, digest sha256:e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55

其他资源