Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

GCP 筆記: Set Up Network and HTTP Load Balancers

負載平衡是什麼

分配使用者的流量,避免效能問題。

Global vs Regional

Global 指有多個地區實體間的負載平衡。可以使用 IPv6 termination,Regional 則只需要 IPv4 termination。(什麼是 IPv6 termination?)

External vs Internal

外部負載平衡會在連線到你的 VPC (Virtual Private Cloud) 前分配流量,內部負載平衡則在 Google Cloud 內進行。使用外部負載平衡時,如果是 Global Load Balancing,須要使用 Premium Tier 才可以。

根據流量來源來選擇負載平衡方式

  • For HTTP and HTTPS traffic, use:
    • External HTTP(S) Load Balancing
    • Internal HTTP(S) Load Balancing
  • For TCP traffic, use:
    • TCP Proxy Load Balancing
    • Network Load Balancing
    • Internal TCP/UDP Load Balancing
  • For UDP traffic, use:
    • Network Load Balancing
    • Internal TCP/UDP Load Balancing

這次的 Lab 用的是下列兩種負載平衡

  1. Network Load Balancer
  2. HTTP(s) Load Balancer

NLB 是將 TCP 與 UDP 流量,分配到同一個地區中不同虛擬機器的負載平衡方式。

NLB 跟代理伺服器 (proxy) 不同,有以下特性:

  • 負載平衡的封包 (packets) 的來源 IP 在後端 VM 接收時不變。
  • 附載平衡的連線是由後端 VM 終止。
  • 後端 VM 直接回應到客戶端,而非透過負載平衡器。也就是所謂的伺服器直接回傳 (direct server return)。

用 GCP 設定負載平衡

先設定預設的 Zone 與 Region。

gcloud config set compute/zone us-central1-a
gcloud config set compute/region us-central1

要設定負載平衡需要有多個 VM 實體。這次的 Lab 要做三個實體,安裝 Apache,同時防火牆須允許 HTTP 流量。

gcloud compute instances create www1 \
  --image-family debian-9 \
  --image-project debian-cloud \
  --zone us-central1-a \
  --tags network-lb-tag \
  --metadata startup-script="#! /bin/bash
    sudo apt-get update
    sudo apt-get install apache2 -y
    sudo service apache2 restart
    echo '<!doctype html><html><body><h1>www1</h1></body></html>' | tee /var/www/html/index.html"
    
gcloud compute instances create www2 \
  --image-family debian-9 \
  --image-project debian-cloud \
  --zone us-central1-a \
  --tags network-lb-tag \
  --metadata startup-script="#! /bin/bash
    sudo apt-get update
    sudo apt-get install apache2 -y
    sudo service apache2 restart
    echo '<!doctype html><html><body><h1>www2</h1></body></html>' | tee /var/www/html/index.html"
    
gcloud compute instances create www3 \
  --image-family debian-9 \
  --image-project debian-cloud \
  --zone us-central1-a \
  --tags network-lb-tag \
  --metadata startup-script="#! /bin/bash
    sudo apt-get update
    sudo apt-get install apache2 -y
    sudo service apache2 restart
    echo '<!doctype html><html><body><h1>www3</h1></body></html>' | tee /var/www/html/index.html"

設定防火牆規則:

## target-tags 在前面建立實體時已經定義
gcloud compute firewall-rules create www-firewall-network-lb \
    --target-tags network-lb-tag --allow tcp:80

完成後用 gcloud compute instances list 確認三個實體的外部 IP。

gcloud compute instances list

## 結果
NAME  ZONE           MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP     STATUS
www1  us-central1-a  n1-standard-1               10.128.0.2   xxx.xxx.xx.149   RUNNING
www2  us-central1-a  n1-standard-1               10.128.0.3   xxx.xxx.xxx.72   RUNNING
www3  us-central1-a  n1-standard-1               10.128.0.4   xxx.xxx.xxx.31   RUNNING

curl EXTERNAL_IP 確認是否能夠存取。

調校負載平衡

首先,需要先為負載平衡器取得一個靜態 IP。

gcloud compute addresses create network-lb-ip-1 \
 --region us-central1

新增一個 legacy HTTP health check (?) 服務。

gcloud compute http-health-checks create basic-check

在同一個地區設定目標集區 (target pool),並套用前一步驟新增的 Health Check 服務。並將前面建立的實體加入目標集區中。

gcloud compute target-pools create www-pool \
    --region us-central1 --http-health-check basic-check
gcloud compute target-pools add-instances www-pool \
    --instances www1,www2,www3

最後設定轉接 (forwarding) 規則:

gcloud compute forwarding-rules create www-rule \
    --region us-central1 \
    --ports 80 \
    --address network-lb-ip-1 \
    --target-pool www-pool

接著開始測試負載平衡器分流的狀況。

gcloud compute forwarding-rules describe www-rule --region us-central1

## 結果
IPAddress: xxx.xxx.xxx.xxx ## 負載平衡器 IP
IPProtocol: TCP 
creationTimestamp: '2021-06-04T06:12:27.936-07:00'
description: ''
fingerprint: 
id: 
## 下略

while true; do curl -m1 IPAddress; done # 帶入負載平衡器 IP

