Posted at

GKE本番環境へ向けた準備のベストプラクティス

More than 1 year has passed since last update.

以下のメモ。図なども以下のサイトから引用。

https://cloud.google.com/solutions/prep-container-engine-for-prod?hl=ja#communicating_within_the_same_cluster


プロジェクト、ネットワーク、クラスタの構成

以下の構成がベストな構成。

スクリーンショット 2017-07-18 18.07.20.png

本番環境用とテスト開発環境用のプロジェクトは分けて、本番環境は厳密なポリシーを設定する。

デフォルトネットワークを使うのではなく、自分でネットワークを作成し、管理しているIPアドレスにマップした方がよい。

FirewallルールはGKEノードへのIngressとEgressのトラフィックをフィルタするためにネットワークに適用される。

デフォルトではGKEノードに対する全てのインターネットトラフィックは拒否される。

サブネットワークは複数のゾーンを跨げるが、リージョンは跨げない。サブネットワーク間の通信をコントロールするために、トラフィックをパスするfirewallルールを作成する必要がある。"--tags"フラグをクラスタやノードプール作成時に付与すると、firewallルールの効果を受けることができる。またタグはルーティングにも利用できる。


Identityとアクセス管理

プロジェクトレベルアクセス

IAMロールはユーザだけではなくグループに対しても付与できる。

スクリーンショット 2017-07-19 12.48.38.png

チーム
IAMロール
プロジェクト
権限

Developers
container.developer
dev
既に存在するクラスタに対してk8sのリソースを作成可能。クラスタの作成や削除は禁止。

Operations
container.admin
prod
クラスタとk8sリソースに対する全ての管理者アクセスを許可。

Security
container.viewer, security.admin
prod
FirewallルールやSSL証明書の作成、修正、削除とリソース(ログを含む)の参照権限。

Network
network.admin
prod
ネットワークリソースに対する作成、修正、削除。ただしFirewallルールやSSL証明書は除く。

prodプロジェクトにアクセスできる3チームに加えて、"container.developer"のロールを与えられたサービスアカウントがリソースの作成、リスト、削除が可能。サービスアカウントは自動化スクリプトや開発フレームワークで使用される。クラスタへのデプロイは自動化されたパイプラインによってされるべきである。

devプロジェクトでは同じクラスタ上で複数の開発者が同じアプリケーションの開発を行っている。これはネームスペースによって分けられるべきである。そのためネームスペースのコンフリクトを避けないといけない。

ネームスペースはクラスタ内のCPUやメモリ、ストレージ使用のquotaを作成するためにも使用される。quotaによりあまりに多くのリソースが使用されるのを防ぐ。


RBAC authorization

k8s 1.6以上で起動しているコンテナエンジンクラスタは更なる制限をユーザに適用することができる。

Cloud IAMはユーザにクラスタやリソースのフルアクセスを提供することができるが、k8sのRole Based Access Control(RBAC)はクラスタ内でのユーザの行動を抑止することができる。

RBACで、クラスタ管理者は細かいポリシーを個々のネームスペースに適用することができる。

kubectlはgcloud toolからアクティブなクレデンシャルを使用して、ロールをユーザやサービスアカウントにマップする。

この例では2人のユーザがおり、app-aネームスペースのconfig-readerとpod-readerロールを持っている。

スクリーンショット 2017-07-19 18.20.19.png

この例では、GCPプロジェクトレベルのIAMロールはユーザにクラスタへのアクセスを与え、ネームスペースとクラスタレベルのロール割当はRBACによって細かいアクセスが与えられる。

スクリーンショット 2017-07-19 18.31.46.png

k8sはいくつかのデフォルトロールを含んでいるが、クラスタ管理者は組織の要求に合ったロールを作成することができる。

ConfigMapsのview,, edit, updateを許可するロールの例

スクリーンショット 2017-07-19 20.13.55.png

ロールを定義した後、"bindings"を通してこれらのロールをクラスタやネームスペースに割り当てる。

Bindingsはロールをユーザ、グループ、サービスカウントに関連付ける。

以下は先程作ったロール(config-editor)をbob@example.orgユーザとdevelopmentネームスペースに割り当てる例。

スクリーンショット 2017-07-19 20.31.05.png

RBACの詳細は以下を参照

https://cloud.google.com/container-engine/docs/role-based-access-control?hl=ja


イメージへへのアクセスと共有

Google Container RegistryにあるイメージはGCSにストアされている。

コンテナイメージが含まれる Cloud Storageバケットをpublicにするとイメージをpublicに公開できる。

サービスアカウントにstorage.viewrの権限を付与して、プロジェクト間でimageを共有することもできる。


ネットワーク構成

k8sはサービスの抽象化(ロードバランシングと一連のpodを跨いだサービスディスカバリ)を提供する。

ここではk8sのpodが他システムと通信するためのベストプラクティスを述べる。


同じクラスタ内での通信

クラスタ内のこのpodグループはDNSを使って発見することができる。

kube-dns(クラスタローカルのDNS)は各コンテナエンジンクラスタにデプロイされる。これはサービス名と正常なpodのipをマップするサービス。このDNSはデフォルトではサービスのクラスタIPを返す。このIPへのトラフィックはpodに跨ってロードバランスされる。このiptableはkube proxyにより自動でプログラムされる。

※VIPではなく各podのipを返すようにしたい場合は、ClusterIPフィールドを"None"にセットする。

スクリーンショット 2017-07-19 22.17.03.png


GCPからコンテナエンジンクラスタへの接続

クラスタ外からサービスに接続したい場合(ただしGCP内のprivate ipネットワークから)、internal load balancerを利用すべきである。サービスが外らからアクセス可能とするためにはNodePortを使用してサービスをexposeしないといけない。

スクリーンショット 2017-07-19 22.28.12.png

k8sは一つのポートをサービスを外部に提供する全てのクラスタノードに割り当てることができ、これをバックエンドのinternal load balancerから利用できるようにする。このinternal load balancerはクラスタと同じリージョンに配置しないといけない。kube-proxyはトラフィックをフォワードする一連のiptablesルールを最新状態に保ち、availableでないpodにはtラフィックを送らないなどの処理を行う。


クラスタ内部から外部サービスを利用

以下の3つの方法がある。


スタブドメイン

k8s 1.6以上だとkube-dnsを外部のDNSにフォワードできる。権威DNSサーバを持っている場合は有効な手段。


外部ネームサービス

外部のDNSサーバにレコードを追加する。このときDNSはCNAMEレコードを返す。件数が少ない場合は有効。


selectorなしのサービス

selectorなしでサービスを作成し、エンドポイントを手動でservice discoveryに追加する。この手法は自由度が高いが、多くの設定と長期間のメンテナンスが必要。

https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/


Internetからクラスタへのトラフィックを受ける

k8sはnetwork load balancerをGCPプロジェクト内に作成し、コンテナエンジンクラスタのノードにマップする。同じリージョン内のpodに対するトラフィックはこれでバランスされる。

スクリーンショット 2017-07-20 20.32.47.png

GoogleのグローバルHTTPロードバランサーを活用し、複数のリージョンに跨ったロードバランシングを行うことができる。

スクリーンショット 2017-07-20 20.36.18.png


Firewall

コンテナエンジンのノードはGCEのノードとしてプロビジョニングされるので、GCEインスタンスと同じようにタグによるFIrewallが適用できる。

スクリーンショット 2017-07-20 21.38.14.png


オンプレミスのデータセンターと接続

Cloud Interconnectを使ったオンプレミスのデータセンターと接続にいくつかの方法がある。


  • ダイレクトピアリング

  • キャリアインターコネクト

  • CloudVPN