このページでは、Google Distributed Cloud(GDC)のエアギャップで堅牢で高可用性(HA)の Kubernetes コンテナ アプリケーションを構築するための推奨されるデプロイ戦略について説明します。コンテナ アプリケーションを複数の GDC ゾーンにデプロイし、非同期ストレージ レプリケーションを構成して、予期しないダウンタイムやローカル災害が発生した場合にアプリケーションとそのデータを復元できるようにする必要があります。
このページは、組織のアプリケーション ワークロードの作成を担当するアプリケーション オペレーター グループ内のデベロッパーを対象としています。詳細については、GDC エアギャップの対象読者に関するドキュメントをご覧ください。
目標
- GDC ユニバースの 2 つ以上のゾーンに Kubernetes クラスタを作成します。
- グローバル ロード バランシングを構成します。
- コンテナ ワークロードを各ゾーン Kubernetes クラスタにデプロイします。
- ストレージをプロビジョニングして Pod に接続します。
- ブロック ストレージまたはオブジェクト ストレージを使用して、非同期ストレージ レプリケーションを構成します。
始める前に
- 複数のゾーンが使用可能な GDC ユニバースで作業していることを確認します。 - gdcloud zones listを実行して、ユニバースで使用可能なゾーンを一覧表示します。詳細については、ユニバース内のゾーンを一覧表示するをご覧ください。
- 組織の IAM 管理者に次のロールの付与を依頼します。 - コンテナ ワークロードを作成して管理する名前空間管理者( - namespace-admin)ロール。
- Kubernetes クラスタとそのノードプールを作成して管理するためのユーザー クラスタ管理者( - user-cluster-admin)ロールとユーザー クラスタ デベロッパー(- user-cluster-developer)ロール。
- ロードバランサ管理者( - load-balancer-admin)とグローバル ロードバランサ管理者(- global-load-balancer-admin)のロール。ロードバランサを作成して管理するには、これらのロールが必要です。
- ボリューム レプリケーション グローバル管理者ロール( - app-volume-replication-admin-global)。ボリューム レプリケーションを管理するには、このロールが必要です。
- ゾーン間でプロジェクト ネットワーク ポリシーを作成して管理するグローバル PNP 管理者( - global-project-networkpolicy-admin)ロール。
- Harbor インスタンス管理者( - harbor-instance-admin)、Harbor インスタンス閲覧者(- harbor-instance-viewer)、Harbor プロジェクト作成者(- harbor-project-creator)のロール。これらのロールは、アーティファクト レジストリでコンテナ イメージを作成して管理するために必要です。
- ブロック ストレージ リソースのボリューム レプリケーション関係を管理するボリューム レプリケーション グローバル管理者( - app-volume-replication-admin-global)ロール。
- ストレージ バケットを作成して管理するためのプロジェクト バケット オブジェクト管理者( - project-bucket-object-admin)ロールとプロジェクト バケット管理者(- project-bucket-admin)ロール。
 - 詳細については、ロールの説明をご覧ください。 
- gdcloud CLI をインストールして構成し、ゾーン コンテキストとグローバル コンテキストを構成します。詳細については、ゾーン間のリソースを管理するをご覧ください。 
- kubectl CLI をインストールして構成します。グローバル API サーバー、管理 API サーバー、Kubernetes クラスタに適切な kubeconfig ファイルを設定します。詳細については、kubeconfig ファイルを手動で生成するをご覧ください。 
複数のゾーンに Kubernetes クラスタを作成する
Kubernetes クラスタはゾーンリソースであるため、各ゾーンにクラスタを個別に作成する必要があります。
コンソール
- ナビゲーション メニューで、[Kubernetes Engine] > [クラスタ] を選択します。 
- [クラスタを作成] をクリックします。 
- [名前] フィールドに、クラスタの名前を指定します。 
- クラスタの Kubernetes バージョンを選択します。 
- クラスタを作成するゾーンを選択します。 
- [プロジェクトを接続] をクリックし、既存のプロジェクトを選択してクラスタに接続します。オンにして [保存] をクリックします。クラスタの作成後に、[プロジェクトの詳細] ページでプロジェクトを関連付けたり、関連付けを解除したりできます。コンテナ ワークロードをデプロイする前に、クラスタにプロジェクトを関連付ける必要があります。 
- [次へ] をクリックします。 
- クラスタのネットワーク設定を構成します。クラスタの作成後にこれらのネットワーク設定を変更することはできません。Kubernetes クラスタでサポートされているデフォルトのインターネット プロトコルは、インターネット プロトコル バージョン 4(IPv4)のみです。 - ロードバランサの IP アドレス プールのサイズ( - 20など)を指定します。
- 使用するサービス CIDR(クラスレス ドメイン間ルーティング)を選択します。ロードバランサなどのデプロイされたサービスには、この範囲から IP アドレスが割り当てられます。 
- 使用する Pod CIDR を選択します。クラスタは、この範囲から Pod と VM に IP アドレスを割り当てます。 
- [次へ] をクリックします。 
 
- クラスタ用に自動生成されたデフォルトのノードプールの詳細を確認します。edit [編集] をクリックして、デフォルトのノードプールを変更します。 
- 追加のノードプールを作成するには、[ノードプールを追加] を選択します。デフォルトのノードプールを編集するときや、新しいノードプールを追加するときに、次のオプションを使用してカスタマイズします。 - ノードプールに名前を割り当てます。ノードプールの作成後に名前を変更することはできません。
- ノードプール内に作成するワーカーノードの数を指定します。
- ワークロードの要件に最も適したマシンクラスを選択します。次の設定のリストを表示します。 - マシンタイプ
- CPU
- メモリ
 
- [保存] をクリックします。 
- [作成] をクリックしてクラスタを作成します。 
 
