APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

【AKS】cert-managerを導入して、Argo CDのUI画面へのアクセスにLet's Encryptを利用してみた

はじめに

こんにちは。ACS事業部 木戸と申します。

今まで検証してきたAKS環境のArgoCDのhttps通信は自己署名証明書を利用していた為、今回はcert-managerを導入してLet's EncryptのSSL/TLS証明書を使う方法を検証してみたいと思います。
前提としてAKS環境へのEnvoyGatewayとArgoCDのインストールは完了している状態です。
またFQDNにはAKSで提供されているcloudapp.azure.comを利用して検証したいと思います。

techblog.ap-com.co.jp

1. cert-managerとは

cert-managerはKubernetes上のアプリケーションで利用するSSL/TLS証明書の発行や更新を自動で行う事ができます。
Let's EncryptのSSL/TLS証明書の発行、更新の際によく利用されるツールです。

cert-manager.io

2. Let's Encryptとは

非営利団体ISRGが運営する、無料で利用できるSSL/TLSサーバー証明書発行サービスです。
有効期限が90日間であり、ドメイン(DV)認証のみ発行することができます。
有効期限が短い為、自動的に証明書の更新が行える仕組みを利用する事が一般的です。
OV(企業実在証明)、EV(組織認証)の認証が必要な場合は別の証明書を検討する必要があります。

letsencrypt.org

3. cert-managerのインストール

今回は公式が提供しているHelm Chartを利用してcert-managerをインストールします。
cert-manager.io

GetewayAPIに導入する際に必要なオプションをvalues.yamlに記載します。

# values.yamlの内容
crds:
  enabled: true

# Gateway API サポートの有効化
config:
  enableGatewayAPI: true

Helmによりcert-managerをインストールします。

# cert-managerのインストール
helm install cert-manager oci://quay.io/jetstack/charts/cert-manager \
--namespace cert-manager \
--create-namespace \
-f  values.yaml

次にClusterIssuerのYAMLを作成します。
CluserIssuerにはどの証明書発行機関を利用するかを記載します。
今回はLet's Encryptを利用します。
Let's Encryptの場合、検証用のStaging環境と実利用の為のProduction環境が指定でき、証明書の発行が行われるかどうかを事前に検証することができます。

StagingとProduction用のClusterIssuerのYAMLを作成します。 違いはmetadataのnameとserverのURL、秘密鍵用のシークレット名でその他は同じ内容になります。  

今回はAKSのFQDNを指定するため、以下のFQDNを設定します。
<任意の文字列>.<リージョン>.cloudapp.azure.com
FQDN内の任意の文字列については、EnvoyのGatewayを作成する際にも指定します。

Let's Encryptの証明書管理を自動化する為にACMEプロトコルが利用されます。
cert-managerではACMEのHTTP01チャレンジとDNS01チャレンジが利用可能です。
今回はカスタムドメインではなくAKSのFQDNを利用する為、HTTP01チャレンジを指定します。

cert-manager.io

HTTP-01チャレンジの為のgatewayHTTPRouteはargocd用のGatewayになります。

# Staging ClusterIssuer - テスト用(Let's Encrypt staging環境)
# 本番運用前の動作確認に使用すること。staging証明書はブラウザで信頼されない
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    email: <管理者のメールアドレス>
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: <秘密鍵用のシークレット名>
    solvers:
      # argocd namespace 向け (argocd-gateway)
      - selector:
          dnsNames:
            - <ArgoCDのFQDN> # xxxx.jpeast.cloudapp.azure.com など
        http01:
          gatewayHTTPRoute:
            parentRefs:
              - name: argocd-gateway
                namespace: argocd
                kind: Gateway
                group: gateway.networking.k8s.io
---
# Production ClusterIssuer - テスト用(Let's Encrypt 本番環境)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    email: <管理者のメールアドレス>
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: <秘密鍵用のシークレット名>
    solvers:
      # argocd namespace 向け (argocd-gateway)
      - selector:
          dnsNames:
            - <ArgoCDのFQDN> # xxxx.jpeast.cloudapp.azure.com など
        http01:
          gatewayHTTPRoute:
            parentRefs:
              - name: argocd-gateway
                namespace: argocd
                kind: Gateway
                group: gateway.networking.k8s.io

次にArgoCD用のCertificateのYAMLを作成します。

# ArgoCD用のCertificationの作成
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: argocd-tls
  namespace: argocd
spec:
  secretName: <gatewayのYAMLで設定したSecret名>
  issuerRef:
    name: letsencrypt-staging  # まずはstagingの認証機関を指定
    kind: ClusterIssuer
  dnsNames:
    - <ArgoCDのFQDN名> # xxxx.jpeast.cloudapp.azure.com など

