지원되지 않는 DNS 공급업체에서 Cert manager 확장 및 사용

개요


Cert 관리자는 기본적으로 Cloud DNS와 Route 53을 지원하지만, Alibaba Cloud DNS와 벚꽃 구름을 지원하는 DNS 앱은 지원하지 않아 직접 설치해도 사용할 수 없다.
// github.com/jetstack/cert-manager/pkg/issuer/acme/dns/dns.go

type dnsProviderConstructors struct {
	cloudDNS     func(project string, serviceAccount []byte, dns01Nameservers []string, ambient bool, hostedZoneName string) (*clouddns.DNSProvider, error)
	cloudFlare   func(email, apikey, apiToken string, dns01Nameservers []string) (*cloudflare.DNSProvider, error)
	route53      func(accessKey, secretKey, hostedZoneID, region, role string, ambient bool, dns01Nameservers []string) (*route53.DNSProvider, error)
	azureDNS     func(environment, clientID, clientSecret, subscriptionID, tenantID, resourceGroupName, hostedZoneName string, dns01Nameservers []string, ambient bool) (*azuredns.DNSProvider, error)
	acmeDNS      func(host string, accountJson []byte, dns01Nameservers []string) (*acmedns.DNSProvider, error)
	digitalOcean func(token string, dns01Nameservers []string) (*digitalocean.DNSProvider, error)
}
그러나 Cert 관리자는 웹훅의 확장 인터페이스를 갖추고 이 인터페이스에 맞는 웹 서버를 개발하여 기본적으로 지원하는 DNS 공급자 이외에도 Cert 관리자를 사용할 수 있다.
이번 해설은 웹훅의 구조를 따라 Cert 관리자를 확장하는 방법을 설명한다.

개발하다


웹훅의 확장 기능 개발에서 정부jetstack는 다음과 같은 템플릿 창고를 제공하여 이에 따라 개발할 수 있다.
https://github.com/jetstack/cert-manager-webhook-example
상기 템플릿 창고main.go에서 다음과 같은 내용으로 정의하여 각종 이벤트에 대응하는 방법을 준비하였다.
package main

import (
	"encoding/json"
	"fmt"
	"os"

	extapi "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
	"k8s.io/client-go/rest"

	"github.com/jetstack/cert-manager/pkg/acme/webhook/apis/acme/v1alpha1"
	"github.com/jetstack/cert-manager/pkg/acme/webhook/cmd"
)

var GroupName = os.Getenv("GROUP_NAME")

func main() {
	if GroupName == "" {
		panic("GROUP_NAME must be specified")
	}

	cmd.RunWebhookServer(GroupName,
		&customDNSProviderSolver{},
	)
}

type customDNSProviderSolver struct {
}

type customDNSProviderConfig struct {
}

func (c *customDNSProviderSolver) Name() string {
	return "my-custom-solver"
}

func (c *customDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error {
	cfg, err := loadConfig(ch.Config)
	if err != nil {
		return err
	}
	return nil
}

func (c *customDNSProviderSolver) CleanUp(ch *v1alpha1.ChallengeRequest) error {
	return nil
}

func (c *customDNSProviderSolver) Initialize(kubeClientConfig *rest.Config, stopCh <-chan struct{}) error {
	return nil
}

func loadConfig(cfgJSON *extapi.JSON) (customDNSProviderConfig, error) {
	cfg := customDNSProviderConfig{}
	if cfgJSON == nil {
		return cfg, nil
	}
	if err := json.Unmarshal(cfgJSON.Raw, &cfg); err != nil {
		return cfg, fmt.Errorf("error decoding solver config: %v", err)
	}

	return cfg, nil
}

이루어지다


주로 설치해야 할 곳main.go의 구조체와 방법을 차례로 해설한다.

customDNSProviderConfig


이 구조는 DNS 공급자의 API 키 등에 대한 정보를 설정하기 위해 다음과 같이 정의되어 있습니다.
type customDNSProviderConfig struct {
	...
}

customDNSProviderSolver


Fabric Retention은 Cert manager 이벤트에 대응하는 논리적 방법을 정의합니다.
type customDNSProviderSolver struct {
	:
}

groupName 및 solverName


웹hook에서 실현된 확장 기능은 사전에 정의, 설정된groupNamesolverName를 통해 식별된다.main.go에서 환경 변수GROUP_NAME에서 얻은 값main()을 함수 내cmd.RunWebhookServer()에서 함수의 첫 번째 매개 변수로 전달한 값을 설정groupName한다.
var GroupName = os.Getenv("GROUP_NAME")

func main() {
	if GroupName == "" {
		panic("GROUP_NAME must be specified")
	}

	cmd.RunWebhookServer(GroupName,
		&customDNSProviderSolver{},
	)
}
customDNSProviderSolver 구조체Name()의 방법을 더하면 이 반환값은 solverName로 처리한다.
func (c *customDNSProviderSolver) Name() string ...

DNS01 도전용 TXT 레코드 추가 및 삭제


DNS01 도전에 사용된 TXT 레코드의 추가 및 삭제는 다음 방법 내에서 수행됩니다.
func (solver *SacloudDNSProviderSolver) Present(ch *v1alpha1.ChallengeRequest) error ... // 追加
func (solver *SacloudDNSProviderSolver) CleanUp(ch *v1alpha1.ChallengeRequest) error ... // 削除
상기 방법의 처리는 DNS 제공자가 제공한 다양한 라이브러리와 API를 사용하여 도전용 기록을 제작하고 삭제해야 한다.
이렇게 되면 설치해야 할 곳은 여기까지입니다.

프로그램 설계


Docker 이미지


Kubbernetes의 그룹에서 디버깅을 진행할 때, 위에서 실시한 웹 훅은 반드시 사전에 Docker 이미지화를 해야 한다.자체적으로 Giithub Actions에서 코드의 구축 및 태그, 레지스트리의push를 자동화합니다.

Helm Chart의 준비.


디버그 선언을 위해 템플릿 창고의 deploy/example-webhook 디렉터리에 있는 Helm Chart를 초기 형태로 사용합니다.
이 디렉토리의 values.yaml는 Docker 이미지의 레지스트리, 이미지, 레이블 등의 값을 필요에 따라 설정합니다.
groupName: acme.mycompany.com

certManager:
  namespace: cert-manager
  serviceAccountName: cert-manager

image:
  repository: mycompany/webhook-image
  tag: latest
  pullPolicy: IfNotPresent

nameOverride: ""
fullnameOverride: ""

service:
  type: ClusterIP
  port: 443

resources: {}

nodeSelector: {}

tolerations: []

affinity: {}

Apply


다음 명령을 사용하여 Helm 설치를 수행합니다.
$ helm install ./deploy/example-webhook/ --generate-name

디버깅


디버깅은 주로 k8s.io/klog 소프트웨어 패키지로 코드에 로그 출력 처리를 삽입한다.이외에도 cert-managernamespace에 존재하는 Pod도 로그를 출력하여 참고할 수 있습니다.

주의점


아래의 투구 수정은 적응이 필요하다.
https://github.com/jetstack/cert-manager-webhook-example/pull/14/

참고 자료


스스로 벚꽃 구름이 제공하는 DNS 앱에 웹훅을 설치했고, 다른 것은 알리바바 등으로 구현해 참고 가치가 있다.
https://github.com/DEVmachine-fr/cert-manager-alidns-webhook

좋은 웹페이지 즐겨찾기