K8s Lab 把当前仓库文档整理成一个可阅读的网页站点

Repository Reading Site

本轮操作记录:cert-manager 安装、CA 签发与 Ingress 自动证书实验

这一轮我要把下面几件事情做成真实证据: 1. cert-manager 不是只装个 Pod,而是一套 CRD + controller + webhook + cainjector 2. `SelfSigned -> Root CA -> CA ClusterIssuer` 这条引导链能跑通 3. Ingress 注解确实会触发 `ingress-shim`

Markdown16-操作记录-cert-manager-安装-CA签发与Ingress自动证书实验.md2026年4月10日 08:06

本轮操作记录:cert-manager 安装、CA 签发与 Ingress 自动证书实验

本轮目标

这一轮我要把下面几件事情做成真实证据:

  1. cert-manager 不是只装个 Pod,而是一套 CRD + controller + webhook + cainjector
  2. SelfSigned -> Root CA -> CA ClusterIssuer 这条引导链能跑通
  3. Ingress 注解确实会触发 ingress-shim 自动创建 Certificate
  4. Certificate -> CertificateRequest -> Secret 的控制链能够看见
  5. 这次实验为什么没有 Order / Challenge
  6. 叶子证书为什么 subject 可以为空但 SAN 正常
  7. 为什么 curl 默认失败、-k 成功、--cacert 也能成功
  8. 为什么版本选择不能只看“最新”

Step 1:先核对集群版本和 cert-manager 版本策略

实际命令

KUBECONFIG=~/.kube/config-k8s-lab kubectl version

KUBECONFIG=~/.kube/config-k8s-lab kubectl get nodes -o wide

我看到的关键结果

  • Client Version:v1.31.4
  • Server Version:v1.30.14

为什么这一步重要

因为 cert-manager 这种控制面组件,版本选择绝不能拍脑袋。

你不能只问:

  • 最新版本是多少

你还必须问:

  • 它和当前 Kubernetes 版本是否在官方兼容窗口里

这一步的工程判断

截至 2026-04-10

  • 当前集群是 Kubernetes 1.30.14
  • cert-manager 较新的发布线已经面向 1.31+

所以本轮实验我最终采用:

  • cert-manager v1.18.6

原因不是“它最新”,而是:

  • 它属于与当前 Kubernetes 1.30.x 更匹配的兼容分支

原理解释

这是典型的平台工程判断。

专家不会一看到新版本就无脑上,而是先看三件事:

  1. 兼容矩阵
  2. 支持周期
  3. 升级路径

这和业务代码升级一样,必须有版本意识。


Step 2:安装 cert-manager 控制面

实际命令

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.18.6/cert-manager.yaml

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager wait --for=condition=Available deploy --all --timeout=180s

我额外写入仓库的复现脚本

为什么要用官方发布清单安装

因为 cert-manager 本身就是一个成套控制面:

  • CRD
  • RBAC
  • ServiceAccount
  • Deployment
  • WebhookConfiguration

官方发布清单能保证这些对象组合关系正确。

我看到的关键结果

kubectl apply 成功创建 / 更新了:

  • namespace/cert-manager
  • 多个 CRD
  • 多个 RBAC 对象
  • deployment.apps/cert-manager
  • deployment.apps/cert-manager-cainjector
  • deployment.apps/cert-manager-webhook
  • mutatingwebhookconfiguration/validatingwebhookconfiguration

随后 wait 显示:

  • deployment.apps/cert-manager condition met
  • deployment.apps/cert-manager-cainjector condition met
  • deployment.apps/cert-manager-webhook condition met

原理解释

你要把这次安装看成“给 Kubernetes 装了一个新的控制面子系统”。

它不是一个单容器工具,而是:

  1. CRD 提供新 API
  2. controller 负责 reconcile
  3. webhook 负责准入校验
  4. cainjector 负责把 CA bundle 注入到 webhook 相关对象

如果只看 Pod Running,而不看 CRD / webhook / RBAC 是否完整,那不叫会装 cert-manager。


