- GCP のすべてのリソースは プロジェクト の下に作成される
- プロジェクトごとに請求や IAM の管理が可能
- 本番やステージングといった複数環境のリソースを分離するためにもプロジェクトで分けよう
-
ネットワークはサブネットワーク・外部 IP アドレス・ファイアウォールルール・ルートなどをもつ
-
GCP ではパフォーマンスやシンプルさを追求し、リージョンを跨げるネットワークになっている
-
ファイアウォールはネットワークに対して設定できる
-
ファイアウォールはデフォルトで GKE ノードへの流入トラフィックは禁止している
-
サブネットワークは GKE クラスタへの IN/OUT トラフィックを隔離して制御する柔軟さを提供
-
プロジェクト作成時にデフォルトサブネットワークは作られるが、IP 管理上は別途作ることを推奨
-
サブネットワークはゾーンはまたげるが、リージョンはまたげない
-
サブネットワーク間の通信は、ファイアウォールルール上それが許可されている必要がある
-
プロジェクトデフォルトのサブネットワーク(Auto-mode)はデフォルトでそれが許可されている
-
自作のサブネットワークの場合は新規ルールでサブネット間の通信許可をする必要がある
-
GKE クラスタやノード作成時に tag をつけておくとルート作成時に有用
- IAM ロールはユーザ、グループまたはサービスアカウントに対して関連づけることができる
- 開発用プロジェクトと本番用プロジェクトがあるとして、それぞれに適切な IAM を設定する
- 開発プロジェクトでは、開発者向けに container.developer ロールを
- 本番プロジェクトでは、運用者向けに container.admin、セキュリティチームに container.viewer + security.admin、ネットワークチームに network.admin、CI/CD 自動化用サービスアカウントに container.developer ロールを渡すといった具合
- 開発プロジェクトは複数の開発チームが使うことになるが、それは IAM ではなく k8s の Namespaces を使うことで競合が防げる
- Namespaces を使えば利用できる CPU やメモリ、ストレージの上限も設定可能
- k8s v1.6 以降であれば、各クラスタにおいて、各ユーザのより綿密な権限管理も可能
- RBAC を使えば、ユーザごとに API レベルでクラスタに対し行えることを制御できる
- GKE なら kubectl は gcloud からアクティブなクレデンシャルを受け取る仕組みなので
- クラスタ管理者は、RoleBindings として GCP のユーザやサービスアカウントに適切な RBAC のロールが渡せる
- これによりプロジェクトレベルだけでなく、クラスタレベル、または Namespace レベルでの綿密な権限管理が可能
- Google Container Registry(GCR)のイメージは、実際には GCS に格納されている
- イメージを公開するには、バケットとオブジェクトを公開すれば OK
- プロジェクトを横断してアクセスさせるには、サービスアカウントに storage.viewer ロールを付与すれば OK
- ただしプロジェクトにデフォルトで作成されるサービスアカウントはプロジェクト全体の編集権限を持っているので注意
k8s はクラスタ内の pod だけでなく、クラスタ外のサービスも含めたロードバランスや サービスディスカばりを サービス を使って抽象化しています。
- k8s ではラベルを使い、特定の pod をまとめた サービス が定義できる
- このサービスはクラスタ内では一意の DNS で表現され、探すことができる
- クラスタ内で有効な DNS、kube-dns はサービス名を一連の healthy な IP に解決してくれる
- デフォルトでは、サービスごとに固定で割り当てられた仮想 IP を返す
- その仮想 IP にトラッフィックを向けると、kube-proxy に動的管理されたローカルノードの iptables に従い、適切な pod に送信される
- 仮想 IP ではなく A レコードとして有効な pod の IP リストがほしければ、そのようにサービスを起動することもできる
- ただしその場合、クライアントの DNS リゾルバがキャッシュしてしまうかもしれないし、ローテーションは非効率かもしれない
- GCP のプライペート IP アドレス帯からのアクセスなら、Internal なロードバランサを使うべき
- https://cloud.google.com/compute/docs/load-balancing/internal/
- クラスタ外からのアクセスを受け入れるためには NodePort を指定することになるが
- そうすると、クラスタ内全ノードの該当ポートが解放される
- アクセス制御を確実なものにしたければ、ファイアウォールルールを追加で設定することもできる
- GKE クラスタのノードは同一のインスタンスグループに所属しているので、それをロードバランサのバックエンドに指定できる
- ロードバランサからはセッションアフィニティに基づいて該当ノードへトラフィックが割り振られるが
- kube-proxy が適切にローカルの iptables を管理しているため、必要ならノード間でさらに適切な通信が起こる
- 方法は 3 つある
- k8s v1.6 以降であれば、特定ドメインへの DNS クエリを外部 DNS サーバにフォワードできる
- または外部サービスの DNS レコードをクラスタ内のサービス名に CNAME でマップすることもできる
- またはセレクタなしで、エンドポイントを直指定したサービスを定義することもできる。ただしメンテコストは高い。
- クラスタ内のサービスディスカバリと同じメカニズムで統一できるのは大きなメリットである
- インターネットからのトラフィックを受け入れるには、k8s としては 2 つの方法がある
- k8s のサービスを外部の TCP/UDP を受け入れる LoadBalancer タイプで作成するのが簡単
- 結果生成される GCP の Network Load Balancer はリージョン縛りがあることに注意
- または k8s で Ingress リソースを作り、サービスを NodePort タイプで生成し、Global HTTP(S) Load Balancer を使う
- Global HTTP(S) Load Balancer なら一つの Anycast IP アドレスで複数リージョンをまたいだロードバランスが可能
- すべての GKE ノードは GCE のインスタンスとして起動する
- よってファイアウォールの仕組みもそれに倣った形をとることになる
- デフォルトでは、ノードプールはそれ自身を特定する一意のタグが付与される
- クラスタやノードプールの作成時に --tags でカスタムタグを持つこともできる
- ファイアウォールのルールにはタグが利用できるので、それらを使えばクラスタへのアクセスが容易に制御できる
- ロードバランサへのアクセスをオンプレの前面においた VPN からのみに制限したり
- いくつか Cloud Interconnect にも選択肢がある
- ワークロードや要件に応じて組み合わせるといったこともできる
-
- インターネット経由: 膨大なデータでもレイテンシが重要でもなければ
-
- Direct Peering: L3 接続。専有帯域、低レイテンシ、GCP アクセスなどが必要なワークロードに
-
- Carrier Interconnect: AS 番号を持たない事業者向け、サービスプロバイダが提供する Direct Peering
-
- Cloud VPN: IPsec が必要な場合。自身のプライベートネットワークを GCE に拡張したい時。