Google マネージド SSL 証明書の使用

このページでは、Ingress を使用して、Google マネージド SSL 証明書を構成して外部ロードバランサを作成する方法を説明します。このような証明書は、ドメイン名に対して Google がプロビジョニング、更新、管理するドメイン認証(DV)証明書です。この証明書は個人 ID や組織 ID を示すものではありません。Google マネージド証明書を作成する方法については、Google マネージド証明書をご覧ください。

API バージョン

Google が管理する SSL 証明書は ManagedCertificate カスタム リソースを使用して構成します。このカスタム リソースは GKE クラスタのバージョンに応じて以下の異なる API バージョンで使用できます。

  • ManagedCertificate v1beta2 API は、GKE クラスタ バージョン 1.15 以降で使用できます。
  • ManagedCertificate v1 API は、GKE クラスタ バージョン 1.18.9-gke.801 以降で使用できます。

GKE クラスタは現在 ManagedCertificate v1beta1 API をサポートしていますが、この API バージョンは非推奨で、今後の GKE バージョンで削除される予定です。より新しい API バージョンの使用をおすすめします。

API バージョン間の移行

ManagedCertificate リソースは、新しい API バージョンをサポートするクラスタで更新されると、自動的に新しいバージョンの API に更新されます。リソースは定期的に更新されるため、リソースを移行する必要はありません。

マネージド証明書を使用して Ingress を作成する

マネージド SSL 証明書を構成してそれを Ingress と関連付けるには、次の手順を実行する必要があります。

  • ManagedCertificate オブジェクトを作成する。
  • アノテーション networking.gke.io/managed-certificates を Ingress に追加して、ManagedCertificate オブジェクトを Ingress に関連付ける。この注釈は、ManagedCertificate リソースのカンマ区切りリストです(たとえば、cert1,cert2,cert3)。

制限事項

Google マネージド証明書は、自分で取得して管理する証明書と比べてあまり柔軟性がありません。マネージド証明書は最大 100 までの非ワイルドカード ドメインをサポートしますが、セルフ マネージド証明書はワイルドカード ドメインをサポートします。

セルフマネージド証明書が必要な場合、または Ingress で構成したい SSL 証明書がすでにある場合は、Ingress ドキュメントをご覧ください。

Ingress でサポートされている証明書の数と種類は、Google Cloud マネージド SSL 証明書の制限に応じて定義されます。

Google マネージド証明書に対する更新はサポートされていません。

ダウンタイムを最小限に抑えて手動で変更する場合は、Google マネージド証明書の手動更新の手順に従ってください。

要件

  • ドメイン名を所有している必要があります。ドメイン名は 63 文字以下にする必要があります。Google Domains または他の登録事業者を使用できます。
  • 予約済み(静的)外部 IP アドレスを作成します。静的 IP アドレスを予約すると、Ingress を削除した場合でも、その IP アドレスが自身のものであることが保証されます。アドレスを予約しないと、アドレスが変わりドメインの DNS レコードを再構成することが必要となることがあります。gcloud コマンドライン ツールまたは Cloud Console を使用して、予約済み IP アドレスを作成します。

    gcloud

    予約済み IP アドレスを作成するには、次のコマンドを実行します。

    gcloud compute addresses create address-name --global
    

    ここで、address-name は作成している予約済み IP アドレスの名前です。

    作成した静的 IP アドレスを見つけるには、次のコマンドを実行します。

    gcloud compute addresses describe address-name --global
    

    出力は次のようになります。

    address: 203.0.113.32
    ...
    

    Console

    1. Cloud Console で [静的アドレスの予約] ページに移動します。

      [静的アドレスの予約] ページに移動

    2. この IP アドレスの名前を指定します(例: example-ip-address)。
    3. このアドレスが IPv4IPv6 のどちらであるかを指定します。次の例では、IPv4 アドレスを使用しています。
    4. アドレスのタイプとして [グローバル] オプションを選択します。
    5. [予約] をクリックして IP アドレスを予約します。
    6. IP アドレスが [外部アドレス] 列に表示されます。

    Config Connector

    注: この手順には Config Connector が必要です。Config Connector をクラスタにインストールするには、インストール手順に従ってください。

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: example-ip-address
    spec:
      location: global
    このマニフェストをデプロイするには、マニフェストを compute-address.yaml というファイル名でマシンにダウンロードしてから、次のコマンドを実行します。
    kubectl apply -f compute-address.yaml