Step 3:确认 cert-manager 的 API 和组件已经真的可用

实际命令

KUBECONFIG=~/.kube/config-k8s-lab kubectl get crd | grep -E 'cert-manager.io|acme.cert-manager.io'

KUBECONFIG=~/.kube/config-k8s-lab kubectl api-resources | grep -E '^certificates|^certificaterequests|^issuers|^clusterissuers|^orders|^challenges'

KUBECONFIG=~/.kube/config-k8s-lab kubectl -n cert-manager get deploy,pod,svc -o wide

我看到的关键结果

CRD

已经出现:

  • certificates.cert-manager.io
  • certificaterequests.cert-manager.io
  • issuers.cert-manager.io
  • clusterissuers.cert-manager.io
  • orders.acme.cert-manager.io
  • challenges.acme.cert-manager.io

API 资源

已经能看到:

  • Certificate
  • CertificateRequest
  • Issuer
  • ClusterIssuer
  • Order
  • Challenge

控制器镜像

升级后我确认到:

  • quay.io/jetstack/cert-manager-controller:v1.18.6
  • quay.io/jetstack/cert-manager-cainjector:v1.18.6
  • quay.io/jetstack/cert-manager-webhook:v1.18.6

原理解释

这一步是在回答:

我装进去的到底是“镜像”,还是“整个 API 扩展能力”?

如果 CRD 不存在:

  • Kubernetes 根本不认识 Certificate

如果 controller 不存在:

  • 这些对象只是摆设,没有人会去处理

如果 webhook 不存在或证书链坏了:

  • 你可能在创建 cert-manager 对象时直接被 admission 卡死

所以专家式安装验证一定是:

  • API 看得见
  • 控制器跑得动
  • webhook 可通信

Step 4:验证 webhook 的 TLS 信任链确实被注入了

实际命令

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl get validatingwebhookconfiguration cert-manager-webhook -o yaml | rg -n 'caBundle|name:'

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl get mutatingwebhookconfiguration cert-manager-webhook -o yaml | rg -n 'caBundle|name:'

我看到的关键结果

两类 webhook 配置里都存在:

  • caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...

原理解释

这一步是为了证明:

  • cainjector 不是摆设

API Server 调 webhook 是 HTTPS。

而 HTTPS 要验证服务端证书,就必须知道该信哪张 CA。

caBundle 被注入进去,说明 cert-manager 已经把自己的 webhook 信任链补齐了。

这是一个很容易被忽略,但在控制面里极其关键的细节。


Step 5:创建实验命名空间和签发者引导链

本课清单

实际命令

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl apply \
  -f manifests/16-cert-manager/10-namespace-cert-manager-lab.yaml \
  -f manifests/16-cert-manager/20-bootstrap-selfsigned-clusterissuer.yaml \
  -f manifests/16-cert-manager/21-root-ca-certificate.yaml \
  -f manifests/16-cert-manager/22-root-ca-clusterissuer.yaml

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager wait --for=condition=Ready certificate/lab-root-ca --timeout=180s

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl wait --for=condition=Ready clusterissuer/lab-root-ca-issuer --timeout=180s

我看到的关键结果

创建成功:

  • namespace/cert-manager-lab
  • clusterissuer/lab-selfsigned-bootstrap
  • certificate/lab-root-ca
  • clusterissuer/lab-root-ca-issuer

Ready 验证成功:

  • certificate.cert-manager.io/lab-root-ca condition met
  • clusterissuer.cert-manager.io/lab-root-ca-issuer condition met

这里到底发生了什么

这一段非常关键。

第一步:lab-selfsigned-bootstrap

它是一个 selfSigned 类型的 ClusterIssuer

作用不是给业务直接长期签证书,而是:

  • 先生成一张 root CA 自己的证书

第二步:lab-root-ca

这是一个 Certificate,但它不是业务叶子证书,而是:

  • isCA: true

也就是说,它要产出的不是普通站点证书,而是一张“可用于签发别人”的 CA 证书。

第三步:lab-root-ca-secret

