×

理解密钥

Secret 对象类型提供了一种机制来保存敏感信息,例如密码、Red Hat OpenShift Service on AWS 客户端配置文件、私有源代码库凭据等。密钥将敏感内容与 Pod 解耦。您可以使用卷插件将密钥挂载到容器中,或者系统可以使用密钥代表 Pod 执行操作。

主要属性包括:

  • 密钥数据可以独立于其定义进行引用。

  • 密钥数据卷由临时文件存储设施 (tmpfs) 支持,永远不会在节点上保存。

  • 密钥数据可以在命名空间内共享。

YAML Secret 对象定义
apiVersion: v1
kind: Secret
metadata:
  name: test-secret
  namespace: my-namespace
type: Opaque (1)
data: (2)
  username: <username> (3)
  password: <password>
stringData: (4)
  hostname: myapp.mydomain.com (5)
1 指示密钥的键名和值的结构。
2 data 字段中键的允许格式必须符合Kubernetes 标识符词汇表中的**DNS_SUBDOMAIN**值中的指南。
3 data映射中与键关联的值必须是 base64 编码的。
4 stringData映射中的条目将转换为 base64,然后条目将自动移动到data映射。此字段是只写字段;该值仅通过data字段返回。
5 stringData映射中与键关联的值由纯文本字符串组成。

必须先创建密钥,然后再创建依赖于该密钥的 Pod。

创建密钥时:

  • 创建一个包含密钥数据的密钥对象。

  • 更新 Pod 的服务帐户以允许引用密钥。

  • 创建一个 Pod,它将密钥用作环境变量或文件(使用secret卷)。

密钥类型

type字段中的值指示密钥的键名和值的结构。该类型可用于强制在密钥对象中存在用户名和密钥。如果您不希望进行验证,请使用opaque类型(这是默认类型)。

指定以下类型之一以触发最小的服务器端验证,以确保密钥数据中存在特定键名:

  • kubernetes.io/basic-auth:与基本身份验证一起使用

  • kubernetes.io/dockercfg:用作镜像拉取密钥

  • kubernetes.io/dockerconfigjson:用作镜像拉取密钥

  • kubernetes.io/service-account-token:用于获取旧版服务帐户 API 令牌

  • kubernetes.io/ssh-auth:与 SSH 密钥身份验证一起使用

  • kubernetes.io/tls:与 TLS 证书颁发机构一起使用

如果您不希望进行验证,请指定type: Opaque,这意味着密钥不声明符合任何键名或值的约定。不透明密钥允许包含任意值的非结构化key:value对。

您可以指定其他任意类型,例如example.com/my-secret-type。这些类型不会在服务器端强制执行,但表示密钥的创建者打算符合该类型的键/值要求。

有关创建不同类型密钥的示例,请参见了解如何创建密钥

密钥数据键

密钥必须位于 DNS 子域中。

自动生成的镜像拉取密钥

默认情况下,Red Hat OpenShift Service on AWS 为每个服务帐户创建一个镜像拉取密钥。

在 Red Hat OpenShift Service on AWS 4.16 之前,还会为创建的每个服务帐户生成一个长期存在的服务帐户 API 令牌密钥。从 Red Hat OpenShift Service on AWS 4.16 开始,不再创建此服务帐户 API 令牌密钥。

升级到之后,任何现有的长期存在的服务帐户 API 令牌密钥都不会被删除,并将继续发挥作用。有关检测集群中正在使用的长期存在的 API 令牌或在不需要时删除这些令牌的信息,请参见 Red Hat 知识库文章OpenShift Container Platform 中的长期存在的服务帐户 API 令牌

此镜像拉取密钥对于将 OpenShift 镜像注册表集成到集群的用户身份验证和授权系统中是必要的。

但是,如果您未启用ImageRegistry功能,或者在集群镜像注册表操作器的配置中禁用了集成的 OpenShift 镜像注册表,则不会为每个服务帐户生成镜像拉取密钥。