- GDC ユニバース内の各ゾーンに対して、上記の手順を繰り返します。HA 戦略で必要なすべてのゾーンに Kubernetes クラスタが存在することを確認します。 
API
API を直接使用して新しい Kubernetes クラスタを作成するには、各 GDC ゾーンにカスタム リソースを適用します。
- Clusterカスタム リソースを作成し、ゾーンの Management API サーバーにデプロイします。- kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF \ apiVersion: cluster.gdc.goog/v1 kind: Cluster metadata: name: CLUSTER_NAME namespace: platform spec: clusterNetwork: podCIDRSize: POD_CIDR serviceCIDRSize: SERVICE_CIDR initialVersion: kubernetesVersion: KUBERNETES_VERSION loadBalancer: ingressServiceIPSize: LOAD_BALANCER_POOL_SIZE nodePools: - machineTypeName: MACHINE_TYPE name: NODE_POOL_NAME nodeCount: NUMBER_OF_WORKER_NODES taints: TAINTS labels: LABELS acceleratorOptions: gpuPartitionScheme: GPU_PARTITION_SCHEME releaseChannel: channel: UNSPECIFIED EOF- 次のように置き換えます。 - MANAGEMENT_API_SERVER: ゾーン Management API サーバーの kubeconfig パス。詳細については、ゾーン コンテキストに切り替えるをご覧ください。
- CLUSTER_NAME: クラスタの名前。クラスタ名の末尾を- -systemにすることはできません。- -system接尾辞は、GDC によって作成されたクラスタ用に予約されています。
- POD_CIDR: Pod の仮想 IP アドレス(VIP)が割り当てられるネットワーク範囲のサイズ。設定しない場合、デフォルト値の- 21が使用されます。
- SERVICE_CIDR: サービス VIP が割り当てられるネットワーク範囲のサイズ。設定されていない場合、デフォルト値の- 23が使用されます。
- KUBERNETES_VERSION: クラスタの Kubernetes バージョン(- 1.26.5-gke.2100など)。構成可能な Kubernetes バージョンを一覧表示するには、クラスタで使用可能な Kubernetes バージョンを一覧表示するをご覧ください。
- LOAD_BALANCER_POOL_SIZE: ロードバランサ サービスで使用される重複しない IP アドレスプールのサイズ。設定されていない場合、デフォルト値の- 20が使用されます。
- MACHINE_TYPE: ノードプールのワーカーノードのマシンタイプ。構成可能な内容については、使用可能なマシンタイプをご覧ください。
- NODE_POOL_NAME: ノードプールの名前。
- NUMBER_OF_WORKER_NODES: ノードプールにプロビジョニングするワーカーノードの数。
- TAINTS: このノードプールのノードに適用する taint。このフィールドは省略できます。
- LABELS: このノードプールのノードに適用するラベル。Key-Value ペアのリストが含まれています。このフィールドは省略可能です。
- GPU_PARTITION_SCHEME: GPU ワークロード(- mixed-2など)を実行している場合の GPU パーティショニング スキーム。このフィールドが設定されていない場合、GPU はパーティショニングされません。利用可能なマルチインスタンス GPU(MIG)プロファイルについては、サポートされている MIG プロファイルをご覧ください。
 
- HA 戦略でコンテナ アプリケーションをホストするゾーンごとに、前の手順を繰り返します。 
ロードバランサを構成する
異なるゾーンの Pod 間でトラフィックを分散するには、ロードバランサを作成します。外部ロードバランサ(ELB)と内部ロードバランサ(ILB)を作成できます。どちらもゾーンまたはグローバルに構成できます。この例では、コンテナ アプリケーションのグローバル ILB とグローバル ELB を構成します。
グローバル内部ロードバランサを作成する
内部ロードバランサ(ILB)は、組織に割り当てられた内部 IP アドレス プールから組織内のサービスを公開します。ILB サービスには、組織外のエンドポイントからアクセスできません。
コンテナ ワークロードのグローバル ILB を作成するには、次の操作を行います。
gdcloud
gdcloud CLI を使用して、Pod ワークロードをターゲットとする ILB を作成します。
この ILB は、Backend オブジェクトで定義されたラベルに一致するプロジェクト内のすべてのワークロードをターゲットにします。Backend カスタム リソースは、ゾーンにスコープ設定する必要があります。
gcloud CLI を使用して ILB を作成するには、次の操作を行います。
- ポッドが実行されている各ゾーンにゾーン - Backendリソースを作成して、ILB のエンドポイントを定義します。- gdcloud compute backends create BACKEND_NAME \ --labels=LABELS \ --project=PROJECT \ --cluster=CLUSTER_NAME \ --zone=ZONE- 次のように置き換えます。 - BACKEND_NAME: バックエンド リソースに選択した名前(- my-backendなど)。
- LABELS: このバックエンド リソースに使用する Pod 間のエンドポイントを定義するセレクタ(- app=webなど)。
- PROJECT: プロジェクトの名前。
- CLUSTER_NAME: 定義されたセレクタのスコープが制限される Kubernetes クラスタ。このフィールドが指定されていない場合、指定されたラベルを持つすべてのエンドポイントが選択されます。このフィールドは省略可能です。
- ZONE: この呼び出しに使用するゾーン。ゾーンフラグを必要とするすべてのコマンドに対してゾーンフラグをプリセットするには、- gdcloud config set core/zone ZONEを実行します。ゾーンフラグは、マルチゾーン環境でのみ使用できます。このフィールドは省略可能です。
 - この手順を GDC ユニバースの各ゾーンで繰り返します。 
