cert-manager 和 cert-manager-alidns-webhook 的设计

从 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)

    • 关联的 SecretOrderChallenge 等

协调循环(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 的集成
  1. 注册 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"]
  2. 证书签发流程中的交互

    图表


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 提供商:

  1. 实现 Solver 接口:

    type Solver interface {
        Present(context.Context, *v1alpha1.Challenge) error
        CleanUp(context.Context, *v1alpha1.Challenge) error
    }
  2. 注册 Webhook 服务:

    mux := http.NewServeMux()
    mux.Handle("/solve", solver.NewHandler())
    http.ListenAndServeTLS(":443", certPath, keyPath, mux)

总结

组件Kubernetes 编程技术应用关键接口/CRD
cert-manager控制器模式、CRD 管理、事件驱动CertificateIssuer
alidns-webhook动态准入控制、外部 API 集成ChallengeSolver 接口

通过这种设计,cert-manager 实现了:

  • 解耦:核心逻辑与 DNS 提供商实现分离。

  • 可扩展性:轻松添加新 DNS 提供商。

  • 声明式 API:用户通过 YAML 定义证书需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值