在先前启用了集成的 OpenShift 镜像注册表的集群上禁用它时,先前生成的镜像拉取密钥将自动删除。

了解如何创建密钥

作为管理员,您必须在开发人员创建依赖于该密钥的 Pod 之前创建密钥。

创建密钥时:

  1. 创建一个包含您要保密的密钥的对象。以下部分描述了每种密钥类型所需的具体数据。

    创建不透明密钥的示例 YAML 对象
    apiVersion: v1
    kind: Secret
    metadata:
      name: test-secret
    type: Opaque (1)
    data: (2)
      username: <username>
      password: <password>
    stringData: (3)
      hostname: myapp.mydomain.com
      secret.properties: |
        property1=valueA
        property2=valueB
    1 指定密钥的类型。
    2 指定编码的字符串和数据。
    3 指定解码的字符串和数据。

    使用datastringdata字段中的一个,不要同时使用两者。

  2. 更新 Pod 的服务帐户以引用密钥

    使用密钥的服务帐户的 YAML
    apiVersion: v1
    kind: ServiceAccount
     ...
    secrets:
    - name: test-secret
  3. 创建一个 Pod,它将密钥用作环境变量或文件(使用secret卷)。

    使用密钥数据填充卷中文件的 Pod 的 YAML
    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-example-pod
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: secret-test-container
          image: busybox
          command: [ "/bin/sh", "-c", "cat /etc/secret-volume/*" ]
          volumeMounts: (1)
              - name: secret-volume
                mountPath: /etc/secret-volume (2)
                readOnly: true (3)
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
      volumes:
        - name: secret-volume
          secret:
            secretName: test-secret (4)
      restartPolicy: Never
    1 为需要密钥的每个容器添加volumeMounts字段。
    2 指定您希望密钥显示在其中的未使用的目录名称。密钥数据映射中的每个键都将成为mountPath下的文件名。
    3 设置为true。如果为 true,则指示驱动程序提供只读卷。
    4 指定密钥的名称。
    使用密钥数据填充环境变量的 Pod 的 YAML
    apiVersion: v1
    kind: Pod
    metadata:
      name: secret-example-pod
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: secret-test-container
          image: busybox
          command: [ "/bin/sh", "-c", "export" ]
          env:
            - name: TEST_SECRET_USERNAME_ENV_VAR
              valueFrom:
                secretKeyRef: (1)
                  name: test-secret
                  key: username
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
      restartPolicy: Never
    1 指定使用密钥的变量。
    使用密钥数据填充环境变量的构建配置的 YAML
    apiVersion: build.openshift.io/v1
    kind: BuildConfig
    metadata:
      name: secret-example-bc
    spec:
      strategy:
        sourceStrategy:
          env:
          - name: TEST_SECRET_USERNAME_ENV_VAR
            valueFrom:
              secretKeyRef: (1)
                name: test-secret
                key: username
          from:
            kind: ImageStreamTag
            namespace: openshift
            name: 'cli:latest'
    1 指定使用密钥的变量。

密钥创建限制

要使用密钥,Pod 需要引用该密钥。密钥可以通过三种方式与 Pod 一起使用:

  • 填充容器的环境变量。

  • 作为挂载到其一个或多个容器上的卷中的文件。

  • 由 kubelet 在为 Pod 拉取镜像时使用。

卷类型密钥使用卷机制将数据作为文件写入容器。镜像拉取密钥使用服务帐户将密钥自动注入命名空间中的所有 Pod。

当模板包含密钥定义时,模板使用提供的密钥的唯一方法是确保密钥卷源已验证,并且指定的引用确实指向Secret对象。因此,在任何依赖它的 Pod 之前都需要创建密钥。确保这一点最有效的方法是通过使用服务帐户自动注入它。

Secret API 对象驻留在命名空间中。它们只能被同一命名空间中的 Pod 引用。

单个密钥的大小限制为 1MB。这是为了避免创建可能耗尽 apiserver 和 kubelet 内存的大型密钥。但是,创建许多较小的密钥也可能耗尽内存。