- グローバル - BackendServiceリソースを作成します。- gdcloud compute backend-services create BACKEND_SERVICE_NAME \ --project=PROJECT \ --target-ports=TARGET_PORTS \ --global- 次のように置き換えます。 - BACKEND_SERVICE_NAME: バックエンド サービスの名前。
- PROJECT: プロジェクトの名前。
- TARGET_PORTS: このバックエンド サービスが変換するターゲット ポートのカンマ区切りリスト。各ターゲット ポートは、プロトコル、転送ルールのポート、バックエンド インスタンスのポートを指定します。複数のターゲット ポートを指定できます。このフィールドは- protocol:port:targetport形式(- TCP:80:8080など)にする必要があります。このフィールドは省略可能です。
 
- 各ゾーンで、前に作成した - Backendリソースに- BackendServiceリソースを追加します。- gdcloud compute backend-services add-backend BACKEND_SERVICE_NAME \ --backend-zone=ZONE \ --backend=BACKEND_NAME \ --project=PROJECT \ --global- 次のように置き換えます。 - BACKEND_SERVICE_NAME: グローバル バックエンド サービスの名前。
- ZONE: バックエンドのゾーン。
- BACKEND_NAME: ゾーン バックエンドの名前。
- PROJECT: プロジェクトの名前。
 - この手順は、以前に作成したゾーン バックエンドごとに行います。 
- サービスが利用可能な仮想 IP アドレス(VIP)を定義する内部 - ForwardingRuleリソースを作成します。- gdcloud compute forwarding-rules create FORWARDING_RULE_INTERNAL_NAME \ --backend-service=BACKEND_SERVICE_NAME \ --cidr=CIDR \ --ip-protocol-port=PROTOCOL_PORT \ --load-balancing-scheme=INTERNAL \ --project=PROJECT \ --global- 次のように置き換えます。 - FORWARDING_RULE_INTERNAL_NAME: 転送ルールの名前。
- CIDR: 転送ルールで使用する CIDR。このフィールドは省略可能です。指定しない場合、- IPv4/32CIDR はグローバル IP アドレス プールから自動的に予約されます。この転送ルールと同じ Namespace 内の- Subnetリソースの名前を指定します。- Subnetリソースは、グローバル サブネットのリクエストと割り当て情報を表します。- Subnetリソースの詳細については、サブネットを管理するをご覧ください。
- PROTOCOL_PORT: 転送ルールで公開するプロトコルとポート。このフィールドは- ip-protocol=TCP:80の形式にする必要があります。公開されるポートは、実際のアプリケーションがコンテナ内で公開しているポートと同じである必要があります。
 
- 構成された ILB を検証するには、作成された各オブジェクトの - Ready条件を確認します。VIP への- curlリクエストでトラフィックを確認します。- 割り当てられた VIP を取得するには、転送ルールを説明します。 - gdcloud compute forwarding-rules describe FORWARDING_RULE_INTERNAL_NAME --global
- 転送ルールのフィールドで指定されたポートの VIP に - curlリクエストを送信して、トラフィックを確認します。- curl http://FORWARDING_RULE_VIP:PORT
 - 次のように置き換えます。 - FORWARDING_RULE_VIP: 転送ルールの VIP。
- PORT: 転送ルールのポート番号。
 
API
KRM API を使用して、コンテナ ワークロードをターゲットとする ILB を作成します。この ILB は、Backend オブジェクトで定義されたラベルに一致するプロジェクト内のすべてのワークロードをターゲットにします。KRM API を使用してグローバル ILB を作成する手順は次のとおりです。
- Backendリソースを作成して、ILB のエンドポイントを定義します。コンテナ ワークロードが配置されているゾーンごとに- Backendリソースを作成します。- kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF apiVersion: networking.gdc.goog/v1 kind: Backend metadata: namespace: PROJECT name: BACKEND_NAME spec: clusterName: CLUSTER_NAME endpointsLabels: matchLabels: app: APP_NAME EOF- 次のように置き換えます。 - MANAGEMENT_API_SERVER: ゾーン Management API サーバーの kubeconfig パス。詳細については、ゾーン コンテキストに切り替えるをご覧ください。
- PROJECT: プロジェクトの名前。
- BACKEND_NAME:- Backendリソースの名前。
- CLUSTER_NAME: 定義されたセレクタのスコープが制限される Kubernetes クラスタ。このフィールドが指定されていない場合、指定されたラベルを持つすべてのエンドポイントが選択されます。このフィールドは省略可能です。
- APP_NAME: コンテナ アプリケーションの名前。
 - 各ゾーンに同じ - Backendリソースを使用することも、各ゾーンに異なるラベルセットを持つ- Backendリソースを作成することもできます。
- 前に作成した - Backendリソースを使用して- BackendServiceオブジェクトを作成します。- HealthCheckリソースを含めてください。- kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: BackendService metadata: namespace: PROJECT name: BACKEND_SERVICE_NAME spec: backendRefs: - name: BACKEND_NAME zone: ZONE healthCheckName: HEALTH_CHECK_NAME targetPorts: - port: PORT protocol: PROTOCOL targetPort: TARGET_PORT EOF- 次のように置き換えます。 - GLOBAL_API_SERVER: グローバル API サーバーの kubeconfig パス。
- PROJECT: プロジェクトの名前。
- BACKEND_SERVICE_NAME:- BackendServiceリソースに選択した名前。
- HEALTH_CHECK_NAME: 以前に作成した- HealthCheckリソースの名前。
- BACKEND_NAME: ゾーン- Backendリソースの名前。
- ZONE:- Backendリソースが存在するゾーン。- backendRefsフィールドで複数のバックエンドを指定できます。次に例を示します。- - name: my-backend-1 zone: us-east1-a - name: my-backend-2 zone: us-east1-b- targetPortsフィールドは省略可能です。このリソースは、この- BackendServiceリソースが変換するポートを一覧表示します。このオブジェクトを使用する場合は、次の値を指定します。
- PORT: サービスによって公開されるポート。
- PROTOCOL: トラフィックが一致する必要があるレイヤ 4 プロトコル。TCP と UDP のみがサポートされます。
- TARGET_PORT: 値の変換先となるポート(- 8080など)。値は、特定のオブジェクト内で繰り返すことはできません。- targetPortsの例を次に示します。- targetPorts: - port: 80 protocol: TCP targetPort: 8080
 
