目次
はじめまして、昨年8月よりgrasysにJoinしました大川と申します。
以後お見知り置きを。
構成要素が多く地味に作るのが面倒なHTTP(S) 負荷分散について、シンプルな構成をterraformで作る方法をドキュメントを追>いつつゆるく解説させていただきます。
- GCPを触ったことがある
- terraformを触ったことがある
- httplb作るのメンドい
といった方にとって有用な情報となれば幸いです。
前提知識
GCP HTTP(S) 負荷分散
Google社が提供するロードバランサーです。
https://cloud.google.com/compute/docs/load-balancing/http/?hl=ja
Google Cloud (GCP) Platform(GCP)の HTTP(S) 負荷分散は、インスタンスの HTTP(S) リクエストに対してグローバルな負荷分散を提供します。あるセットのインスタンスに一部の URL をルーティングし、別のインスタンスには別の URL をルーティングする URL ルールを設定できます。
–公式ドキュメントより
HTTPS(S)ロードバランサは下記のように複数のコンポーネントから構成されています。 今回はコンポーネントごとにバックエンドよりフロントに向けて作っていきます。
terraform
hashicorp社が公開しているオーケストレーションツールです。
クラウドや仮想基盤、CDNなど多岐にわたる項目をコードベースで管理することができ、冪等性を担保することが出来ます。 GCPやAWSをはじめとするメジャーなCloud Providerに対応しています。
作ってみる
それでは、実際にHTTP(S) 負荷分散を作ってみます。
まずはバックエンドサービスの配下から作り始めます。
- バックエンド サービス
https://cloud.google.com/compute/docs/load-balancing/http/backend-service?authuser=19&hl=ja
HTTP(S) 負荷分散バックエンド サービスはバックエンドを管理するための集中管理サービスであり、ユーザー リクエストを処理するインスタンスを管理します。負荷分散サービスは、バックエンド サービスにリクエストがルーティングされるように設定します。
1. Backendの作成
ドキュメントより、概要図右端にあるインスタンスグループから作成します。
各バックエンドは、1 つのインスタンス グループと、追加の提供容量メタデータから構成されます。
1.1. Instance Groupに所属するインスタンスの作成
インスタンスグループに所属するインスタンスを作成します。
今回はhttpでアクセスするwebサーバを作成します。
※サーバ内容については割愛します。
https://www.terraform.io/docs/providers/google/r/compute_instance.html
resource "google_compute_instance" "webserver" {
name = "webserver"
machine_type = "n1-standard-1"
zone = "asia-northeast1-a"
tags = ["web"]
boot_disk {
initialize_params {
image = "centos-7-v20180815"
size = "10"
type = "pd-standard"
}
}
network_interface {
network = "default"
access_config {
// Ephemeral IP
}
}
metadata {
foo = "server-web"
}
service_account {
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
}
}
1.2. Instance Groupの作成
次に、1.1で作成したInstanceが所属するInstance Groupを作成します。
code
https://www.terraform.io/docs/providers/google/r/compute_instance_group.html
resource "google_compute_instance_group" "webserver" {
name = "webserver"
description = "webserver instance group"
instances = [
"${google_compute_instance.webserver.self_link}",
]
named_port {
name = "http"
port = "80"
}
zone = "asia-northeast1-a"
}
2. Backend serviceの作成
次に、Backendを管理するBackend serviceを作成します。
バックエンド サービスによって、受信トラフィックが 1 つ以上の関連バックエンドに振り向けられます。
2.1. health check
Backend service作成時に要求されるhealth checkを先に作成します。
ここではSSLはLBで終端し、webserverへはhttpでアクセスするため http_health_checkを指定します。
health checkとして一定間隔でアクセスするため、比較的軽いページを選択するか、status check専用のページを作ると良いでしょう。
document
https://cloud.google.com/compute/docs/load-balancing/health-checks?hl=ja
各バックエンド サービスは、使用可能なインスタンスに対して実行されるヘルスチェックも指定します。
code
https://www.terraform.io/docs/providers/google/r/compute_http_health_check.html
resource "google_compute_http_health_check" "webserver" {
name = "webserver-health-check"
request_path = "/health_check"
timeout_sec = 5
check_interval_sec = 5
healthy_threshold = 2
unhealthy_threshold = 2
}
2.2. Backend service
Backend,health-checkの作成が終わりましたので、backend serviceを作成します。backend``health_checks
の項目にはそれぞれ先に作成したリソースのself_linkを設定します。
code
https://www.terraform.io/docs/providers/google/r/compute_backend_service.html
resource "google_compute_backend_service" "webserver-backend" {
name = "webserver-backend"
description = "webserver-backend"
port_name = "http"
protocol = "HTTP"
timeout_sec = 10
enable_cdn = false
backend {
group = "${google_compute_instance_group.webserver.self_link}"
}
health_checks = ["${google_compute_http_health_check.webserver.self_link}"]
}
2.3 Backend用firewall rule
backendとhealth_checksを設定しただけの状態ではまだfirewall ruleが存在しないため、health-checkが全てInstanceに届かず失敗する状態です。
そこで、health-check用のIPアドレスを許可するfirewall ruleを作成します。
document
HTTP(S)、SSL プロキシ、TCP プロキシまたは内部負荷分散でヘルスチェックを使用した場合、ヘルスチェック プローブを範囲 130.211.0.0/22 と 35.191.0.0/16 のアドレスから受信します。これらの接続を、負荷分散されるすべてのインスタンスに許可するファイアウォール ルールを作成する必要があります。
code
https://www.terraform.io/docs/providers/google/r/compute_firewall.html
resource "google_compute_firewall" "webserver" {
name = "backend-http-server"
network = "default"
allow {
protocol = "tcp"
ports = [
"80", # http
]
}
source_ranges = [
"130.211.0.0/22", # Google LB
"35.191.0.0/16", # Google LB
]
target_tags = [
"web",
]
}
ここまでで、Backend serviceの作成が完了しました。
ようやく半分です。
3. Url Map
URL マップを作成します。
URLベースでバックエンドサービスを指定できる機能で、アクセス頻度や負荷の高い処理は別ディレクトリに切り出しバックエンドサーバを分けて負荷の影響を昨日単位にとどめるといった運用も可能です。
最低でも一つ path_rule が必要なため、ここでは /
に対するルールを作成します。
document
https://cloud.google.com/compute/docs/load-balancing/http/url-map?authuser=19&hl=ja
Compute Engine の HTTP(S)負荷分散を使用すると、受信 URL に基づいてトラフィックを異なるインスタンスに転送できます。たとえば、http://www.example.com/audio へのリクエストは音声ファイル配信用に設定されているインスタンスを含むバックエンド サービスに送信し、http://www.example.com/video へのリクエストは動画ファイル配信用に設定されているインスタンスを含む別のバックエンド サービスに送信することができます。
code
https://www.terraform.io/docs/providers/google/r/compute_url_map.html
resource "google_compute_url_map" "website" {
name = "website"
description = "a description"
default_service = "${google_compute_backend_service.webserver-backend.self_link}"
host_rule {
hosts = ["example.grasys.io"]
path_matcher = "allpaths"
}
path_matcher {
name = "allpaths"
default_service = "${google_compute_backend_service.webserver-backend.self_link}"
path_rule {
paths = ["/"]
service = "${google_compute_backend_service.webserver-backend.self_link}"
}
}
}
4. Target Proxy
プロトコルとURLマップを指定します。
document
https://cloud.google.com/compute/docs/load-balancing/http/target-proxies?authuser=19&hl=ja
ターゲット プロキシはグローバル転送ルールによって参照されます。HTTP(S) 負荷分散の場合、プロキシは着信リクエストを URL マップにルーティングします。SSL プロキシと TCP プロキシの負荷分散の場合、ターゲット プロキシは着信リクエストを直接バックエンド サービスにルーティングします。
4.1. SSL certificate
ここではhttpsのルールを作成するため、SSL証明書を登録します。
証明書は中間証明書を連結して登録します。
nginxを運用されている方にはおなじみかと思います。
document
https://cloud.google.com/compute/docs/load-balancing/http/ssl-certificates?authuser=19&hl=ja
HTTPS または SSL 負荷分散を使用するには、ロードバランサのターゲット プロキシで使用できる SSL 証明書を少なくとも 1 つ作成する必要があります。最大 10 個の SSL 証明書を使用してターゲット プロキシを設定できます。SSL 証明書ごとに、まず SSL 証明書リソースを作成します。SSL 証明書リソースには証明書情報が含まれています。
code
https://www.terraform.io/docs/providers/google/r/compute_ssl_certificate.html
resource "google_compute_ssl_certificate" "website-20180815" {
name = "website-20180815"
description = "a description"
private_key = "${file("path/to/private.key")}"
certificate = "${file("path/to/certificate.crt")}"
}
4.2. target https proxy
先立って作成したurl_mapとssl_certificateを設定します。
code
https://www.terraform.io/docs/providers/google/r/compute_target_https_proxy.html
resource "google_compute_target_https_proxy" "website" {
name = "website"
description = "a description"
url_map = "${google_compute_url_map.website.self_link}"
ssl_certificates = ["${google_compute_ssl_certificate.website-20180815.self_link}"]
}
5. Global Forwarding Rule
最後にグローバル転送ルールを設定します。
5.1. global address
HTTP(S) 負荷分散が受け付けるIPアドレスを設定します。
静的外部IPアドレスのうち、グローバル静的外部IPアドレスが必要になります。
document
https://cloud.google.com/compute/docs/ip-addresses/#reservedaddress
グローバル静的外部 IP アドレスは、グローバル負荷分散に使用されるグローバル転送ルールでのみ使用できます。グローバル IP アドレスをリージョン IP アドレスまたはゾーンリソースに割り当てることはできません。
code
https://www.terraform.io/docs/providers/google/d/datasource_compute_global_address.html
resource "google_compute_global_address" "website" {
name = "website"
}
5.2. global_forwarding_rule
作成されたグローバル静的IPアドレスとURLマップを設定します。
これによりInternetから受け付けるIPアドレスとその後の経路の紐付けを行えます。
document
https://cloud.google.com/compute/docs/load-balancing/http/global-forwarding-rules?authuser=19&hl=ja
グローバル転送ルールは、自分のサイトの DNS レコードで使用できる単一のグローバル IPv4 または IPv6 アドレスを提供します。特定のプロキシについて複数の転送ルールを使用することができるため、IPv4 トラフィック用に 1 つ、IPv6 トラフィック用に 1 つのルールを設定することができます。
code
https://www.terraform.io/docs/providers/google/r/compute_global_forwarding_rule.html
resource "google_compute_global_forwarding_rule" "website" {
name = "website"
depends_on = [
"google_compute_target_https_proxy.website",
"google_compute_global_address.website"
]
target = "${google_compute_target_https_proxy.website.self_link}"
ip_protocol = "TCP"
port_range = "443"
ip_address = "${google_compute_global_address.website.address}"
}
まとめ
だいぶ駆け足となってしまいましたが、以上でHTTP(S)負荷分散を作成できたかと思います。
こうして紐解いてみると案外多数の要素で構成されていることがわかるかと思います。 機能をひとつひとつ読み解くことで理解の一助になりますと幸いです。
株式会社grasys(グラシス)は、技術が好きで一緒に夢中になれる仲間を募集しています。
grasysは、大規模・高負荷・高集積・高密度なシステムを多く扱っているITインフラの会社です。Google Cloud (GCP)、Amazon Web Services (AWS)、Microsoft Azureの最先端技術を活用してクラウドインフラやデータ分析基盤など、ITシステムの重要な基盤を設計・構築し、改善を続けながら運用しています。
お客様の課題解決をしながら技術を広げたい方、攻めのインフラ技術を習得したい方、とことん技術を追求したい方にとって素晴らしい環境が、grasysにはあります。
お気軽にご連絡ください。