このページでは、GKE クラスタ間でアプリケーションにサービスを提供する Ingress のデプロイ方法について説明します。マルチクラスタ Ingress の詳細については、マルチクラスタ Ingress をご覧ください。
マルチクラスタ Ingress(MCI)、マルチクラスタ Gateway(MCG)、スタンドアロン ネットワーク エンドポイント グループを使用するロードバランサ(LB とスタンドアロン NEG)の詳細な比較については、GKE のマルチクラスタ ロード バランシング API を選択するをご覧ください。
デプロイのチュートリアル
以下のタスクでは、whereami
という名前の架空のアプリと MultiClusterIngress
を 2 つのクラスタにデプロイします。Ingress は、アプリのデプロイ用に共有仮想 IP アドレス(VIP)を提供します。
このページは、マルチクラスタ Ingress の設定で 2 つのクラスタを作成して登録した作業に基づいています。2 つのクラスタがフリートにも登録されていることを確認します。
gcloud container clusters list
出力は次のようになります。
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
gke-eu europe-west1-b 1.16.8-gke.9 *** e2-medium 1.16.8-gke.9 2 RUNNING
gke-us us-central1-b 1.16.8-gke.9 *** e2-medium 1.16.6-gke.13 * 2 RUNNING
Namespace の作成
フリートには Namespace の同一性という特徴があるため、同じ Namespace が同じグループで所有および管理されるように、クラスタ間で Namespace の作成と管理を調整することをおすすめします。Namespace は、チームごと、環境ごと、アプリケーションごと、アプリケーション コンポーネントごとに作成できます。あるクラスタ内の Namespace ns1
の意味と使用法が別のクラスタ内の ns1
のものと同じである限り、必要に応じて細かく Namespace を設定できます。
この例では、各クラスタでアプリケーションごとに whereami
Namespace を作成します。
次のコンテンツを含むファイルを
namespace.yaml
という名前で作成します。apiVersion: v1 kind: Namespace metadata: name: whereami
gke-us コンテキストに切り替えます。
kubectl config use-context gke-us
Namespace を作成します。
kubectl apply -f namespace.yaml
gke-eu コンテキストに切り替えます。
kubectl config use-context gke-eu
Namespace を作成します。
kubectl apply -f namespace.yaml
出力は次のようになります。
namespace/whereami created
アプリのデプロイ
次のコンテンツを含むファイルを
deploy.yaml
という名前で作成します。apiVersion: apps/v1 kind: Deployment metadata: name: whereami-deployment namespace: whereami labels: app: whereami spec: selector: matchLabels: app: whereami template: metadata: labels: app: whereami spec: containers: - name: frontend image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20 ports: - containerPort: 8080
gke-us コンテキストに切り替えます。
kubectl config use-context gke-us
whereami
アプリをデプロイします。kubectl apply -f deploy.yaml
gke-eu コンテキストに切り替えます。
kubectl config use-context gke-eu
whereami
アプリをデプロイします。kubectl apply -f deploy.yaml
whereami
アプリが各クラスタに正常にデプロイされたことを確認します。kubectl get deployment --namespace whereami
両方のクラスタで、出力は次のようになります。
NAME READY UP-TO-DATE AVAILABLE AGE whereami-deployment 1/1 1 1 12m
構成クラスタを使用したデプロイ
アプリケーションが gke-us
と gke-eu
にデプロイされたので、構成クラスタに MultiClusterIngress
と MultiClusterService
のリソースをデプロイすることによって、ロードバランサをデプロイします。これらは、マルチクラスタでの Ingress リソースと Service リソースに相当します。
設定ガイドで、gke-us
クラスタを構成クラスタとして構成しました。構成クラスタは、すべてのクラスタに Ingress をデプロイして構成するために使用されます。
コンテキストを構成クラスタに設定します。
kubectl config use-context gke-us
MultiClusterService
次のコンテンツを含むファイルを
mcs.yaml
という名前で作成します。apiVersion: networking.gke.io/v1 kind: MultiClusterService metadata: name: whereami-mcs namespace: whereami spec: template: spec: selector: app: whereami ports: - name: web protocol: TCP port: 8080 targetPort: 8080
whereami
アプリと一致するMultiClusterService
リソースをデプロイします。kubectl apply -f mcs.yaml
whereami-mcs
リソースが構成クラスタに正常にデプロイされたことを確認します。kubectl get mcs -n whereami
出力は次のようになります。
NAME AGE whereami-mcs 9m26s
この
MultiClusterService
は、app: whereami
と Pod を一致させるすべてのクラスタに派生ヘッドレス Service を作成します。Service が、gke-us
クラスタkubectl get service -n whereami
に存在することを確認できます。出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mci-whereami-mcs-svc-lgq966x5mxwwvvum ClusterIP None <none> 8080/TCP 4m59s
同様のヘッドレス Service が gke-eu
にも存在します。これらのローカル Service は、Pod エンドポイントを動的に選択して、グローバルな Ingress ロードバランサをバックエンドでプログラムするために使用されます。
MultiClusterIngress
次のコンテンツを含むファイルを
mci.yaml
という名前で作成します。apiVersion: networking.gke.io/v1 kind: MultiClusterIngress metadata: name: whereami-ingress namespace: whereami spec: template: spec: backend: serviceName: whereami-mcs servicePort: 8080
この構成では、すべてのトラフィックが、
whereami
Namespace に存在するwhereami-mcs
という名前のMultiClusterService
にルーティングされます。whereami-mcs
をバックエンドとして参照するMultiClusterIngress
リソースをデプロイします。kubectl apply -f mci.yaml
出力は次のようになります。
multiclusteringress.networking.gke.io/whereami-ingress created
MultiClusterIngress
のスキーマは Kubernetes Ingress と同じです。Ingress リソースのセマンティクスも、backend.serviceName
フィールドを除き同じです。
MultiClusterIngress
の backend.serviceName
フィールドは、Kubernetes クラスタの Service ではなく、Fleet API の MultiClusterService
を参照します。つまり、TLS 終端など、Ingress の設定はすべて同じ方法で構成できます。
デプロイの成功ステータスを検証する
Google Cloud ロードバランサのデプロイでは、新しいロードバランサのデプロイに数分かかることがあります。新しいリソースをデプロイする必要がないため、既存のロードバランサの更新は、より短時間で完了します。MultiClusterIngress
リソースは、MultiClusterIngress
の代わりとして作成された、基盤となる Compute Engine リソースの詳細を示します。
デプロイが成功したことを確認します。
kubectl describe mci whereami-ingress -n whereami
出力は次のようになります。
Name: whereami-ingress Namespace: whereami Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"networking.gke.io/v1","kind":"MultiClusterIngress","metadata":{"annotations":{},"name":"whereami-ingress","namespace":"whe... API Version: networking.gke.io/v1 Kind: MultiClusterIngress Metadata: Creation Timestamp: 2020-04-10T23:35:10Z Finalizers: mci.finalizer.networking.gke.io Generation: 2 Resource Version: 26458887 Self Link: /apis/networking.gke.io/v1/namespaces/whereami/multiclusteringresses/whereami-ingress UID: 62bec0a4-8a08-4cd8-86b2-d60bc2bda63d Spec: Template: Spec: Backend: Service Name: whereami-mcs Service Port: 8080 Status: Cloud Resources: Backend Services: mci-8se3df-8080-whereami-whereami-mcs Firewalls: mci-8se3df-default-l7 Forwarding Rules: mci-8se3df-fw-whereami-whereami-ingress Health Checks: mci-8se3df-8080-whereami-whereami-mcs Network Endpoint Groups: zones/europe-west1-b/networkEndpointGroups/k8s1-e4adffe6-whereami-mci-whereami-mcs-svc-lgq966x5m-808-88670678 zones/us-central1-b/networkEndpointGroups/k8s1-a6b112b6-whereami-mci-whereami-mcs-svc-lgq966x5m-808-609ab6c6 Target Proxies: mci-8se3df-whereami-whereami-ingress URL Map: mci-8se3df-whereami-whereami-ingress VIP: 34.98.102.37 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 3m35s multi-cluster-ingress-controller whereami/whereami-ingress Normal UPDATE 3m10s (x2 over 3m34s) multi-cluster-ingress-controller whereami/whereami-ingress
この Ingress デプロイのステータスを示すフィールドがいくつかあります。
Events
は最初に見るべき場所です。エラーが発生した場合は、ここに表示されます。Cloud Resource
は、マルチクラスタ Ingress コントローラによって作成された転送ルール、バックエンド サービス、ファイアウォール ルールなどの Compute Engine リソースを一覧表示します。これらが一覧表示されない場合は、まだ作成されていない状態です。コンソールまたはgcloud
コマンドを使用して、個々の Compute Engine リソースを調べ、そのステータスを取得できます。VIP
は、割り振られた IP アドレスをリストします。VIP が存在しても、ロードバランサがまだトラフィックを処理していない可能性があります。数分経っても VIP が表示されない場合や、10 分以内にロードバランサが 200 レスポンスを返さない場合は、トラブルシューティングとオペレーションをご覧ください。
出力イベントが
Normal
の場合、MultiClusterIngress
のデプロイが成功している可能性はありますが、完全なトラフィック パスが機能していることを判断する唯一の方法は、テストを行うことです。アプリケーションが
/ping
エンドポイントを使用して VIP で機能していることを確認します。curl INGRESS_VIP/ping
INGRESS_VIP
は、仮想 IP(VIP)アドレスに置き換えます。出力は次のようになります。
{ "cluster_name": "gke-us", "host_header": "34.120.175.141", "pod_name": "whereami-deployment-954cbf78-mtlpf", "pod_name_emoji": "😎", "project_id": "my-project", "timestamp": "2021-11-29T17:01:59", "zone": "us-central1-b" }
出力にアプリケーションのリージョンとバックエンドが表示されます。
ブラウザで
http://INGRESS_VIP
の URL にアクセスして、アプリケーションへのサービス提供元のリージョンが表示された、グラフィカル バージョンのアプリケーションを確認できます。トラフィックの転送先のクラスタは、ロケーションによって異なります。GCLB は、クライアント トラフィックを、容量のある最も近いバックエンドに転送するように設計されています。
リソースの仕様
MultiClusterService の仕様
MultiClusterService
定義は次の 2 つで構成されます。
Kubernetes クラスタで作成される Service を定義する
template
セクション。template
セクションには一般的な Service でサポートされているフィールドがありますが、MultiClusterService
でサポートされているフィールドはselector
とports
の 2 つのフィールドだけが存在します。他のフィールドは無視されます。トラフィックを受信するクラスタを定義するセクションと、各クラスタのロード バランシング プロパティを定義するセクションである、オプションの
clusters
セクション。clusters
セクションが指定されていない場合、またはクラスタがリストされていない場合は、デフォルトですべてのクラスタが使用されます。
次のマニフェストは、標準の MultiClusterService
を記述しています。
apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
name: NAME
namespace: NAMESPACE
spec:
template:
spec:
selector:
app: POD_LABEL
ports:
- name: web
protocol: TCP
port: PORT
targetPort: TARGET_PORT
次のように置き換えます。
NAME
:MultiClusterService
の名前。この名前は、MultiClusterIngress
リソースのserviceName
フィールドで参照されます。NAMESPACE
:MultiClusterService
がデプロイされている Kubernetes Namespace。これは、フリート内のすべてのクラスタで、MultiClusterIngress
および Pod と同じ Namespace にする必要があります。POD_LABEL
: フリート内のすべてのクラスタでこのMultiClusterService
のバックエンドとして選択される Pod を決定するラベル。PORT
: このMultiClusterService
を参照するMultiClusterIngress
によって参照されるポートと一致する必要があります。TARGET_PORT
: GCLB から Pod にトラフィックを送信するために使用されるポート。このポートをサービスポートとして使用し、各クラスタに NEG が作成されます。
MultiClusterIngress の仕様
次の mci.yaml
は、ロードバランサのフロントエンドを記述します。
apiVersion: networking.gke.io/v1
kind: MultiClusterIngress
metadata:
name: NAME
namespace: NAMESPACE
spec:
template:
spec:
backend:
serviceName: DEFAULT_SERVICE
servicePort: PORT
rules:
- host: HOST_HEADER
http:
paths:
- path: PATH
backend:
serviceName: SERVICE
servicePort: PORT
次のように置き換えます。
NAME
:MultiClusterIngress
リソースの名前。NAMESPACE
:MultiClusterIngress
がデプロイされている Kubernetes Namespace。これは、フリート内のすべてのクラスタで、MultiClusterService
および Pod と同じ Namespace にする必要があります。DEFAULT_SERVICE
: ホストルールまたはパスルールに一致しないすべてのトラフィックのデフォルトのバックエンドとして機能します。これは必須フィールドであり、他のホストまたはパスの一致が構成されている場合でも、MultiClusterIngress
でデフォルトのバックエンドを指定する必要があります。PORT
: 有効なポート番号。これは、MultiClusterService
リソースのport
フィールドと一致する必要があります。HOST_HEADER
: HTTP ホストヘッダー フィールドによってトラフィックを照合します。host
フィールドは省略可能です。PATH
: HTTP URL のパスによってトラフィックを照合します。path
フィールドは省略可能です。SERVICE
: このMultiClusterIngress
と同じ Namespace と構成クラスタにデプロイされるMultiClusterService
の名前です。
マルチクラスタ Ingress の機能
このセクションでは、マルチクラスタ Ingress のその他の機能を構成する方法について説明します。
クラスタの選択
デフォルトでは、マルチクラスタ Ingress から派生した Service は、すべてのメンバー クラスタでスケジュール設定されます。ただし、特定のクラスタに Ingress ルールを適用することもできます。ユースケースには、次のようなものがあります。
- 構成クラスタを分離するために、構成クラスタを除くすべてのクラスタにマルチクラスタ Ingress を適用する。
- クラスタ間でワークロードを青緑色に移行する。
- クラスタのサブセットにのみ存在するアプリケーション バックエンドにルーティングする。
- 異なるクラスタに存在するバックエンドへのホストまたはパスのルーティングに単一の L7 VIP を使用する。
クラスタを選択すると、MultiClusterService
オブジェクトのリージョンまたは名前でクラスタを選択できます。これにより、MultiClusterIngress
が指すクラスタと派生した Service がスケジュールされる場所を制御できます。クラスタを一意に参照できるように、同じフリートとリージョン内のクラスタで名前の重複が生じないようにします。
mcs.yaml
を開くapiVersion: networking.gke.io/v1 kind: MultiClusterService metadata: name: whereami-mcs namespace: whereami spec: template: spec: selector: app: whereami ports: - name: web protocol: TCP port: 8080 targetPort: 8080
この仕様では、すべてのクラスタに派生 Service が作成されるというデフォルトの動作になります。
クラスタ セクションに次の行を追加します。
apiVersion: networking.gke.io/v1 kind: MultiClusterService metadata: name: whereami-mcs namespace: whereami spec: template: spec: selector: app: whereami ports: - name: web protocol: TCP port: 8080 targetPort: 8080 clusters: - link: "us-central1-b/gke-us" - link: "europe-west1-b/gke-eu"
この例では、gke-us クラスタと gke-eu クラスタにのみ派生 Service のリソースを作成します。Ingress ルールを個別に適用するには、クラスタを選択する必要があります。
MultiClusterService
の「クラスタ」セクションが指定されていない場合、またはクラスタが一覧表示されていない場合は、デフォルトで「すべて」のクラスタと解釈されます。
HTTPS サポート
Kubernetes Secret は HTTPS をサポートしています。HTTPS サポートを有効にする前に、静的 IP アドレスを作成する必要があります。この静的 IP では、HTTP と HTTPS で同じ IP アドレスを共有できます。詳細については、静的 IP の作成をご覧ください。
静的 IP アドレスを作成したら、Secret を作成できます。
Secret を作成します。
kubectl -n whereami create secret tls SECRET_NAME --key PATH_TO_KEYFILE --cert PATH_TO_CERTFILE
次のように置き換えます。
SECRET_NAME
は、Secret の名前に置き換えます。PATH_TO_KEYFILE
は、TLS 鍵ファイルのパスに置き換えます。PATH_TO_CERTFILE
は、TLS 証明書ファイルのパスで置き換えます。
mci.yaml
ファイルを Secret 名で更新します。apiVersion: networking.gke.io/v1 kind: MultiClusterIngress metadata: name: whereami-ingress namespace: whereami annotations: networking.gke.io/static-ip: STATIC_IP_ADDRESS spec: template: spec: backend: serviceName: whereami-mcs servicePort: 8080 tls: - secretName: SECRET_NAME
SECRET_NAME
は、Secret の名前に置き換えます。STATIC_IP_ADDRESS
は、静的 IP の作成で割り振ったアドレスの IP アドレスまたは完全な URL です。MultiClusterIngress
リソースを再デプロイします。kubectl apply -f mci.yaml
出力は次のようになります。
multiclusteringress.networking.gke.io/whereami-ingress configured
BackendConfig のサポート
次の BackendConfig CRD を使用すると、Compute Engine BackendService リソースの設定をカスタマイズできます。
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: whereami-health-check-cfg
namespace: whereami
spec:
healthCheck:
checkIntervalSec: [int]
timeoutSec: [int]
healthyThreshold: [int]
unhealthyThreshold: [int]
type: [HTTP | HTTPS | HTTP2 | TCP]
port: [int]
requestPath: [string]
timeoutSec: [int]
connectionDraining:
drainingTimeoutSec: [int]
sessionAffinity:
affinityType: [CLIENT_IP | CLIENT_IP_PORT_PROTO | CLIENT_IP_PROTO | GENERATED_COOKIE | HEADER_FIELD | HTTP_COOKIE | NONE]
affinityCookieTtlSec: [int]
cdn:
enabled: [bool]
cachePolicy:
includeHost: [bool]
includeQueryString: [bool]
includeProtocol: [bool]
queryStringBlacklist: [string list]
queryStringWhitelist: [string list]
securityPolicy:
name: ca-how-to-security-policy
logging:
enable: [bool]
sampleRate: [float]
iap:
enabled: [bool]
oauthclientCredentials:
secretName: [string]
BackendConfig を使用するには、アノテーションを使用して MultiClusterService
リソースに接続します。
apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
name: whereami-mcs
namespace: whereami
annotations:
cloud.google.com/backend-config: '{"ports": {"8080":"whereami-health-check-cfg"}}'
spec:
template:
spec:
selector:
app: whereami
ports:
- name: web
protocol: TCP
port: 8080
targetPort: 8080
BackendConfig セマンティクスの詳細については、Service ポートと BackendConfig の関連付けをご覧ください。
gRPC のサポート
マルチクラスタ Ingress で gRPC アプリケーションを構成するには、かなり詳細な設定を行う必要があります。ロードバランサを適切に構成するには、次のヒントを参考にしてください。
- ロードバランサからアプリケーションへのトラフィックが HTTP/2 であることを確認します。これは、アプリケーション プロトコルを使用して構成します。
- アプリケーションが SSL 用に正しく構成されていることを確認します。これは、HTTP/2 の要件です。なお、自己署名証明書も使用できます。
- L7 外部ロードバランサでは mTLS がサポートされていないため、アプリケーションで mTLS をオフにする必要があります。
リソースのライフサイクル
構成の変更
MultiClusterIngress
リソースと MultiClusterService
リソースは標準の Kubernetes オブジェクトとして動作するため、オブジェクトへの変更は非同期でシステムに反映されます。変更が無効な構成になった場合、関連付けられた Google Cloud オブジェクトは変更されず、オブジェクトのイベント ストリームでエラーが発生します。構成に関連付けられたエラーは、イベントとして報告されます。
Kubernetes リソースの管理
Ingress オブジェクトを削除すると、HTTP(S) ロードバランサが破棄され、トラフィックは定義済みのどの MultiClusterService
にも転送されなくなります。
MultiClusterService
を削除すると、各クラスタ内の関連する派生サービスが削除されます。
クラスタの管理
ロードバランサの対象となる一連のクラスタは、フリートでクラスタを追加または削除することで変更できます。
たとえば、gke-eu
クラスタを Ingress のバックエンドとして削除するには、次のコマンドを実行します。
gcloud container fleet memberships unregister CLUSTER_NAME \
--gke-uri=URI
次のように置き換えます。
CLUSTER_NAME
: クラスタの名前。URI
: GKE クラスタの URI。
ヨーロッパのクラスタを追加するには、次のコマンドを実行します。
gcloud container fleet memberships register europe-cluster \
--context=europe-cluster --enable-workload-identity
クラスタ登録オプションの詳細については、GKE クラスタを登録するをご覧ください。
クラスタの登録または登録解除を行うと、すべての Ingress のバックエンドとしてのステータスが変更されることにご注意ください。gke-eu
クラスタの登録を解除すると、作成したすべての Ingress で使用可能なバックエンドからクラスタが削除されます。新しいクラスタを登録する場合は、その逆です。
マルチクラスタ Ingress の無効化
マルチクラスタ Ingress を無効にする前に、まず MultiClusterIngress
リソースと MultiClusterService
リソースを削除し、関連付けられたネットワーキング リソースが削除されたことを確認する必要があります。
マルチクラスタ Ingress を無効にするには、次のコマンドを使用します。
gcloud container fleet ingress disable
マルチクラスタ Ingress を無効にする前に MultiClusterIngress
リソースと MultiClusterService
リソースを削除しないと、次のようなエラーが発生することがあります。
Feature has associated resources that should be cleaned up before deletion.
マルチクラスタ Ingress を強制的に無効にするには、次のコマンドを使用します。
gcloud container fleet ingress disable --force
アノテーション
MultiClusterIngress
リソースと MultiClusterService
リソースでは、次のアノテーションがサポートされています。
MultiClusterIngress アノテーション
アノテーション | 説明 |
---|---|
networking.gke.io/frontend-config | MultiClusterIngress リソースと同じ Namespace 内の FrontendConfig リソースを参照します。 |
networking.gke.io/static-ip | グローバル静的 IP のリテラル IP アドレスを指します。 |
networking.gke.io/pre-shared-certs | グローバル SSLCertificate リソースを参照します。 |
MultiClusterService アノテーション
アノテーション | 説明 |
---|---|
networking.gke.io/app-protocols | このアノテーションを使用して、ロードバランサとアプリケーション間の通信用のプロトコルを設定します。有効なプロトコルは HTTP、HTTPS、HTTP/2 です。ロードバランサとアプリケーション間の HTTPS と Ingress による HTTP/2 を使用したロードバランサをご覧ください。 |
cloud.google.com/backend-config | このアノテーションを使用して、servicePort に関連付けられるバックエンド サービスを構成します。詳細については、Ingress の構成をご覧ください。 |
SSL ポリシーと HTTPS リダイレクト
FrontendConfig リソースを使用して、SSL ポリシーと HTTPS リダイレクトを構成できます。SSL ポリシーを使用すると、ロードバランサが受け入れる暗号スイートと TLS バージョンを指定できます。HTTPS リダイレクトを使用すると、HTTP またはポート 80 から HTTPS またはポート 443 へのリダイレクトを適用できます。次の手順では、SSL ポリシーと HTTPS リダイレクトを一緒に構成します。これらは個別に構成することもできます。
TLS v1.2 より前のバージョンを使用するリクエストを拒否する SSL ポリシーを作成します。
gcloud compute ssl-policies create tls-12-policy \ --profile MODERN \ --min-tls-version 1.2 \ --project=PROJECT_ID
PROJECT_ID
は、GKE クラスタが実行されているプロジェクト ID に置き換えます。ポリシーを表示してポリシーが作成されていることを確認します。
gcloud compute ssl-policies list --project=PROJECT_ID
出力は次のようになります。
NAME PROFILE MIN_TLS_VERSION tls-12-policy MODERN TLS_1_2
例のように、
foo.example.com
の証明書を作成します。key.pem
とcert.pem
を取得したら、これらの認証情報を MultiClusterIngress リソースによって参照される Secret として保存します。kubectl -n whereami create secret tls SECRET_NAME --key key.pem --cert cert.pem
次の FrontendConfig リソースを
frontendconfig.yaml
として保存します。FrontendConfig でサポートされるフィールドの詳細については、FrontendConfig リソースの構成をご覧ください。apiVersion: networking.gke.io/v1beta1 kind: FrontendConfig metadata: name: frontend-redirect-tls-policy namespace: whereami spec: sslPolicy: tls-12-policy redirectToHttps: enabled: true
この FrontendConfig により、HTTPS リダイレクトと、最小 TLS バージョン 1.2 を適用する SSL ポリシーが有効になります。
frontendconfig.yaml
を構成クラスタにデプロイします。kubectl apply -f frontendconfig.yaml --context MCI_CONFIG_CLUSTER
MCI_CONFIG_CLUSTER
は、構成クラスタの名前に置き換えます。次の MultiClusterIngress を
mci-frontendconfig.yaml
として保存します。apiVersion: networking.gke.io/v1 kind: MultiClusterIngress metadata: name: foo-ingress namespace: whereami annotations: networking.gke.io/frontend-config: frontend-redirect-tls-policy networking.gke.io/static-ip: STATIC_IP_ADDRESS spec: template: spec: backend: serviceName: default-backend servicePort: 8080 rules: - host: foo.example.com http: paths: - backend: serviceName: whereami-mcs servicePort: 8080 tls: - secretName: SECRET_NAME
STATIC_IP_ADDRESS
は、すでにプロビジョニングされている静的グローバル IP アドレスに置き換えます。SECRET_NAME
は、foo.example.com
証明書が保存されている Secret に置き換えます。
HTTPS リダイレクトを有効にする場合、次の 2 つの要件を満たす必要があります。
- TLS は、
spec.tls
フィールドまたは事前共有証明書アノテーションnetworking.gke.io/pre-shared-certs
を使用して有効にする必要があります。HTTPS リダイレクトが有効になっていても、HTTPS が有効でないと、MultiClusterIngress はデプロイされません。 - 静的 IP は
networking.gke.io/static-ip
アノテーションを介して参照する必要があります。MultiClusterIngress で HTTPS を有効にする場合は、静的 IP が必要です。
MultiClusterIngress を構成クラスタにデプロイします。
kubectl apply -f mci-frontendconfig.yaml --context MCI_CONFIG_CLUSTER
1~2 分待ってから
foo-ingress
を調べます。kubectl describe mci foo-ingress --context MCI_CONFIG_CLUSTER
正常な出力は次のようになります。
Cloud Resources
ステータスにリソース名が示されます。VIP
フィールドに、ロードバランサの IP アドレスが示されます。
Name: foobar-ingress Namespace: whereami ... Status: Cloud Resources: Backend Services: mci-otn9zt-8080-whereami-bar mci-otn9zt-8080-whereami-default-backend mci-otn9zt-8080-whereami-foo Firewalls: mci-otn9zt-default-l7 Forwarding Rules: mci-otn9zt-fw-whereami-foobar-ingress mci-otn9zt-fws-whereami-foobar-ingress Health Checks: mci-otn9zt-8080-whereami-bar mci-otn9zt-8080-whereami-default-backend mci-otn9zt-8080-whereami-foo Network Endpoint Groups: zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluste-mci-default-backend-svc--80-9e362e3d zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluster--mci-bar-svc-067a3lzs8-808-89846515 zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluster--mci-foo-svc-820zw3izx-808-8bbcb1de zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluste-mci-default-backend-svc--80-a528cc75 zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluster--mci-bar-svc-067a3lzs8-808-36281739 zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluster--mci-foo-svc-820zw3izx-808-ac733579 Target Proxies: mci-otn9zt-whereami-foobar-ingress mci-otn9zt-whereami-foobar-ingress URL Map: mci-otn9zt-rm-whereami-foobar-ingress VIP: 34.149.29.76 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal UPDATE 38m (x5 over 62m) multi-cluster-ingress-controller whereami/foobar-ingress
HTTP リクエストを
curl
経由で送信して、HTTPS リダイレクトが正しく機能することを確認します。curl VIP
VIP
は、MultiClusterIngress の IP アドレスに置き換えます。出力には、リクエストが HTTPS ポートにリダイレクトされていることが示されます。これは、リダイレクトが正しく機能していることを示します。
TLS バージョン 1.1 を使用して HTTPS リクエストを送信し、TLS ポリシーが正しく機能することを確認します。このドメインに DNS は構成されていないため、
--resolve
オプションを使用してcurl
に IP アドレスを直接解決するように指示します。curl https://foo.example.com --resolve foo.example.com:443:VIP --cacert CERT_FILE -v
この手順では、MultiClusterIngress の保護に使用する証明書 PEM ファイルが必要です。正常な出力は次のようになります。
... * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=foo.example.com * start date: Sep 1 10:32:03 2021 GMT * expire date: Aug 27 10:32:03 2022 GMT * common name: foo.example.com (matched) * issuer: O=example; CN=foo.example.com * SSL certificate verify ok. * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x7fa10f00e400) > GET / HTTP/2 > Host: foo.example.com > User-Agent: curl/7.64.1 > Accept: */* > * Connection state changed (MAX_CONCURRENT_STREAMS == 100)! < HTTP/2 200 < content-type: application/json < content-length: 308 < access-control-allow-origin: * < server: Werkzeug/1.0.1 Python/3.8.6 < date: Wed, 01 Sep 2021 11:39:06 GMT < via: 1.1 google < alt-svc: clear < {"cluster_name":"gke-us","host_header":"foo.example.com","metadata":"foo","node_name":"gke-gke-us-default-pool-22cb07b1-r5r0.c.mark-church-project.internal","pod_name":"foo-75ccd9c96d-dkg8t","pod_name_emoji":"👞","project_id":"mark-church-project","timestamp":"2021-09-01T11:39:06","zone":"us-central1-b"} * Connection #0 to host foo.example.com left intact * Closing connection 0
レスポンス コードは 200 で、TLSv1.2 が使用されています。これは、すべてが正常に機能していることを示します。
次に、TLS 1.1 への接続を試行して、SSL ポリシーが正しい TLS バージョンを適用していることを確認します。このステップを行うには、SSL ポリシーが 1.2 以降のバージョンになるように構成されている必要があります。
前のステップと同じリクエストを送信しますが、今回は TLS バージョン 1.1 を適用します。
curl https://foo.example.com --resolve foo.example.com:443:VIP -v \ --cacert CERT_FILE \ --tls-max 1.1
正常な出力は次のようになります。
* Added foo.example.com:443:34.149.29.76 to DNS cache * Hostname foo.example.com was found in DNS cache * Trying 34.149.29.76... * TCP_NODELAY set * Connected to foo.example.com (34.149.29.76) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: cert.pem CApath: none * TLSv1.1 (OUT), TLS handshake, Client hello (1): * TLSv1.1 (IN), TLS alert, protocol version (582): * error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert protocol version * Closing connection 0 curl: (35) error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert protocol version
TLS handshake が失敗していれば、SSL ポリシーが TLS 1.1 を正常にブロックしています。
静的 IP の作成
静的 IP を割り振ります。
gcloud compute addresses create ADDRESS_NAME --global
ADDRESS_NAME
は、割り振る静的 IP の名前に置き換えます。次のように、作成したアドレスの完全な URL が出力に表示されます。
Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses/ADDRESS_NAME].
作成したばかりの IP アドレスを確認します。
gcloud compute addresses list
出力は次のようになります。
NAME ADDRESS/RANGE TYPE STATUS ADDRESS_NAME STATIC_IP_ADDRESS EXTERNAL RESERVED
この出力に含まれる情報:
- 定義した
ADDRESS_NAME
。 - 割り振られた
STATIC_IP_ADDRESS
。
- 定義した
mci.yaml
ファイルを静的 IP で更新します。apiVersion: networking.gke.io/v1 kind: MultiClusterIngress metadata: name: whereami-ingress namespace: whereami annotations: networking.gke.io/static-ip: STATIC_IP_ADDRESS spec: template: spec: backend: serviceName: whereami-mcs servicePort: 8080
STATIC_IP_ADDRESS
は、次のいずれかに置き換えます。- 割り振られた IP アドレス。例:
34.102.201.47
- 作成したアドレスの完全な URL。例:
"https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses/ADDRESS_NAME"
STATIC_IP_ADDRESS
は、リソース名(ADDRESS_NAME
)ではありません。- 割り振られた IP アドレス。例:
MultiClusterIngress
リソースを再デプロイします。kubectl apply -f mci.yaml
出力は次のようになります。
multiclusteringress.networking.gke.io/whereami-ingress configured
デプロイの成功ステータスを検証するの手順を行い、
STATIC_IP_ADDRESS
でデプロイが実行されていることを確認します。
事前共有証明書
事前共有証明書は、Kubernetes Secret に保存されている証明書ではなく、Google Cloud にアップロードされる証明書で、ロードバランサが TLS 終端に使用します。これらの証明書は、GKE から Google Cloud に帯域外でアップロードされ、MultiClusterIngress
リソースによって参照されます。事前共有証明書または Kubernetes Secret を介した複数の証明書がサポートされます。
マルチクラスタ Ingress で証明書を使用するには、networking.gke.io/pre-shared-certs
アノテーションと証明書の名前が必要です。特定の MultiClusterIngress
に複数の証明書が指定されている場合、証明書は事前定義された順序でクライアントに提示されます。
次のコマンドを実行して、使用可能な SSL 証明書を一覧表示できます。
gcloud compute ssl-certificates list
次の例では、事前共有証明書の共通名と一致する特定のホストへのクライアント トラフィックを記述することで、ドメイン名と一致する証明書が提示されます。
kind: MultiClusterIngress
metadata:
name: shopping-service
namespace: whereami
annotations:
networking.gke.io/pre-shared-certs: "domain1-cert, domain2-cert"
spec:
template:
spec:
rules:
- host: my-domain1.gcp.com
http:
paths:
- backend:
serviceName: domain1-svc
servicePort: 443
- host: my-domain2.gcp.com
http:
paths:
- backend:
serviceName: domain2-svc
servicePort: 443
Google マネージド証明書
Google マネージド証明書は、networking.gke.io/pre-shared-certs
アノテーションによって MultiClusterIngress
リソースでサポートされます。マルチクラスタ Ingress は、MultiClusterIngress
リソースへの Google マネージド証明書の適用をサポートしていますが、単一クラスタ Ingress とは異なり、MultiClusterIngress
リソースでは Kubernetes ManagedCertificate
リソースの宣言型生成はサポートされていません。Google マネージド証明書は、MultiClusterIngress
に接続する前に、compute ssl-certificates create
API を使用して直接作成する必要があります。手順は次のとおりです。
この手順のステップ 1 で Google マネージド証明書を作成します。証明書はマルチクラスタ Ingress によって適用されるため、ステップ 2 に進まないでください。
gcloud compute ssl-certificates create my-google-managed-cert \ --domains=my-domain.gcp.com \ --global
networking.gke.io/pre-shared-certs
アノテーションを使用して、MultiClusterIngress
内の証明書の名前を参照します。kind: MultiClusterIngress metadata: name: shopping-service namespace: whereami annotations: networking.gke.io/pre-shared-certs: "my-google-managed-cert" spec: template: spec: rules: - host: my-domain.gcp.com http: paths: - backend: serviceName: my-domain-svc servicePort: 8080
上記のマニフェストで証明書が MultiClusterIngress
にアタッチされ、バックエンド GKE クラスタのトラフィックを終了できます。証明書が期限切れになる前に、Google Cloud によって証明書が自動更新されます。更新は透過的に行われます。マルチクラスタ Ingress を更新する必要はありません。
アプリケーション プロトコル
デフォルトでは、ロードバランサ プロキシからアプリケーションへの接続には HTTP が使用されます。networking.gke.io/app-protocols
アノテーションを使用して、ロードバランサがリクエストをアプリケーションに転送するときに HTTPS または HTTP/2 を使用するようにロードバランサを構成できます。次の例の annotation
フィールドで、http2
は MultiClusterService
ポート名、HTTP2
はロードバランサが使用するプロトコルを表します。
kind: MultiClusterService
metadata:
name: shopping-service
namespace: whereami
annotations:
networking.gke.io/app-protocols: '{"http2":"HTTP2"}'
spec:
template:
spec:
ports:
- port: 443
name: http2
BackendConfig
アノテーションの構成方法については、上記のセクションをご覧ください。
次のステップ
- GKE ネットワークの概要を読む。
- Ingress で HTTP ロード バランシングを設定する方法を学習する。
- エンドツーエンドの HTTPS を使用したマルチクラスタ Ingress を実装する。