このページでは、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/32
CIDR はグローバル 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/32
CIDR はグローバル 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/32
CIDR はグローバル 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/32
CIDR はグローバル 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-rwo
PVC を使用する 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
: ボリューム レプリケーション関係の名前。