8.4. 配置 ACME 签发者


Red Hat OpenShift 的 cert-manager Operator 支持使用自动证书管理环境 (ACME) CA 服务器(如 Let’s Encrypt)来发布证书。通过在 Issuer API 对象中指定 secret 详情来配置显式凭证。方便的凭证从环境、元数据服务或本地文件中提取,这些文件没有在 Issuer API 对象中明确配置。

注意

Issuer 对象是命名空间范围。它只能从同一命名空间中发布证书。您还可以使用 ClusterIssuer 对象在集群中的所有命名空间中发布证书。

定义 ClusterIssuer 对象的 YAML 文件示例

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: acme-cluster-issuer
spec:
  acme:
    ...

注意

默认情况下,您可以将 ClusterIssuer 对象与 ambient 凭证一起使用。要将 Issuer 对象与 ambient 凭证搭配使用,您必须为 cert-manager 控制器启用 --issuer-ambient-credentials 设置。

8.4.1. 关于 ACME 签发者

Red Hat OpenShift 的 cert-manager Operator 的 ACME 签发者类型代表自动的证书颁发机构 (ACME) 证书颁发机构 (CA) 服务器。ACME CA 服务器依赖于一个 质询(challenge) 来验证客户端是否拥有请求证书的域名。如果质询成功,Red Hat OpenShift 的 cert-manager Operator 可以发布证书。如果失败,Red Hat OpenShift 的 cert-manager Operator 不会发布证书。

注意

Let’s Encrypt 和 internet ACME 服务器不支持私有 DNS 区域。

8.4.1.1. 支持的 ACME 质询类型

Red Hat OpenShift 的 cert-manager Operator 支持 ACME 签发者的以下质询类型:

HTTP-01

使用 HTTP-01 质询类型,您可以在域中的 HTTP URL 端点上提供一个计算的密钥。如果 ACME CA 服务器可以从 URL 获取密钥,它可以验证您作为域的所有者。

如需更多信息,请参阅上游 cert-manager 文档中的 HTTP01

注意

HTTP-01 要求 Let’s Encrypt 服务器可以访问集群的路由。如果内部或私有集群位于代理后面,则证书颁发的 HTTP-01 验证会失败。

HTTP-01 质询仅限于端口 80。如需更多信息,请参阅 HTTP-01 质询 (Let’s Encrypt)。

DNS-01

使用 DNS-01 质询类型,您可以在 DNS TXT 记录中提供一个计算的密钥。如果 ACME CA 服务器可以通过 DNS 查找获取密钥,它可以验证您作为域的所有者。

如需更多信息,请参阅上游 cert-manager 文档中的 DNS01

8.4.1.2. 支持的 DNS-01 供应商

Red Hat OpenShift 的 cert-manager Operator 支持以下 ACME 签发者的 DNS-01 供应商:

  • Amazon Route 53
  • Azure DNS

    注意

    Red Hat OpenShift 的 cert-manager Operator 不支持使用 Azure Active Directory (Azure AD) pod 身份为 pod 分配受管身份。

  • Google Cloud DNS

8.4.2. 配置 ACME 签发者以解决 HTTP-01 质询

您可以使用 cert-manager Operator for Red Hat OpenShift 设置 ACME 签发者来解决 HTTP-01 质询。此流程使用 Let 的 Encrypt 作为 ACME CA 服务器。

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 您有一个要公开的服务。在此过程中,该服务名为 sample-workload

