このページでは、Google Kubernetes Engine(GKE)Ingress のトラフィックを保護して最適化する方法について説明します。クライアントとロードバランサ間の SSL 証明書を構成し、ロードバランサとバックエンド アプリケーション間のトラフィックを保護できます。続行する前に、GKE が HTTPS で Ingress を保護する方法を理解しておいてください。
このページは、組織のネットワークを設計し、ネットワーク機器の設置、構成、サポートを行うネットワーク スペシャリストを対象としています。Google Cloud のコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE ユーザーのロールとタスクをご覧ください。
クライアントとロードバランサ間のトラフィックを保護して最適化する
クライアントからの HTTPS リクエストを受け入れるには、ロードバランサはクライアントに ID を証明するための証明書を持っている必要があります。さらに、ロードバランサには、HTTPS handshake を完了するための秘密鍵も必要です。HTTP(S) ロードバランサに SSL 証明書を提供する方法については、クライアントとロードバランサ間の TLS を構成するをご覧ください。
Google マネージド証明書を使用する
1 つ以上の Google マネージド SSL 証明書を構成して Ingress と関連付けるには、次の操作を行う必要があります。
- Ingress と同じ Namespace に 1 つ以上の
ManagedCertificateオブジェクトを作成します。ロードバランサに最大 15 個の証明書を指定できます。 networking.gke.io/managed-certificatesアノテーションを Ingress に追加して、ManagedCertificateオブジェクトを Ingress に関連付けます。このアノテーションは、ManagedCertificateオブジェクトのカンマ区切りリストです。
制限事項
このセクションでは、Google マネージド証明書の制限事項について説明します。セルフマネージド証明書が必要な場合、または Ingress で構成する SSL 証明書がすでにある場合は、クライアントとロードバランサ間の HTTPS(TLS)の設定をご覧ください。
Google マネージド証明書は、自分で取得して管理する証明書と比べてあまり柔軟性がありません。Google マネージド証明書は、最大 100 個の非ワイルドカード ドメインをサポートします。セルフ マネージド証明書とは異なり、Google マネージド証明書はワイルドカード ドメインをサポートしません。
Ingress でサポートされている証明書の数と種類は、Google マネージド SSL 証明書の制限に応じて定義されます。
Google マネージド証明書に対する更新はサポートされていません。詳細については、Google マネージド証明書の手動更新をご覧ください。
証明書が認証局によって直接取り消された場合、Google は証明書を自動的にローテーションしません。ManagedCertificate を削除して、新しい証明書を作成する必要があります。
GKE Ingress は、Certificate Manager で管理される証明書をサポートしていません。Certificate Manager で管理される証明書を使用するには、Gateway API を使用します。
前提条件
ドメイン名を所有している必要があります。ドメイン名は 63 文字以下にする必要があります。ドメイン名は、任意のドメイン名登録事業者から取得できます。
GKE Standard クラスタを使用する場合は、
HttpLoadBalancingアドオンを有効にする必要があります。Ingress マニフェストには
kubernetes.io/ingress.class: "gce"アノテーションを含める必要があります。ingressClassNameフィールドはサポートされていませんIngressリソースとManagedCertificateリソースは、同じプロジェクトと Namespace に適用する必要があります。予約済み(静的)外部 IP アドレスを作成します。静的 IP アドレスを予約すると、Ingress を削除した場合でも、その IP アドレスが自身のものであることが保証されます。IP アドレスを予約しないと、アドレスが変わりドメインの DNS レコードを再構成することが必要となることがあります。Google Cloud CLI または Google Cloud コンソールを使用して、予約済み IP アドレスを作成します。
gcloud
予約済み IP アドレスを作成するには、次のコマンドを実行します。
gcloud compute addresses create ADDRESS_NAME --globalADDRESS_NAMEは、作成する予約済み IP アドレスの名前に置き換えます。作成した静的 IP アドレスを見つけるには、次のコマンドを実行します。
gcloud compute addresses describe ADDRESS_NAME --global出力は次のようになります。
address: 203.0.113.32 ...Console
予約済み IP アドレスを作成するには、次の手順を行います。
Google Cloud コンソールで [外部 IP アドレス] ページに移動します。
IP アドレスの名前を指定します(例:
example-ip-address)。IPv4 アドレスまたは IPv6 アドレスのどちらにするかを指定します。
[タイプ] には、[グローバル] オプションを選択します。
[予約] をクリックします。IP アドレスが [外部アドレス] 列に表示されます。
Config Connector
注: この手順には Config Connector が必要です。Config Connector をクラスタにインストールするには、インストール手順を実施してください。
このマニフェストをデプロイするには、マニフェストをcompute-address.yamlというファイル名でマシンにダウンロードしてから、次のコマンドを実行します。kubectl apply -f compute-address.yaml
Google マネージド証明書の設定
ManagedCertificateオブジェクトを作成します。このリソースは、SSL 証明書のドメインを指定します。ワイルドカード ドメインはサポートされません。次のマニフェストでは、
ManagedCertificateオブジェクトを記述します。マニフェストをmanaged-cert.yamlとして保存します。apiVersion: networking.gke.io/v1 kind: ManagedCertificate metadata: name: FIRST_CERT_NAME spec: domains: - FIRST_DOMAIN --- apiVersion: networking.gke.io/v1 kind: ManagedCertificate metadata: name: SECOND_CERT_NAME spec: domains: - SECOND_DOMAIN次のように置き換えます。
FIRST_CERT_NAME: 1 つ目のManagedCertificateオブジェクトの名前。FIRST_DOMAIN: 所有する 1 つ目のドメイン。SECOND_CERT_NAME: 2 番目のManagedCertificateオブジェクトの名前。SECOND_DOMAIN: 所有する 2 番目のドメイン
ManagedCertificateオブジェクトの名前は、実際に作成する証明書の名前とは異なります。Ingress で使用するManagedCertificateオブジェクトの名前を確認しておいてください。マニフェストをクラスタに適用します。
kubectl apply -f managed-cert.yaml手順に沿って、Deployment と Service を作成し、アプリケーションをインターネットに公開します。
この
ManagedCertificateオブジェクトをActiveにするには、次の例のように、networking.gke.io/managed-certificatesアノテーションを使用して Ingress に関連付けます。Ingress に接続するために、ManagedCertificateがActiveである必要はありません。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-gmc-ingress annotations: networking.gke.io/managed-certificates: "FIRST_CERT_NAME,SECOND_CERT_NAME" spec: rules: - host: FIRST_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60001 - host: SECOND_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60002 ``` Replace <code><var>FIRST_DOMAIN</var></code> and <code><var>SECOND_DOMAIN</var></code> with your domain names. This manifest describes an Ingress that lists pre-shared certificate resources in an annotation. Note: It might take several hours for Google Cloud to provision the load balancer and the managed certificates, and for the load balancer to begin using the new certificates. For more information, see [Deploy a Google-managed certificate with load balancer authorization](/certificate-manager/docs/deploy-google-managed-lb-auth#wait_until_the_certificate_has_been_activated).Google マネージド証明書のプロビジョニングが完了するまで待ちます。この処理には 60 分ほどかかる場合があります。次のコマンドを使用して、証明書のステータスを確認できます。
kubectl describe managedcertificate managed-cert出力は次のようになります。
Name: managed-cert Namespace: default Labels: <none> Annotations: <none> API Version: networking.gke.io/v1 Kind: ManagedCertificate (...) Spec: Domains: FQDN_1 FQDN_2 Status: CertificateStatus: Active (...)Status.CertificateStatusフィールドの値は、証明書のプロビジョニング状態を示します。Status.CertificateStatusがActiveでない場合、証明書はまだプロビジョニングされていません。https://接尾辞を使用してドメインにアクセスし、SSL が機能していることを確認します。ブラウザ上に接続が安全であることが示され、証明書の詳細を確認できます。
セルフ マネージド証明書から Google マネージド証明書への移行
セルフ マネージド SSL 証明書から Google マネージド SSL 証明書に Ingress を移行する場合、Google マネージド SSL 証明書が有効になるまではセルフ マネージド SSL 証明書を削除しないでください。Google マネージド SSL 証明書は正常にプロビジョニングされると自動的に有効になります。Google マネージド SSL 証明書が有効になったら、セルフ マネージド SSL 証明書を削除できます。
以下の手順でセルフ マネージド SSL 証明書から Google マネージド SSL 証明書に移行します。
- 前のセクションの説明に従って、新しい Google マネージド証明書を Ingress に追加します。
Google マネージド証明書リソースのステータスが
Activeになるまで待ちます。次のコマンドを使用して、証明書のステータスを確認します。kubectl describe managedcertificate managed-certステータスが
Activeになったら、Ingress を更新してセルフマネージド証明書への参照を削除します。
Google マネージド証明書の削除
クラスタから Google マネージド証明書を削除するには、ManagedCertificate オブジェクトを削除するとともに、そのリソースを参照する Ingress アノテーションも削除する必要があります。
ManagedCertificateオブジェクトを削除します。kubectl delete -f managed-cert.yaml出力は次のようになります。
managedcertificate.networking.gke.io "managed-cert" deletedIngress からアノテーションを削除します。
kubectl annotate ingress managed-cert-ingress networking.gke.io/managed-certificates-コマンドの最後にマイナス記号(
-)が付いていることに注意してください。ロードバランサ用に予約した静的 IP アドレスを解放します。
Google Cloud CLI、 Google Cloud コンソール、または Config Connector を使用して、予約済み IP アドレスを解放できます。
gcloud
次のコマンドを使用して、予約済みの IP アドレスを解放します。
gcloud compute addresses delete ADDRESS_NAME --globalADDRESS_NAMEは、IP アドレスの名前に置き換えます。Console
予約済みの IP アドレスを解放するには、次の手順を行います。
Google Cloud コンソールで [外部 IP アドレス] ページに移動します。
解放する IP アドレスの横にあるチェックボックスをオンにします。
[IP アドレスを解放] をクリックします。
Config Connector
注: この手順には Config Connector が必要です。Config Connector をクラスタにインストールするには、インストール手順を実施してください。
このマニフェストをデプロイするには、マニフェストを
compute-address.yamlというファイル名でマシンにダウンロードしてから、次のコマンドを実行します。kubectl delete -f compute-address.yaml
証明書と鍵を作成する
事前共有証明書または Kubernetes Secret を使用するには、まず 1 つ以上の証明書と対応する秘密鍵が必要です。各証明書には、所有しているドメイン名と同じ共通名(CN)を設定する必要があります。共通名として適切な値が設定された 2 つの証明書ファイルがすでに存在する場合は、次のセクションまでスキップできます。
1 番目の鍵を作成します。
openssl genrsa -out test-ingress-1.key 20481 番目の証明書署名リクエストを作成します。
openssl req -new -key test-ingress-1.key -out test-ingress-1.csr \ -subj "/CN=FIRST_DOMAIN"FIRST_DOMAINは、所有しているドメイン名(example.comなど)に置き換えます。1 番目の証明書を作成します。
openssl x509 -req -days 365 -in test-ingress-1.csr -signkey test-ingress-1.key \ -out test-ingress-1.crt2 番目の鍵を作成します。
openssl genrsa -out test-ingress-2.key 20482 番目の証明書署名リクエストを作成します。
openssl req -new -key test-ingress-2.key -out test-ingress-2.csr \ -subj "/CN=SECOND_DOMAIN"SECOND_DOMAINは、所有している別のドメイン名(examplepetstore.comなど)に置き換えます。2 番目の証明書を作成します。
openssl x509 -req -days 365 -in test-ingress-2.csr -signkey test-ingress-2.key \ -out test-ingress-2.crt
証明書と鍵の詳細については、SSL 証明書の概要をご覧ください。
これで、2 つの証明書ファイルと 2 つの鍵ファイルの作成が終了しました。
残りのタスクでは、次のプレースホルダを使用して、ドメイン、証明書、鍵を参照します。
FIRST_CERT_FILE: 最初の証明書ファイルのパス。FIRST_KEY_FILE: 最初の証明書に対応する鍵ファイルのパス。FIRST_DOMAIN: 所有しているドメイン名。FIRST_SECRET_NAME: 最初の証明書と鍵が含まれている Secret の名前。SECOND_CERT_FILE: 2 番目の証明書ファイルのパス。SECOND_KEY_FILE: 2 番目の証明書に対応する鍵ファイルのパス。SECOND_DOMAIN: 所有している 2 番目のドメイン名。SECOND_SECRET_NAME: 2 番目の証明書と鍵が含まれている Secret の名前。
事前共有証明書を使用する
Google Cloud プロジェクトにアップロードするセルフマネージド SSL 証明書を使用できます。これらは事前共有証明書と呼ばれます。Ingress に 1 つ以上の事前共有証明書を指定できます。
複数の事前共有証明書を使用する手順は次のとおりです。
証明書と鍵のペアごとに、 Google Cloudに公開されている SSL 証明書リソースを作成します。
gcloud compute ssl-certificates create FIRST_CERT_NAME \ --certificate=FIRST_CERT_FILE \ --private-key=FIRST_KEY_FILE ``` ```sh gcloud compute ssl-certificates create SECOND_CERT_NAME \ --certificate=SECOND_CERT_FILE \ --private-key=SECOND_KEY_FILE ``` Replace the following:FIRST_CERT_NAME、SECOND_CERT_NAME: 1 番目と 2 番目の証明書の名前。FIRST_CERT_FILE、SECOND_CERT_FILE: 1 つ目と 2 つ目の証明書ファイル。FIRST_KEY_FILE、SECOND_KEY_FILE: 1 つ目と 2 つ目の鍵ファイル。
Ingress マニフェストに
ingress.gcp.kubernetes.io/pre-shared-certアノテーションを追加します。アノテーションの値は、証明書名のカンマ区切りリストです。また、spec.rulesセクションにhostフィールドを含めて、サービスのドメインを指定します。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-psc-ingress annotations: ingress.gcp.kubernetes.io/pre-shared-cert: "FIRST_CERT_NAME,SECOND_CERT_NAME" spec: rules: - host: FIRST_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60001 - host: SECOND_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60002 ``` Replace <code><var>FIRST_DOMAIN</var></code> and <code><var>SECOND_DOMAIN</var></code> with your domain names. This manifest describes an Ingress that lists pre-shared certificate resources in an annotation.
Kubernetes Secret を使用する
自分で作成した証明書と鍵を HTTP(S) ロードバランサに提供するには、1 つ以上の Kubernetes Secret オブジェクトを作成します。各 Secret には証明書と鍵が格納されます。Secret を Ingress マニフェストの tls フィールドに追加します。ロードバランサは、TLS handshake のドメイン名に基づいて、Server Name Indication(SNI)を使用してクライアントに提示する証明書を決定します。
複数の証明書を使用する手順は次のとおりです。
証明書と鍵のペアごとに Secret を作成します。
kubectl create secret tls FIRST_SECRET_NAME \ --cert=FIRST_CERT_FILE \ --key=FIRST_KEY_FILE ``` ```sh kubectl create secret tls SECOND_SECRET_NAME \ --cert=SECOND_CERT_FILE \ --key=SECOND_KEY_FILE ```Ingress マニフェストの
spec.tlsセクションで、作成した Secret を一覧表示します。また、spec.rulesセクションにhostフィールドを含めて、サービスのドメインを指定します。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-mc-ingress spec: tls: - secretName: FIRST_SECRET_NAME - secretName: SECOND_SECRET_NAME rules: - host: FIRST_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60001 - host: SECOND_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60002FIRST_DOMAINとSECOND_DOMAINは、example.comやexamplepetstore.comなどの所有しているドメイン名に置き換えてください。
Secret の変更内容は一定期間ごとに反映されるので、Secret 内のデータを変更した場合、それらの変更がロードバランサに適用されるまでに最大で 10 分かかります。
GKE クラスタの HTTPS で暗号化された Ingress を保護するには、Ingress の保護の例をご覧ください。
HTTP の無効化
クライアントとロードバランサ間のすべてのトラフィックに HTTPS を使用する場合は、Ingress マニフェストに kubernetes.io/ingress.allow-http アノテーションを追加します。アノテーションの値を "false" に設定します。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress-2
annotations:
kubernetes.io/ingress.allow-http: "false"
spec:
tls:
- secretName: SECRET_NAME
...
このマニフェストには、作成した Secret の名前である SECRET_NAME が含まれています。
クライアントとロードバランサ間の HTTP/2
クライアントは HTTP/2 を使用してロードバランサにリクエストを送信できます。構成は不要です。
ロードバランサとアプリケーション間のトラフィックを保護して最適化する
ロードバランサとアプリケーション Pod 間の通信に使用されるプロトコルを構成して、エンドツーエンドのセキュリティを確保したり、内部トラフィックのパフォーマンスを最適化したりできます。ロードバランサは、バックエンド接続にデフォルトで暗号化されていない HTTP/1.1 を使用しますが、アプリケーションの特定の要件を満たすために HTTPS または HTTP/2 を有効にできます。
ロードバランサとアプリケーション間の HTTPS
GKE Pod で実行しているアプリケーションが HTTPS リクエストを受信できる場合は、ロードバランサがリクエストをアプリケーションに転送するときに HTTPS を使用するようにロードバランサを構成できます。詳しくは、ロードバランサとアプリケーション間の HTTPS(TLS)をご覧ください。
ロードバランサとアプリケーションの間で使用されるプロトコルを構成するには、cloud.google.com/app-protocols アノテーションを Service マニフェストで使用します。
コンテナ ネイティブのロード バランシングを使用しない場合、このサービス マニフェストに type: NodePort を含める必要があります。コンテナ ネイティブのロード バランシングを使用する場合は、type: ClusterIP を使用します。
次の Service マニフェストでは、2 つのポートを指定しています。そのアノテーションによると、HTTP(S) ロードバランサが Service のポート 80 をターゲットにしているとき、HTTP を使用する必要があります。また、ロードバランサが Service のポート 443 をターゲットにしているとき、HTTPS を使用する必要があります。
Service マニフェストでは、ポートのアノテーションに name 値を含める必要があります。Service ポートを編集するには、targetPort 値ではなく、割り当てられた name を参照します。
apiVersion: v1
kind: Service
metadata:
name: my-service-3
annotations:
cloud.google.com/app-protocols: '{"my-https-port":"HTTPS","my-http-port":"HTTP"}'
spec:
type: NodePort
selector:
app: metrics
department: sales
ports:
- name: my-https-port
port: 443
targetPort: 8443
- name: my-http-port
port: 80
targetPort: 50001
ロードバランサとアプリケーション間で HTTP/2 を使用する
GKE Pod で実行しているアプリケーションが HTTP/2 リクエストを受信できる場合は、ロードバランサがリクエストをアプリケーションに転送するときに HTTP/2 を使用するようにロードバランサを構成できます。
HTTP/2 を有効にするには、Kubernetes Service マニフェストで cloud.google.com/app-protocols アノテーションを使用する必要があります。このアノテーションは、ロードバランサがアプリケーションとの通信に使用するプロトコルを指定します。ロードバランサが正しい HTTP/2 リクエストをバックエンドに送信できるようにするには、バックエンドを SSL で構成する必要があります。
HTTP/2 用に構成された Service マニフェストの例を次に示します。
apiVersion: v1
kind: Service
metadata:
name: my-http2-service
annotations:
cloud.google.com/app-protocols: '{"my-port":"HTTP2"}'
spec:
type: NodePort
selector:
app: my-app
ports:
- name: my-port
protocol: TCP
port: 443
targetPort: 8443
次の点にご注意ください。
cloud.google.com/app-protocolsアノテーションは'{"my-port":"HTTP2"}'に設定されています。これにより、ロードバランサはmy-portという名前のポートに送信されるトラフィックに HTTP/2 を使用します。- ポートは
443に設定され、targetPort8443の Pod にトラフィックを転送します。