- サービスが利用可能な仮想 IP アドレス(VIP)を定義する内部 - ForwardingRuleリソースを作成します。- kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ForwardingRuleInternal metadata: namespace: PROJECT name: FORWARDING_RULE_INTERNAL_NAME spec: cidrRef: CIDR ports: - port: PORT protocol: PROTOCOL backendServiceRef: name: BACKEND_SERVICE_NAME EOF- 次のように置き換えます。 - GLOBAL_API_SERVER: グローバル API サーバーの kubeconfig パス。
- PROJECT: プロジェクトの名前。
- FORWARDING_RULE_INTERNAL_NAME:- ForwardingRuleInternalリソースに選択した名前。
- CIDR: 転送ルールに使用する CIDR。このフィールドは省略可能です。指定しない場合、- IPv4/32CIDR はグローバル IP アドレス プールから自動的に予約されます。この転送ルールと同じ Namespace 内の- Subnetリソースの名前を指定します。- Subnetリソースは、グローバル サブネットのリクエストと割り当て情報を表します。- Subnetリソースの詳細については、サブネットを管理するをご覧ください。
- PORT: 転送ルールで公開するポート。- portsフィールドを使用して、この転送ルールで構成されたバックエンドにパケットが転送される L4 ポートの配列を指定します。少なくとも 1 つのポートを指定する必要があります。- portフィールドを使用して、ポート番号を指定します。公開されるポートは、実際のアプリケーションがコンテナ内で公開しているポートと同じである必要があります。
- PROTOCOL: 転送ルールに使用するプロトコル(- TCPなど)。- ports配列のエントリは次のようになります。- ports: - port: 80 protocol: TCP
 
- 構成された ILB を検証するには、作成された各オブジェクトの - Ready条件を確認します。VIP への- curlリクエストでトラフィックを確認します。- VIP を取得します。 - kubectl get forwardingruleinternal -n PROJECT- 出力は次のようになります。 - NAME BACKENDSERVICE CIDR READY ilb-name BACKEND_SERVICE_NAME 192.0.2.0/32 True
- 転送ルールのフィールドで指定されたポートの VIP に - curlリクエストを送信して、トラフィックをテストします。- curl http://FORWARDING_RULE_VIP:PORT- 次のように置き換えます。 - FORWARDING_RULE_VIP: 転送ルールの VIP。
- PORT: 転送ルールのフィールドのポート番号。
 
 
グローバル外部ロードバランサを作成する
外部ロードバランサ(ELB)は、組織に割り当てられたプール IP アドレスから、組織外からのアクセス用にサービスを公開します。このプール IP アドレスは、より大きなインスタンス外部 IP アドレス プールから割り当てられます。
コンテナ ワークロードのグローバル ELB を作成するには、次の操作を行います。
gdcloud
gdcloud CLI を使用して、Backend オブジェクトで定義されたラベルに一致するプロジェクト内のすべてのワークロードをターゲットとするグローバル ELB を作成します。Backend カスタム リソースはゾーンにスコープ設定する必要があります。
- ELB サービスが機能するには、独自のカスタマイズされた - ProjectNetworkPolicyデータ転送をポリシーで構成して適用し、この ELB サービスのワークロードへのトラフィックを許可する必要があります。ネットワーク ポリシーは、ロードバランサ自体ではなく、ワークロードへのアクセスを制御します。ELB はワークロードを顧客ネットワークに公開します。このため、外部トラフィックがワークロード ポート(- 8080など)にアクセスできるように、明示的なネットワーク ポリシーが必要です。- この ELB のワークロードへのトラフィックを許可する外部 CIDR アドレスを指定します。 - kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ProjectNetworkPolicy metadata: namespace: PROJECT name: allow-inbound-traffic-from-external spec: policyType: Ingress subject: subjectType: UserWorkload ingress: - from: - ipBlock: cidr: CIDR ports: - protocol: TCP port: PORT EOF- 次のように置き換えます。 - GLOBAL_API_SERVER: グローバル API サーバーの kubeconfig パス。グローバル API サーバーの kubeconfig ファイルをまだ生成していない場合は、kubeconfig ファイルを手動で生成するをご覧ください。
- PROJECT: プロジェクトの名前。
- CIDR: ELB にアクセスする必要がある外部 CIDR。このポリシーは、外部ロードバランサが Direct Server Return(DSR)を使用し、送信元外部 IP アドレスを保持して、戻りパスでロードバランサをバイパスするため必要です。詳細については、組織間のトラフィック用のグローバル上り(内向き)ファイアウォール ルールを作成するをご覧ください。
- PORT: ロードバランサの背後にある Pod のバックエンド ポート。この値は、- Serviceリソースのマニフェストの- .spec.ports[].targetPortfieldフィールドにあります。このフィールドは省略可能です。
 - この構成により、プロジェクト内のすべてのリソースが指定された CIDR 範囲にアクセスできるようになります。 
