证书和证书签名请求

Kubernetes 证书和信任包 API 通过为 Kubernetes API 的客户端提供一个编程接口来请求和获取来自证书颁发机构 (CA) 的 X.509 证书,从而实现 X.509 凭据配置的自动化。

还对分发信任包提供实验性(alpha)支持。

证书签名请求

功能状态: Kubernetes v1.19 [稳定版]

CertificateSigningRequest (CSR) 资源用于请求由指定的签名者对证书进行签名,之后可以在最终签名之前批准或拒绝该请求。

请求签名过程

CertificateSigningRequest 资源类型允许客户端根据签名请求来请求颁发 X.509 证书。CertificateSigningRequest 对象在 spec.request 字段中包含 PEM 编码的 PKCS#10 签名请求。CertificateSigningRequest 使用 spec.signerName 字段表示签名者(请求发送给的接收者)。请注意,spec.signerName 是 API 版本 certificates.k8s.io/v1 之后的必需键。在 Kubernetes v1.22 及更高版本中,客户端可以选择设置 spec.expirationSeconds 字段以请求颁发的证书的特定生命周期。此字段的最小有效值为 600,即十分钟。

创建后,必须先批准 CertificateSigningRequest 才能签名。根据所选签名者,控制器可以自动批准 CertificateSigningRequest。否则,必须通过 REST API(或 client-go)或运行 kubectl certificate approve 手动批准 CertificateSigningRequest。同样,也可以拒绝 CertificateSigningRequest,这将告诉配置的签名者不能对请求进行签名。

对于已批准的证书,下一步是签名。相关的签名控制器首先验证是否满足签名条件,然后创建证书。然后,签名控制器将更新 CertificateSigningRequest,并将新证书存储到现有 CertificateSigningRequest 对象的 status.certificate 字段中。status.certificate 字段要么为空,要么包含以 PEM 格式编码的 X.509 证书。在签名者执行此操作之前,CertificateSigningRequest status.certificate 字段为空。

一旦填充了 status.certificate 字段,请求就完成了,客户端现在可以从 CertificateSigningRequest 资源中获取签名的证书 PEM 数据。如果未满足批准条件,签名者可以拒绝证书签名。

为了减少集群中剩余的旧 CertificateSigningRequest 资源的数量,垃圾回收控制器会定期运行。垃圾回收会删除一些时长内状态未更改的 CertificateSigningRequest。

  • 已批准的请求:1 小时后自动删除
  • 被拒绝的请求:1 小时后自动删除
  • 失败的请求:1 小时后自动删除
  • 待处理的请求:24 小时后自动删除
  • 所有请求:在颁发的证书过期后自动删除

证书签名授权

允许创建 CertificateSigningRequest 并检索任何 CertificateSigningRequest

  • 动词:creategetlistwatch,组:certificates.k8s.io,资源:certificatesigningrequests

例如

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: csr-creator
rules:
- apiGroups:
  - certificates.k8s.io
  resources:
  - certificatesigningrequests
  verbs:
  - create
  - get
  - list
  - watch

