证书和证书签名请求
Kubernetes 证书和信任包 API 通过提供一个编程接口,使 Kubernetes API 客户端可以请求和获取证书颁发机构 (CA) 的 X.509 证书,从而实现 X.509 凭证的自动化供应。
还提供了分发信任包的实验性(Alpha)支持。
证书签名请求
Kubernetes v1.19 [stable]
CertificateSigningRequest(CSR)资源用于请求由指定签名者签署证书,在此之前,请求可以被批准或拒绝,然后最终被签署。
请求签名过程
CertificateSigningRequest 资源类型允许客户端请求颁发一个 X.509 证书,该证书基于签名请求。CertificateSigningRequest 对象在 spec.request
字段中包含一个 PEM 编码的 PKCS#10 签名请求。CertificateSigningRequest 使用 spec.signerName
字段指定签名者(请求的接收方)。请注意,在 API 版本 certificates.k8s.io/v1
之后,spec.signerName
是一个必需的键。在 Kubernetes v1.22 及更高版本中,客户端可以选择设置 spec.expirationSeconds
字段来请求颁发证书的特定有效期。该字段的最小有效值为 600
,即十分钟。
CertificateSigningRequest 创建后,必须先获得批准才能进行签名。根据选择的签名者,CertificateSigningRequest 可能会由控制器自动批准。否则,CertificateSigningRequest 必须通过 REST API(或 client-go)手动批准,或者通过运行 kubectl certificate approve
来批准。同样,CertificateSigningRequest 也可以被拒绝,这会告诉配置的签名者不得签署该请求。
对于已获批准的证书,下一步是签名。相关的签名控制器首先验证是否满足签名条件,然后创建证书。签名控制器然后更新 CertificateSigningRequest,将新证书存储到现有 CertificateSigningRequest 对象的 status.certificate
字段中。status.certificate
字段为空或包含一个 X.509 证书,采用 PEM 格式编码。在签名者完成此操作之前,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
签名者
签名者抽象地代表可能签署或已签署安全证书的一个或多个实体。
任何在特定集群外部可用的签名者都应提供有关签名者工作方式的信息,以便消费者了解这对 CertificateSigningRequest 和(如果启用)ClusterTrustBundles 意味着什么。这包括:
- 信任分发:信任锚(CA 证书或证书包)如何分发。
- 允许的主题:当请求不允许的主题时,是否有任何限制和行为。
- 允许的 X.509 扩展:包括 IP subjectAltNames、DNS subjectAltNames、Email subjectAltNames、URI subjectAltNames 等,以及当请求不允许的扩展时,签名者的行为。
- 允许的密钥用途/扩展密钥用途:当 CSR 中指定了与签名者确定的用途不同的用途时,是否有任何限制和行为。
- 过期/证书生命周期:是否由签名者固定,管理员可配置,由 CSR 的
spec.expirationSeconds
字段确定等,以及当签名者确定的过期时间与 CSR 的spec.expirationSeconds
字段不同时的行为。 - 允许/禁止 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.expirationSeconds
和 ClusterSigningDuration
的最小值。
注意
spec.expirationSeconds
字段是在 Kubernetes v1.22 中添加的。早期版本的 Kubernetes 不支持此字段。Kubernetes v1.22 之前的 API 服务器在创建对象时会默默丢弃此字段。Kubernetes 签名者
Kubernetes 提供了内置签名者,每个签名者都有一个众所周知的 signerName
。
kubernetes.io/kube-apiserver-client
:签署将被 API 服务器视为客户端证书的证书。从不被 kube-controller-manager 自动批准。- 信任分发:签署的证书必须被 API 服务器视为客户端证书。CA 捆绑包不通过任何其他方式分发。
- 允许的主题 - 没有主题限制,但批准者和签名者可以选择不批准或签署。某些主题,如集群管理员级别用户或组,在不同分发和安装之间有所不同,但在批准和签署之前需要额外的审查。
CertificateSubjectRestriction
准入插件默认启用以限制system:masters
,但这通常不是集群中唯一的集群管理员主题。 - 允许的 X.509 扩展 - 接受 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}
"。 - 允许的 X.509 扩展 - 接受密钥用途扩展,禁止 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}
"。 - 允许的 X.509 扩展 - 接受密钥用途和 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 集群中,此签名者没有标准信任或分发。
- 允许的主题 - 任何
- 允许的 X.509 扩展 - 接受 subjectAltName 和密钥用途扩展,并丢弃其他扩展。
- 允许的密钥用途 - 任何
- 过期/证书生命周期 - 对于此签名者的 kube-controller-manager 实现,设置为
--cluster-signing-duration
选项的最小值,或者如果指定,则为 CSR 对象的spec.expirationSeconds
字段。 - 允许/禁止 CA 位 - 不允许。
kube-controller-manager 为每个内置签名者实现控制平面签名。所有这些失败仅在 kube-controller-manager 日志中报告。
注意
spec.expirationSeconds
字段是在 Kubernetes v1.22 中添加的。早期版本的 Kubernetes 不支持此字段。Kubernetes v1.22 之前的 API 服务器在创建对象时会默默丢弃此字段。这些签名者的信任分发是带外的。除上述之外的任何信任纯属巧合。例如,某些分发可能会将 kubernetes.io/legacy-unknown
视为 kube-apiserver 的客户端证书,但这并非标准。所有这些用途都与 ServiceAccount 令牌 secret 的 .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 的一部分。
注意
在 Kubernetes v1.18 之前,kube-controller-manager 会签署所有标记为已批准的 CSR。注意
spec.expirationSeconds
字段是在 Kubernetes v1.22 中添加的。早期版本的 Kubernetes 不支持此字段。Kubernetes v1.22 之前的 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 附带了一个内置的批准者,用于 kubernetes.io/kube-apiserver-client-kubelet
签名名称的证书,它将节点凭据的 CSR 的各种权限委托给授权。kube-controller-manager 将 SubjectAccessReview 资源 POST 到 API 服务器以检查证书批准的授权。
使用 kubectl
批准或拒绝
Kubernetes 管理员(具有适当权限)可以使用 kubectl certificate approve
和 kubectl certificate deny
命令手动批准(或拒绝)CertificateSigningRequest。
用 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 来批准它们。
当你提出批准或拒绝请求时,根据你确定的状态设置 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
字段。
Pod证书请求
Kubernetes v1.34 [alpha]
(默认禁用)注意
在 Kubernetes 1.34 中,你必须使用PodCertificateRequest
Feature Gate 和 --runtime-config=certificates.k8s.io/v1alpha1/podcertificaterequests=true
kube-apiserver 标志来启用 Pod 证书支持。PodCertificateRequests 是 API 对象,专门用于为在集群中作为 Pod 运行的工作负载提供证书。用户通常不直接与 PodCertificateRequests 交互,而是使用podCertificate 投射卷源,这是一项 kubelet
功能,负责安全密钥供应和自动证书刷新。Pod 内的应用程序只需知道如何从文件系统读取证书。
PodCertificateRequests 类似于 CertificateSigningRequests,但由于其用途较窄,格式更简单。
一个 PodCertificateRequest 具有以下 spec 字段:
signerName
:此请求指向的签名者。podName
和podUID
:Kubelet 正在为其请求证书的 Pod。serviceAccountName
和serviceAccountUID
:与 Pod 对应的 ServiceAccount。nodeName
和nodeUID
:与 Pod 对应的节点。maxExpirationSeconds
:工作负载作者将接受的此证书的最大生命周期。如果未指定,则默认为 24 小时。pkixPublicKey
:应为其颁发证书的公钥。proofOfPossession
:证明请求者控制pkixPublicKey
对应的私钥的签名。
节点自动获得创建 PodCertificateRequest 和读取与其相关的 PodCertificateRequest(由 spec.nodeName
字段确定)的权限。如果启用,NodeRestriction
准入插件可确保节点只能创建与当前正在节点上运行的真实 Pod 对应的 PodCertificateRequest。
创建后,PodCertificateRequest 的 spec
是不可变的。
与 CSR 不同,PodCertificateRequests 没有批准阶段。一旦创建了 PodCertificateRequest,签名者的控制器将直接决定是颁发还是拒绝请求。如果遇到永久错误,它还可以选择将请求标记为失败。
要执行这些操作,签名控制器需要拥有 PodCertificateRequest 类型以及签名名称的相应权限:
- 动词:update,组:
certificates.k8s.io
,资源:podcertificaterequests/status
- 动词:sign,组:
certificates.k8s.io
,资源:signers
,资源名称:<signerNameDomain>/<signerNamePath>
或<signerNameDomain>/*
签名控制器可以自由考虑请求中包含的信息之外的其他信息,但它可以依赖请求中的信息是准确的。例如,签名控制器可能会加载 Pod 并读取其上设置的注解,或者对 ServiceAccount 执行 SubjectAccessReview。
为了响应请求颁发证书,签名控制器:
- 向
status.conditions
添加Issued
条件。 - 将颁发的证书放入
status.certificateChain
。 - 将证书的
NotBefore
和NotAfter
字段放入status.notBefore
和status.notAfter
字段 — 这些字段被非规范化到 Kubernetes API 中,以帮助调试。 - 建议使用
status.beginRefreshAt
开始尝试刷新证书的时间。
要拒绝请求,签名控制器会将 "Denied" 条件添加到 status.conditions[]
。
要将请求标记为失败,签名控制器会将 "Failed" 条件添加到 status.conditions[]
。
所有这些条件都是互斥的,并且必须具有“True”状态。PodCertificateRequests 上不允许其他条件类型。此外,一旦设置了任何这些条件,status
字段将变为不可变。
像所有条件一样,status.conditions[].reason
字段用于包含机器可读的代码,以 TitleCase 描述条件。status.conditions[].message
字段用于供人工阅读的自由格式解释。
为了确保终端 PodCertificateRequests 不会在集群中堆积,kube-controller-manager
控制器会删除所有超过 15 分钟的 PodCertificateRequests。所有证书颁发流程都应在 15 分钟的限制内完成。
集群信任包
注意
在 Kubernetes 1.34 中,您必须启用ClusterTrustBundle
特性门**和** certificates.k8s.io/v1alpha1
API 组 才能使用此 API。ClusterTrustBundle 是一个集群范围的对象,用于将 X.509 信任锚(根证书)分发给集群中的工作负载。它们旨在与 CertificateSigningRequest 中的签名者概念很好地配合使用。
ClusterTrustBundle 可以以两种模式使用:签名者关联和签名者非关联。
常见属性和验证
所有 ClusterTrustBundle 对象对其 trustBundle
字段的内容都有严格的验证。该字段必须包含一个或多个 X.509 证书,DER 序列化,每个证书都封装在 PEM CERTIFICATE
块中。证书必须解析为有效的 X.509 证书。
像块间数据和块内头这样的深奥 PEM 特性要么在对象验证期间被拒绝,要么可以被对象的消费者忽略。此外,消费者可以按照自己的任意但稳定的顺序重新排列包中的证书。
ClusterTrustBundle 对象应被视为集群中可全局读取的。如果你的集群使用 RBAC 授权,则所有 ServiceAccounts 默认都具有允许它们**获取**、**列出**和**观察**所有 ClusterTrustBundle 对象的权限。如果你使用自己的授权机制,并且已在集群中启用了 ClusterTrustBundles,则应设置一个等效规则,使这些对象在集群中公开,以便它们按预期工作。
如果您的集群默认没有列出集群信任包的权限,您可以模拟您有权访问的服务帐户以查看可用的 ClusterTrustBundles。
kubectl get clustertrustbundles --as='system:serviceaccount:mynamespace:default'
签名者关联的 ClusterTrustBundle
签名者关联的 ClusterTrustBundle 与*签名者名称*相关联,如下所示:
apiVersion: certificates.k8s.io/v1alpha1
kind: ClusterTrustBundle
metadata:
name: example.com:mysigner:foo
spec:
signerName: example.com/mysigner
trustBundle: "<... PEM data ...>"
这些 ClusterTrustBundle 旨在由集群中的特定于签名者的控制器维护,因此它们具有以下几个安全特性:
- 要创建或更新签名者关联的 ClusterTrustBundle,您必须被允许在签名者上进行**证明**(自定义授权动词
attest
,API 组certificates.k8s.io
;资源路径signers
)。您可以为特定资源名称<signerNameDomain>/<signerNamePath>
配置授权,或匹配模式,例如<signerNameDomain>/*
。 - 签名者关联的 ClusterTrustBundles **必须**以其
spec.signerName
字段派生的前缀命名。斜杠 (/
) 替换为冒号 (:
),并附加一个最终的冒号。这之后是任意名称。例如,签名者example.com/mysigner
可以链接到 ClusterTrustBundleexample.com:mysigner:<arbitrary-name>
。
签名者关联的 ClusterTrustBundle 通常会在工作负载中通过签名者名称的字段选择器和单独的标签选择器组合来使用。
签名者非关联的 ClusterTrustBundle
签名者非关联的 ClusterTrustBundle 具有空的 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 都是一个独立对象,这与与签名者关联的 ClusterTrustBundle 的惯常分组行为形成对比。
未与签名者关联的 ClusterTrustBundle 没有 attest
动词要求。相反,您使用常用机制(例如基于角色的访问控制)直接控制对其的访问。
为了将它们与签名者关联的 ClusterTrustBundle 区分开来,签名者未关联的 ClusterTrustBundle 的名称**不能**包含冒号 (:
)。
从 Pod 访问 ClusterTrustBundle
ClusterTrustBundle 的内容可以注入到容器文件系统,类似于 ConfigMaps 和 Secrets。有关详细信息,请参阅clusterTrustBundle 投射卷源。
下一步
- 阅读管理集群中的 TLS 证书
- 阅读使用 CertificateSigningRequest 为 Kubernetes API 客户端颁发证书
- 查看 kube-controller-manager 内置签名者的源代码
- 查看 kube-controller-manager 内置批准者的源代码
- 有关 X.509 本身的详细信息,请参阅 RFC 5280 第 3.1 节
- 有关 PKCS#10 证书签名请求语法的相关信息,请参阅 RFC 2986
- 阅读关于 ClusterTrustBundle API
- %!s(
)
- %!s(