上記YAMLをAKS環境にデプロイします。 その後、Staging用のClusterIssuerを指定したCertificateを作成します。

# ClusterIssuerのデプロイ
kubectl apply -f cluster_issuer.yaml

# Certificateのデプロイ
kubectl apply -f certificate_argocd.yaml

4. EnvoyGatewayの設定

ArgoCD用のEnvoyGatewayのGatewayを指定します。
今回はAKSで利用可能なFQDNを指定するためにannotationを追加します。 annotationに指定するDNSのラベル名はCertificateを指定した際に記載した任意の文字列になります。
またHTTP-01 チャレンジを利用するため、80ポートの通信用のListenerを定義しています。

letsencrypt.org

GatewayClass用YAML

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: eg-class
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller

Gateway用YAML

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: argocd-gateway
  namespace: argocd
spec:
  gatewayClassName: eg-class
  infrastructure:
      annotations:
        # cloudapp.azure.comのドメインを利用する場合
        service.beta.kubernetes.io/azure-dns-label-name: "<FQDNに含まれる任意の文字列>"
  listeners:
    - name: http
      protocol: HTTP
      port: 80
      allowedRoutes:
        namespaces:
          # cert-manager (ACME チャレンジ用 HTTPRoute) と argocd (ArgoCD 本体の HTTPRoute) のみ許可
          from: Selector
          selector:
            matchExpressions:
              - key: kubernetes.io/metadata.name
                operator: In
                values:
                  - cert-manager
                  - argocd      # 自名前空間(argocd)も許可が必要
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          # TLS 証明書の参照設定
          - name: <Certificateで指定したSecret名:argocd-tls>

Argo CD用のGatewayをデプロイします。

// GatewayClassのデプロイ
kubectl apply -f gateway_class.yaml

// Argo CD用のGatewayのデプロイ
kubectl apply -f argocd-gateway.yaml

// 結果
kubectl get gateway -n argocd

NAME             CLASS      ADDRESS       PROGRAMMED   AGE
argocd-gateway   eg-class   xx.xx.xx.xx   True         23m

5. Let's Encryptの証明書が利用できているか確認する

ブラウザでArgoCD用のFQDNを指定してアクセスをします。
キャッシュ等による影響が発生する場合があるので、アクセス時はブラウザのシークレットウィンドウを利用しています。
Stagingの証明書は自己署名証明書の為、ブラウザのエラーは発生しますが、Let's Encryptの証明書が利用されている事が確認できます。

Let’s Encryptの証明書の利用が可能な事が確認できたため、CertificateのClusterIssuerを本番の方に切り替えます。

# ArgoCD用のCertificationの作成
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: argocd-tls
  namespace: argocd
spec:
  secretName: <gatewayのYAMLのcertificateRefsで設定したSecret名>   #Gatewayリソースの certificateRefs で指定するSecret名と一致させる必要がある
  issuerRef:
    name: letsencrypt-prod  # stagingから本運用のcluster issuerに変更
    kind: ClusterIssuer
  dnsNames:
    - <ArgoCDのFQDN名>

// Certificateのデプロイ
kubectl apply -f certificate_argocd.yaml

再度、ブラウザでArgoCD用のFQDNを指定してアクセスをします。
今度はブラウザのエラーが表示されずアクセスが可能になります。
証明書も本運用のものに変更されている事が確認できます。

6. まとめ

今回は、AKSにcert-managerを導入し、Argo CDのUIへのアクセスにLet's Encryptの証明書を利用する検証を行いました。

Argo CDのUIを利用するにはHTTPS通信が必要となるため、FQDNや証明書の準備など考慮すべき点が多くなります。
しかし、無償のLet's Encryptを利用することで検証時の証明書コストを削減でき、cert-managerで有効期限の更新を自動化することで、導入や運用のハードルが下がると実感しました。

昨今、Let's Encryptに限らずSSL/TLS証明書の有効期限は短縮化されていく傾向にあります。Kubernetes環境においては、cert-managerのような自動化ツールを活用することが、今後のセキュリティ要件の変化に柔軟に対応していくために必要になると思います。

ACS事業部のご紹介

私達ACS事業部はクラウドネイティブ技術、Azure AI サービス、Platform Engineering、AI駆動開発支援などを通して、攻めのDX成功に向けた開発者体験・開発生産性の向上・内製化のご支援をしております。

www.ap-com.co.jp また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。
※求人名の冒頭に【ACSD】と入っている求人が当事業部の求人となります。 www.ap-com.co.jp