## 結果
<!doctype html><html><body><h1>www3</h1></body></html>
<!doctype html><html><body><h1>www3</h1></body></html>
<!doctype html><html><body><h1>www3</h1></body></html>
<!doctype html><html><body><h1>www3</h1></body></html>
<!doctype html><html><body><h1>www1</h1></body></html>
<!doctype html><html><body><h1>www3</h1></body></html>
<!doctype html><html><body><h1>www2</h1></body></html>
<!doctype html><html><body><h1>www1</h1></body></html>
<!doctype html><html><body><h1>www3</h1></body></html>
<!doctype html><html><body><h1>www1</h1></body></html>
<!doctype html><html><body><h1>www3</h1></body></html>
<!doctype html><html><body><h1>www3</h1></body></html>

建立 HTTP(s) 負載平衡

HTTP(s) 的負載平衡機制,是透過 Google Front End (GFE) 實作。GFE 部署於全世界,並使用 Google 的全球網路運作。使用者可以設定讓部分的 URL 路由傳送 (route) 至特定虛擬主機實體,將另一部份 URL 路由傳送到另一個實體。

要設定 HTTP(s) 負載平衡時,需要將 VM 設在同一個實體群組中。

建立實體群組範本

首先需要用 gcloud compute instance-templates create 建立負載平衡實體群組的範本。

gcloud compute instance-templates create lb-backend-template \
   --region=us-central1 \
   --network=default \
   --subnet=default \
   --tags=allow-health-check \
   --image-family=debian-9 \
   --image-project=debian-cloud \
   --metadata=startup-script='#! /bin/bash
     apt-get update
     apt-get install apache2 -y
     a2ensite default-ssl
     a2enmod ssl
     vm_hostname="$(curl -H "Metadata-Flavor:Google" \
     http://169.254.169.254/computeMetadata/v1/instance/name)"
     echo "Page served from: $vm_hostname" | \
     tee /var/www/html/index.html
     systemctl restart apache2'

更換實體群組用的範本

在進行挑戰的時候,發現實體群組的設定可能有問題,所以想要變更。GCP 並不能直接編輯原本的範本,因此要另外建立。可以透過以下指令更換使用的範本。

gcloud compute instance-groups managed set-instance-template [範本名稱]

建立受管理實體

接著用 gcloud compute instance-groups managed create 建立受管理的實體。這個例子中建立了兩個實體。

gcloud compute instance-groups managed create lb-backend-group \
   --template=lb-backend-template --size=2 --zone=us-central1-a

設定名為 fw-allow-health-check 的防火牆規則,允許來自 Health Check 服務的輸入流量 (130.211.0.0/12 與 35.191.0.0/16),接著用範本中定義的 allow-health-check 標籤來辨識套用此規則的實體。

gcloud compute firewall-rules create fw-allow-health-check \
    --network=default \
    --action=allow \
    --direction=ingress \
    --source-ranges=130.211.0.0/22,35.191.0.0/16 \
    --target-tags=allow-health-check \
    --rules=tcp:80

設定可存取的外部 IP。

gcloud compute addresses create lb-ipv4-1 \
    --ip-version=IPV4 \
    --global

## 取得外部 IP
gcloud compute addresses describe lb-ipv4-1 \
    --format="get(address)" \
    --global

建立 HTTP Health Check 的規則

gcloud compute health-checks create http http-basic-check \
    --port 80
    
# 結果
NAME              PROTOCOL
http-basic-check  HTTP

建立後端服務。

gcloud compute backend-services create web-backend-service \
    --protocol=HTTP \
    --port-name=http \
    --health-checks=http-basic-check \
    --global

# 結果
NAME                 BACKENDS  PROTOCOL
web-backend-service            HTTP

將實體加入後端服務中。

gcloud compute backend-services add-backend web-backend-service \
    --instance-group=lb-backend-group \
    --instance-group-zone=us-central1-a \
    --global

建立對應的路由轉送規則 web-map-http

gcloud compute url-maps create web-map-http \
    --default-service web-backend-service
    
# 結果
NAME          DEFAULT_SERVICE
web-map-http  backendServices/web-backend-service

建立目標 HTTP Proxy 規則 http-lb-proxy

gcloud compute target-http-proxies create http-lb-proxy \
    --url-map web-map-http

建立全域轉送規則,將存取 lb-ipv4-1 的流量路由傳送到 Proxy 中。

gcloud compute forwarding-rules create http-content-rule \
        --address=lb-ipv4-1\
        --global \
        --target-http-proxy=http-lb-proxy \
        --ports=80

可以從 GCP 的主控版,前往 Network Services > Load Balancing,便可以看到剛才建立的負載平衡規則 web-map-http,接著可以看到 Backends 的健康狀態。

如果確認是 Healthy 的話,就可以在瀏覽器存取剛才的靜態 IP,接著會看到 Page served from: lb-backend-group-xxxx 的字樣,可以重新整理看到負載平衡的狀態。

Challenge Lab 解答

Eric Chuang
Eric Chuang

正職是廣告行銷人員,因為 Google Tag Manager 的關係開始踏入網站製作的領域,進一步把 WordPress 當成 PHP + HTML + CSS + JavaScript 的學習教材。此外,因為工作的關係,曾經用 Automattic 的 Underscores (_s) 替客戶與公司官網進行全客製化佈景主題開發。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料