このページの本文へ

FIXER Tech Blog - Development

Kubernetesのcert-managerについて簡潔にまとめておきますね

2024年05月22日 10時00分更新

文● なむゆ/FIXER

  • この記事をはてなブックマークに追加
  • 本文印刷

 本記事はFIXERが提供する「cloud.config Tech Blog」に掲載された「cert-manager について簡潔にまとめておきますね」を再編集したものです。

はじめに

 最近触った環境でcert-managerというソフトウェアを使用していて、その概要について把握するのにまあまあ時間がかかったため、あとで忘れたときの備忘録として、そして同様にソフトウェアについて把握したい方向けに簡潔にまとめておきます。

cert-managerとは

 KubernetesやOpenShift上で動作するTLS証明書の管理ソフトウェアです。

 Kubernetes上でPodが常駐し、証明書が期限切れになる前に定期的に証明書の更新を自動的に行ってくれます。

 作成した証明書はKubernetesのSecretとして自動生成されます。

 Helmまたはマニフェストで直接インストール可能です。

↓生成されるSecretの例 https://cert-manager.io/docs/usage/certificate/#target-secret

apiVersion: v1
    kind: Secret
    metadata:
      name: my-cert-tls
    type: kubernetes.io/tls
    data:
      ca.crt: <PEM CA certificate>
      tls.key: <PEM private key>
      tls.crt: <PEM signed certificate chain>
      tls-combined.pem: <PEM private key + "\n" + PEM signed certificate chain>
      key.der: <DER binary format of private key>

インストール方法

※前提条件としてHelmのインストールが必要ですが未インストールであれば別途インストールしてください

■マニフェストでインストールする

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.5/cert-manager.yaml

 これで、cert-managerネームスペースにcert-managerがインストールされます

■Helmでインストールする

helm repo add jetstack https://charts.jetstack.io --force-update
    helm repo update
    
helm install \
      cert-manager jetstack/cert-manager \
      --namespace cert-manager \
      --create-namespace \
      --version v1.14.5 \
      --set installCRDs=true

インストールされるカスタムリソース例

 cert-managerをインストールすると、cert-managerで使用するいくつかのカスタムリソースがKubernetes上にインストールされます。

 cert-managerを使用しているクラスターには以下のリソースが存在するため、探してみてください。

 インストールされるものの中で代表的なものは以下です。

■Issuer
 証明書を取得する認証局の設定を行います。
 取得する元の認証局によって設定値が異なります。
https://cert-manager.io/docs/concepts/issuer/
 パターンによる実装例はこちらから
https://cert-manager.io/docs/configuration/issuers/

↓例 https://cert-manager.io/docs/concepts/issuer/

apiVersion: cert-manager.io/v1
    kind: Issuer
    metadata:
      name: ca-issuer
      namespace: mesh-system
    spec:
      ca:
        secretName: ca-key-pair

■ClusterIssuer
 Issuer を全てのNamespaceで使いまわす場合に使用します。
 設定値はIssuerとほぼ同じです。Namespaceの指定がないのが大きな差異です。

↓ Azure DNSの例 https://cert-manager.io/docs/configuration/acme/dns01/azuredns/

apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: letsencrypt-staging
    spec:
      acme:
        server: https://acme-staging-v02.api.letsencrypt.org/directory
        email: $EMAIL_ADDRESS
        privateKeySecretRef:
          name: letsencrypt-staging
        solvers:
        - dns01:
            azureDNS:
              hostedZoneName: $AZURE_ZONE_NAME
              resourceGroupName: $AZURE_RESOURCE_GROUP
              subscriptionID: $AZURE_SUBSCRIPTION_ID
              environment: AzurePublicCloud
              managedIdentity:
                clientID: $IDENTITY_CLIENT_ID

■Certificate
 作成する証明書の詳細設定を行うリソースです。
 証明書の有効期限や期限の何時間前に更新処理を行うか、作成した証明書を保存するSecretリソースの名前、証明書のCommonName等を設定します。
https://cert-manager.io/docs/usage/certificate/#creating-certificate-resources

↓例 https://cert-manager.io/docs/usage/certificate/

apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: example-com
      namespace: sandbox
    spec:
      # Secret names are always required.
      secretName: example-com-tls
      # secretTemplate is optional. If set, these annotations and labels will be
      # copied to the Secret named example-com-tls. These labels and annotations will
      # be re-reconciled if the Certificate's secretTemplate changes. secretTemplate
      # is also enforced, so relevant label and annotation changes on the Secret by a
      # third party will be overwriten by cert-manager to match the secretTemplate.
      secretTemplate:
        annotations:
          my-secret-annotation-1: "foo"
          my-secret-annotation-2: "bar"
        labels:
          my-secret-label: foo
      duration: 2160h # 90d
      renewBefore: 360h # 15d
      subject:
        organizations:
          - jetstack
      # The use of the common name field has been deprecated since 2000 and is
      # discouraged from being used.
      commonName: example.com
      isCA: false
      privateKey:
        algorithm: RSA
        encoding: PKCS1
        size: 2048
      usages:
        - server auth
        - client auth
      # At least one of a DNS Name, URI, IP address or otherName is required.
      dnsNames:
        - example.com
        - www.example.com
      uris:
        - spiffe://cluster.local/ns/sandbox/sa/example
      ipAddresses:
        - 192.168.0.5
      # Needs cert-manager 1.14+ and "OtherNames" feature flag
      otherNames:
        # Should only supply oid of ut8 valued types
        - oid: 1.3.6.1.4.1.311.20.2.3 # User Principal Name "OID"
          utf8Value: upn@example.local
      # Issuer references are always required.
      issuerRef:
        name: ca-issuer
        # We can reference ClusterIssuers by changing the kind here.
        # The default value is Issuer (i.e. a locally namespaced Issuer)
        kind: Issuer
        # This is optional since cert-manager will default to this value however
        # if you are using an external issuer, change this to that issuer group.
        group: cert-manager.io
      # keystores allows adding additional output formats. This is an example for reference only.
      keystores:
        pkcs12:
          create: true
          passwordSecretRef:
            name: example-com-tls-keystore
            key: password
          profile: Modern2023

何か問題が起きたときは

 証明書発行に何か問題が起きた場合は、まずcert-managerのPodのログを確認することをお勧めします。

 デフォルトではcert-managerネームスペースに証明書更新を実行するPodがいるはずなので、kubectl logsコマンドでPodのログを確認してください。

 また、cert-manager は起動時の設定次第ではPrometheus用フォーマットでメトリクスを出力できるので、そのメトリクスを監視することで証明書の更新失敗を検知できそうです。

 具体的にどんな値が取得できるかは未検証&ドキュメントが見つかりません・・・

https://cert-manager.io/docs/devops-tips/prometheus-metrics/

おわりに

 以前作業を行った環境で、名前だけは聞いていたcert-managerについて実際に操作する段階でいろいろと調べる羽目になったため、同様に調べるときに欲しそうな情報だけまとめておきました。

 同様の場面に遭遇した誰かの役に立つと幸いです。

なむゆ/FIXER
 Kubestronautになりました。

 たぶん社内Kubernetes最強です。

カテゴリートップへ

この連載の記事