マネージド証明書の設定

  1. ManagedCertificate リソースを作成します。このリソースは、SSL 証明書が作成される対象のドメインを指定します。ワイルドカード ドメインはサポートされません。

    これは、ManagedCertificate マニフェストのサンプルです。

    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: certificate-name
    spec:
      domains:
        - domain-name1
        - domain-name2
    

    ここで

    • certificate-nameManagedCertificate リソースの名前です。
    • domain-name1domain-name2 は、example.commail.example.comwww.example.com などのドメイン名です。

    マニフェストを certificate-name.yaml という名前のファイルとして保存し、次のコマンドでリソースを作成します。

    kubectl apply -f certificate-name.yaml
    
  2. アプリケーションをインターネットに公開するための NodePort Service を作成します。

    次に示したのは、Service マニフェスト ファイルの例です。

    apiVersion: v1
    kind: Service
    metadata:
      name: service-name
    spec:
      selector:
        key: value
      type: NodePort
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    

    この例では、selector を使用して Service を含む Pod を選択しています。Service の構成方法の詳細については、NodePort のドキュメントをご覧ください。

    マニフェストを service-name.yaml という名前のファイルとして保存し、次のコマンドで Service を作成します。

    kubectl apply -f service-name.yaml
    
  3. Ingress を作成し、以前に作成した ManagedCertificate にリンクします。

    次に、Ingress マニフェストのサンプルを示します。

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: ingress-name
      annotations:
        kubernetes.io/ingress.global-static-ip-name: address-name
        networking.gke.io/managed-certificates: certificate-name
    spec:
      backend:
        serviceName: service-name
        servicePort: service-port
    

    ここで

    • ingress-name は Ingress オブジェクトの名前です。
    • address-name は、予約済み IP アドレスの名前です。
    • certificate-name は証明書の名前です。
    • service-name は、前の手順で作成したサービスの名前です。
    • service-port は、Service マニフェストで指定したポートです。この値は targetPort ではなく port フィールドの値にする必要があります。

    マニフェストを ingress-name.yaml という名前のファイルとして保存し、次のコマンドで Ingress を作成します。

    kubectl apply -f ingress-name.yaml
    
  4. 前の手順で作成したロードバランサの IP アドレスを検索します。ロードバランサの IP アドレスを取得するには、次のコマンドを使用します。

    kubectl get ingress
    

    出力は次のようになります。

    NAME              HOSTS     ADDRESS         PORTS     AGE
    example-ingress   *         203.0.113.32     80        54s
    

    ロードバランサの IP アドレスが ADDRESS 列に表示されます。予約済みの静的 IP アドレスを使用している場合、その IP アドレスがロードバランサのアドレスになります。

    アドレスが表示されない場合は、Ingress の設定が完了するのを待ちます。

  5. ロードバランサの IP アドレスを指すように、ドメインの DNS レコードを構成します。Cloud DNS を使用している場合の詳細についてはレコードの管理ガイドをご覧ください。

  6. マネージド証明書がプロビジョニングされるのを待ちます。最大で 15 分ほどかかることがあります。次のコマンドで証明書のステータスを確認できます。

    kubectl describe managedcertificate certificate-name
    

    証明書が正常にプロビジョニングされると、Status.CertificateStatus フィールドの値は Active になります。次の例は、証明書が正常にプロビジョニングされた後の kubectl describe の出力を示しています。

    Name:         certificate-name
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1
    Kind:         ManagedCertificate
    (...)
    Spec:
      Domains:
        domain-name1
        domain-name2
    Status:
      CertificateStatus: Active
    (...)
    
  7. https:// 接尾辞を使用してドメインにアクセスし、SSL が機能していることを確認します。ブラウザ上で接続が安全であることが示され、証明書の詳細を確認できます。

セルフ マネージド証明書から Google マネージド SSL 証明書への移行

セルフ マネージド SSL 証明書から Google マネージド SSL 証明書に Ingress を移行する場合、Google マネージド SSL 証明書が有効になるまではセルフ マネージド SSL 証明書を削除しないでください。Google マネージド SSL 証明書は正常にプロビジョニングされると自動的に有効になります。 Google マネージド SSL 証明書が有効になったら、セルフ マネージド SSL 証明書を削除できます。

以下の手順でセルフ マネージド SSL 証明書から Google マネージド SSL 証明書に移行します。

  1. マネージド証明書の設定セクションの説明に従って、新しいマネージド証明書を Ingress に追加します。
  2. Google マネージド証明書リソースのステータスがアクティブになるまで待ちます。次のコマンドを使用して、証明書のステータスを確認します。

    kubectl describe managedcertificate certificate-name
    
  3. ステータスがアクティブになったら、Ingress を更新してセルフマネージド証明書への参照を削除します。

マネージド証明書の削除