允许批准 CertificateSigningRequest

  • 动词:getlistwatch,组:certificates.k8s.io,资源:certificatesigningrequests
  • 动词:update,组:certificates.k8s.io,资源:certificatesigningrequests/approval
  • 动词:approve,组:certificates.k8s.io,资源:signers,resourceName:<signerNameDomain>/<signerNamePath><signerNameDomain>/*

例如

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: csr-approver
rules:
- apiGroups:
  - certificates.k8s.io
  resources:
  - certificatesigningrequests
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - certificates.k8s.io
  resources:
  - certificatesigningrequests/approval
  verbs:
  - update
- apiGroups:
  - certificates.k8s.io
  resources:
  - signers
  resourceNames:
  - example.com/my-signer-name # example.com/* can be used to authorize for all signers in the 'example.com' domain
  verbs:
  - approve

允许签署 CertificateSigningRequest

  • 动词:getlistwatch,组:certificates.k8s.io,资源:certificatesigningrequests
  • 动词:update,组:certificates.k8s.io,资源:certificatesigningrequests/status
  • 动词:sign,组:certificates.k8s.io,资源:signers,resourceName:<signerNameDomain>/<signerNamePath><signerNameDomain>/*
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: csr-signer
rules:
- apiGroups:
  - certificates.k8s.io
  resources:
  - certificatesigningrequests
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - certificates.k8s.io
  resources:
  - certificatesigningrequests/status
  verbs:
  - update
- apiGroups:
  - certificates.k8s.io
  resources:
  - signers
  resourceNames:
  - example.com/my-signer-name # example.com/* can be used to authorize for all signers in the 'example.com' domain
  verbs:
  - sign

签名者

签名者抽象地表示可能签署或已签署安全证书的实体。

任何可供特定集群外部使用的签名者都应提供有关其工作方式的信息,以便使用者能够理解这对 CertificateSigningRequests 和(如果启用)ClusterTrustBundles 的意义。这包括:

  1. 信任分发:信任锚(CA 证书或证书包)是如何分发的。
  2. 允许的主题:对不允许的主题的任何限制和行为。
  3. 允许的 x509 扩展:包括 IP 主题备用名称、DNS 主题备用名称、电子邮件主题备用名称、URI 主题备用名称等,以及当请求不允许的扩展时的行为。
  4. 允许的密钥用途/扩展密钥用途:对 CSR 中指定的与签名者确定的用途不同的任何限制和行为。
  5. 过期/证书生命周期:是否由签名者固定、由管理员配置、由 CSR spec.expirationSeconds 字段确定等,以及当签名者确定的过期时间与 CSR spec.expirationSeconds 字段不同时的行为。
  6. 允许/不允许 CA 位:以及当 CSR 包含请求 CA 证书但在签名者不允许的情况下时的行为。

通常,一旦 CSR 获得批准并颁发证书,CertificateSigningRequest 的 status.certificate 字段将包含一个 PEM 编码的 X.509 证书。某些签名者将多个证书存储到 status.certificate 字段中。在这种情况下,签名者的文档应指定其他证书的含义;例如,这可能是证书加上在 TLS 握手期间要呈现的中间证书。

如果要使信任锚(根证书)可用,则应与 CertificateSigningRequest 及其 status.certificate 字段分开进行。例如,您可以使用 ClusterTrustBundle。

PKCS#10 签名请求格式没有指定证书过期或生命周期的标准机制。因此,过期或生命周期必须通过 CSR 对象的 spec.expirationSeconds 字段设置。内置签名者使用 ClusterSigningDuration 配置选项,该选项默认为 1 年(kube-controller-manager 的 --cluster-signing-duration 命令行标志),作为未指定 spec.expirationSeconds 时的默认值。指定 spec.expirationSeconds 时,将使用 spec.expirationSecondsClusterSigningDuration 中的最小值。

Kubernetes 签名者

Kubernetes 提供了内置签名者,每个签名者都有一个众所周知的 signerName

  1. kubernetes.io/kube-apiserver-client:签署将被 API 服务器识别为客户端证书的证书。永远不会被 kube-controller-manager 自动批准。

    1. 信任分发:签名的证书必须被 API 服务器识别为客户端证书。CA 包不通过任何其他方式分发。
    2. 允许的主题 - 没有主题限制,但批准者和签名者可以选择不批准或签名。诸如集群管理员级别用户或组之类的某些主题在不同分发版和安装之间有所不同,但在批准和签名之前应进行额外审查。默认情况下启用 CertificateSubjectRestriction 准入插件来限制 system:masters,但它通常不是集群中唯一的集群管理员主题。
    3. 允许的 x509 扩展 - 接受 subjectAltName 和密钥用法扩展,并丢弃其他扩展。
    4. 允许的密钥用法 - 必须包括 ["client auth"]。不能包括 ["digital signature", "key encipherment", "client auth"] 之外的密钥用法。
    5. 过期/证书生命周期 - 对于此签名者的 kube-controller-manager 实现,设置为 --cluster-signing-duration 选项的最小值,或者,如果指定,则设置为 CSR 对象的 spec.expirationSeconds 字段的最小值。
    6. 允许/不允许 CA 位 - 不允许。
  2. kubernetes.io/kube-apiserver-client-kubelet:签署将被 API 服务器识别为客户端证书的客户端证书。可能被 kube-controller-manager 自动批准。

    1. 信任分发:签名的证书必须被 API 服务器识别为客户端证书。CA 包不通过任何其他方式分发。
    2. 允许的主题 - 组织完全是 ["system:nodes"],通用名称是 "system:node:${NODE_NAME}"。
    3. 允许的 x509 扩展 - 接受密钥用法扩展,禁止 subjectAltName 扩展,并丢弃其他扩展。
    4. 允许的密钥用法 - ["key encipherment", "digital signature", "client auth"]["digital signature", "client auth"]
    5. 过期/证书生命周期 - 对于此签名者的 kube-controller-manager 实现,设置为 --cluster-signing-duration 选项的最小值,或者,如果指定,则设置为 CSR 对象的 spec.expirationSeconds 字段的最小值。
    6. 允许/不允许 CA 位 - 不允许。
  3. kubernetes.io/kubelet-serving:签署被 API 服务器识别为有效的 kubelet 服务证书的服务证书,但没有其他保证。永远不会被 kube-controller-manager 自动批准。

    1. 信任分发:签名的证书必须被 API 服务器识别为有效,以终止与 kubelet 的连接。CA 包不通过任何其他方式分发。
    2. 允许的主题 - 组织完全是 ["system:nodes"],通用名称是 "system:node:${NODE_NAME}"。
    3. 允许的 x509 扩展 - 接受密钥用法和 DNSName/IPAddress subjectAltName 扩展,禁止 EmailAddress 和 URI subjectAltName 扩展,并丢弃其他扩展。必须至少存在一个 DNS 或 IP subjectAltName。
    4. 允许的密钥用法 - ["key encipherment", "digital signature", "server auth"]["digital signature", "server auth"]
    5. 过期/证书生命周期 - 对于此签名者的 kube-controller-manager 实现,设置为 --cluster-signing-duration 选项的最小值,或者,如果指定,则设置为 CSR 对象的 spec.expirationSeconds 字段的最小值。
    6. 允许/不允许 CA 位 - 不允许。
  4. kubernetes.io/legacy-unknown:根本没有信任保证。Kubernetes 的某些第三方分发版可能会接受由其签名的客户端证书。稳定的 CertificateSigningRequest API(版本 certificates.k8s.io/v1 及更高版本)不允许将 signerName 设置为 kubernetes.io/legacy-unknown。永远不会被 kube-controller-manager 自动批准。

    1. 信任分发:无。Kubernetes 集群中此签名者没有标准信任或分发。
    2. 允许的主题 - 任意
    3. 允许的 x509 扩展 - 接受 subjectAltName 和密钥用法扩展,并丢弃其他扩展。
    4. 允许的密钥用法 - 任意
    5. 过期/证书生命周期 - 对于此签名者的 kube-controller-manager 实现,设置为 --cluster-signing-duration 选项的最小值,或者,如果指定,则设置为 CSR 对象的 spec.expirationSeconds 字段的最小值。
    6. 允许/不允许 CA 位 - 不允许。

kube-controller-manager 为每个内置签名者实现 控制平面签名。所有这些的失败仅在 kube-controller-manager 日志中报告。

这些签名者的信任分发是带外进行的。上述描述之外的任何信任都是纯粹的巧合。例如,某些分发版可能会接受 kubernetes.io/legacy-unknown 作为 kube-apiserver 的客户端证书,但这不是标准。这些用法都与 ServiceAccount 令牌密钥的 .data[ca.crt] 无关。该 CA 包仅保证验证使用默认服务 (kubernetes.default.svc) 与 API 服务器的连接。

自定义签名者

您还可以引入自己的自定义签名者,该签名者应具有类似的前缀名称,但使用您自己的域名。例如,如果您代表一个使用域名 open-fictional.example 的开源项目,那么您可以使用 issuer.open-fictional.example/service-mesh 作为签名者名称。

自定义签名者使用 Kubernetes API 来颁发证书。请参阅基于 API 的签名者

签名

控制平面签名者

Kubernetes 控制平面将每个 Kubernetes 签名者 作为 kube-controller-manager 的一部分来实现。

基于 API 的签名者

REST API 的用户可以通过向要签名的 CSR 的 status 子资源提交 UPDATE 请求来签署 CSR。

作为此请求的一部分,应将 status.certificate 字段设置为包含签名的证书。此字段包含一个或多个 PEM 编码的证书。

所有 PEM 块必须具有“CERTIFICATE”标签,不包含任何标头,并且编码的数据必须是 RFC5280 的第 4 节中描述的 BER 编码的 ASN.1 证书结构。

示例证书内容

-----BEGIN CERTIFICATE-----
MIIDgjCCAmqgAwIBAgIUC1N1EJ4Qnsd322BhDPRwmg3b/oAwDQYJKoZIhvcNAQEL
BQAwXDELMAkGA1UEBhMCeHgxCjAIBgNVBAgMAXgxCjAIBgNVBAcMAXgxCjAIBgNV
BAoMAXgxCjAIBgNVBAsMAXgxCzAJBgNVBAMMAmNhMRAwDgYJKoZIhvcNAQkBFgF4
MB4XDTIwMDcwNjIyMDcwMFoXDTI1MDcwNTIyMDcwMFowNzEVMBMGA1UEChMMc3lz
dGVtOm5vZGVzMR4wHAYDVQQDExVzeXN0ZW06bm9kZToxMjcuMC4wLjEwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDne5X2eQ1JcLZkKvhzCR4Hxl9+ZmU3
+e1zfOywLdoQxrPi+o4hVsUH3q0y52BMa7u1yehHDRSaq9u62cmi5ekgXhXHzGmm
kmW5n0itRECv3SFsSm2DSghRKf0mm6iTYHWDHzUXKdm9lPPWoSOxoR5oqOsm3JEh
Q7Et13wrvTJqBMJo1GTwQuF+HYOku0NF/DLqbZIcpI08yQKyrBgYz2uO51/oNp8a
sTCsV4OUfyHhx2BBLUo4g4SptHFySTBwlpRWBnSjZPOhmN74JcpTLB4J5f4iEeA7
2QytZfADckG4wVkhH3C2EJUmRtFIBVirwDn39GXkSGlnvnMgF3uLZ6zNAgMBAAGj
YTBfMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDAjAMBgNVHRMB
Af8EAjAAMB0GA1UdDgQWBBTREl2hW54lkQBDeVCcd2f2VSlB1DALBgNVHREEBDAC
ggAwDQYJKoZIhvcNAQELBQADggEBABpZjuIKTq8pCaX8dMEGPWtAykgLsTcD2jYr
L0/TCrqmuaaliUa42jQTt2OVsVP/L8ofFunj/KjpQU0bvKJPLMRKtmxbhXuQCQi1
qCRkp8o93mHvEz3mTUN+D1cfQ2fpsBENLnpS0F4G/JyY2Vrh19/X8+mImMEK5eOy
o0BMby7byUj98WmcUvNCiXbC6F45QTmkwEhMqWns0JZQY+/XeDhEcg+lJvz9Eyo2
aGgPsye1o3DpyXnyfJWAWMhOz7cikS5X2adesbgI86PhEHBXPIJ1v13ZdfCExmdd
M1fLPhLyR54fGaY+7/X8P9AZzPefAkwizeXwe9ii6/a08vWoiE4=
-----END CERTIFICATE-----

PEM 块之前或之后可能出现非 PEM 内容,并且未经过验证,以允许如RFC7468 第 5.2 节所述的说明性文本。

以 JSON 或 YAML 编码时,此字段采用 base-64 编码。包含上述示例证书的 CertificateSigningRequest 如下所示:

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
...
status:
  certificate: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JS..."

批准或拒绝

签名者根据 CertificateSigningRequest 颁发证书之前,签名者通常会检查该 CSR 的颁发是否已获得批准

控制平面自动批准

kube-controller-manager 附带一个内置批准者,用于 signerName 为 kubernetes.io/kube-apiserver-client-kubelet 的证书,该批准者将节点凭据的 CSR 的各种权限委托给授权。kube-controller-manager 向 API 服务器 POST SubjectAccessReview 资源,以检查证书批准的授权。

使用 kubectl 批准或拒绝

Kubernetes 管理员(具有适当权限)可以使用 kubectl certificate approvekubectl certificate deny 命令手动批准(或拒绝)CertificateSigningRequests。

要使用 kubectl 批准 CSR,请执行以下操作:

kubectl certificate approve <certificate-signing-request-name>

同样,要拒绝 CSR,请执行以下操作:

kubectl certificate deny <certificate-signing-request-name>

使用 Kubernetes API 批准或拒绝

REST API 的用户可以通过向要批准的 CSR 的 approval 子资源提交 UPDATE 请求来批准 CSR。例如,您可以编写一个 operator 来监视特定类型的 CSR,然后发送 UPDATE 以批准它们。

当您发出批准或拒绝请求时,根据您确定的状态设置 ApprovedDenied 状态条件。

对于 Approved CSR

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
...
status:
  conditions:
  - lastUpdateTime: "2020-02-08T11:37:35Z"
    lastTransitionTime: "2020-02-08T11:37:35Z"
    message: Approved by my custom approver controller
    reason: ApprovedByMyPolicy # You can set this to any string
    type: Approved

对于 Denied CSR

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
...
status:
  conditions:
  - lastUpdateTime: "2020-02-08T11:37:35Z"
    lastTransitionTime: "2020-02-08T11:37:35Z"
    message: Denied by my custom approver controller
    reason: DeniedByMyPolicy # You can set this to any string
    type: Denied

通常将 status.conditions.reason 设置为使用 TitleCase 的机器友好原因代码;这是一个约定,但您可以将其设置为您喜欢的任何内容。如果要添加供人使用的注释,请使用 status.conditions.message 字段。

集群信任包

特性状态: Kubernetes v1.27 [alpha]

ClusterTrustBundles 是一个集群范围的对象,用于将 X.509 信任锚(根证书)分发到集群中的工作负载。它们旨在与 CertificateSigningRequests 中的 签名者概念配合使用。

ClusterTrustBundles 可以以两种模式使用:签名者链接签名者未链接

通用属性和验证

所有 ClusterTrustBundle 对象都对其 trustBundle 字段的内容进行严格的验证。该字段必须包含一个或多个 X.509 证书,以 DER 序列化,每个证书都包裹在 PEM CERTIFICATE 块中。这些证书必须解析为有效的 X.509 证书。

诸如块间数据和块内头之类的深奥的 PEM 功能要么在对象验证期间被拒绝,要么可以被对象的消费者忽略。此外,允许消费者使用他们自己任意但稳定的排序方式重新排列捆绑包中的证书。

ClusterTrustBundle 对象在集群内应被视为世界可读的。如果你的集群使用 RBAC 授权,则所有 ServiceAccount 都有一个默认授权,允许它们获取列出监视所有 ClusterTrustBundle 对象。如果你使用自己的授权机制并且在你的集群中启用了 ClusterTrustBundles,则应设置等效规则,使这些对象在集群内公开,以便它们按预期工作。

如果你的集群默认情况下没有列出集群信任捆绑包的权限,你可以模拟你有权访问的服务帐户,以便查看可用的 ClusterTrustBundles。

kubectl get clustertrustbundles --as='system:serviceaccount:mynamespace:default'

与签名者关联的 ClusterTrustBundles

与签名者关联的 ClusterTrustBundles 与一个签名者名称相关联,如下所示:

apiVersion: certificates.k8s.io/v1alpha1
kind: ClusterTrustBundle
metadata:
  name: example.com:mysigner:foo
spec:
  signerName: example.com/mysigner
  trustBundle: "<... PEM data ...>"

这些 ClusterTrustBundles 旨在由集群中特定于签名者的控制器维护,因此它们具有多个安全功能。

  • 要创建或更新与签名者关联的 ClusterTrustBundle,你必须被允许对签名者进行证明(自定义授权动词 attest,API 组 certificates.k8s.io;资源路径 signers)。你可以为特定的资源名称 <signerNameDomain>/<signerNamePath> 配置授权,或者匹配诸如 <signerNameDomain>/* 之类的模式。
  • 与签名者关联的 ClusterTrustBundles 必须使用从其 spec.signerName 字段派生的前缀命名。斜杠 (/) 被替换为冒号 (:),并附加一个最终冒号。后面跟着任意名称。例如,签名者 example.com/mysigner 可以链接到 ClusterTrustBundle example.com:mysigner:<任意名称>

与签名者关联的 ClusterTrustBundles 通常会在工作负载中通过签名者名称的字段选择器和单独的标签选择器组合使用。

未与签名者关联的 ClusterTrustBundles

未与签名者关联的 ClusterTrustBundles 具有空的 spec.signerName 字段,如下所示:

apiVersion: certificates.k8s.io/v1alpha1
kind: ClusterTrustBundle
metadata:
  name: foo
spec:
  # no signerName specified, so the field is blank
  trustBundle: "<... PEM data ...>"

它们主要用于集群配置用例。与签名者关联的 ClusterTrustBundles 的习惯分组行为相反,每个未与签名者关联的 ClusterTrustBundle 都是一个独立的对象。

未与签名者关联的 ClusterTrustBundles 没有 attest 动词要求。相反,你可以使用通常的机制(例如,基于角色的访问控制)直接控制对它们的访问。

为了将它们与签名者关联的 ClusterTrustBundles 区分开来,未与签名者关联的 ClusterTrustBundles 的名称不得包含冒号 (:)。

从 Pod 访问 ClusterTrustBundles

特性状态: Kubernetes v1.29 [alpha]

ClusterTrustBundles 的内容可以注入到容器文件系统中,类似于 ConfigMaps 和 Secrets。有关更多详细信息,请参阅clusterTrustBundle 投影卷源

如何为用户颁发证书

要让普通用户能够进行身份验证并调用 API,需要几个步骤。首先,此用户必须具有 Kubernetes 集群颁发的证书,然后将该证书呈现给 Kubernetes API。

创建私钥

以下脚本展示了如何生成 PKI 私钥和 CSR。设置 CSR 的 CN 和 O 属性非常重要。CN 是用户的名称,O 是该用户将属于的组。你可以参考RBAC以了解标准组。

openssl genrsa -out myuser.key 2048
openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"

创建 CertificateSigningRequest

创建一个CertificateSigningRequest 并通过 kubectl 将其提交到 Kubernetes 集群。以下是生成 CertificateSigningRequest 的脚本。

cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: myuser
spec:
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 86400  # one day
  usages:
  - client auth
EOF

需要注意的一些要点

  • usages 必须是 'client auth'

  • expirationSeconds 可以设置得更长(即 864000 表示十天)或更短(即 3600 表示一小时)

  • request 是 CSR 文件内容的 base64 编码值。你可以使用以下命令获取内容

    cat myuser.csr | base64 | tr -d "\n"
    

批准 CertificateSigningRequest

使用 kubectl 创建 CSR 并批准它。

获取 CSR 列表

kubectl get csr

批准 CSR

kubectl certificate approve myuser

获取证书

从 CSR 中检索证书

kubectl get csr/myuser -o yaml

证书值以 Base64 编码格式位于 status.certificate 下。

从 CertificateSigningRequest 导出颁发的证书。

kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt

创建 Role 和 RoleBinding

创建证书后,现在是时候为此用户定义 Role 和 RoleBinding 以访问 Kubernetes 集群资源了。

这是为此新用户创建 Role 的示例命令

kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods

这是为此新用户创建 RoleBinding 的示例命令

kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser

添加到 kubeconfig

最后一步是将此用户添加到 kubeconfig 文件中。

首先,你需要添加新的凭据

kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true

然后,你需要添加上下文

kubectl config set-context myuser --cluster=kubernetes --user=myuser

要测试它,请将上下文更改为 myuser

kubectl config use-context myuser

下一步是什么

上次修改时间:2024 年 5 月 25 日,太平洋标准时间晚上 11:44:改进 bootstrap-tokens 证书签名请求的格式 (7215e3919f)