csi-driver
csi-driver 是 Kubernetes 的 容器存储接口 (CSI) 驱动程序插件,与证书管理器一起工作。
挂载证书管理器 csi-driver 的 Pod 将从证书管理器请求证书,而无需创建 Certificate
资源。这些证书将直接挂载到 Pod 中,不会创建任何中间机密。
为什么要使用 csi-driver?
- 确保私钥永远不会离开节点,并且永远不会通过网络发送。私钥存储在内存中,不应写入磁盘。
- 每个应用程序副本都有唯一的密钥和证书
- 更少的
Certificate
资源意味着更少的 YAML 代码 - 密钥和证书在应用程序终止时被销毁
- 不需要
Secret
资源来存储证书,这意味着更少的 RBAC - 非常适合短暂的、短生命周期的证书,这些证书不需要在重启后仍然存在(例如 mTLS 的证书)
为什么不使用 csi-driver?
- 如果您需要证书在节点重启后仍然存在
- 如果您需要多个组件共享同一个证书
安装
有关如何安装 csi-driver 的说明,请参阅 安装指南。
请求和挂载证书
使用 csi-driver 请求证书意味着挂载卷,并设置一些属性以定义您需要请求的确切内容。
以下示例是一个虚拟应用程序,它将密钥证书对挂载到 /tls
,使用名为 ca-issuer
的 cert-manager 发行者签署,该发行者具有对 my-service.sandbox.svc.cluster.local
有效的 DNS 名称。
apiVersion: v1kind: Podmetadata:name: my-csi-appnamespace: sandboxlabels:app: my-csi-appspec:containers:- name: my-frontendimage: busyboxvolumeMounts:- mountPath: "/tls"name: tlscommand: [ "sleep", "1000000" ]volumes:- name: tlscsi:driver: csi.cert-manager.iovolumeAttributes:csi.cert-manager.io/issuer-name: ca-issuercsi.cert-manager.io/dns-names: ${POD_NAME}.${POD_NAMESPACE}.svc.cluster.local
创建后,CSI 驱动程序将在本地生成私钥(针对 Pod),根据给定的属性从 cert-manager 请求证书,并将证书存储起来供 Pod 使用。
Pod 将保持挂起状态,直到颁发完成。
有关如何为您的集群设置发行者的更多信息,请参阅 cert-manager 文档 此处。
注意 使用 csi-driver 时无法使用 SelfSigned
发行者,因为 SelfSigned
发行者是一个特殊情况。
支持的卷属性
csi-driver 驱动程序旨在与通过 cert-manager API 可用的所有可能值具有完整的特性奇偶校验。它目前支持以下值
属性 | 描述 | 默认值 | 示例 |
---|---|---|---|
csi.cert-manager.io/issuer-name | 用于签署证书请求的发行者名称。 | ca-issuer | |
csi.cert-manager.io/issuer-kind | 用于签署证书请求的发行者类型。 | 颁发者 | ClusterIssuer |
csi.cert-manager.io/issuer-group | Issuer 所属的组名称。 | cert-manager.io | out.of.tree.foo |
csi.cert-manager.io/common-name | 证书通用名称(支持变量)。 | my-cert.foo | |
csi.cert-manager.io/dns-names | 将为其请求证书的 DNS 名称。必须至少存在一个 DNS 名称、IP 或 URI 名称(支持变量)。 | a.b.foo.com,c.d.foo.com | |
csi.cert-manager.io/ip-sans | 将为其请求证书的 IP 地址。 | 192.0.0.1,192.0.0.2 | |
csi.cert-manager.io/uri-sans | 将为其请求证书的 URI 名称(支持变量)。 | spiffe://foo.bar.cluster.local | |
csi.cert-manager.io/duration | 请求签署证书的有效期。 | 720h | 1880h |
csi.cert-manager.io/is-ca | 将证书标记为证书颁发机构。 | false | true |
csi.cert-manager.io/key-usages | 设置证书请求上的密钥用途。 | digital signature,key encipherment | server auth,client auth |
csi.cert-manager.io/key-encoding | 设置密钥编码格式(PKCS1 或 PKCS8)。 | PKCS1 | PKCS8 |
csi.cert-manager.io/certificate-file | 在其中存储证书文件的文件名。 | tls.crt | foo.crt |
csi.cert-manager.io/ca-file | 在其中存储 ca 证书文件的文件名。 | ca.crt | foo.ca |
csi.cert-manager.io/privatekey-file | 在其中存储密钥文件的文件名。 | tls.key | foo.key |
csi.cert-manager.io/fs-group | 设置写入文件的 FS 组。应与使用容器的 runAsGroup 值配对并匹配。 | 2000 | |
csi.cert-manager.io/renew-before | 在证书到期前续订证书的时间。默认设置为请求持续时间的 1/3。 | $CERT_DURATION/3 | 72h |
csi.cert-manager.io/reuse-private-key | 在续订证书时重新使用相同的私钥。 | false | true |
csi.cert-manager.io/pkcs12-enable | 启用将签署的证书链和私钥作为 PKCS12 文件写入。 | true | |
csi.cert-manager.io/pkcs12-filename | 写入 PKCS12 文件的文件位置。需要将 csi.cert-manager.io/keystore-pkcs12-enable 设置为 true 。 | keystore.p12 | tls.p12 |
csi.cert-manager.io/pkcs12-password | 用于编码 PKCS12 文件的密码。在启用 PKCS12 时需要(csi.cert-manager.io/keystore-pkcs12-enable: true )。 | my-password |
变量
以下属性支持在请求挂载 Pod 时评估的变量。这些变量对于使用来自挂载 Pod 的值的 SAN 构建请求很有用。
csi.cert-manager.io/common-namecsi.cert-manager.io/dns-namescsi.cert-manager.io/uri-sans
变量遵循 go os.Expand
结构,这通常是您在 UNIX shell 上所期望的。CSI 驱动程序可以访问以下变量
${POD_NAME}${POD_NAMESPACE}${POD_UID}${SERVICE_ACCOUNT_NAME}
示例用法
volumeAttributes:csi.cert-manager.io/issuer-name: ca-issuercsi.cert-manager.io/dns-names: "${POD_NAME}.${POD_NAMESPACE}.svc.cluster.local"csi.cert-manager.io/uri-sans: "spiffe://cluster.local/ns/${POD_NAMESPACE}/pod/${POD_NAME}/${POD_UID}"csi.cert-manager.io/common-name: "${SERVICE_ACCOUNT_NAME}.${POD_NAMESPACE}"
使用挂载 Pod 的 ServiceAccount 请求证书
如果在 csi-driver DaemonSet 上启用了标志 --use-token-request
,则将由挂载 Pod 的 ServiceAccount 创建 CertificateRequest 资源。这可以与 approver-policy 配合使用,以便在每个 ServiceAccount 基础上启用高级策略控制。
确保您在启用此标志的情况下为 Pod ServiceAccount 授予创建 CertificateRequest 的权限,例如
# WARNING: This RBAC will enable any identity in the cluster to create# CertificateRequests and is dangerous to use in production. Instead, you should# give permissions only to identities which need to be able to create certificates.# This would be done via scoping the set of identities in the `ClusterRoleBinding` `subjects` stanza.kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata:name: cert-manager-csi-driver-all-cr-createrules:- apiGroups: ["cert-manager.io"]resources: ["certificaterequests"]verbs: [ "create" ]---kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata:name: cert-manager-csi-driver-all-cr-createroleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: cert-manager-csi-driver-all-cr-createsubjects:- apiGroup: rbac.authorization.k8s.iokind: Groupname: system:authenticated