クラスタからマネージド証明書を削除するには、ManagedCertificate リソースを削除するとともに、そのリソースを参照する Ingress アノテーションも削除する必要があります。

  1. kubectl で ManagedCertificate リソースを削除します。

    kubectl delete -f certificate-name.yaml
    

    出力は次のようになります。

    managedcertificate.networking.gke.io "certificate-name" deleted
    
  2. Ingress からアノテーションを削除します。

    kubectl annotate ingress ingress-name networking.gke.io/managed-certificates-
    

    コマンドの最後にマイナス記号「-」があることにご注意ください。

  3. ロードバランサ用に予約した静的 IP アドレスを解放します。

    gcloud

    gcloud コマンドライン ツールの使用

    gcloud compute addresses delete address-name --global
    

    ここで、address-name は IP アドレスの名前です。

    Console

    1. Cloud Console の [外部 IP アドレス] ページに移動します。

      [外部 IP アドレス] ページに移動

    2. 解放する IP アドレスの横のチェックボックスをオンにします。
    3. [IP アドレスを解放] をクリックします。

    Config Connector

    注: この手順には Config Connector が必要です。Config Connector をクラスタにインストールするには、インストール手順に従ってください。

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: example-ip-address
    spec:
      location: global

    このマニフェストをデプロイするには、マニフェストを compute-address.yaml というファイル名でマシンにダウンロードしてから、次のコマンドを実行します。

    kubectl delete -f compute-address.yaml

トラブルシューティング

このセクションでは、マネージド証明書の問題を解決する方法について説明します。

ManagedCertificate と Ingress リソースでイベントを確認する

許可されている証明書数を超えると、TooManyCertificates 理由を含むイベントが ManagedCertificate v1 に追加されます。次のコマンドを使用して、ManagedCertificate オブジェクトでイベントを確認できます。

kubectl describe managedcertificate certificate-name

ここで

  • certificate-name は ManagedCertificate オブジェクトの名前です。

存在しない ManagedCertificate v1 を Ingress に接続すると、MissingCertificate 理由を含むイベントが Ingress に追加されます。次のコマンドを使用して、Ingress リソースでイベントを確認できます。

kubectl describe ingress ingress-name

ここで

  • ingress-name は Ingress オブジェクトの名前です。

ドメインが複数のロードバランサの IP アドレスに解決される場合、マネージド証明書がプロビジョニングされない

ドメインが複数のロードバランサ(複数の Ingress)の IP アドレスに解決される場合、ManagedCertificate リソースを 1 つ作成し、すべての Ingress にアタッチする必要があります。Ingress の数だけ ManagedCertificate リソースを作成してそれぞれにアタッチした場合、認証局がドメインの所有権を確認できないために、一部の証明書がプロビジョニングされないことがあります。所有権の確認を成功させるには、ドメイン解決されるすべての IP アドレスの下に証明書が表示されている必要があります。

具体的には、ドメインが IPv4 アドレスと IPv6 アドレスに解決され、それぞれが異なる Ingress リソースで構成されている場合、ManagedCertificate リソースを 1 つ作成し、両方の Ingress にアタッチします。

マネージド証明書と Ingress 間の通信の中断

マネージド証明書は、kubernetes.io/pre-shared-cert アノテーションを使用して Ingress と通信します。この通信が中断するのは、たとえば次のような場合です。

  • kubernetes.io/pre-shared-cert アノテーションを消去する自動プロセスを実行する。
  • Ingress のスナップショットを保存し、その Ingress を破棄して、スナップショットから Ingress を復元する。この間に、Ingress の pre-shared-cert アノテーションにリストされていた SslCertificate リソースが削除される可能性があります。Ingress は絶対的な動作を行うため、添付された証明書がない場合は機能しません。

マネージド証明書の作成時の検証エラー

ManagedCertificate リソースを作成する前に ManagedCertificate 定義を検証します。検証に失敗した場合、ManagedCertificate リソースは作成されず、エラー メッセージが表示されます。エラー メッセージとその理由の説明は次のとおりです。

spec.domains in body should have at most 100 items

ManagedCertificate マニフェストで、spec.domains フィールドに 100 を超えるドメインがリストされています。マネージド証明書でサポートされるドメインは 100 までです。

spec.domains in body should match '^(([a-zA-Z0-9]+|[a-zA-Z0-9][-a-zA-Z0-9]*[a-zA-Z0-9])\.)+[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]\.?$'

spec.domains フィールドに無効なドメイン名またはワイルドカード ドメイン名が指定されています。ManagedCertificate リソースは、ワイルドカード ドメイン(*.example.com など)をサポートしません。

spec.domains in body should be at most 63 chars long

指定したドメイン名が長すぎます。マネージド証明書は最長 63 文字までのドメイン名をサポートします。

Google マネージド証明書の手動更新

新しいドメインの証明書がプロビジョニングされるまで古いドメインの証明書が引き続き機能するように、証明書を手動で更新する手順は次のとおりです。

  1. 新しいドメイン用にマネージド証明書を新たに作成します。
  2. 古い証明書を削除せずに Ingress に接続します。
  3. 接続が有効になるまで待機します。
  4. 古い証明書を Ingress から切断し、この証明書を削除します。

次のステップ