- 各ゾーンに - Backendリソースを作成して、ELB のエンドポイントを定義します。- gdcloud compute backends create BACKEND_NAME \ --labels=LABELS \ --project=PROJECT \ --cluster=CLUSTER_NAME \ --zone=ZONE- 次のように置き換えます。 - BACKEND_NAME: バックエンド リソースの名前(- my-backendなど)。
- LABELS: このバックエンド リソースに使用する Pod 間のエンドポイントを定義するセレクタ(- app=webなど)。
- PROJECT: プロジェクトの名前。
- CLUSTER_NAME: 定義されたセレクタのスコープが制限される Kubernetes クラスタ。このフィールドが指定されていない場合、指定されたラベルを持つすべてのエンドポイントが選択されます。このフィールドは省略可能です。
- ZONE: この呼び出しに使用するゾーン。ゾーンフラグを必要とするすべてのコマンドに対してゾーンフラグをプリセットするには、- gdcloud config set core/zone ZONEを実行します。ゾーンフラグは、マルチゾーン環境でのみ使用できます。このフィールドは省略可能です。
 - 各ゾーンに同じ - Backendリソースを使用することも、各ゾーンに異なるラベルセットを持つ- Backendリソースを作成することもできます。
- グローバル - BackendServiceリソースを作成します。- gdcloud compute backend-services create BACKEND_SERVICE_NAME \ --project=PROJECT \ --target-ports=TARGET_PORTS \ --health-check=HEALTH_CHECK_NAME \ --global- 次のように置き換えます。 - BACKEND_SERVICE_NAME: このバックエンド サービスに選択した名前。
- PROJECT: プロジェクトの名前。
- TARGET_PORTS: このバックエンド サービスが変換するターゲット ポートのカンマ区切りリスト。各ターゲット ポートは、プロトコル、転送ルールのポート、バックエンド インスタンスのポートを指定します。複数のターゲット ポートを指定できます。このフィールドは、- TCP:80:8080などの- protocol:port:targetport形式にする必要があります。このフィールドは省略可能です。
- HEALTH_CHECK_NAME: ヘルスチェック リソースの名前。このフィールドは省略可能です。
 
- グローバル - BackendServiceリソースを、前に作成したゾーン- Backendリソースに追加します。- gdcloud compute backend-services add-backend BACKEND_SERVICE_NAME \ --backend=BACKEND_NAME \ --backend-zone=ZONE \ --project=PROJECT \ --global- この手順は、以前に作成したゾーン バックエンドごとに行います。 
- サービスが利用可能な VIP を定義する外部 - ForwardingRuleリソースを作成します。- gdcloud compute forwarding-rules create FORWARDING_RULE_EXTERNAL_NAME \ --backend-service=BACKEND_SERVICE_NAME \ --cidr=CIDR \ --ip-protocol-port=PROTOCOL_PORT \ --load-balancing-scheme=EXTERNAL \ --project=PROJECT \ --global- 次のように置き換えます。 - FORWARDING_RULE_EXTERNAL_NAME: 転送ルールの名前。
- CIDR: 転送ルールで使用する CIDR。このフィールドは省略可能です。指定しない場合、- IPv4/32CIDR はグローバル IP アドレス プールから自動的に予約されます。この転送ルールと同じ Namespace 内の- Subnetリソースの名前を指定します。- Subnetリソースは、グローバル サブネットのリクエストと割り当て情報を表します。- Subnetリソースの詳細については、サブネットを管理するをご覧ください。
- PROTOCOL_PORT: 転送ルールで公開するプロトコルとポート。このフィールドは- ip-protocol=TCP:80の形式にする必要があります。公開されるポートは、実際のアプリケーションがコンテナ内で公開しているポートと同じである必要があります。
- PROJECT: プロジェクトの名前。
 
- 構成された ELB を検証するには、作成された各オブジェクトの - Ready条件を確認します。VIP への- curlリクエストでトラフィックを確認します。- 割り当てられた VIP を取得するには、転送ルールを説明します。 - gdcloud compute forwarding-rules describe FORWARDING_RULE_EXTERNAL_NAME
- 転送ルールの - PROTOCOL_PORTフィールドで指定されたポートの VIP への- curlリクエストでトラフィックを確認します。- curl http://FORWARDING_RULE_VIP:PORT- 次のように置き換えます。 - FORWARDING_RULE_VIP: 転送ルールの VIP。
- PORT: 転送ルールの- PROTOCOL_PORTフィールドのポート番号。
 
 
API
KRM API を使用して、Pod ワークロードをターゲットとする ELB を作成します。この ELB は、Backend オブジェクトで定義されたラベルに一致するプロジェクト内のすべてのワークロードをターゲットにします。KRM API を使用してゾーン ELB を作成する手順は次のとおりです。
- ELB サービスが機能するには、独自のカスタマイズされた - ProjectNetworkPolicyデータ転送をポリシーで構成して適用し、この ELB サービスのワークロードへのトラフィックを許可する必要があります。ネットワーク ポリシーは、ロードバランサ自体ではなく、ワークロードへのアクセスを制御します。ELB はワークロードを顧客ネットワークに公開します。このため、外部トラフィックがワークロード ポート(- 8080など)にアクセスできるように、明示的なネットワーク ポリシーが必要です。- この ELB のワークロードへのトラフィックを許可する外部 CIDR アドレスを指定します。 - kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ProjectNetworkPolicy metadata: namespace: PROJECT name: allow-inbound-traffic-from-external spec: policyType: Ingress subject: subjectType: UserWorkload ingress: - from: - ipBlock: cidr: CIDR ports: - protocol: TCP port: PORT EOF- 次のように置き換えます。 - GLOBAL_API_SERVER: グローバル API サーバーの kubeconfig パス。グローバル API サーバーの kubeconfig ファイルをまだ生成していない場合は、kubeconfig ファイルを手動で生成するをご覧ください。
- PROJECT: プロジェクトの名前。
- CIDR: ELB にアクセスする必要がある外部 CIDR。このポリシーは、外部ロードバランサが Direct Server Return(DSR)を使用し、送信元外部 IP アドレスを保持して、戻りパスでロードバランサをバイパスするため必要です。詳細については、組織間のトラフィック用のグローバル上り(内向き)ファイアウォール ルールを作成するをご覧ください。
- PORT: ロードバランサの背後にある Pod のバックエンド ポート。この値は、- Serviceリソースのマニフェストの- .spec.ports[].targetPortfieldフィールドにあります。このフィールドは省略可能です。
 