创建不透明密钥

作为管理员,您可以创建一个不透明密钥,允许您存储非结构化的key:value对,这些对可以包含任意值。

步骤
  1. 在 YAML 文件中创建Secret对象。

    例如

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    type: Opaque (1)
    data:
      username: <username>
      password: <password>
    1 指定不透明密钥。
  2. 使用以下命令创建Secret对象

    $ oc create -f <filename>.yaml
  3. 在 Pod 中使用密钥

    1. 更新 Pod 的服务帐户以引用密钥,如“了解如何创建密钥”部分所示。

    2. 创建 Pod,它将密钥用作环境变量或文件(使用secret卷),如“了解如何创建密钥”部分所示。

创建旧版服务帐户令牌密钥

作为管理员,您可以创建一个旧版服务帐户令牌密钥,允许您将服务帐户令牌分发给必须向 API 进行身份验证的应用程序。

建议使用 TokenRequest API 获取绑定的服务帐户令牌,而不是使用旧版服务帐户令牌密钥。只有在您无法使用 TokenRequest API 并且可接受在可读 API 对象中使用不会过期的令牌的安全风险时,才应创建服务帐户令牌密钥。

绑定的服务帐户令牌比服务帐户令牌密钥更安全,原因如下:

  • 绑定的服务帐户令牌具有有限的生命周期。

  • 绑定的服务帐户令牌包含受众。

  • 绑定的服务帐户令牌可以绑定到 Pod 或密钥,并且在删除绑定对象时,绑定的令牌将失效。

工作负载会自动注入投影卷以获取绑定的服务帐户令牌。如果您的工作负载需要其他服务帐户令牌,请在工作负载清单中添加其他投影卷。

有关更多信息,请参见“使用卷投影配置绑定的服务帐户令牌”。

步骤
  1. 在 YAML 文件中创建一个Secret对象

    示例Secret对象
    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-sa-sample
      annotations:
        kubernetes.io/service-account.name: "sa-name" (1)
    type: kubernetes.io/service-account-token (2)
    1 指定现有的服务帐户名称。如果您同时创建ServiceAccountSecret对象,请先创建ServiceAccount对象。
    2 指定服务帐户令牌密钥。
  2. 使用以下命令创建Secret对象

    $ oc create -f <filename>.yaml
  3. 在 Pod 中使用密钥

    1. 更新 Pod 的服务帐户以引用密钥,如“了解如何创建密钥”部分所示。

    2. 创建 Pod,它将密钥用作环境变量或文件(使用secret卷),如“了解如何创建密钥”部分所示。

创建基本身份验证密钥

作为管理员,您可以创建一个基本身份验证密钥,允许您存储基本身份验证所需的凭据。使用此密钥类型时,Secret对象的data参数必须包含以下以 base64 格式编码的键:

  • username:身份验证的用户名

  • password:身份验证的密码或令牌

您可以使用stringData参数使用明文内容。

步骤
  1. 在 YAML 文件中创建一个Secret对象

    示例secret对象
    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-basic-auth
    type: kubernetes.io/basic-auth (1)
    data:
    stringData: (2)
      username: admin
      password: <password>
    1 指定基本身份验证密钥。
    2 指定要使用的基本身份验证值。
  2. 使用以下命令创建Secret对象

    $ oc create -f <filename>.yaml
  3. 在 Pod 中使用密钥

    1. 更新 Pod 的服务帐户以引用密钥,如“了解如何创建密钥”部分所示。

    2. 创建 Pod,它将密钥用作环境变量或文件(使用secret卷),如“了解如何创建密钥”部分所示。

创建 SSH 身份验证密钥

作为管理员,您可以创建一个 SSH 身份验证密钥,允许您存储用于 SSH 身份验证的数据。使用此密钥类型时,Secret对象的data参数必须包含要使用的 SSH 凭据。