流程

  1. 创建 ACME 集群签发者。

    1. 创建定义 ClusterIssuer 对象的 YAML 文件:

      acme-cluster-issuer.yaml 文件示例

      apiVersion: cert-manager.io/v1
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-staging                                        1
      spec:
        acme:
          preferredChain: ""
          privateKeySecretRef:
            name: <secret_for_private_key>                               2
          server: https://acme-staging-v02.api.letsencrypt.org/directory 3
          solvers:
          - http01:
              ingress:
                class: openshift-default                                 4

      1
      为集群签发者提供名称。
      2
      <secret_private_key> 替换为要存储 ACME 帐户私钥的 secret 名称。
      3
      指定用于访问 ACME 服务器的 directory 端点 URL。这个示例使用 Let’s Encrypt staging 环境。
      4
      指定 Ingress 类。
    2. 运行以下命令来创建 ClusterIssuer 对象:

      $ oc create -f acme-cluster-issuer.yaml
  2. 创建一个 Ingress 来公开用户工作负载的服务。

    1. 创建定义 Namespace 对象的 YAML 文件:

      namespace.yaml 文件示例

      apiVersion: v1
      kind: Namespace
      metadata:
        name: my-ingress-namespace 1

      1
      指定 Ingress 的命名空间。
    2. 运行以下命令来创建 Namespace 对象:

      $ oc create -f namespace.yaml
    3. 创建定义 Ingress 对象的 YAML 文件:

      ingress.yaml 文件示例

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: sample-ingress                                           1
        namespace: my-ingress-namespace                                2
        annotations:
          cert-manager.io/cluster-issuer: letsencrypt-staging          3
          acme.cert-manager.io/http01-ingress-class: openshift-default 4
      spec:
        ingressClassName: openshift-default                            5
        tls:
        - hosts:
          - <hostname>                                                 6
          secretName: sample-tls                                       7
        rules:
        - host: <hostname>                                             8
          http:
            paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: sample-workload                                9
                  port:
                    number: 80

      1
      指定 Ingress 的名称。
      2
      指定您为 Ingress 创建的命名空间。
      3
      指定您创建的集群签发者。
      4
      指定 Ingress 类。
      5
      指定 Ingress 类。
      6
      <hostname> 替换为要与证书关联的 Subject Alternative Name。此名称用于在证书中添加 DNS 名称。
      7
      指定要存储创建证书的 secret。
      8
      <hostname> 替换为主机名。您可以使用 <host_name>.<cluster_ingress_domain> 语法来利用 *.<cluster_ingress_domain> 通配符 DNS 记录并为集群提供证书。例如,您可以使用 apps.<cluster_base_domain>。否则,您必须确保为所选主机名存在 DNS 记录。
      9
      指定要公开的服务名称。本例使用名为 sample-workload 的服务。
    4. 运行以下命令来创建 Ingress 对象:

      $ oc create -f ingress.yaml

8.4.3. 使用 AWS Route53 的显式凭证配置 ACME 签发者

您可以使用 cert-manager Operator for Red Hat OpenShift 设置自动证书管理环境(ACME)签发者,通过使用 AWS 上的显式凭证来解决 DNS-01 质询。此流程使用 Let's Encrypt 作为 ACME 证书颁发机构(CA)服务器,并演示了如何解决 Amazon Route 53 的 DNS-01 质询。

先决条件

  • 您必须提供显式 accessKeyIDsecretAccessKey 凭证。如需更多信息,请参阅上游 cert-manager 文档中的 Route53

    注意

    您可以在 AWS 上运行的 OpenShift Container Platform 集群中使用带有显式凭证的 Amazon Route 53。