- Backendリソースを作成して、ELB のエンドポイントを定義します。ワークロードが配置されているゾーンごとに- Backendリソースを作成します。- kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF apiVersion: networking.gdc.goog/v1 kind: Backend metadata: namespace: PROJECT name: BACKEND_NAME spec: clusterName: CLUSTER_NAME endpointsLabels: matchLabels: app: APP_NAME EOF- 次のように置き換えます。 - MANAGEMENT_API_SERVER: ゾーン Management API サーバーの kubeconfig パス。ターゲット ゾーンの API サーバーの kubeconfig ファイルをまだ生成していない場合は、kubeconfig ファイルを手動で生成するをご覧ください。
- PROJECT: プロジェクトの名前。
- BACKEND_NAME:- Backendリソースの名前。
- CLUSTER_NAME: 定義されたセレクタのスコープが制限される Kubernetes クラスタ。このフィールドを指定しない場合、指定されたラベルを持つすべてのエンドポイントが選択されます。このフィールドは省略可能です。
- APP_NAME: コンテナ アプリケーションの名前。
 - 各ゾーンに同じ - Backendリソースを使用することも、各ゾーンに異なるラベルセットを持つ- Backendリソースを作成することもできます。
- 前に作成した - Backendリソースを使用して- BackendServiceオブジェクトを作成します。- kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: BackendService metadata: namespace: PROJECT name: BACKEND_SERVICE_NAME spec: backendRefs: - name: BACKEND_NAME zone: ZONE healthCheckName: HEALTH_CHECK_NAME EOF- 次のように置き換えます。 - BACKEND_SERVICE_NAME:- BackendServiceリソースに選択した名前。
- HEALTH_CHECK_NAME: 以前に作成した- HealthCheckリソースの名前。Pod ワークロードの ELB を構成する場合は、このフィールドを含めないでください。
- ZONE:- Backendリソースが存在するゾーン。- backendRefsフィールドで複数のバックエンドを指定できます。次に例を示します。
 - - name: my-backend-1 zone: us-east1-a - name: my-backend-2 zone: us-east1-b
- サービスが利用可能な VIP を定義する外部 - ForwardingRuleリソースを作成します。- kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ForwardingRuleExternal metadata: namespace: PROJECT name: FORWARDING_RULE_EXTERNAL_NAME spec: cidrRef: CIDR ports: - port: PORT protocol: PROTOCOL backendServiceRef: name: BACKEND_SERVICE_NAME EOF- 次のように置き換えます。 - FORWARDING_RULE_EXTERNAL_NAME:- ForwardingRuleExternalリソースに選択した名前。
- CIDR: 転送ルールで使用する CIDR。このフィールドは省略可能です。指定しない場合、- IPv4/32CIDR はグローバル IP アドレス プールから自動的に予約されます。この転送ルールと同じ Namespace 内の- Subnetリソースの名前を指定します。- Subnetリソースは、グローバル サブネットのリクエストと割り当て情報を表します。- Subnetリソースの詳細については、サブネットを管理するをご覧ください。
- PORT: 転送ルールで公開するポート。- portsフィールドを使用して、この転送ルールで構成されたバックエンドにパケットが転送される L4 ポートの配列を指定します。少なくとも 1 つのポートを指定する必要があります。- portフィールドを使用して、ポート番号を指定します。公開されるポートは、実際のアプリケーションがコンテナ内で公開しているポートと同じである必要があります。
- PROTOCOL: 転送ルールに使用するプロトコル(- TCPなど)。- ports配列のエントリは次のようになります。
 - ports: - port: 80 protocol: TCP
- 構成された ELB を検証するには、作成された各オブジェクトの - Ready条件を確認します。VIP への- curlリクエストでトラフィックをテストします。- プロジェクトの VIP を取得します。 - kubectl get forwardingruleexternal -n PROJECT- 出力は次のようになります。 - NAME BACKENDSERVICE CIDR READY elb-name BACKEND_SERVICE_NAME 192.0.2.0/32 True
- 転送ルールの - PORTフィールドで指定されたポートの VIP に curl リクエストを送信して、トラフィックを確認します。- curl http://FORWARDING_RULE_VIP:PORT- FORWARDING_RULE_VIP:PORTは、転送ルールの VIP とポート(- 192.0.2.0:80など)に置き換えます。
 
各ゾーン クラスタにコンテナ ワークロードをデプロイする
コンテナ ワークロードはグローバル リソースではありません。つまり、コンテナ アプリケーションをゾーン Kubernetes クラスタに個別にデプロイする必要があります。
- Kubernetes クラスタをホストするゾーンにログインします。 - gdcloud config set core/zone ZONE
- マネージド Harbor レジストリからコンテナ イメージを使用できることを確認します。詳細については、コンテナ アプリをデプロイするチュートリアルをご覧ください。 
- コンテナ ワークロードのマニフェスト ファイルを作成し、ゾーン Kubernetes クラスタにデプロイします。 - kubectl --kubeconfig KUBERNETES_CLUSTER -n PROJECT \ apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: DEPLOYMENT_NAME spec: replicas: NUMBER_OF_REPLICAS selector: matchLabels: run: APP_NAME template: metadata: labels: run: APP_NAME spec: containers: - name: CONTAINER_NAME image: HARBOR_INSTANCE_URL/HARBOR_PROJECT_NAME/IMAGE:TAG EOF- 次のように置き換えます。 - KUBERNETES_CLUSTER: コンテナ ワークロードをデプロイするゾーン Kubernetes クラスタの kubeconfig ファイル。ゾーン Kubernetes クラスタの kubeconfig ファイルをまだ生成していない場合は、kubeconfig ファイルを手動で生成するをご覧ください。
- PROJECT: コンテナ ワークロードをデプロイするプロジェクト Namespace。
- DEPLOYMENT_NAME: コンテナ デプロイの名前。
- NUMBER_OF_REPLICAS: Deployment が管理する複製- Podオブジェクトの数。
- APP_NAME: デプロイ内で実行するアプリケーションの名前。
- CONTAINER_NAME: コンテナの名前。
- HARBOR_INSTANCE_URL: Harbor インスタンスの URL(- harbor-1.org-1.zone1.google.gdc.test.など)。Harbor インスタンスの URL を取得するには、Harbor レジストリ インスタンスを表示するをご覧ください。
- HARBOR_PROJECT_NAME: Harbor プロジェクトの名前(- my-projectなど)。
- IMAGE: イメージの名前(- nginxなど)。
- TAG: pull するイメージ バージョンのタグ(- 1.0など)。
 