lab-root-ca Ready 后,cert-manager 把结果写进了 Secret。

第四步:lab-root-ca-issuer

这是一个 ca 类型的 ClusterIssuer

它的工作不是自签自己,而是:

  • 使用 lab-root-ca-secret 里的 CA 私钥和证书去给其他证书签名

原理解释

你可以把这四步理解成:

先把“印章”造出来
再拿这枚“印章”去盖业务证书

如果没有 bootstrap 这一步,你就没有自己的 CA 基座。


Step 6:检查 root CA Secret 里到底有什么

实际命令

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager get secret lab-root-ca-secret \
  -o go-template='{{.type}}{{"\n"}}{{range $k,$v := .data}}{{printf "%s\n" $k}}{{end}}'

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager get secret lab-root-ca-secret \
  -o go-template='{{index .data "tls.crt"}}' | base64 -d | \
  openssl x509 -noout -subject -issuer -dates -text | sed -n '1,40p'

我看到的关键结果

Secret 类型:

  • kubernetes.io/tls

数据键:

  • ca.crt
  • tls.crt
  • tls.key

证书摘要:

subject=O=k8s-lab, CN=lab-root-ca
issuer=O=k8s-lab, CN=lab-root-ca
notBefore=Apr 10 07:40:19 2026 GMT
notAfter=Apr 10 07:40:19 2027 GMT

原理解释

这段输出证明了两件事:

  1. 这张证书是 root CA
  2. 它是自签的

为什么?

因为:

  • subjectissuer 相同

这就是典型的 root CA 表现。

这一步让你真正看到:

  • selfSigned 不是抽象概念
  • 它确实签出了一个可作为信任根的 CA 证书

Step 7:部署业务应用、Service 和带注解的 Ingress

本课业务清单

实际命令

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl apply \
  -f manifests/16-cert-manager/30-web.yaml \
  -f manifests/16-cert-manager/31-service.yaml \
  -f manifests/16-cert-manager/40-ingress-annotated.yaml

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager-lab wait --for=condition=Available deploy/cm-web --timeout=180s

我创建了什么

Deployment

  • cm-web

返回一个静态页面,写出:

  • pod 名称
  • pod IP
  • 节点名
  • host
  • issuer

Service

  • cm-web-svc

Ingress

  • cm-web
  • host:auto-secure.k8s-lab.local
  • annotation:cert-manager.io/cluster-issuer: lab-root-ca-issuer
  • tls.secretName:cm-web-tls

原理解释

这一步的关键不是业务本身,而是:

我故意只写 Ingress 注解和 tls.secretName,让 cert-manager 自己去补 Certificate

这样才能看清 ingress-shim 的真实作用。


Step 8:观察 ingress-shim 自动补出的证书对象

实际命令

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager-lab get ingress,certificate,certificaterequest,secret,pod,svc,endpoints -o wide

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager-lab get certificate cm-web-tls -o yaml | sed -n '1,240p'

我看到的关键结果

Ingress

  • cm-web
  • HOSTS: auto-secure.k8s-lab.local
  • ADDRESS: 10.109.198.120

自动生成的 Certificate

  • certificate.cert-manager.io/cm-web-tls
  • READY: True
  • SECRET: cm-web-tls
  • ISSUER: lab-root-ca-issuer

更关键的是它的 ownerReferences

ownerReferences:
  - apiVersion: networking.k8s.io/v1
    kind: Ingress
    name: cm-web

原理解释

这是一条非常重要的证据链:

  • 我没有手工创建 cm-web-tls 这个 Certificate
  • 但它出现了
  • 而且 owner 指向 Ingress cm-web

所以我们可以明确得出结论:

这个 Certificate 是 ingress-shim 根据带 cert-manager 注解的 Ingress 自动补出来的。


Step 9:检查 CertificateRequest 和最终 Secret

实际命令

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager-lab get certificaterequest cm-web-tls-1 -o yaml | sed -n '1,240p'

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager-lab get secret cm-web-tls \
  -o go-template='{{.type}}{{"\n"}}{{range $k,$v := .data}}{{printf "%s\n" $k}}{{end}}'

