证书和证书签名请求
Kubernetes 证书和信任包 API 通过为 Kubernetes API 的客户端提供一个编程接口来请求和获取 X.509 证书,从而使 X.509 凭证供应的自动化成为可能。 X.509 从证书颁发机构 (CA) 获取。
还有一些实验性(alpha)支持用于分发 信任包。
证书签名请求
Kubernetes v1.19 [稳定]
一个 证书签名请求 (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
- 动词:
create
、get
、list
、watch
、组: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
- 动词:
get
、list
、watch
、组:certificates.k8s.io
、资源:certificatesigningrequests
- 动词:
update
、组:certificates.k8s.io
、资源:certificatesigningrequests/approval
- 动词:
approve
、组:certificates.k8s.io
、资源:signers
、资源名称:<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
- 动词:
get
、list
、watch
、组:certificates.k8s.io
、资源:certificatesigningrequests
- 动词:
update
、组:certificates.k8s.io
、资源:certificatesigningrequests/status
- 动词:
sign
、组:certificates.k8s.io
、资源:signers
、资源名称:<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
签名者
签名者抽象地代表可能签署或已签署安全证书的实体或实体。
任何在特定集群外部提供使用的签名者都应提供有关签名者工作原理的信息,以便使用者可以了解这对 CertifcateSigningRequests 和(如果启用) ClusterTrustBundles 的意义。这包括
- 信任分发:如何分发信任锚(CA 证书或证书包)。
- 允许的主题:对不允许的主题的任何限制和行为。
- 允许的 x509 扩展:包括 IP subjectAltNames、DNS subjectAltNames、Email subjectAltNames、URI subjectAltNames 等,以及当请求不允许的扩展时如何处理。
- 允许的密钥用途/扩展密钥用途:对与签名者确定的用途不同的用途的任何限制和行为,这些用途在 CSR 中指定。
- 到期时间/证书生存期:它是否由签名者固定、由管理员配置、由 CSR
spec.expirationSeconds
字段确定等,以及当签名者确定的到期时间与 CSRspec.expirationSeconds
字段不同时的行为。 - 允许/不允许的 CA 位:以及当 CSR 包含请求 CA 证书而签名者不允许时如何处理。
通常,一旦 CSR 被批准并颁发证书,CertificateSigningRequest 的 status.certificate
字段包含一个 PEM 编码的 X.509 证书。某些签名者将多个证书存储到 status.certificate
字段中。在这种情况下,签名者的文档应指定附加证书的含义;例如,这可能是证书加上在 TLS 握手期间要呈现的中介证书。
如果要使信任锚(根证书)可用,则应与 CertificateSigningRequest 及其 status.certificate
字段分开执行。例如,您可以使用 ClusterTrustBundle。
PKCS#10 签名请求格式没有标准机制来指定证书到期时间或生存期。因此,到期时间或生存期必须通过 CSR 对象的 spec.expirationSeconds
字段设置。内置签名者使用 ClusterSigningDuration
配置选项(kube-controller-manager 的 --cluster-signing-duration
命令行标志),该选项默认值为 1 年,作为未指定 spec.expirationSeconds
时的默认值。当指定 spec.expirationSeconds
时,将使用 spec.expirationSeconds
和 ClusterSigningDuration
中的较小者。
注意
spec.expirationSeconds
字段是在 Kubernetes v1.22 中添加的。早于 Kubernetes v1.22 的版本不遵守此字段。在 v1.22 之前的 Kubernetes API 服务器会在创建对象时静默删除此字段。Kubernetes 签名者
Kubernetes 提供内置签名者,每个签名者都有一个众所周知的 signerName
kubernetes.io/kube-apiserver-client
:签署将被 API 服务器认可为客户端证书的证书。从不自动被 kube-controller-manager 批准。- 信任分发:签署的证书必须被 API 服务器认可为客户端证书。CA 包不会通过其他方式分发。
- 允许的主题 - 没有主题限制,但批准者和签名者可以选择不批准或不签署。某些主题,例如集群管理员级别用户或组,在不同发行版和安装之间有所不同,但在批准和签署之前需要额外的审查。
CertificateSubjectRestriction
准入插件默认启用以限制system:masters
,但它通常不是集群中唯一的集群管理员主题。 - 允许的 x509 扩展 - 遵守 subjectAltName 和密钥用途扩展,并丢弃其他扩展。
- 允许的密钥用途 - 必须包含
["client auth"]
。不能包含超出["digital signature", "key encipherment", "client auth"]
的密钥用途。 - 到期时间/证书有效期 - 对于 kube-controller-manager 实现的此签名者,设置为 `--cluster-signing-duration` 选项的最小值,或者如果指定,则设置为 CSR 对象的 `spec.expirationSeconds` 字段。
- 允许/不允许的 CA 位 - 不允许。
kubernetes.io/kube-apiserver-client-kubelet
: 签署 API 服务器将作为客户端证书接受的客户端证书。可以被 kube-controller-manager 自动批准。- 信任分发:签署的证书必须被 API 服务器认可为客户端证书。CA 包不会通过其他方式分发。
- 允许的主题 - 组织恰好是
["system:nodes"]
,通用名称是 "system:node:${NODE_NAME}
"。 - 允许的 x509 扩展 - 遵守密钥使用扩展,禁止 subjectAltName 扩展并删除其他扩展。
- 允许的密钥使用 -
["key encipherment", "digital signature", "client auth"]
或["digital signature", "client auth"]
。 - 到期时间/证书有效期 - 对于 kube-controller-manager 实现的此签名者,设置为 `--cluster-signing-duration` 选项的最小值,或者如果指定,则设置为 CSR 对象的 `spec.expirationSeconds` 字段。
- 允许/不允许的 CA 位 - 不允许。
kubernetes.io/kubelet-serving
: 签署 API 服务器将作为有效的 kubelet 服务器证书接受的服务器证书,但没有其他保证。绝不会被 kube-controller-manager 自动批准。- 信任分发:签署的证书必须被 API 服务器接受为有效才能终止到 kubelet 的连接。CA 捆绑包不会通过任何其他方式分发。
- 允许的主题 - 组织恰好是
["system:nodes"]
,通用名称是 "system:node:${NODE_NAME}
"。 - 允许的 x509 扩展 - 遵守密钥使用和 DNSName/IPAddress subjectAltName 扩展,禁止 EmailAddress 和 URI subjectAltName 扩展,并删除其他扩展。必须至少存在一个 DNS 或 IP subjectAltName。
- 允许的密钥使用 -
["key encipherment", "digital signature", "server auth"]
或["digital signature", "server auth"]
。 - 到期时间/证书有效期 - 对于 kube-controller-manager 实现的此签名者,设置为 `--cluster-signing-duration` 选项的最小值,或者如果指定,则设置为 CSR 对象的 `spec.expirationSeconds` 字段。
- 允许/不允许的 CA 位 - 不允许。
kubernetes.io/legacy-unknown
: 完全没有信任保证。Kubernetes 的一些第三方发行版可能会接受由它签署的客户端证书。稳定的 CertificateSigningRequest API(版本 `certificates.k8s.io/v1` 及更高版本)不允许将 `signerName` 设置为 `kubernetes.io/legacy-unknown`。绝不会被 kube-controller-manager 自动批准。- 信任分发:无。此签名者在 Kubernetes 集群中没有标准的信任或分发。
- 允许的主题 - 任何主题
- 允许的 x509 扩展 - 遵守 subjectAltName 和密钥用途扩展,并丢弃其他扩展。
- 允许的密钥使用 - 任何密钥使用
- 到期时间/证书有效期 - 对于 kube-controller-manager 实现的此签名者,设置为 `--cluster-signing-duration` 选项的最小值,或者如果指定,则设置为 CSR 对象的 `spec.expirationSeconds` 字段。
- 允许/不允许的 CA 位 - 不允许。
kube-controller-manager 为每个内置签名者实现 控制平面签名。所有这些签名者的故障仅在 kube-controller-manager 日志中报告。
注意
spec.expirationSeconds
字段是在 Kubernetes v1.22 中添加的。早于 Kubernetes v1.22 的版本不遵守此字段。在 v1.22 之前的 Kubernetes API 服务器会在创建对象时静默删除此字段。这些签名者的信任分发是在带外进行的。除上述描述以外的任何信任都是严格的巧合。例如,某些发行版可能会接受 `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 控制平面作为 kube-controller-manager 的一部分,实现了每个 Kubernetes 签名者。
注意
在 Kubernetes v1.18 之前,kube-controller-manager 会签署所有标记为已批准的 CSR。注意
spec.expirationSeconds
字段是在 Kubernetes v1.22 中添加的。早于 Kubernetes v1.22 的版本不遵守此字段。在 v1.22 之前的 Kubernetes API 服务器会在创建对象时静默删除此字段。基于 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 内容可能出现在 CERTIFICATE 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 approve` 和 `kubectl 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。例如,您可以编写一个 操作符,该操作符监视特定类型的 CSR,然后发送 UPDATE 来批准它们。
当您发出批准或拒绝请求时,请根据您确定的状态设置 `Approved` 或 `Denied` 状态条件。
对于 `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]
注意
在 Kubernetes 1.31 中,您必须启用 `ClusterTrustBundle` 功能门控 *和* `certificates.k8s.io/v1alpha1` API 组 才能使用此 API。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:<arbitrary-name>`。
签名者链接的 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 ...>"
它们主要用于集群配置用例。每个签名者未链接的 ClusterTrustBundle 都是一个独立的对象,与签名者链接的 ClusterTrustBundles 的习惯性分组行为形成对比。
签名者未链接的 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
下一步
- 阅读 在集群中管理 TLS 证书
- 查看 kube-controller-manager 中内置的 signer 的源代码
- 查看 kube-controller-manager 中内置的 approver 的源代码
- 有关 X.509 本身的详细信息,请参阅 RFC 5280 的第 3.1 节
- 有关 PKCS#10 证书签名请求语法的详细信息,请参阅 RFC 2986
- 了解 ClusterTrustBundle API