- GDC ユニバース内の各ゾーンに対して、上記の手順を繰り返します。コンテナ アプリケーションが、HA 戦略で必要なすべてのゾーンに存在することを確認します。 
Kubernetes を使用してコンテナ アプリケーションを公開する
コンテナ アプリケーションを公開して、GDC ユニバース内の他のリソースからアクセスできるようにする必要があります。
- type: LoadBalancerの- Serviceリソースを作成します。このリソースは、ネットワーク経由でアプリケーションの Pod を公開します。- kubectl --kubeconfig KUBERNETES_CLUSTER -n PROJECT \ apiVersion: v1 kind: Service metadata: name: SERVICE_NAME spec: selector: app: APP_NAME ports: - port: 80 protocol: TCP type: LoadBalancer EOF- 次のように置き換えます。 - KUBERNETES_CLUSTER: コンテナ ワークロードをデプロイするゾーン Kubernetes クラスタの kubeconfig ファイル。
- PROJECT: コンテナ ワークロードが存在するプロジェクト Namespace。
- SERVICE_NAME: ロードバランサ サービスの名前。
- APP_NAME: コンテナ アプリケーションに適用したラベル。
 
- すべてのネットワーク トラフィックをデフォルトの Namespace に許可する - NetworkPolicyカスタム リソースを作成します。- kubectl --kubeconfig KUBERNETES_CLUSTER -n PROJECT \ apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: annotations: name: allow-all spec: ingress: - from: - ipBlock: cidr: 0.0.0.0/0 podSelector: {} policyTypes: - Ingress EOF
Pod の永続ストレージをプロビジョニングする
アプリケーション Pod に永続ストレージを提供するには、PersistentVolumeClaim リソース(PVC)を作成する必要があります。
次の手順では、GDC standard-rwo StorageClass を使用してボリュームを作成する方法について説明します。
- PersistentVolumeClaimリソースを作成するたとえば、- ReadWriteOnceアクセスモードと- standard-rwoストレージ クラスで構成します。- kubectl --kubeconfig KUBERNETES_CLUSTER \ --namespace PROJECT apply -f - <<EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: PVC_NAME spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: standard-rwo EOF- 次のように置き換えます。 - KUBERNETES_CLUSTER: Kubernetes クラスタの kubeconfig ファイル。
- PROJECT: PVC を作成するプロジェクト Namespace。
- PVC_NAME:- PersistentVolumeClaimオブジェクトの名前。
 
- PersistentVolume(PV)オブジェクトは動的にプロビジョニングされます。Kubernetes クラスタ内の新しい PV のステータスを確認します。- kubectl get pv --kubeconfig KUBERNETES_CLUSTER- 出力は次のようになります。 - NAME CAPACITY ACCESS MODES STATUS CLAIM STORAGECLASS AGE pvc-uuidd 10Gi RWO Bound pvc-name standard-rwo 60s
- PVC を使用するようにコンテナ ワークロードを構成します。次は、 - standard-rwoPVC を使用する Pod マニフェストの例です。- kubectl --kubeconfig KUBERNETES_CLUSTER \ --namespace PROJECT apply -f - <<EOF apiVersion: apps/v1 kind: Pod metadata: name: web-server-deployment labels: app: APP_LABEL spec: containers: - name: CONTAINER_NAME image: HARBOR_INSTANCE_URL/HARBOR_PROJECT_NAME/IMAGE:TAG volumeMounts: - mountPath: MOUNT_PATH name: data volumes: - name: data persistentVolumeClaim: claimName: PVC_NAME EOF- 次のように置き換えます。 - KUBERNETES_CLUSTER: コンテナ ワークロードをデプロイする Kubernetes クラスタの kubeconfig ファイル。
- PROJECT: PVC が存在するプロジェクト Namespace。
- APP_LABEL: コンテナ アプリケーションに適用したラベル。
- CONTAINER_NAME: コンテナの名前。
- HARBOR_INSTANCE_URL: Harbor インスタンスの URL(- harbor-1.org-1.zone1.google.gdc.test.など)。Harbor インスタンスの URL を取得するには、Harbor レジストリ インスタンスを表示するをご覧ください。
- HARBOR_PROJECT_NAME: Harbor プロジェクトの名前(- my-projectなど)。
- IMAGE: イメージの名前(- nginxなど)。
- TAG: pull するイメージ バージョンのタグ(- 1.0など)。
- MOUNT_PATH: ボリュームをマウントする Pod 内のパス。
- PVC_NAME: 作成した PVC。
 