我看到的关键结果

CertificateRequest

  • 名字:cm-web-tls-1
  • APPROVED: True
  • READY: True
  • REQUESTER: system:serviceaccount:cert-manager:cert-manager
  • ISSUER: lab-root-ca-issuer

状态里有:

  • type: Approved
  • type: Ready

最终 Secret

  • type: kubernetes.io/tls
  • keys:
    • ca.crt
    • tls.crt
    • tls.key

原理解释

这一段证明 cert-manager 的签发流程不是“黑盒一步到位”,而是经历了:

  1. Certificate
  2. CertificateRequest
  3. Secret

三个阶段。

你以后排障时,一定要把 CertificateRequest 单独看。

因为它往往是问题分界点:

  • 如果 Certificate 有,但 CertificateRequest 没有,说明前面的控制链没触发
  • 如果 CertificateRequest 有,但没 Approved 或没 Ready,说明签发链卡住了
  • 如果 CertificateRequest Ready 了但 Secret 还不对,就要继续看结果写回阶段

Step 10:用事件把整条控制循环串起来

实际命令

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager-lab get events --sort-by=.lastTimestamp

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager-lab describe certificate cm-web-tls

我看到的关键事件顺序

CreateCertificate    ingress/cm-web
Issuing              certificate/cm-web-tls
Generated            certificate/cm-web-tls
Requested            certificate/cm-web-tls
Certificate request has been approved by cert-manager.io
CertificateIssued    certificaterequest/cm-web-tls-1
The certificate has been successfully issued

这条时序怎么理解

CreateCertificate

说明 ingress-shim 已经开始工作。

Issuing

说明 cert-manager 发现目标 Secret 不存在,需要开始签发。

Generated

说明它先生成了私钥,并暂存到临时 Secret,例如:

  • cm-web-tls-k2xl9

Requested

说明它创建了正式的 CertificateRequest

Approved

说明请求经过了批准流程。

CertificateIssued

说明 issuer 已经把证书签出来。

原理解释

这一串事件就是你以后看 cert-manager 的“时序望远镜”。

你完全可以根据它来判断:

  • 卡在 shim
  • 卡在 key generation
  • 卡在 request
  • 卡在 approval
  • 卡在 issuer signing

Step 11:确认这次为什么没有 Order / Challenge

实际命令

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager-lab get orders.acme.cert-manager.io,challenges.acme.cert-manager.io

我看到的关键结果

No resources found in cert-manager-lab namespace.

原理解释

这是正常现象。

因为本轮签发是:

  • CA ClusterIssuer

不是:

  • ACME ClusterIssuer

所以不需要:

  • 向外部 ACME CA 下单
  • 接收 challenge
  • 创建 solver
  • 对公网证明域名控制权

这一步是在帮你建立一个非常重要的边界感:

cert-manager 是通用证书生命周期控制器,ACME 只是其中一种 issuer 模式。


Step 12:做 TLS 握手层验证,而不是只看 Kubernetes 对象

为什么要从节点本机验证

因为当前工作站存在:

  • HTTP_PROXY=http://127.0.0.1:7890
  • HTTPS_PROXY=http://127.0.0.1:7890

直接从本机打公网 NodePort,容易被本地代理污染结果。

所以这一轮我优先用:

  • ssh root@107.148.176.193
  • 节点本机回环地址 127.0.0.1:30443
  • --resolve
  • openssl s_client

这样链路最干净。

实际命令

ssh -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=8 root@107.148.176.193 \
  "echo | openssl s_client -connect 127.0.0.1:30443 -servername auto-secure.k8s-lab.local 2>/dev/null | \
   openssl x509 -noout -subject -issuer -dates -ext subjectAltName"

我看到的关键结果

subject=
issuer=O = k8s-lab, CN = lab-root-ca
notBefore=Apr 10 07:41:12 2026 GMT
notAfter=Jul  9 07:41:12 2026 GMT
X509v3 Subject Alternative Name: critical
    DNS:auto-secure.k8s-lab.local

