从 Kubernetes 编程的角度来看,cert-manager
和 cert-manager-alidns-webhook
的设计体现了 Kubernetes 控制器模式、Custom Resource Definitions (CRDs) 和 Webhook 扩展机制 的核心思想。下面通过代码层面的设计拆解它们的协作原理:
1. cert-manager 的架构与编程模型
核心组件
// cert-manager 的核心控制器结构(简化版)
type CertificateController struct {
kubeClient kubernetes.Interface
cmClient certmanager.Interface
recorder record.EventRecorder
issuerHelper issuer.Helper // 负责与 Issuer/ClusterIssuer 交互
}
-
监听的资源:
-
Certificate
(CRD) -
Issuer/ClusterIssuer
(CRD) -
关联的
Secret
、Order
、Challenge
等
-
协调循环(Reconcile Loop)
func (c *CertificateController) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
// 1. 获取 Certificate 对象
cert := &v1.Certificate{}
if err := c.client.Get(ctx, req.NamespacedName, cert); err != nil {
return reconcile.Result{}, err
}
// 2. 验证并准备签发条件
if !isReadyForIssuance(cert) {
return c.retryAfter(5 * time.Minute), nil
}
// 3. 调用 Issuer 签发证书
issuerObj, err := c.issuerHelper.GetIssuer(ctx, cert)
if err != nil {
return reconcile.Result{}, err
}
// 4. 根据 Issuer 类型(ACME/CA/Vault)触发不同逻辑
switch issuerObj.Spec.Type {
case "acme":
return c.handleACMEIssuance(ctx, cert, issuerObj)
case "ca":
return c.handleCAIssuance(ctx, cert, issuerObj)
}
}
关键编程技巧
-
控制器模式:通过
client-go
的Informer
监听资源变化。 -
状态机管理:
Certificate
的状态转换(Issuing
→Ready
)。 -
事件驱动:使用
EventRecorder
记录 Kubernetes Events。
2. cert-manager-alidns-webhook 的扩展机制
Webhook 的职责
// 阿里云 DNS Webhook 的请求处理逻辑(简化)
type AlidnsSolver struct {
client alidns.Client // 阿里云 SDK 客户端
recorder record.EventRecorder
}
func (s *AlidnsSolver) Present(ctx context.Context, challenge *v1alpha1.Challenge) error {
// 1. 解析域名和 TXT 记录值
domain := challenge.Spec.DNSName
record := "_acme-challenge." + domain
value := challenge.Spec.Key
// 2. 调用阿里云 API 添加 DNS 记录
resp, err := s.client.AddDomainRecord(&alidns.AddDomainRecordRequest{
DomainName: domain,
RR: record,
Type: "TXT",
Value: value,
})
if err != nil {
s.recorder.Eventf(challenge, "Failed", "调用阿里云 API 失败: %v", err)
return err
}
// 3. 更新 Challenge 状态
patchChallengeStatus(challenge, "DNS记录已添加")
return nil
}
func (s *AlidnsSolver) CleanUp(ctx context.Context, challenge *v1alpha1.Challenge) error {
// 清理 DNS 记录的逻辑
}
与 cert-manager 的集成
-
注册 Webhook:
# cert-manager 通过 MutatingWebhookConfiguration 发现 Webhook apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: name: cert-manager-webhook-alidns webhooks: - name: webhook.cert-manager.io clientConfig: service: name: cert-manager-webhook-alidns namespace: cert-manager path: "/solve" rules: - apiGroups: ["acme.cert-manager.io"] apiVersions: ["v1"] operations: ["CREATE", "UPDATE"] resources: ["challenges"]
-
证书签发流程中的交互:
图表
3. 关键 Kubernetes 编程概念应用
(1) Custom Resource Definitions (CRDs)
# cert-manager 定义的 CRD 示例(Certificate)
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: certificates.cert-manager.io
spec:
group: cert-manager.io
names:
kind: Certificate
plural: certificates
scope: Namespaced
versions:
- name: v1
schema:
openAPIV3Schema:
properties:
spec:
properties:
dnsNames:
type: array
items: string
issuerRef:
type: object
properties:
name: string
kind: string
(2) 控制器模式
-
cert-manager:主控制器监听
Certificate
,协调签发流程。 -
alidns-webhook:辅助控制器处理
Challenge
资源。
(3) 动态准入控制(Webhook)
-
挑战分派:cert-manager 根据
Challenge.Spec.Solver
选择对应的 Webhook。 -
插件化架构:通过
groupName
和solverName
实现多 DNS 提供商支持。
4. 调试与扩展建议
调试技巧
# 查看 cert-manager 内部状态
kubectl get certificaterequests,orders,challenges -o yaml
# 检查 Webhook 调用日志
kubectl logs -n cert-manager deploy/cert-manager-webhook-alidns
扩展自定义 Provider
若需支持其他 DNS 提供商:
-
实现
Solver
接口:type Solver interface { Present(context.Context, *v1alpha1.Challenge) error CleanUp(context.Context, *v1alpha1.Challenge) error }
-
注册 Webhook 服务:
mux := http.NewServeMux() mux.Handle("/solve", solver.NewHandler()) http.ListenAndServeTLS(":443", certPath, keyPath, mux)
总结
组件 | Kubernetes 编程技术应用 | 关键接口/CRD |
---|---|---|
cert-manager | 控制器模式、CRD 管理、事件驱动 | Certificate 、Issuer |
alidns-webhook | 动态准入控制、外部 API 集成 | Challenge 、Solver 接口 |
通过这种设计,cert-manager 实现了:
-
解耦:核心逻辑与 DNS 提供商实现分离。
-
可扩展性:轻松添加新 DNS 提供商。
-
声明式 API:用户通过 YAML 定义证书需求。