流程

  1. 可选:覆盖 DNS-01 自我检查的名称服务器设置。

    只有在目标公共托管区与集群的默认私有托管区重叠时才需要这一步。

    1. 运行以下命令来编辑 CertManager 资源:

      $ oc edit certmanager cluster
    2. 使用以下覆盖参数添加 spec.controllerConfig 部分:

      apiVersion: operator.openshift.io/v1alpha1
      kind: CertManager
      metadata:
        name: cluster
        ...
      spec:
        ...
        controllerConfig:                                1
          overrideArgs:
            - '--dns01-recursive-nameservers-only'       2
            - '--dns01-recursive-nameservers=1.1.1.1:53' 3
      1
      添加 spec.controllerConfig 部分。
      2
      指定只使用递归名称服务器,而不是检查与该域关联的权威名称服务器。
      3
      提供以逗号分隔的 <host>:<port> 名称服务器列表来查询 DNS-01 自我检查。您必须使用 1.1.1.1:53 值来避免公共和私有区重叠。
    3. 保存文件以使改变生效。
  2. 可选:为签发者创建一个命名空间:

    $ oc new-project <issuer_namespace>
  3. 运行以下命令,创建一个 secret 来存储 AWS 凭证:

    $ oc create secret generic aws-secret --from-literal=awsSecretAccessKey=<aws_secret_access_key> \ 1
        -n my-issuer-namespace
    1
    <aws_secret_access_key> 替换为您的 AWS secret 访问密钥。
  4. 创建签发者:

    1. 创建定义 Issuer 对象的 YAML 文件:

      issuer.yaml 文件示例

      apiVersion: cert-manager.io/v1
      kind: Issuer
      metadata:
        name: <letsencrypt_staging>                                        1
        namespace: <issuer_namespace>                                   2
      spec:
        acme:
          server: https://acme-staging-v02.api.letsencrypt.org/directory 3
          email: "<email_address>"                                       4
          privateKeySecretRef:
            name: <secret_private_key>                                   5
          solvers:
          - dns01:
              route53:
                accessKeyID: <aws_key_id>                                6
                hostedZoneID: <hosted_zone_id>                           7
                region: <region_name>                                    8
                secretAccessKeySecretRef:
                  name: "aws-secret"                                     9
                  key: "awsSecretAccessKey"                              10

      1
      为签发者提供名称。
      2
      指定您为签发者创建的命名空间。
      3
      指定用于访问 ACME 服务器的 directory 端点 URL。这个示例使用 Let’s Encrypt staging 环境。
      4
      <email_address> 替换为您的电子邮件地址。
      5
      <secret_private_key> 替换为要存储 ACME 帐户私钥的 secret 名称。
      6
      <aws_key_id> 替换为您的 AWS 密钥 ID。
      7
      <hosted_zone_id> 替换为您的托管区 ID。
      8
      <region_name> 替换为 AWS 区域名称。例如,us-east-1
      9
      指定您创建的 secret 的名称。
      10
      指定您创建的 secret 中的密钥,用于存储 AWS secret 访问密钥。
    2. 运行以下命令来创建 Issuer 对象:

      $ oc create -f issuer.yaml

8.4.4. 在 AWS 上使用 ambient 凭证配置 ACME 签发者

您可以使用 Red Hat OpenShift 的 cert-manager Operator 设置 ACME 签发者,通过使用 AWS 上的 ambient 凭证来解决 DNS-01 质询。此流程使用 Let’s Encrypt 作为 ACME CA 服务器,并演示了如何解决 Amazon Route 53 的 DNS-01 质询。

先决条件

  • 如果您的集群被配置为使用 AWS 安全令牌服务 (STS),则遵循为 Red Hat OpenShift 为 AWS Security Token Service 集群配置 cert-manager Operator 的云凭证 一节中的内容。
  • 如果您的集群没有使用 AWS STS,按照 为 Red Hat OpenShift on AWS 的 cert-manager Operator 配置云凭证中的内容进行操作。

流程

  1. 可选:覆盖 DNS-01 自我检查的名称服务器设置。

    只有在目标公共托管区与集群的默认私有托管区重叠时才需要这一步。

    1. 运行以下命令来编辑 CertManager 资源:

      $ oc edit certmanager cluster
    2. 使用以下覆盖参数添加 spec.controllerConfig 部分:

      apiVersion: operator.openshift.io/v1alpha1
      kind: CertManager
      metadata:
        name: cluster
        ...
      spec:
        ...
        controllerConfig:                                1
          overrideArgs:
            - '--dns01-recursive-nameservers-only'       2
            - '--dns01-recursive-nameservers=1.1.1.1:53' 3
      1
      添加 spec.controllerConfig 部分。
      2
      指定只使用递归名称服务器,而不是检查与该域关联的权威名称服务器。
      3
      提供以逗号分隔的 <host>:<port> 名称服务器列表来查询 DNS-01 自我检查。您必须使用 1.1.1.1:53 值来避免公共和私有区重叠。
    3. 保存文件以使改变生效。
  2. 可选:为签发者创建一个命名空间:

    $ oc new-project <issuer_namespace>
  3. 修改 CertManager 资源以添加 --issuer-ambient-credentials 参数:

    $ oc patch certmanager/cluster \
      --type=merge \
      -p='{"spec":{"controllerConfig":{"overrideArgs":["--issuer-ambient-credentials"]}}}'
  4. 创建签发者:

    1. 创建定义 Issuer 对象的 YAML 文件:

      issuer.yaml 文件示例

      apiVersion: cert-manager.io/v1
      kind: Issuer
      metadata:
        name: <letsencrypt_staging>                                        1
        namespace: <issuer_namespace>                                   2
      spec:
        acme:
          server: https://acme-staging-v02.api.letsencrypt.org/directory 3
          email: "<email_address>"                                       4
          privateKeySecretRef:
            name: <secret_private_key>                                   5
          solvers:
          - dns01:
              route53:
                hostedZoneID: <hosted_zone_id>                           6
                region: us-east-1

      1
      为签发者提供名称。
      2
      指定您为签发者创建的命名空间。
      3
      指定用于访问 ACME 服务器的 directory 端点 URL。这个示例使用 Let’s Encrypt staging 环境。
      4
      <email_address> 替换为您的电子邮件地址。
      5
      <secret_private_key> 替换为要存储 ACME 帐户私钥的 secret 名称。
      6
      <hosted_zone_id> 替换为您的托管区 ID。
    2. 运行以下命令来创建 Issuer 对象:

      $ oc create -f issuer.yaml