原理解释

这段输出很有价值。

第一:issuer 是 lab-root-ca

说明 ingress-nginx 当前加载的已经不是默认假证书,而是 cert-manager 签发出来的业务证书。

第二:subject= 为空

这不是异常。

这说明叶子证书没有显式设置 CN,但:

  • SAN 里有 DNS:auto-secure.k8s-lab.local

现代 TLS 主机名校验主要看 SAN,这完全符合预期。


Step 13:验证“未信任”和“跳过校验”是两件不同的事

实际命令

ssh -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=8 root@107.148.176.193 \
  "curl --resolve auto-secure.k8s-lab.local:30443:127.0.0.1 -sS -D - https://auto-secure.k8s-lab.local:30443/"

ssh -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=8 root@107.148.176.193 \
  "curl -k --resolve auto-secure.k8s-lab.local:30443:127.0.0.1 -sS -D - https://auto-secure.k8s-lab.local:30443/"

我看到的关键结果

不带 -k

curl: (60) SSL certificate problem: unable to get local issuer certificate

-k

HTTP/2 200
...
<h1>cert-manager ingress-shim demo</h1>
<p>pod: cm-web-7b8d4c85d-g6jmc</p>
<p>pod_ip: 10.244.242.61</p>
<p>node: cp-3</p>

原理解释

不带 -k 失败

说明:

  • 客户端默认不信任我们自己的 root CA

-k 成功

说明:

  • TLS 握手和加密本身没有问题
  • 只是跳过了身份校验

这是排障里特别重要的判断能力。

很多人看到 curl -k 成功,就误以为证书没问题。

其实这只能说明:

  • 数据面握手通了

不能说明:

  • 证书信任链对客户端是成立的

Step 14:给客户端显式灌入 CA 后,再做一次正确校验

实际命令

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager-lab get secret cm-web-tls \
  -o go-template='{{index .data "ca.crt"}}' | base64 -d > /tmp/cm-web-ca.crt

ssh -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=8 root@107.148.176.193 \
  'cat > /tmp/cm-web-ca.crt' < /tmp/cm-web-ca.crt

ssh -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=8 root@107.148.176.193 \
  "curl --cacert /tmp/cm-web-ca.crt --resolve auto-secure.k8s-lab.local:30443:127.0.0.1 -sS -D - https://auto-secure.k8s-lab.local:30443/"

我看到的关键结果

HTTP/2 200
...
<h1>cert-manager ingress-shim demo</h1>
<p>pod: cm-web-7b8d4c85d-g6jmc</p>

我随后又做了一个纯状态码验证:

ssh root@107.148.176.193 \
  "curl --cacert /tmp/cm-web-ca.crt --resolve auto-secure.k8s-lab.local:30443:127.0.0.1 -sS -o /dev/null -w '%{http_code}\n' https://auto-secure.k8s-lab.local:30443/"

结果:

  • 200

原理解释

这一步证明:

  • 证书链本身是正确的
  • 只是客户端原本不认识这张根 CA

也就是说,这不是“证书坏了”,而是:

  • trust store 缺少对应根证书

这正是企业内网 CA 场景里最常见的现实:

  • 平台能自动签
  • 但客户端是否信任,还取决于信任根分发策略

Step 15:验证升级到 v1.18.6 后,控制面和业务面仍然正常

为什么要做这一步

因为平台工程里,升级不是“apply 完就结束”,而是:

  1. 控制面组件是否全部 rollout 成功
  2. 旧的证书对象是否仍然 Ready
  3. 数据面请求是否仍然正常

实际命令

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager rollout status deploy/cert-manager --timeout=180s

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager rollout status deploy/cert-manager-cainjector --timeout=180s

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager rollout status deploy/cert-manager-webhook --timeout=180s

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager get deploy,pod -o wide

KUBECONFIG=~/.kube/config-k8s-lab \
kubectl -n cert-manager-lab get certificate,certificaterequest,secret,ingress -o wide

