:wq!

GKE ServiceをGCE HTTP Load Balancingで負荷分散する #gcpja

ども、takiponeです。

このエントリーはDocker Advent Calendar 2014Google Cloud Platform Advent Calendar 2014の2日目です。

Google Container Engine(GKE)は、Dockerクラスタの管理ソフトウェアKubernetesを簡単に扱うクラウドサービスで、Serviceは外部からのアクセスをコンテナにサーブするためのKubernetesコンポーネントです。

GKEでは、ServiceをGCE(Google Compute Engine)のNetwork Load Balancing(NLB)のターゲットとして簡単に設定できるのですが、昨日のsoundTrickerさんのエントリーにあるContent-based Load BalancingなどNLBの代わりにHTTP Load Balancing(HTTP LB)をGKE Serviceのフロントに置きたい場合もあるのかなぁと思い、検証してみました。

GKEの構成

今回は、GKEのドキュメントにあるサンプルのGuestbookアプリケーションをそのままデプロイして利用します。まずは、ダウンロードしてJSONの構成ファイルを確認します。

$ wget https://cloud.google.com/container-engine/docs/downloads/guestbook.zip
$ unzip guestbook.zip
$ ls
guestbook-controller.json     redis-master-service.json
guestbook-service.json        redis-worker-controller.json
redis-master-pod.json         redis-worker-service.json
$ 

お作法的な感じですが、GCPのProject名とゾーンを事前に設定しておきます。今回はasia-east1-cゾーンにGKEクラスタを作成してみます。

$ gcloud config set project project1
$ gcloud config set compute/zone asia-east1-c

あとはドキュメントにある手順通り、JSONの構成ファイルを読み込んでPod/ReplicationControllerとServiceをデプロイします。

$ gcloud preview container clusters create guestbook
$ gcloud preview container pods create redis-master-pod --config-file ./redis-master-pod.json
$ gcloud preview container services create --config-file ./redis-master-service.json
$ gcloud preview container replicationcontrollers create --config-file ./redis-worker-controller.json
$ gcloud preview container services create --config-file ./redis-worker-service.json
$ gcloud preview container replicationcontrollers create --config-file ./guestbook-controller.json
$ gcloud preview container services create --config-file ./guestbook-service.json
$ gcloud compute firewall-rules create guestbook-node-3000 --allow=tcp:3000     --target-tags k8s-guestbook-node

Guestbookは、データストアとしてのRedisクラスタとWeb層としてGo言語で書かれたWebアプリケーションが構成されます。今回は、Web層のService設定であるguestbook-service.jsonに合わせてHTTP LBのターゲットを設定することになります。

guestbook-service.json

{
  "apiVersion": "v1beta1",
  "kind": "Service",
  "id": "guestbook",
  "port": 3000,
  "containerPort": "http-server",
  "selector": { "name": "guestbook" },
  "createExternalLoadBalancer": true
}

3000番ポートを使用していることがわかりますね。KubernetesのServiceは、全クラスタノード(Dockerホスト)で提供ポートをListenし、Pod(Dockerコンテナ)へプロキシします。従って、HTTP LBからはクラスタの任意のノードにリクエストを転送すればOKです。

ちなみに、guestbook-service.jsonの最後のcreateExternalLoadBalancer要素がNLBを作成する定義なので、今回のHTTP LB構成ではfalseでも構いません。

GCE HTTP Load Balancingの構成

では、GCEのHTTP LBを設定していきます。

HTTP LBのターゲットはインスタンスグループとして、先に作成しておきます。Developers Consoleから[Compute Engine] - [インスタンスグループ]のグループ作成画面で[既存インスタンスを選択]から、GKEのノードインスタンスを選択します。

続いて、[Compute Engine] - [HTTP負荷分散]を選択し、新規HTTPロードバランサを作成します。

自動作成されたバックエンドサービスを設定していきます。

[編集]ボタンをクリックします。

インスタンスグループに、先ほど作成したグループを追加するため[インスタンスグループを追加]ボタンをクリックします。

[既存のインスタンスグループを選択]から、先ほどのguestbook-nodesを選択します。

インスタンスグループへの既定のポートは80なので、3000ポートに変更します。

[HTTPバックエンドポート]に「3000」と入力し、[保存]をクリックします。

バックエンドサービスの画面に戻り、ヘルスチェックを選択します。

[編集]ボタンから、ヘルスチェックの編集画面を表示します。

ヘルスチェックからアクセスするポート番号も、今回の3000番に変更します。

HTTP LBの設定に戻り、[+グローバル転送ルールを追加]から転送ルールを追加します。今回はパスなど特に設定せず、そのまま作成します。

これで準備ができました![受信トラフィック]にあるグローバルIPにアクセスしてみます。

GuestbookのWeb画面が表示されました!HTTP LBが正常に動作し、Service経由でGuestbook Podにトラフィックが転送されていることがわかります。

まとめと感想

特別な設定などなく、一般的な対応でGKE Service + HTTP LB構成を動かすことができました。せっかく高機能なHTTP LBを組み合わせているので、GKEがAutoscalerに対応すれば、負荷に応じたノード数の増減など柔軟な構成も考えられると思います。

また、NLBでも同じことが言えるのですが、GCEの*LBとGKEのServiceでトラフィックの転送処理を2回行うことになるので、グローバルIPからPodに直接転送できるGKE向けのLBがあると良いのかなぁと思いました。

余談

ところで、ここ数日Developers ConsoleのGKEの画面が息してない気がするのですが、私だけでしょうか?