8.4.5. 使用 GCP Cloud DNS 的显式凭证配置 ACME 签发者

您可以使用 Red Hat OpenShift 的 cert-manager Operator 设置 ACME 签发者,以便在 GCP 上使用显式凭证来解决 DNS-01 质询。此流程使用 Let's Encrypt 作为 ACME CA 服务器,并演示了如何解决 Google CloudDNS 的 DNS-01 质询。

先决条件

  • 您已为 Google CloudDNS 设置具有所需角色的 Google Cloud 服务帐户。如需更多信息,请参阅上游 cert-manager 文档中的 Google CloudDNS

    注意

    您可以在没有在 GCP 上运行的 OpenShift Container Platform 集群中使用带有显式凭证的 Google CloudDNS。

流程

  1. 可选:覆盖 DNS-01 自我检查的名称服务器设置。

    只有在目标公共托管区与集群的默认私有托管区重叠时才需要这一步。

    1. 运行以下命令来编辑 CertManager 资源:

      $ oc edit certmanager cluster
    2. 使用以下覆盖参数添加 spec.controllerConfig 部分:

      apiVersion: operator.openshift.io/v1alpha1
      kind: CertManager
      metadata:
        name: cluster
        ...
      spec:
        ...
        controllerConfig:                                1
          overrideArgs:
            - '--dns01-recursive-nameservers-only'       2
            - '--dns01-recursive-nameservers=1.1.1.1:53' 3
      1
      添加 spec.controllerConfig 部分。
      2
      指定只使用递归名称服务器,而不是检查与该域关联的权威名称服务器。
      3
      提供以逗号分隔的 <host>:<port> 名称服务器列表来查询 DNS-01 自我检查。您必须使用 1.1.1.1:53 值来避免公共和私有区重叠。
    3. 保存文件以使改变生效。
  2. 可选:为签发者创建一个命名空间:

    $ oc new-project my-issuer-namespace
  3. 运行以下命令,创建一个 secret 来存储 GCP 凭证:

    $ oc create secret generic clouddns-dns01-solver-svc-acct --from-file=service_account.json=<path/to/gcp_service_account.json> -n my-issuer-namespace
  4. 创建签发者:

    1. 创建定义 Issuer 对象的 YAML 文件:

      issuer.yaml 文件示例

      apiVersion: cert-manager.io/v1
      kind: Issuer
      metadata:
        name: <acme_dns01_clouddns_issuer> 1
        namespace: <issuer_namespace> 2
      spec:
        acme:
          preferredChain: ""
          privateKeySecretRef:
            name: <secret_private_key> 3
          server: https://acme-staging-v02.api.letsencrypt.org/directory 4
          solvers:
          - dns01:
              cloudDNS:
                project: <project_id> 5
                serviceAccountSecretRef:
                  name: clouddns-dns01-solver-svc-acct 6
                  key: service_account.json 7

      1
      为签发者提供名称。
      2
      <issuer_namespace> 替换为您的签发者命名空间。
      3
      <secret_private_key> 替换为要存储 ACME 帐户私钥的 secret 名称。
      4
      指定用于访问 ACME 服务器的 directory 端点 URL。这个示例使用 Let’s Encrypt staging 环境。
      5
      <project_id> 替换为包含 Cloud DNS 区的 GCP 项目的名称。
      6
      指定您创建的 secret 的名称。
      7
      指定您创建的 secret 中存储 GCP secret 访问密钥的密钥。
    2. 运行以下命令来创建 Issuer 对象:

      $ oc create -f issuer.yaml