ssh root@107.148.176.193 \
  "curl -k --resolve auto-secure.k8s-lab.local:30443:127.0.0.1 -sS -o /dev/null -w '%{http_code}\n' https://auto-secure.k8s-lab.local:30443/"

ssh root@107.148.176.193 \
  "curl --cacert /tmp/cm-web-ca.crt --resolve auto-secure.k8s-lab.local:30443:127.0.0.1 -sS -o /dev/null -w '%{http_code}\n' https://auto-secure.k8s-lab.local:30443/"

我看到的关键结果

rollout

  • deployment "cert-manager" successfully rolled out
  • deployment "cert-manager-cainjector" successfully rolled out
  • deployment "cert-manager-webhook" successfully rolled out

镜像

  • controller:v1.18.6
  • cainjector:v1.18.6
  • webhook:v1.18.6

业务资源

  • certificate/cm-web-tlsReady=True
  • certificaterequest/cm-web-tls-1Approved=True, Ready=True
  • secret/cm-web-tls:存在
  • ingress/cm-webADDRESS=10.109.198.120

数据面

  • curl -k 返回 200
  • curl --cacert 返回 200

原理解释

这一步是在训练你形成“升级闭环验证”的习惯。

很多事故不是出在:

  • 安装失败

而是出在:

  • 安装成功了
  • 但旧资源没有按预期继续工作

所以升级验证一定要同时覆盖:

  • 控制面
  • 资源状态
  • 数据面

Step 16:回看这次实验,整条链到底被证明了什么

已被证实的事实一

cert-manager 安装成功的标准,不只是 Pod Running,而是:

  • CRD 存在
  • API 可见
  • controller 可用
  • webhook 可用
  • cainjector 注入了 caBundle

已被证实的事实二

SelfSigned 可以用于引导出 root CA。

证据:

  • lab-root-ca Ready
  • lab-root-ca-secret 内含 tls.crt/tls.key
  • subject == issuer == lab-root-ca

已被证实的事实三

带 cert-manager 注解的 Ingress 会触发 ingress-shim 自动创建 Certificate

证据:

  • Certificate cm-web-tls 自动出现
  • ownerReferences 指向 Ingress cm-web

已被证实的事实四

签发链路真实经过:

  • Certificate
  • CertificateRequest
  • Secret

证据:

  • 事件时序
  • cm-web-tls-1
  • cm-web-tls

已被证实的事实五

本轮没有 Order / Challenge 是正常的,因为我们不是 ACME。

已被证实的事实六

TLS 数据面实际加载的是 cert-manager 生成的证书,而不是默认假证书。

证据:

  • issuer=O = k8s-lab, CN = lab-root-ca
  • SAN 为 auto-secure.k8s-lab.local

已被证实的事实七

“是否加密”和“是否被信任”是两件不同的事。

证据:

  • curl 默认失败
  • curl -k 成功
  • curl --cacert 也成功

这轮实验里最值得你记住的 8 个结论

  1. cert-manager 是一套控制面,不是一个签证书脚本。
  2. Certificate 是期望状态,Secret 是结果状态。
  3. ingress-shim 让 Ingress 也能成为证书声明入口。
  4. CertificateRequest 是排障关键点,不能跳过。
  5. SelfSigned 适合引导 root CA,CA Issuer 适合拿 root 去签 leaf。
  6. Order / Challenge 只属于 ACME,不属于所有 cert-manager 场景。
  7. SANCN 更关键,叶子证书 subject 为空不一定有问题。
  8. curl -k 成功不代表证书被信任,只代表你跳过了验证。

下一轮最自然的推进方向

基于这一轮成果,下一课最自然就是进入:

  • ACME / Let's Encrypt / HTTP-01 / DNS-01

届时我会重点讲:

  • 公网域名自动签发到底多了哪些对象
  • 为什么会出现 Order / Challenge
  • solver Ingress / Pod / Service 是怎么工作的
  • HTTP-01 和 DNS-01 如何选择
  • 为什么通配符证书基本离不开 DNS-01
  • 生产里最常见的失败点和速率限制