步骤
  1. 在控制平面节点上创建 YAML 文件中的Secret对象

    示例secret对象
    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-ssh-auth
    type: kubernetes.io/ssh-auth (1)
    data:
      ssh-privatekey: | (2)
              MIIEpQIBAAKCAQEAulqb/Y ...
    1 指定 SSH 身份验证密钥。
    2 指定 SSH 密钥/值对作为要使用的 SSH 凭据。
  2. 使用以下命令创建Secret对象

    $ oc create -f <filename>.yaml
  3. 在 Pod 中使用密钥

    1. 更新 Pod 的服务帐户以引用密钥,如“了解如何创建密钥”部分所示。

    2. 创建 Pod,它将密钥用作环境变量或文件(使用secret卷),如“了解如何创建密钥”部分所示。

创建 Docker 配置密钥

作为管理员,您可以创建一个 Docker 配置密钥,允许您存储访问容器镜像注册表的凭据。

  • kubernetes.io/dockercfg。使用此密钥类型存储您的本地 Docker 配置文件。secret对象的data参数必须包含以 base64 格式编码的.dockercfg文件的内容。

  • kubernetes.io/dockerconfigjson。使用此密钥类型存储您的本地 Docker 配置 JSON 文件。secret对象的data参数必须包含以 base64 格式编码的.docker/config.json文件的内容。

步骤
  1. 在 YAML 文件中创建Secret对象。

    示例 Docker 配置secret对象
    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-docker-cfg
      namespace: my-project
    type: kubernetes.io/dockerconfig (1)
    data:
      .dockerconfig:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== (2)
    1 指定密钥使用 Docker 配置文件。
    2 Base64 编码的 Docker 配置文件的输出。
    Docker 配置 JSON secret 对象示例
    apiVersion: v1
    kind: Secret
    metadata:
      name: secret-docker-json
      namespace: my-project
    type: kubernetes.io/dockerconfig (1)
    data:
      .dockerconfigjson:bm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== (2)
    1 指定密钥使用 Docker 配置 JSON 文件。
    2 Base64 编码的 Docker 配置 JSON 文件的输出。
  2. 使用以下命令创建Secret对象

    $ oc create -f <filename>.yaml
  3. 在 Pod 中使用密钥

    1. 更新 Pod 的服务帐户以引用密钥,如“了解如何创建密钥”部分所示。

    2. 创建 Pod,它将密钥用作环境变量或文件(使用secret卷),如“了解如何创建密钥”部分所示。

使用 Web 控制台创建密钥

您可以使用 Web 控制台创建密钥。

步骤
  1. 导航到 工作负载密钥

  2. 点击 创建从 YAML

    1. 手动编辑 YAML 以满足您的规范,或者将文件拖放到 YAML 编辑器中。例如:

      apiVersion: v1
      kind: Secret
      metadata:
        name: example
        namespace: <namespace>
      type: Opaque (1)
      data:
        username: <base64 encoded username>
        password: <base64 encoded password>
      stringData: (2)
        hostname: myapp.mydomain.com
      1 此示例指定了一个不透明密钥;但是,您可能会看到其他类型的密钥,例如服务帐户令牌密钥、基本身份验证密钥、SSH 身份验证密钥或使用 Docker 配置的密钥。
      2 stringData映射中的条目将转换为 base64,然后条目将自动移动到data映射。此字段是只写字段;该值仅通过data字段返回。
  3. 点击 创建

  4. 点击 将密钥添加到工作负载

    1. 从下拉菜单中选择要添加的工作负载。

    2. 点击 保存

了解如何更新密钥

修改密钥的值后,值(由已运行的 Pod 使用)不会动态更改。要更改密钥,必须删除原始 Pod 并创建一个新的 Pod(可能具有相同的 PodSpec)。

更新密钥的流程与部署新的容器镜像相同。您可以使用 kubectl rolling-update 命令。

引用密钥时,不会指定密钥中的 resourceVersion 值。因此,如果在 Pod 启动的同时更新密钥,则用于 Pod 的密钥版本未定义。

