GCP Autoscalerで遊ぶ
日曜は犬と留守番をしていたので、時間をもてあましたので犬とオートスケールで遊ぶことにした
GCPのオートスケール機能Autoscalerの正式版は去年の9月ころ出たようです。
ウォームアップ不要ってところがAWSとの差別化ですね。5分以内に1000台一気に増やせるってすごくて怖い・・w
SSL終端できないとかもありますがが
まだマネコンにメニューもなくAPIのみの提供で、AWSの最初の頃のAutoscaleみたいな感じ、、って思ってたらインスタンスグループなるところにあった!
AWSのAutoscalingGroupのような感じですねきっと。
HTTPロードバランサを使ったAutoscalerで設定するものは以下
- Global IP(HTTPロードバランサで使う場合タイプをグローバルにする)
- Image File(オートスケールする際の作られるサーバーの元イメージ、これをもとにサーバーが増えていく)
- Instance Template(マシンタイプ、Image File、ディスクタイプ、ディスクサイズ、所属ネットワークなどのインスタンスにまつわる情報をまとめたもの)
- Instance Group(Instance Template、ゾーン、オートスケールのオンオフや閾値設定)
※この下はどちらかというとHTTPロードバランサの構成要素
- Health Check(URLパス、ポート、間隔、タイムアウト)
- Target Proxy(URLマップ、プロキシタイプ)
- Global Transfer Rule(外部IP、プロトコル、Target Proxy)
- Backend Service(リッスンプロトコル、タイムアウト値、バックエンドとなるInstance Group、Health Check)
- HTTP Load Balancer(Backend Service、Global Transfer Rule)
項目多いし文字だとわかりづらいので図にしてみる、が、やっぱわかりはずらい。。 ただこういう機能なんでこんなもんかと
ぽちぽちは大変なので、Terraformでやってみる
(テンプレは↓の方に張ったので変数を変えてよしなに試してみてもらえるとうれしい)
グローバルIPを作る場合、画面からだと以下のようにタイプを地域かGlobalかを選ぶところがある(どちらもグローバルIPではあるが、HTTPロードバランサにはグローバル指定のIPしか使えない)
※多分リージョン跨ぎのロードバランシングの為だと思うが今回は割愛
Terraformで使うResourceは地域IPの場合"google_compute_address"でグローバルIPの場合"google_compute_global_address"と分かれていて最初オプションで指定するものと勝手に思ってたから迷った><
AutoScalerどうだったか?
あたりまえだがAutoScaleしたw
インスタンス台数の最小値、最大値は設定できます。
とりあえず最小値4台、最大値16台、チェックはCPU50%とかで
InstanceGroup単位でCPU使用率を見ますが、4台のうち2台を100%にしました。
予想は行っても60%くらいかと思いきやグラフは一瞬80%くらい行きました。
結果的に無事インスタンスがAutoでScaleしましたがInsntance Groupのメトリクスがどういう計算になってるのか
最初の4台状態↓
CPU負荷かけて増えた状態。
10台に増えた。
AWSだと1度の増加台数を決めれるけどGCPはよしなに増やすっぽい。
だからスパイクにも強いってことだろう。最大数は決めれるけど
10台に増えてる↓
Instance Groupにある初期遅延時間(最初のヘルスチェックまでの時間)がデフォは300秒だけどTerraformだと変えられないっぽい?(いやどっかにある気がするがInstanceGroupとAutoscalerにはなかった。。)
なので多分ですが初期遅延時間(300s)+Cool Down(180s)の8分とインターバルのタイミングなので8分強。
CPU負荷を止めて、ぼーっとF5押しながらストップウォッチ見てたら10分弱くらいで減っていった↓
Cooldown値はあるのですが、AWSでは出来た一度に増設する台数とかきめ細かい設定はGCPはない(?)っぽいですね。
あと、LBのメトリクスがそもそも少ないw
あと、MultiZoneのAutoScaleはできない??これもAWSではできたけどもしできないなら痛い、
ほんとに出来ないかは不明、、Zoneの最小単位となるBackendを同じパス(/とか)で複数選択出来ればいいのだが、"URL MAP"設定でBackendを複数指定する場合、同じパス名でマップすると怒られる。なので同じパスにBackendを複数設定が出来なそうと思ったが違うかなぁ、、来週GCPUGおじゃまするので聞いてみよ。
※自己解決しました。HTTPLBのバランシング範囲はRegionでNWLBのバランシング範囲はZoneなのですね。
ちなみにTerraformのVarsとTemplateはこちら
構成としては
※ GCPのCredentialファイルは各自環境のものをカレントに置いといてね
### GCP project_name = "test-project01" region_asia = "asia-east1" zone_asia1 = "asia-east1-a" zone_asia2 = "asia-east1-b" ### GCE server_name = "test-op01" machine_type = "f1-micro" image_name = "image-1" ### NW http_port = "80" ssh_port = "22" any_port = "0.0.0.0/0" kyoten_ip = "xx.xx.xx.xx" ip_op = "test-opip01" ip_lb = "test-lbip01" fw_name = "test-allow-web"
## vars variable "project_name" {} variable "region_asia" {} variable "zone_asia1" {} variable "zone_asia2" {} variable "server_name" {} variable "machine_type" {} variable "image_name" {} variable "any_port" {} variable "http_port" {} variable "ssh_port" {} variable "kyoten_ip" {} variable "ip_op" {} variable "fw_name" {} variable "ip_lb" {} provider "google" { credentials = "${file("account.json")}" project = "${var.project_name}" region = "${var.region_asia}" } ## Global IP Address resource "google_compute_address" "default1" { name = "${var.ip_op}" } resource "google_compute_global_address" "default1" { name = "${var.ip_lb}" } ## Instance resource "google_compute_instance" "default1" { name = "${var.server_name}" machine_type = "${var.machine_type}" zone = "${var.zone_asia1}" disk { image = "${var.image_name}" } network_interface { network = "${google_compute_network.default.name}" access_config { nat_ip = "${google_compute_address.default1.address}" } } } ## Firewall resource "google_compute_firewall" "default1" { name = "${var.fw_name}" network = "${google_compute_network.default.name}" allow { protocol = "tcp" ports = ["${var.http_port}"] } source_ranges = ["${var.any_port}"] source_tags = ["test-any"] } resource "google_compute_firewall" "default2" { name = "test-allow-ssh1" network = "${google_compute_network.default.name}" allow { protocol = "tcp" ports = ["${var.ssh_port}"] } source_ranges = ["10.10.0.0/16"] source_tags = ["op01"] } resource "google_compute_firewall" "default3" { name = "test-allow-ssh2" network = "${google_compute_network.default.name}" allow { protocol = "tcp" ports = ["${var.ssh_port}"] } source_ranges = ["${var.kyoten_ip}"] source_tags = ["test-office"] } ## Network Address resource "google_compute_network" "default" { name = "test-nw" ipv4_range = "10.10.0.0/16" } ### LB ## HTTP Health Check resource "google_compute_http_health_check" "default" { name = "test-check" request_path = "/" check_interval_sec = 5 timeout_sec = 5 } ## TargetPool resource "google_compute_target_pool" "default" { name = "test-pool" health_checks = ["${google_compute_http_health_check.default.name}"] region = "${var.region_asia}" } ### AutoScaler ## Instance Template resource "google_compute_instance_template" "default" { name = "test-template" machine_type = "f1-micro" disk { source_image = "image-1" } network_interface { network = "${google_compute_network.default.name}" } } ## Instance Group resource "google_compute_instance_group_manager" "default1" { name = "test-instansgrp1" instance_template = "${google_compute_instance_template.default.self_link}" target_pools = ["${google_compute_target_pool.default.self_link}"] base_instance_name = "test-svr" zone = "${var.zone_asia1}" } ## Autoscaler resource "google_compute_autoscaler" "default1" { name = "test-as1" zone = "${var.zone_asia1}" target = "${google_compute_instance_group_manager.default1.self_link}" autoscaling_policy = { max_replicas = 16 min_replicas = 4 cooldown_period = 180 cpu_utilization = { target = 0.5 } } } resource "google_compute_backend_service" "default1" { name = "test-backend1" description = "Hello World 1234" port_name = "http" protocol = "HTTP" timeout_sec = 10 region = "${var.region_asia}" backend { group = "${google_compute_instance_group_manager.default1.instance_group}" } health_checks = ["${google_compute_http_health_check.default.self_link}"] } ### LB resource "google_compute_target_http_proxy" "default" { name = "test-proxy" description = "a description" url_map = "${google_compute_url_map.default.self_link}" } resource "google_compute_url_map" "default" { name = "test-urlmap" description = "a description" default_service = "${google_compute_backend_service.default1.self_link}" host_rule { hosts = ["mysite.com"] path_matcher = "allpaths" } path_matcher { default_service = "${google_compute_backend_service.default1.self_link}" name = "allpaths" path_rule { paths = ["/*"] service = "${google_compute_backend_service.default1.self_link}" } } } ## Forwarding Rule resource "google_compute_global_forwarding_rule" "default" { name = "test-forward" target = "${google_compute_target_http_proxy.default.self_link}" ip_address = "${google_compute_global_address.default1.address}" port_range = "${var.http_port}" }
ちなみにAWSでオートスケール
AWS側のイメージとしては以下は多少参考になるかも。本番実装までしたので。ってか3年前かぁ、、古すぎる・・
www.slideshare.net