非同期ストレージ レプリケーションを構成する
GDC マルチゾーン ユニバースでは、障害復旧シナリオで非同期モードのボリュームやバケットなどのレプリケートされたストレージ リソースを使用できます。これらのストレージ リソース オプションは、同じリージョン内の任意の 2 つのゾーン間で非同期データ レプリケーションを提供します。非同期レプリケーションはバックグラウンドで実行され、障害が発生した場合に目標復旧時点(RPO)をゼロに近い値に設定できます。複製されたすべてのデータはオンラインで、すぐにアクセスできますが、セカンダリ ゾーンへの書き込みを有効にするには、手動のフェイルオーバー手順が必要になる場合があります。
コンテナ アプリケーションには、次のいずれかの非同期ストレージ レプリケーション タイプを選択できます。
オブジェクト ストレージ用のデュアルゾーン バケットを作成する
オブジェクト ストレージ データは、両方のゾーンにデータが保存されている単一のバケットに書き込まれます。データはゾーン間で非同期でコピーされるため、ゾーンに同じオブジェクト バージョンが含まれていない可能性がありますが、追加の変更が行われない限り、最終的には同等になります。ボリューム レプリケーションとは異なり、レプリケートされたバケットはゾーン パーティション中に書き込み可能です。オブジェクトへの書き込みごとに異なるバージョンが生成され、接続が復元された後の最終状態は、いずれかのゾーンの最新バージョンになります。
- インフラストラクチャ オペレータ(IO)が - BucketLocationConfigカスタム リソースを作成したことを確認します。これは、オブジェクト ストレージのゾーン間の非同期レプリケーションに必要です。このリソースは、ルート グローバル API サーバーにデプロイする必要があります。
- デュアルゾーンの - Bucketカスタム リソースを作成します。- kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: object.global.gdc.goog/v1 kind: Bucket metadata: name: BUCKET_NAME namespace: PROJECT spec: location: LOCATION_NAME description: Sample DZ Bucket storageClass: Standard EOF- 次のように置き換えます。 - GLOBAL_API_SERVER: グローバル API サーバーの kubeconfig ファイル。
- BUCKET_NAME: ストレージ バケットの名前。
- PROJECT: バケットが存在するプロジェクトの名前。
- LOCATION_NAME: バケット内のオブジェクト データが存在する物理的な場所。これは、既存の- BucketLocationリソースの名前にマッピングする必要があります。組織のグローバル API サーバーに利用可能な- BucketLocationリソースのリストをクエリするには、- kubectl --kubeconfig GLOBAL_API_SERVER bucketlocationsを実行します。- BucketLocationリソースがない場合は、IO に連絡して、非同期レプリケーションが有効になっていることを確認します。
 
ゾーン間の非同期ブロック ストレージ レプリケーションを構成する
レプリケートされたブロック ストレージは、プライマリ ボリュームとセカンダリ ボリューム間のブロックの同等性を維持する非同期レプリケート ボリューム(PV)を提供します。非同期であるため、セカンダリ ボリュームには過去のある時点のプライマリ ゾーンの状態が反映されます(RPO はゼロではありません)。セカンダリ ボリュームはレプリケーションのターゲットである間はマウントできません。関係を終了して書き込みを有効にするには、手動での操作が必要です。
ソースゾーンのデータが使用できなくなった場合にフェイルオーバーに使用できる複製データを作成するには、ゾーン間でストレージ レプリケーション関係を構成する必要があります。これは、コンテナ アプリケーションにブロック ストレージを使用している場合に該当します。
開始する前に、インフラストラクチャ オペレーター(IO)が StorageClusterPeering カスタム リソースと StorageVirtualMachinePeering カスタム リソースを作成して構成し、ゾーン間のブロック ストレージ レプリケーションを許可していることを確認します。このリソースは、ルート グローバル API サーバーにデプロイする必要があります。
- VolumeReplicationRelationshipカスタム リソース YAML ファイルを作成し、グローバル API サーバーにデプロイします。- kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: storage.global.gdc.goog/v1 kind: VolumeReplicationRelationship metadata: name: PVC_REPL_NAME namespace: PROJECT spec: source: pvc: clusterRef: SOURCE_PVC_CLUSTER pvcRef: SOURCE_PVC zoneRef: SOURCE_ZONE destination: pvc: clusterRef: DEST_PVC_CLUSTER zoneRef: DEST_ZONE EOF- 次のように置き換えます。 - GLOBAL_API_SERVER: グローバル API サーバーの kubeconfig ファイル。
- PVC_REPL_NAME: ボリューム レプリケーション関係の名前。
- PROJECT: ストレージ インフラストラクチャが存在するプロジェクト。
- SOURCE_PVC_CLUSTER: PVC がホストされている Kubernetes クラスタ。
- SOURCE_PVC: レプリケートするソースゾーンの PVC。
- SOURCE_ZONE: PVC がホストされているソースゾーン。
- DEST_PVC_CLUSTER: PVC の複製先の Kubernetes クラスタ。
- DEST_ZONE: PVC のレプリケーション先のゾーン。
 
- 宛先ゾーンに - VolumeFailoverカスタム リソースを作成します。これにより、ソースゾーンが何らかの理由で利用できなくなった場合に、宛先ゾーンへのレプリケーションが停止します。- kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f - <<EOF apiVersion: storage.gdc.goog/v1 kind: VolumeFailover metadata: name: PVC_FAILOVER_NAME namespace: PROJECT spec: volumeReplicationRelationshipRef: PVC_REPL_NAME EOF- 次のように置き換えます。 - MANAGEMENT_API_SERVER: ゾーン Management API サーバーの kubeconfig ファイル。
- PVC_FAILOVER_NAME: PVC フェイルオーバーの名前。
- PROJECT: ストレージ インフラストラクチャが存在するプロジェクト。
- PVC_REPL_NAME: ボリューム レプリケーション関係の名前。