目前,无法检查创建 Pod 时使用的密钥对象的资源版本。计划让 Pod 报告此信息,以便控制器可以重新启动使用旧 resourceVersion 的 Pod。在此期间,不要更新现有密钥的数据,而是创建具有不同名称的新密钥。

创建和使用密钥

作为管理员,您可以创建一个服务帐户令牌密钥。这允许您将服务帐户令牌分发给必须向 API 进行身份验证的应用程序。

步骤
  1. 通过运行以下命令在您的命名空间中创建一个服务帐户:

    $ oc create sa <service_account_name> -n <your_namespace>
  2. 将以下 YAML 示例保存到名为 service-account-token-secret.yaml 的文件中。此示例包含一个 Secret 对象配置,您可以使用它来生成服务帐户令牌:

    apiVersion: v1
    kind: Secret
    metadata:
      name: <secret_name> (1)
      annotations:
        kubernetes.io/service-account.name: "sa-name" (2)
    type: kubernetes.io/service-account-token (3)
    1 <secret_name> 替换为您的服务令牌密钥的名称。
    2 指定现有的服务帐户名称。如果您同时创建ServiceAccountSecret对象,请先创建ServiceAccount对象。
    3 指定服务帐户令牌密钥类型。
  3. 通过应用文件来生成服务帐户令牌:

    $ oc apply -f service-account-token-secret.yaml
  4. 通过运行以下命令从密钥中获取服务帐户令牌:

    $ oc get secret <sa_token_secret> -o jsonpath='{.data.token}' | base64 --decode (1)
    示例输出:
    ayJhbGciOiJSUzI1NiIsImtpZCI6IklOb2dtck1qZ3hCSWpoNnh5YnZhSE9QMkk3YnRZMVZoclFfQTZfRFp1YlUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImJ1aWxkZXItdG9rZW4tdHZrbnIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiYnVpbGRlciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjNmZGU2MGZmLTA1NGYtNDkyZi04YzhjLTNlZjE0NDk3MmFmNyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmJ1aWxkZXIifQ.OmqFTDuMHC_lYvvEUrjr1x453hlEEHYcxS9VKSzmRkP1SiVZWPNPkTWlfNRp6bIUZD3U6aN3N7dMSN0eI5hu36xPgpKTdvuckKLTCnelMx6cxOdAbrcw1mCmOClNscwjS1KO1kzMtYnnq8rXHiMJELsNlhnRyyIXRTtNBsy4t64T3283s3SLsancyx0gy0ujx-Ch3uKAKdZi5iT-I8jnnQ-ds5THDs2h65RJhgglQEmSxpHrLGZFmyHAQI-_SjvmHZPXEc482x3SkaQHNLqpmrpJorNqh1M8ZHKzlujhZgVooMvJmWPXTb2vnvi3DGn2XI-hZxl1yD2yGH1RBpYUHA
    1 将 <sa_token_secret> 替换为您的服务令牌密钥的名称。
  5. 使用您的服务帐户令牌向集群的 API 进行身份验证:

    $ curl -X GET <openshift_cluster_api> --header "Authorization: Bearer <token>"  (1) (2)
    1 <openshift_cluster_api> 替换为 OpenShift 集群 API。
    2 <token> 替换为前面命令中输出的服务帐户令牌。

关于使用签名证书与密钥

为了保护与您的服务的通信安全,您可以将 Red Hat OpenShift Service on AWS 配置为生成一个签名的服务证书/密钥对,您可以将其添加到项目中的密钥中。

服务服务证书密钥旨在支持需要开箱即用证书的复杂中间件应用程序。它与管理员工具为节点和主节点生成的服务器证书具有相同的设置。

为服务服务证书密钥配置的服务 Pod 规范。
apiVersion: v1
kind: Service
metadata:
  name: registry
  annotations:
    service.beta.openshift.io/serving-cert-secret-name: registry-cert(1)
# ...
1 指定证书的名称。