8.4.6. 使用 GCP 上的 ambient 凭证配置 ACME 签发者

您可以使用 Red Hat OpenShift 的 cert-manager Operator 设置 ACME 签发者,通过使用 GCP 上的 ambient 凭证来解决 DNS-01 质询。此流程使用 Let's Encrypt 作为 ACME CA 服务器,并演示了如何解决 Google CloudDNS 的 DNS-01 质询。

先决条件

  • 如果您的集群被配置为使用 GCP Workload Identity,则遵循 为带有 GCP Workload Identity 的 Red Hat OpenShift 为 cert-manager Operator 配置云凭证 中的内容。
  • 如果您的集群没有使用 GCP Workload Identity,按照 为 Red Hat OpenShift on GCP 上的 cert-manager Operator 配置云凭证 中的内容进行操作。

流程

  1. 可选:覆盖 DNS-01 自我检查的名称服务器设置。

    只有在目标公共托管区与集群的默认私有托管区重叠时才需要这一步。

    1. 运行以下命令来编辑 CertManager 资源:

      $ oc edit certmanager cluster
    2. 使用以下覆盖参数添加 spec.controllerConfig 部分:

      apiVersion: operator.openshift.io/v1alpha1
      kind: CertManager
      metadata:
        name: cluster
        ...
      spec:
        ...
        controllerConfig:                                1
          overrideArgs:
            - '--dns01-recursive-nameservers-only'       2
            - '--dns01-recursive-nameservers=1.1.1.1:53' 3
      1
      添加 spec.controllerConfig 部分。
      2
      指定只使用递归名称服务器,而不是检查与该域关联的权威名称服务器。
      3
      提供以逗号分隔的 <host>:<port> 名称服务器列表来查询 DNS-01 自我检查。您必须使用 1.1.1.1:53 值来避免公共和私有区重叠。
    3. 保存文件以使改变生效。
  2. 可选:为签发者创建一个命名空间:

    $ oc new-project <issuer_namespace>
  3. 修改 CertManager 资源以添加 --issuer-ambient-credentials 参数:

    $ oc patch certmanager/cluster \
      --type=merge \
      -p='{"spec":{"controllerConfig":{"overrideArgs":["--issuer-ambient-credentials"]}}}'
  4. 创建签发者:

    1. 创建定义 Issuer 对象的 YAML 文件:

      issuer.yaml 文件示例

      apiVersion: cert-manager.io/v1
      kind: Issuer
      metadata:
        name: <acme_dns01_clouddns_issuer> 1
        namespace: <issuer_namespace>
      spec:
        acme:
          preferredChain: ""
          privateKeySecretRef:
            name: <secret_private_key> 2
          server: https://acme-staging-v02.api.letsencrypt.org/directory 3
          solvers:
          - dns01:
              cloudDNS:
                project: <gcp_project_id> 4

      1
      为签发者提供名称。
      2
      <secret_private_key> 替换为要存储 ACME 帐户私钥的 secret 名称。
      3
      指定用于访问 ACME 服务器的 directory 端点 URL。这个示例使用 Let’s Encrypt staging 环境。
      4
      <gcp_project_id> 替换为包含 Cloud DNS 区的 GCP 项目的名称。
    2. 运行以下命令来创建 Issuer 对象:

      $ oc create -f issuer.yaml

8.4.7. 使用 Microsoft Azure DNS 的显式凭证配置 ACME 签发者

