文章目录cert-manager介绍cert-manager概述涉及概念免费证书签发原理cert-manager安装manifest 方式安装helm 方式安装验证自签名cert-manager Issuer 签发器Issuer 签发器介绍SelfSigned 自签名签发器SelfSigned 创建SelfSigned 构建 CAcert-manager介绍cert-manager概述cert-manager 是 Kubernetes 里的证书自动化控制器controller。它通过 CRD自定义资源引入一套对象从而实现基于 “声明式” 的方式管理证书生命周期流程大致为声明需要某域名的证书Certificate 资源cert-manager 自动完成生成私钥走 ACME 流程去 Let’s Encrypt 申请证书完成域名验证HTTP-01 或 DNS-01拿到证书后写入一个 Kubernetes Secretkubernetes.io/tls快到期前自动续期、更新 SecretIngress-Nginx 引用这个 Secret就能自动变 HTTPS 并跟随续期更新。cert-manager 能够从多种证书颁发机构获取证书包括Let’s Encrypt、HashiCorp Vault、CyberArk Certificate Manager 以及私有 PKI。涉及概念使用 cert-manager 的时候主要有如下概念Issuer / ClusterIssuer签发器向谁申请/由谁签用于指示 cert-manager 签发证书的方式。Issuer 作用域是 namespaceClusterIssuer 集群级一般建议用它所有 namespace 都能用提示Issuer 与 ClusterIssuer 之间的区别是Issuer 只能用来签发自身所在 namespace 下的证书ClusterIssuer 可以签发任意 namespace 下的证书。Certificate证书申请单要哪些域名、存到哪个 Secret、用哪个 Issuer用于向 cert-manager 传递域名证书的信息、签发证书所需要的配置以及对 Issuer/ClusterIssuer 的引用。Order / ChallengeACME 协议内部过程对象一般无需手动创建Secret最终落地的证书与私钥kubernetes.io/tls类型被 Ingress 的 spec.tls[].secretName 引用。Ingress让 HTTPS 生效Ingress-Nginx 读取指定的 TLS SecretSecret 一更新Ingress-Nginx 会自动加载通常无需重启。免费证书签发原理Let’s Encrypt 利用 ACME 协议校验域名的归属校验成功后可以自动颁发免费证书。免费证书有效期只有90天需在到期前再校验一次实现续期。使用 cert-manager 可以自动续期即实现永久使用免费证书。校验域名归属的两种方式分别是 HTTP-01 和 DNS-01校验原理可参考使用 cert-manager 签发免费证书 。cert-manager安装manifest 方式安装这种方式指所有资源CustomResourceDefinitions 以及 cert-manager、cainjector 和 webhook 组件均包含在单个 YAML 清单文件中。[rootmaster01 ~]# mkdir cert-manager[rootmaster01 ~]# cd cert-manager/[rootmaster01 cert-manager]# CM_VERv1.19.4[rootmaster01 cert-manager]# kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/${CM_VER}/cert-manager.yaml默认情况下cert-manager 将被安装到 cert-manager 命名空间。确认验证如下 cert-manager 、 cert-manager-cainjector 和 cert-manager-webhook 的 pod 均处于 Running 状态。其中 webhook 组件的成功启动时间可能略长于其他组件。[rootmaster01 cert-manager]# kubectl get pods --namespace cert-managerNAME READY STATUS RESTARTS AGE cert-manager-59976b9f8b-2q2b21/1 Running03m4s cert-manager-cainjector-689d8b44f5-gtvpp1/1 Running03m4s cert-manager-webhook-58dcbfd978-pk92v1/1 Running03m4s提示更多安装参考 kubectl 安装 cert-managerhelm 方式安装cert-manager 将 Helm 图表作为在 Kubernetes 和 OpenShift 上的首选安装方式。cert-manager 作为 OCI Helm 图表提供同时也发布于 Helm 仓库。对于较新版本的 cert-manager推荐使用 OCI Helm 图表。OCI Helm 图表是官方来源发布后即刻更新。而位于 https://charts.jetstack.io 的传统 HTTP Helm 仓库会在 OCI 图表发布几小时后更新。启用 OCI Helm Chart方式[rootmaster01 cert-manager]# helm install \cert-manager oci://quay.io/jetstack/charts/cert-manager\--versionv1.19.4\--namespacecert-manager\--create-namespace\--setcrds.enabledtrue[rootmaster01 cert-manager]# kubectl get pods --namespace cert-managerNAME READY STATUS RESTARTS AGE cert-manager-746886b79c-g5twr1/1 Running03m27s cert-manager-cainjector-5664b56fc6-npljq1/1 Running03m27s cert-manager-webhook-7f644f6b8f-jcxvx1/1 Running03m27s[rootmaster01 cert-manager]# helm -n cert-manager listNAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cert-manager cert-manager12026-03-0515:28:37.385314815 0800 CST deployed cert-manager-v1.19.4 v1.19.4采用 Helm repository方式[rootmaster01 cert-manager]# helm repo add jetstack https://charts.jetstack.io --force-update #添加仓库[rootmaster01 cert-manager]# helm install \cert-manager jetstack/cert-manager\--namespacecert-manager\--create-namespace\--versionv1.19.4\--setcrds.enabledtrue[rootmaster01 cert-manager]# kubectl get pods --namespace cert-managerNAME READY STATUS RESTARTS AGE cert-manager-746886b79c-l2ldj1/1 Running079s cert-manager-cainjector-5664b56fc6-7w59h1/1 Running079s cert-manager-webhook-7f644f6b8f-w9bnt1/1 Running078s[rootmaster01 cert-manager]# helm -n cert-manager listNAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cert-manager cert-manager12026-03-0515:32:53.389566373 0800 CST deployed cert-manager-v1.19.4 v1.19.4提示建议采用OCI Helm Chart方式以便于及时获取最新版的版本。提示若需要修改helm安装的默认值可参考cert-manager该说明包括了所有helm chart可配置的值。验证自签名完整验证安装成功与否的最佳方法是签发测试证书。可在cert-manager-test命名空间中创建一个自签名签发者Issuer和一个证书Certificate资源。[rootmaster01 cert-manager]# cat EOF test-resources.yamlapiVersion: v1 kind: Namespace metadata: name: cert-manager-test --- apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: test-selfsigned namespace: cert-manager-test spec: selfSigned:{}--- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: selfsigned-cert namespace: cert-manager-test spec: dnsNames: - linuxsb.com secretName: selfsigned-cert-tls issuerRef: name: test-selfsigned privateKey: rotationPolicy: Always EOF[rootmaster01 cert-manager]# kubectl apply -f test-resources.yaml[rootmaster01 cert-manager]# kubectl -n cert-manager-test get secret selfsigned-cert-tlsNAME TYPE DATA AGE selfsigned-cert-tls kubernetes.io/tls36m6s[rootmaster01 cert-manager]# kubectl -n cert-manager-test get certificateNAME READY SECRET AGE selfsigned-cert True selfsigned-cert-tls 5m56s[rootmaster01 cert-manager]# kubectl -n cert-manager-test describe certificate selfsigned-cert# ……Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Issuing 6m2s cert-manager-certificates-trigger Issuing certificate as Secret does not exist Normal Generated 6m2s cert-manager-certificates-key-manager Stored new private keyintemporary Secret resourceselfsigned-cert-rwmglNormal Requested 6m2s cert-manager-certificates-request-manager Created new CertificateRequest resourceselfsigned-cert-1Normal Issuing 6m2s cert-manager-certificates-issuing The certificate has been successfully issuedcert-manager Issuer 签发器Issuer 签发器介绍安装 cert-manager 后首先需配置的是 Issuer 或 ClusterIssuer 。这些资源代表能够响应证书签名请求CSR的证书颁发机构CA。cert-manager 自带多种内置证书签发者均属于 cert-manager.io 分组。除内置类型外还可安装外部签发者。内置与外部签发者处理方式相同配置方法也相似。使用 ClusterIssuer 资源类型时ClusterIssuer 资源具有集群作用域。这意味着通过 secretName 字段引用 Secret 时将在 Cluster Resource Namespace 中查找 Secret 资源。默认命名空间为 cert-manager 但可通过 cert-manager-controller 组件的标志--cluster-resource-namespacemy-namespace进行修改。当前已集成的签发器包括Issuers 签发方SelfSigned 自签名签发器SelfSigned 发行者通常用于在本地引导 PKI公钥基础设施即本地内部私有环境。自签名签发者 SelfSigned 本身不代表证书颁发机构而是表示证书将使用指定私钥自行签署。换言之证书的私钥将被用于签署证书本身。SelfSigned 创建由于 SelfSigned 发行方不依赖任何其他资源其配置最为简单。发行方规范中仅需包含 SelfSigned 配置段无需其他设置。SelfSigned Issuer 是最简单的 issuer 类型不依赖外部系统不像 ACME 要连 Let’s Encrypt、DNS、HTTP 验证不依赖现有 CA Secret不像 CA issuer 一开始就需要有个 CA Secret。Issuernamespace 级。它引用的 Secret 也在同 namespace。ClusterIssuer集群级不在任何 namespace。但它要引用 CA 私钥的 SecretSecret 又必须放在某个 namespace。cert-manager 的约定是ClusterIssuer 引用的 Secret 默认在 cert-manager namespace 。[rootmaster01 cert-manager]# cat selfsigned-resources.yaml--- apiVersion: v1 kind: Namespace metadata: name:test--- apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: selfsigned-issuer namespace:testspec: selfSigned:{}--- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: selfsigned-cluster-issuer#集群级别的资源spec: selfSigned:{}[rootmaster01 cert-manager]# kubectl apply -f selfsigned-resources.yaml[rootmaster01 cert-manager]# kubectl -n test get issuers.cert-manager.io -owideNAME READY STATUS AGE selfsigned-issuer True 13s[rootmaster01 cert-manager]# kubectl get clusterissuers.cert-manager.io -owideNAME READY STATUS AGE selfsigned-cluster-issuer True 30sSelfSigned 构建 CACA证书颁发机构有一对固定的 CA 私钥/证书Root/Intermediate用它去给别的证书签名。被签发的证书链能追溯到这个 CA。SelfSigned Issuer对每一张证书它用“这张证书自己的私钥”给“这张证书”签名——也就是自签名。对于 “自签名证书” 最大的问题不是生成而是信任分发签一张自签名证书给服务端用客户端并不会自动信任它必须把证书或其 CA分发到所有客户端/命名空间/系统信任库里在生产环境中会涉及信任库分发、轮换、吊销、灾备等一整套 PKI 运维。因此官方的建议是使用 SelfSigned “引导bootstrap出一个真正的 CA” 然后对于每个需要自签名的证书后续不使用 SelfSigned 自签而是用 CA Issuer 去签发其它证书。单纯使用 selfSigned 也可以实现自签名证书的创建但每一张证书都是孤岛客户端信任管理会更难即selfSigned每张证书都得单独信任或 TOFU轮换时更麻烦CA issuer只要客户端信任“根 CA”后续业务证书怎么换都行链路更合理。所以 selfSigned 更像“临时/引导工具”CA issuer 才是“自建 PKI 的最佳方式”。相当于用 SelfSigned 只做第一步生成一张“Root CA 证书”自签名、isCAtrue把它保存成 Secret。然后用这个 Root CA Secret 配一个 CA Issuer后续所有业务证书都用 CA Issuer 去签形成“同一个私有 CA”体系这样就从“每张证书都自签”变成了“由统一 CA 签发”。相当于先构建一个CA然后由CA去签名。这是 SelfSigned 签发器的理想用例之一即为私有 PKI 引导自定义根证书包括配合 cert-manager CA 签发器使用。以下 YAML 配置将创建 SelfSigned 签发器签发根证书并使用该根证书作为 CA 签发器命名空间级别命名空间级别的 ca 的特点资源放在 sandbox 里示例先创建了 Namespace: sandbox生成 Root CA 的 Certificate 也在 sandbox产物 Secret 是sandbox/root-secret最终创建的是 Issuer不是 ClusterIssuerkind: Issuer spec.ca.secretName: root-secret这个 my-ca-issuer 只能在 sandbox 这个 namespace 里被引用。适用场景你只想在某个 namespace 内部使用私有 CA不打算全集群共享。[rootmaster01 cert-manager]# vi selfsigned-root-ns.yaml---# 创建命名空间apiVersion: v1 kind: Namespace metadata: name: sandbox ---# 创建集群级别的 SelfSigned Issuer工具人apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: selfsigned-issuer spec: selfSigned:{}---# 用 SelfSigned Issuer 签一张 Root CA 证书# cert-manager 生成 Root CA 的私钥# 用 SelfSigned issuer 让这张 Root CA 证书“自签”# 把 Root CA 证书私钥 保存到 root-secret 这个 SecretapiVersion: cert-manager.io/v1 kind: Certificate metadata: name: my-selfsigned-ca namespace: sandbox spec: isCA:truecommonName: my-selfsigned-ca secretName: root-secret privateKey: algorithm: ECDSA size:256rotationPolicy: Always issuerRef: name: selfsigned-issuer kind: ClusterIssuer group: cert-manager.io ---# 创建 CA Issuer真正干活的 CA# 以后凡是引用这个 my-ca-issuer 的 Certificate# 都会用 root-secret 里那对 CA 私钥/证书来签发# 从此就有了一个“私有 CA”apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: my-ca-issuer namespace: sandbox spec: ca: secretName: root-secret[rootmaster01 cert-manager]# kubectl apply -f selfsigned-root-ns.yaml[rootmaster01 cert-manager]# kubectl get clusterissuers.cert-manager.ioNAME READY AGE selfsigned-cluster-issuer True 13m selfsigned-issuer True 31s[rootmaster01 cert-manager]# kubectl -n test get certificateNAME READY SECRET AGE my-selfsigned-ca True root-secret 76s集群级别也可使用 ClusterIssuer 通过 SelfSigned Certificate CA 为集群中任意位置的 Certificates 签名请采用以下 YAML 配置稍作修改集群级别的 ca 的特点不再需要 sandbox因为目标是 ClusterIssuerRoot CA 的 Secret 被放到 cert-manager namespace通常默认cert-manager/root-secret最终创建的是 ClusterIssuerkind: ClusterIssuer spec.ca.secretName: root-secretClusterIssuer 不在任何 namespace所以它引用的 secretName 默认会去 cert-manager namespace 找这是 cert-manager 的约定/实现。适用场景希望全集群任何 namespace 都能引用同一个 CA 来签证书统一内部 PKI。[rootmaster01 cert-manager]# vim selfsigned-root-cl.yaml--- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: selfsigned-issuer spec: selfSigned:{}--- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: my-selfsigned-ca namespace: cert-manager spec: isCA:truecommonName: my-selfsigned-ca secretName: root-secret privateKey: algorithm: ECDSA size:256rotationPolicy: Always issuerRef: name: selfsigned-issuer kind: ClusterIssuer group: cert-manager.io --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: my-ca-issuer spec: ca: secretName: root-secret[rootmaster01 cert-manager]# kubectl apply -f selfsigned-root-cl.yaml[rootmaster01 cert-manager]# kubectl get clusterissuers.cert-manager.ioNAME READY AGE my-ca-issuer True 32s selfsigned-cluster-issuer True 18m selfsigned-issuer True 5m28s[rootmaster01 cert-manager]# kubectl -n cert-manager get certificateNAME READY SECRET AGE my-selfsigned-ca True root-secret 46s提示使用 SelfSigned 证书的客户端无法信任这些证书需要事先在客户端导入这些证书。
055.Kubernetes cert-manager安装及签发器介绍
文章目录cert-manager介绍cert-manager概述涉及概念免费证书签发原理cert-manager安装manifest 方式安装helm 方式安装验证自签名cert-manager Issuer 签发器Issuer 签发器介绍SelfSigned 自签名签发器SelfSigned 创建SelfSigned 构建 CAcert-manager介绍cert-manager概述cert-manager 是 Kubernetes 里的证书自动化控制器controller。它通过 CRD自定义资源引入一套对象从而实现基于 “声明式” 的方式管理证书生命周期流程大致为声明需要某域名的证书Certificate 资源cert-manager 自动完成生成私钥走 ACME 流程去 Let’s Encrypt 申请证书完成域名验证HTTP-01 或 DNS-01拿到证书后写入一个 Kubernetes Secretkubernetes.io/tls快到期前自动续期、更新 SecretIngress-Nginx 引用这个 Secret就能自动变 HTTPS 并跟随续期更新。cert-manager 能够从多种证书颁发机构获取证书包括Let’s Encrypt、HashiCorp Vault、CyberArk Certificate Manager 以及私有 PKI。涉及概念使用 cert-manager 的时候主要有如下概念Issuer / ClusterIssuer签发器向谁申请/由谁签用于指示 cert-manager 签发证书的方式。Issuer 作用域是 namespaceClusterIssuer 集群级一般建议用它所有 namespace 都能用提示Issuer 与 ClusterIssuer 之间的区别是Issuer 只能用来签发自身所在 namespace 下的证书ClusterIssuer 可以签发任意 namespace 下的证书。Certificate证书申请单要哪些域名、存到哪个 Secret、用哪个 Issuer用于向 cert-manager 传递域名证书的信息、签发证书所需要的配置以及对 Issuer/ClusterIssuer 的引用。Order / ChallengeACME 协议内部过程对象一般无需手动创建Secret最终落地的证书与私钥kubernetes.io/tls类型被 Ingress 的 spec.tls[].secretName 引用。Ingress让 HTTPS 生效Ingress-Nginx 读取指定的 TLS SecretSecret 一更新Ingress-Nginx 会自动加载通常无需重启。免费证书签发原理Let’s Encrypt 利用 ACME 协议校验域名的归属校验成功后可以自动颁发免费证书。免费证书有效期只有90天需在到期前再校验一次实现续期。使用 cert-manager 可以自动续期即实现永久使用免费证书。校验域名归属的两种方式分别是 HTTP-01 和 DNS-01校验原理可参考使用 cert-manager 签发免费证书 。cert-manager安装manifest 方式安装这种方式指所有资源CustomResourceDefinitions 以及 cert-manager、cainjector 和 webhook 组件均包含在单个 YAML 清单文件中。[rootmaster01 ~]# mkdir cert-manager[rootmaster01 ~]# cd cert-manager/[rootmaster01 cert-manager]# CM_VERv1.19.4[rootmaster01 cert-manager]# kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/${CM_VER}/cert-manager.yaml默认情况下cert-manager 将被安装到 cert-manager 命名空间。确认验证如下 cert-manager 、 cert-manager-cainjector 和 cert-manager-webhook 的 pod 均处于 Running 状态。其中 webhook 组件的成功启动时间可能略长于其他组件。[rootmaster01 cert-manager]# kubectl get pods --namespace cert-managerNAME READY STATUS RESTARTS AGE cert-manager-59976b9f8b-2q2b21/1 Running03m4s cert-manager-cainjector-689d8b44f5-gtvpp1/1 Running03m4s cert-manager-webhook-58dcbfd978-pk92v1/1 Running03m4s提示更多安装参考 kubectl 安装 cert-managerhelm 方式安装cert-manager 将 Helm 图表作为在 Kubernetes 和 OpenShift 上的首选安装方式。cert-manager 作为 OCI Helm 图表提供同时也发布于 Helm 仓库。对于较新版本的 cert-manager推荐使用 OCI Helm 图表。OCI Helm 图表是官方来源发布后即刻更新。而位于 https://charts.jetstack.io 的传统 HTTP Helm 仓库会在 OCI 图表发布几小时后更新。启用 OCI Helm Chart方式[rootmaster01 cert-manager]# helm install \cert-manager oci://quay.io/jetstack/charts/cert-manager\--versionv1.19.4\--namespacecert-manager\--create-namespace\--setcrds.enabledtrue[rootmaster01 cert-manager]# kubectl get pods --namespace cert-managerNAME READY STATUS RESTARTS AGE cert-manager-746886b79c-g5twr1/1 Running03m27s cert-manager-cainjector-5664b56fc6-npljq1/1 Running03m27s cert-manager-webhook-7f644f6b8f-jcxvx1/1 Running03m27s[rootmaster01 cert-manager]# helm -n cert-manager listNAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cert-manager cert-manager12026-03-0515:28:37.385314815 0800 CST deployed cert-manager-v1.19.4 v1.19.4采用 Helm repository方式[rootmaster01 cert-manager]# helm repo add jetstack https://charts.jetstack.io --force-update #添加仓库[rootmaster01 cert-manager]# helm install \cert-manager jetstack/cert-manager\--namespacecert-manager\--create-namespace\--versionv1.19.4\--setcrds.enabledtrue[rootmaster01 cert-manager]# kubectl get pods --namespace cert-managerNAME READY STATUS RESTARTS AGE cert-manager-746886b79c-l2ldj1/1 Running079s cert-manager-cainjector-5664b56fc6-7w59h1/1 Running079s cert-manager-webhook-7f644f6b8f-w9bnt1/1 Running078s[rootmaster01 cert-manager]# helm -n cert-manager listNAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cert-manager cert-manager12026-03-0515:32:53.389566373 0800 CST deployed cert-manager-v1.19.4 v1.19.4提示建议采用OCI Helm Chart方式以便于及时获取最新版的版本。提示若需要修改helm安装的默认值可参考cert-manager该说明包括了所有helm chart可配置的值。验证自签名完整验证安装成功与否的最佳方法是签发测试证书。可在cert-manager-test命名空间中创建一个自签名签发者Issuer和一个证书Certificate资源。[rootmaster01 cert-manager]# cat EOF test-resources.yamlapiVersion: v1 kind: Namespace metadata: name: cert-manager-test --- apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: test-selfsigned namespace: cert-manager-test spec: selfSigned:{}--- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: selfsigned-cert namespace: cert-manager-test spec: dnsNames: - linuxsb.com secretName: selfsigned-cert-tls issuerRef: name: test-selfsigned privateKey: rotationPolicy: Always EOF[rootmaster01 cert-manager]# kubectl apply -f test-resources.yaml[rootmaster01 cert-manager]# kubectl -n cert-manager-test get secret selfsigned-cert-tlsNAME TYPE DATA AGE selfsigned-cert-tls kubernetes.io/tls36m6s[rootmaster01 cert-manager]# kubectl -n cert-manager-test get certificateNAME READY SECRET AGE selfsigned-cert True selfsigned-cert-tls 5m56s[rootmaster01 cert-manager]# kubectl -n cert-manager-test describe certificate selfsigned-cert# ……Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Issuing 6m2s cert-manager-certificates-trigger Issuing certificate as Secret does not exist Normal Generated 6m2s cert-manager-certificates-key-manager Stored new private keyintemporary Secret resourceselfsigned-cert-rwmglNormal Requested 6m2s cert-manager-certificates-request-manager Created new CertificateRequest resourceselfsigned-cert-1Normal Issuing 6m2s cert-manager-certificates-issuing The certificate has been successfully issuedcert-manager Issuer 签发器Issuer 签发器介绍安装 cert-manager 后首先需配置的是 Issuer 或 ClusterIssuer 。这些资源代表能够响应证书签名请求CSR的证书颁发机构CA。cert-manager 自带多种内置证书签发者均属于 cert-manager.io 分组。除内置类型外还可安装外部签发者。内置与外部签发者处理方式相同配置方法也相似。使用 ClusterIssuer 资源类型时ClusterIssuer 资源具有集群作用域。这意味着通过 secretName 字段引用 Secret 时将在 Cluster Resource Namespace 中查找 Secret 资源。默认命名空间为 cert-manager 但可通过 cert-manager-controller 组件的标志--cluster-resource-namespacemy-namespace进行修改。当前已集成的签发器包括Issuers 签发方SelfSigned 自签名签发器SelfSigned 发行者通常用于在本地引导 PKI公钥基础设施即本地内部私有环境。自签名签发者 SelfSigned 本身不代表证书颁发机构而是表示证书将使用指定私钥自行签署。换言之证书的私钥将被用于签署证书本身。SelfSigned 创建由于 SelfSigned 发行方不依赖任何其他资源其配置最为简单。发行方规范中仅需包含 SelfSigned 配置段无需其他设置。SelfSigned Issuer 是最简单的 issuer 类型不依赖外部系统不像 ACME 要连 Let’s Encrypt、DNS、HTTP 验证不依赖现有 CA Secret不像 CA issuer 一开始就需要有个 CA Secret。Issuernamespace 级。它引用的 Secret 也在同 namespace。ClusterIssuer集群级不在任何 namespace。但它要引用 CA 私钥的 SecretSecret 又必须放在某个 namespace。cert-manager 的约定是ClusterIssuer 引用的 Secret 默认在 cert-manager namespace 。[rootmaster01 cert-manager]# cat selfsigned-resources.yaml--- apiVersion: v1 kind: Namespace metadata: name:test--- apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: selfsigned-issuer namespace:testspec: selfSigned:{}--- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: selfsigned-cluster-issuer#集群级别的资源spec: selfSigned:{}[rootmaster01 cert-manager]# kubectl apply -f selfsigned-resources.yaml[rootmaster01 cert-manager]# kubectl -n test get issuers.cert-manager.io -owideNAME READY STATUS AGE selfsigned-issuer True 13s[rootmaster01 cert-manager]# kubectl get clusterissuers.cert-manager.io -owideNAME READY STATUS AGE selfsigned-cluster-issuer True 30sSelfSigned 构建 CACA证书颁发机构有一对固定的 CA 私钥/证书Root/Intermediate用它去给别的证书签名。被签发的证书链能追溯到这个 CA。SelfSigned Issuer对每一张证书它用“这张证书自己的私钥”给“这张证书”签名——也就是自签名。对于 “自签名证书” 最大的问题不是生成而是信任分发签一张自签名证书给服务端用客户端并不会自动信任它必须把证书或其 CA分发到所有客户端/命名空间/系统信任库里在生产环境中会涉及信任库分发、轮换、吊销、灾备等一整套 PKI 运维。因此官方的建议是使用 SelfSigned “引导bootstrap出一个真正的 CA” 然后对于每个需要自签名的证书后续不使用 SelfSigned 自签而是用 CA Issuer 去签发其它证书。单纯使用 selfSigned 也可以实现自签名证书的创建但每一张证书都是孤岛客户端信任管理会更难即selfSigned每张证书都得单独信任或 TOFU轮换时更麻烦CA issuer只要客户端信任“根 CA”后续业务证书怎么换都行链路更合理。所以 selfSigned 更像“临时/引导工具”CA issuer 才是“自建 PKI 的最佳方式”。相当于用 SelfSigned 只做第一步生成一张“Root CA 证书”自签名、isCAtrue把它保存成 Secret。然后用这个 Root CA Secret 配一个 CA Issuer后续所有业务证书都用 CA Issuer 去签形成“同一个私有 CA”体系这样就从“每张证书都自签”变成了“由统一 CA 签发”。相当于先构建一个CA然后由CA去签名。这是 SelfSigned 签发器的理想用例之一即为私有 PKI 引导自定义根证书包括配合 cert-manager CA 签发器使用。以下 YAML 配置将创建 SelfSigned 签发器签发根证书并使用该根证书作为 CA 签发器命名空间级别命名空间级别的 ca 的特点资源放在 sandbox 里示例先创建了 Namespace: sandbox生成 Root CA 的 Certificate 也在 sandbox产物 Secret 是sandbox/root-secret最终创建的是 Issuer不是 ClusterIssuerkind: Issuer spec.ca.secretName: root-secret这个 my-ca-issuer 只能在 sandbox 这个 namespace 里被引用。适用场景你只想在某个 namespace 内部使用私有 CA不打算全集群共享。[rootmaster01 cert-manager]# vi selfsigned-root-ns.yaml---# 创建命名空间apiVersion: v1 kind: Namespace metadata: name: sandbox ---# 创建集群级别的 SelfSigned Issuer工具人apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: selfsigned-issuer spec: selfSigned:{}---# 用 SelfSigned Issuer 签一张 Root CA 证书# cert-manager 生成 Root CA 的私钥# 用 SelfSigned issuer 让这张 Root CA 证书“自签”# 把 Root CA 证书私钥 保存到 root-secret 这个 SecretapiVersion: cert-manager.io/v1 kind: Certificate metadata: name: my-selfsigned-ca namespace: sandbox spec: isCA:truecommonName: my-selfsigned-ca secretName: root-secret privateKey: algorithm: ECDSA size:256rotationPolicy: Always issuerRef: name: selfsigned-issuer kind: ClusterIssuer group: cert-manager.io ---# 创建 CA Issuer真正干活的 CA# 以后凡是引用这个 my-ca-issuer 的 Certificate# 都会用 root-secret 里那对 CA 私钥/证书来签发# 从此就有了一个“私有 CA”apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: my-ca-issuer namespace: sandbox spec: ca: secretName: root-secret[rootmaster01 cert-manager]# kubectl apply -f selfsigned-root-ns.yaml[rootmaster01 cert-manager]# kubectl get clusterissuers.cert-manager.ioNAME READY AGE selfsigned-cluster-issuer True 13m selfsigned-issuer True 31s[rootmaster01 cert-manager]# kubectl -n test get certificateNAME READY SECRET AGE my-selfsigned-ca True root-secret 76s集群级别也可使用 ClusterIssuer 通过 SelfSigned Certificate CA 为集群中任意位置的 Certificates 签名请采用以下 YAML 配置稍作修改集群级别的 ca 的特点不再需要 sandbox因为目标是 ClusterIssuerRoot CA 的 Secret 被放到 cert-manager namespace通常默认cert-manager/root-secret最终创建的是 ClusterIssuerkind: ClusterIssuer spec.ca.secretName: root-secretClusterIssuer 不在任何 namespace所以它引用的 secretName 默认会去 cert-manager namespace 找这是 cert-manager 的约定/实现。适用场景希望全集群任何 namespace 都能引用同一个 CA 来签证书统一内部 PKI。[rootmaster01 cert-manager]# vim selfsigned-root-cl.yaml--- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: selfsigned-issuer spec: selfSigned:{}--- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: my-selfsigned-ca namespace: cert-manager spec: isCA:truecommonName: my-selfsigned-ca secretName: root-secret privateKey: algorithm: ECDSA size:256rotationPolicy: Always issuerRef: name: selfsigned-issuer kind: ClusterIssuer group: cert-manager.io --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: my-ca-issuer spec: ca: secretName: root-secret[rootmaster01 cert-manager]# kubectl apply -f selfsigned-root-cl.yaml[rootmaster01 cert-manager]# kubectl get clusterissuers.cert-manager.ioNAME READY AGE my-ca-issuer True 32s selfsigned-cluster-issuer True 18m selfsigned-issuer True 5m28s[rootmaster01 cert-manager]# kubectl -n cert-manager get certificateNAME READY SECRET AGE my-selfsigned-ca True root-secret 46s提示使用 SelfSigned 证书的客户端无法信任这些证书需要事先在客户端导入这些证书。