其他 Pod 可以通过使用自动安装在其 Pod 中的 /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt 文件中的 CA 捆绑包来信任集群创建的证书(这些证书仅针对内部 DNS 名称签名)。

此功能的签名算法为 x509.SHA256WithRSA。要手动轮换,请删除生成的密钥。将创建一个新的证书。

生成用于密钥的签名证书

要在 Pod 中使用签名的服务证书/密钥对,请创建或编辑服务以添加 service.beta.openshift.io/serving-cert-secret-name 注解,然后将密钥添加到 Pod。

步骤

要创建服务服务证书密钥

  1. 编辑服务的 Pod 规范。

  2. 添加 service.beta.openshift.io/serving-cert-secret-name 注解,并使用您要用于密钥的名称。

    kind: Service
    apiVersion: v1
    metadata:
      name: my-service
      annotations:
          service.beta.openshift.io/serving-cert-secret-name: my-cert (1)
    spec:
      selector:
        app: MyApp
      ports:
      - protocol: TCP
        port: 80
        targetPort: 9376

    证书和密钥采用 PEM 格式,分别存储在 tls.crttls.key 中。

  3. 创建服务:

    $ oc create -f <file-name>.yaml
  4. 查看密钥以确保已创建密钥:

    1. 查看所有密钥的列表:

      $ oc get secrets
      示例输出:
      NAME                     TYPE                                  DATA      AGE
      my-cert                  kubernetes.io/tls                     2         9m
    2. 查看您的密钥的详细信息:

      $ oc describe secret my-cert
      示例输出:
      Name:         my-cert
      Namespace:    openshift-console
      Labels:       <none>
      Annotations:  service.beta.openshift.io/expiry: 2023-03-08T23:22:40Z
                    service.beta.openshift.io/originating-service-name: my-service
                    service.beta.openshift.io/originating-service-uid: 640f0ec3-afc2-4380-bf31-a8c784846a11
                    service.beta.openshift.io/expiry: 2023-03-08T23:22:40Z
      
      Type:  kubernetes.io/tls
      
      Data
      ====
      tls.key:  1679 bytes
      tls.crt:  2595 bytes
  5. 使用该密钥编辑您的 Pod 规范。

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-service-pod
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
      - name: mypod
        image: redis
        volumeMounts:
        - name: my-container
          mountPath: "/etc/my-path"
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: [ALL]
      volumes:
      - name: my-volume
        secret:
          secretName: my-cert
          items:
          - key: username
            path: my-group/my-username
            mode: 511

    可用后,您的 Pod 将运行。证书将对内部服务 DNS 名称 <service.name>.<service.namespace>.svc 有效。

    证书/密钥对在接近过期时会自动替换。在密钥上的 service.beta.openshift.io/expiry 注解中查看过期日期,该日期采用 RFC3339 格式。

    在大多数情况下,服务 DNS 名称 <service.name>.<service.namespace>.svc 不可外部路由。<service.name>.<service.namespace>.svc 的主要用途是用于集群内或服务内通信,以及使用重新加密路由。

密钥疑难解答

如果服务证书生成失败(服务的 service.beta.openshift.io/serving-cert-generation-error 注解包含):

secret/ssl-key references serviceUID 62ad25ca-d703-11e6-9d6f-0e9c0057b608, which does not match 77b6dd80-d716-11e6-9d6f-0e9c0057b60

生成证书的服务已不存在,或具有不同的 serviceUID。您必须通过删除旧密钥并清除服务上的以下注解来强制重新生成证书:service.beta.openshift.io/serving-cert-generation-errorservice.beta.openshift.io/serving-cert-generation-error-num

  1. 删除密钥:

    $ oc delete secret <secret_name>
  2. 清除注解:

    $ oc annotate service <service_name> service.beta.openshift.io/serving-cert-generation-error-
    $ oc annotate service <service_name> service.beta.openshift.io/serving-cert-generation-error-num-

删除注解的命令在要删除的注解名称后带有 -