您可以使用 Red Hat OpenShift 的 cert-manager Operator 设置 ACME 签发者,以便在 Microsoft Azure 上使用显式凭证来解决 DNS-01 质询。此流程使用 Let's Encrypt 作为 ACME CA 服务器,并演示了如何解决 Azure DNS 的 DNS-01 质询。

先决条件

  • 您已为 Azure DNS 设置具有所需角色的服务主体。如需更多信息,请参阅上游 cert-manager 文档中的 Azure DNS

    注意

    对于不在 Microsoft Azure 上运行的 OpenShift Container Platform 集群,您可以按照以下步骤操作。

流程

  1. 可选:覆盖 DNS-01 自我检查的名称服务器设置。

    只有在目标公共托管区与集群的默认私有托管区重叠时才需要这一步。

    1. 运行以下命令来编辑 CertManager 资源:

      $ oc edit certmanager cluster
    2. 使用以下覆盖参数添加 spec.controllerConfig 部分:

      apiVersion: operator.openshift.io/v1alpha1
      kind: CertManager
      metadata:
        name: cluster
        ...
      spec:
        ...
        controllerConfig:                                1
          overrideArgs:
            - '--dns01-recursive-nameservers-only'       2
            - '--dns01-recursive-nameservers=1.1.1.1:53' 3
      1
      添加 spec.controllerConfig 部分。
      2
      指定只使用递归名称服务器,而不是检查与该域关联的权威名称服务器。
      3
      提供以逗号分隔的 <host>:<port> 名称服务器列表来查询 DNS-01 自我检查。您必须使用 1.1.1.1:53 值来避免公共和私有区重叠。
    3. 保存文件以使改变生效。
  2. 可选:为签发者创建一个命名空间:

    $ oc new-project my-issuer-namespace
  3. 运行以下命令,创建一个 secret 来存储 Azure 凭证:

    $ oc create secret generic <secret_name> --from-literal=<azure_secret_access_key_name>=<azure_secret_access_key_value> \ 1 2 3
        -n my-issuer-namespace
    1
    <secret_name> 替换为您的 secret 名称。
    2
    <azure_secret_access_key_name> 替换为您的 Azure secret 访问密钥名称。
    3
    <azure_secret_access_key_value> 替换为您的 Azure secret 键。
  4. 创建签发者:

    1. 创建定义 Issuer 对象的 YAML 文件:

      issuer.yaml 文件示例

      apiVersion: cert-manager.io/v1
      kind: Issuer
      metadata:
        name: <acme-dns01-azuredns-issuer>   1
        namespace: <issuer_namespace>   2
      spec:
        acme:
          preferredChain: ""
          privateKeySecretRef:
            name: <secret_private_key> 3
          server: https://acme-staging-v02.api.letsencrypt.org/directory 4
          solvers:
          - dns01:
              azureDNS:
                clientID: <azure_client_id> 5
                clientSecretSecretRef:
                  name: <secret_name> 6
                  key: <azure_secret_access_key_name> 7
                subscriptionID: <azure_subscription_id> 8
                tenantID: <azure_tenant_id> 9
                resourceGroupName: <azure_dns_zone_resource_group> 10
                hostedZoneName: <azure_dns_zone> 11
                environment: AzurePublicCloud

      1
      为签发者提供名称。
      2
      <issuer_namespace> 替换为您的签发者命名空间。
      3
      <secret_private_key> 替换为要存储 ACME 帐户私钥的 secret 名称。
      4
      指定用于访问 ACME 服务器的 directory 端点 URL。这个示例使用 Let’s Encrypt staging 环境。
      5
      <azure_client_id> 替换为您的 Azure 客户端 ID。
      6
      <secret_name> 替换为客户端 secret 的名称。
      7
      <azure_secret_access_key_name> 替换为客户端 secret 密钥名称。
      8
      <azure_subscription_id> 替换为您的 Azure 订阅 ID。
      9
      <azure_tenant_id> 替换为您的 Azure 租户 ID。
      10
      <azure_dns_zone_resource_group> 替换为 Azure DNS 区资源组的名称。
      11
      <azure_dns_zone> 替换为 Azure DNS 区的名称。
    2. 运行以下命令来创建 Issuer 对象:

      $ oc create -f issuer.yaml

8.4.8. 其他资源

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.