Alibaba Cloud Service Mesh (ASM) イングレスゲートウェイを介してサービスを公開する場合、ブラウザは安全な HTTPS 接続を確立するために信頼された TLS 証明書を必要とします。証明書の手動取得および更新はエラーが発生しやすく、スケールも困難です。Automatic Certificate Management Environment (ACME) プロトコルは、認証局(CA)がドメイン所有権を検証し、手動介入なしに証明書を発行・更新することで、X.509 証明書の発行および更新を自動化します。
Let's Encrypt は、ACME を実装した非営利のパブリック CA であり、その証明書はほとんどのブラウザで信頼されています。本トピックでは、Let's Encrypt と cert-manager を連携させ、ASM イングレスゲートウェイ向けにブラウザで信頼される HTTPS 証明書を発行する方法について説明します。
処理の概要
設定には以下の 4 つのステップがあります:
[パブリックドメインの準備] — ドメインを ASM イングレスゲートウェイに割り当てます。
[Issuer の作成] — cert-manager を ACME Issuer リソース経由で Let's Encrypt と接続します。
[証明書の要求] — ドメイン向けの証明書発行を cert-manager にトリガーする Certificate リソースを作成します。
[ゲートウェイの設定] — 発行済み証明書を ASM イングレスゲートウェイにアタッチし、HTTPS アクセスを確認します。
ACME 証明書発行の仕組み
ACME Issuer を作成すると、cert-manager は CA サーバーにアカウントを登録し、安全な通信のための秘密鍵を生成します。証明書を発行する前に、CA は申請者が要求したドメインを制御していることを チャレンジ を通じて検証します。
cert-manager は以下の 2 種類のチャレンジをサポートしています:
HTTP-01: CA がドメイン上の特定の URL(例:
http://<your-domain>/.well-known/acme-challenge/<token>)に対して HTTP リクエストを送信します。cert-manager は一時的な Ingress リソースおよび応答用の solver Pod を作成し、所定のキーを返します。検証が成功すると、cert-manager はこれらの一時リソースを削除します。DNS-01: CA がドメインの DNS TXT レコードを照会します。cert-manager は DNS プロバイダーの API を使用して該当の TXT レコードを作成します。この手法はワイルドカード証明書や、HTTP で外部から到達できないドメインにも対応します。
本トピックでは HTTP-01 チャレンジを採用します。ACME プロトコルの詳細については、「RFC 8555」をご参照ください。
ACME をサポートする任意の認証局で本手法は利用可能です。たとえば、Sectigo も ACME プロトコルをサポートしています。
前提条件
開始する前に、以下の条件を満たしていることを確認してください。
Container Service for Kubernetes (ACK) クラスターが追加された ASM インスタンス(バージョン 1.16 以降)。詳細については、「ASM インスタンスへのクラスターの追加」および「ASM インスタンスのアップデート」をご参照ください。
ポート 80 および 443 を公開したイングレスゲートウェイ。詳細については、「イングレスゲートウェイの作成」をご参照ください。
ACK クラスターにデプロイ済みの HTTPBin アプリケーション。詳細については、「HTTPBin アプリケーションのデプロイ」をご参照ください。
クラスター内に cert-manager がインストール済みであること。詳細については、「クラスターへの cert-manager のインストール」をご参照ください。
ASM イングレスゲートウェイで Ingress API アクセスが有効化されていること。詳細については、「ASM ゲートウェイでの Ingress の有効化」をご参照ください。
ステップ 1:パブリックドメインの準備
ASM イングレスゲートウェイの外部 IP アドレスにパブリックドメインを割り当てます。Let's Encrypt はチャレンジ処理中に、このドメインに対して HTTP リクエストを送信してドメイン所有権を検証します。
ご利用のドメインを ASM イングレスゲートウェイに指向する DNS レコードを設定します。詳細については、DNS プロバイダーのドキュメントをご参照ください。Alibaba Cloud DNS をご利用の場合、「DNS レコードの追加」をご参照ください。
ステップ 2:Issuer リソースの作成
Issuer は cert-manager を Let's Encrypt の ACME サーバーと接続します。データプレーン上の ACK クラスターの kubeconfig を使用し、以下のリソースを作成します:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-prod-issuer
namespace: istio-system
spec:
acme:
email: 'te**@mail.com' # オプションですが推奨されます。ACME サーバーから証明書関連の重要通知がこのアドレスに送信される場合があります。
privateKeySecretRef:
name: letsencrypt-prod
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- http01:
ingress:
ingressClassName: istio # ASM ゲートウェイで使用される Ingress クラスと一致させる必要があります。この Issuer は HTTP-01 ソルバーを使用します。ingressClassName を istio に設定することで、cert-manager はチャレンジリクエストを ASM イングレスゲートウェイ経由でルーティングする一時的な Ingress リソースを作成します。
cert-manager は Ingress API および Gateway API の両方のソルバーをサポートしており、ASM も両方をサポートしています。本トピックでは Ingress API を使用します。
Issuer が準備完了状態であることを確認します:
kubectl -n istio-system get issuer letsencrypt-prod-issuer期待される出力:
NAME READY AGE
letsencrypt-prod-issuer True 8m3sREADY が True でない場合は、エラーを確認するために Issuer の詳細を表示します:
kubectl -n istio-system describe issuer letsencrypt-prod-issuerステップ 3:証明書の要求
ターゲットドメインを指定し、ステップ 2 で作成した Issuer を参照する Certificate リソースを作成します。データプレーン上の ACK クラスターの kubeconfig を使用し、以下のリソースを作成します:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: istio-ingressgateway-certs
namespace: istio-system
spec:
dnsNames:
- <your-domain> # 例:example.com のように、ご利用のドメインに置き換えます。
issuerRef:
group: cert-manager.io
kind: Issuer
name: letsencrypt-prod-issuer # ステップ 2 で作成した Issuer 名と一致させる必要があります。
secretName: istio-ingressgateway-certs # TLS 証明書はこのシークレットに格納されます。後ほどゲートウェイで参照されます。<your-domain> を、ステップ 1 で設定したパブリックドメインに置き換えます。
このリソースを適用すると、cert-manager は以下の処理を行います:
Let's Encrypt へ証明書発行リクエストを送信します。
HTTP-01 チャレンジを solver Pod へルーティングするための一時的な Ingress リソース(
ingressClassName: istio)を作成します。Let's Encrypt からの検証リクエスト(
http://<your-domain>/.well-known/acme-challenge/<token>)を受信します。ASM イングレスゲートウェイがこのリクエストを solver へルーティングします。検証が成功すると、発行された証明書を
istio-ingressgateway-certsシークレットに格納します。一時的な Ingress、Service、Deployment リソースをクリーンアップします。
Certificate が準備完了状態であることを確認します:
kubectl -n istio-system get certificate istio-ingressgateway-certs期待される出力:
NAME READY SECRET AGE
istio-ingressgateway-certs True istio-ingressgateway-certs 59mチャレンジフローの確認(オプション)
HTTP-01 チャレンジが正常に処理されたことを確認するには、ASM イングレスゲートウェイのアクセスログを確認します:
kubectl -n istio-system logs <ingress-gateway-pod-name> | grep letsencrypt | tail -1<ingress-gateway-pod-name> を、ASM イングレスゲートウェイの Pod 名に置き換えます。
チャレンジが成功すると、以下のようなログエントリが出力されます。path フィールドには ACME チャレンジ URL が含まれ、response_code は 200、upstream_cluster は cert-manager の solver Pod を指します:
ステップ 4:ゲートウェイの設定および HTTPS の確認
Istio ゲートウェイへの証明書のアタッチ
ポート 443 で証明書を利用する Istio ゲートウェイを作成します。詳細については、「Istio ゲートウェイの管理」をご参照ください。
apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: httpbin-https namespace: default spec: selector: istio: ingressgateway servers: - hosts: - <your-domain> # Certificate の dnsNames フィールドのドメインと一致させる必要があります。 port: name: https number: 443 protocol: HTTPS tls: credentialName: istio-ingressgateway-certs # Certificate の secretName と一致させる必要があります。 mode: SIMPLEhttpbin-vsVirtualService を更新し、新しいゲートウェイを含めます。詳細については、「仮想サービスの管理」をご参照ください。apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: httpbin-vs namespace: default spec: gateways: - httpbin - httpbin-https # HTTPS トラフィックを有効化するために、このゲートウェイを追加します。 hosts: - '*' http: - name: test route: - destination: host: httpbin.default.svc.cluster.local port: number: 8000
HTTPS アクセスの確認
ブラウザで https://<your-domain> を開きます。アドレスバーに、安全な接続を示すロックアイコンが表示されます。
アイコンをクリックします。接続は安全です と表示され、ブラウザがお客様の証明書を信頼していることを示しています。
