最新:在 TwitterMastodon 获取项目更新。

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: v1
kind: Pod
metadata:
name: my-csi-app
namespace: sandbox
labels:
app: my-csi-app
spec:
containers:
- name: my-frontend
image: busybox
volumeMounts:
- mountPath: "/tls"
name: tls
command: [ "sleep", "1000000" ]
volumes:
- name: tls
csi:
driver: csi.cert-manager.io
volumeAttributes:
csi.cert-manager.io/issuer-name: ca-issuer
csi.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-groupIssuer 所属的组名称。cert-manager.ioout.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请求签署证书的有效期。720h1880h
csi.cert-manager.io/is-ca将证书标记为证书颁发机构。falsetrue
csi.cert-manager.io/key-usages设置证书请求上的密钥用途。digital signature,key enciphermentserver auth,client auth
csi.cert-manager.io/key-encoding设置密钥编码格式(PKCS1 或 PKCS8)。PKCS1PKCS8
csi.cert-manager.io/certificate-file在其中存储证书文件的文件名。tls.crtfoo.crt
csi.cert-manager.io/ca-file在其中存储 ca 证书文件的文件名。ca.crtfoo.ca
csi.cert-manager.io/privatekey-file在其中存储密钥文件的文件名。tls.keyfoo.key
csi.cert-manager.io/fs-group设置写入文件的 FS 组。应与使用容器的 runAsGroup 值配对并匹配。2000
csi.cert-manager.io/renew-before在证书到期前续订证书的时间。默认设置为请求持续时间的 1/3。$CERT_DURATION/372h
csi.cert-manager.io/reuse-private-key在续订证书时重新使用相同的私钥。falsetrue
csi.cert-manager.io/pkcs12-enable启用将签署的证书链和私钥作为 PKCS12 文件写入。true
csi.cert-manager.io/pkcs12-filename写入 PKCS12 文件的文件位置。需要将 csi.cert-manager.io/keystore-pkcs12-enable 设置为 truekeystore.p12tls.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-name
csi.cert-manager.io/dns-names
csi.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-issuer
csi.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: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cert-manager-csi-driver-all-cr-create
rules:
- apiGroups: ["cert-manager.io"]
resources: ["certificaterequests"]
verbs: [ "create" ]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cert-manager-csi-driver-all-cr-create
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cert-manager-csi-driver-all-cr-create
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:authenticated