最近在弄GCP上面的web server, 遇到一些有趣的事.

一般來說我們會需要load balancer做幾件事情, 導向不同的服務到不同的機器, http轉https...等等.

GCP的load balancer概念上分成三部分, frontend-service, url-maps(Host and path rules), 以及backend-service.

backend-service裡面可以套多個instance-group, instance-group基本上就是一個VM set, 加上auto-scaling的概念的群組.

而使用letsencrypt的時候, 躲在load balancer背後的機器要走DNS-01會有點麻煩, 我的case是domain provider不support, DNS也不是我管的到的.

所以只能走HTTP-01, 那就必須允許let's encrypt取得http/.well-known/acme-challenge路徑的能力. 所以frontend-services會需要做成兩個, HTTPS跟HTTP.

這時候就會遇到一個狀況, 現在我只有兩台機器, 只有一個instance group(用unmanaged mode, 表示不讓他auto-scaling).

如果我在url-maps那邊設定/.well-known/acme-challenge去對到後面backend-service, 那當我在其中一台機器跑dehydrated的時候, 怎麼知道會取到對的機器. 總不能運氣運氣50%吧.

所以我後來多開了一個unmanaged instance-group, 裡面就一台最簡單的機器, dehydrated, 設成另一個backend-service, /.well-known/acme-challenge只走這個backend-service, 然後寫了一段scrpit在之前兩台機器中的一台. 讓他時間一到就啟動剛剛的instance, 跑dehydrated, 更新憑證, 然後打完收工關機.

另外的話就是http轉https, 這個也是要在url-map那邊做掉.

所以總體來說, 就是會設定兩個load balancer, 一個http, 另一個https, 沒錯GCP就是這麼奇妙, 要兩個load balancer.

https那個簡單, url-maps也就預設就過了.

http那個就比較麻煩一點, url-maps那邊要挑進階, 然後要設成兩個:

兩個url-maps

然後像下圖一樣, 一個設定成301轉:

http轉https

一個給單獨要跑dehydrated的backend-service:

dehydrated使用

然後在不是跑dehydrated的機器的其中一台設個crontab job, 跑下面的scrpit.

# 開機
sudo gcloud compute instances start dehydrated的機器 --zone=跑dehydrated的機器的Zone

# 取憑證
sudo gcloud compute ssh dehydrated的機器 --command="sudo dehydrated -c" --zone=跑dehydrated的機器的Zone

# 上傳憑證到HTTPS load balancer
sudo gcloud compute ssh dehydrated的機器 --command="sudo gcloud compute ssl-certificates create 憑證名稱-$(date +%Y-%m-%d) --certificate /etc/dehydrated/certs/你的domain/fullchain.pem --private-key /etc/dehydrated/certs/你的domain/privkey.pem" --zone=跑dehydrated的機器的Zone

# 更新HTTPS load balancer的憑證
sudo gcloud compute ssh dehydrated的機器 --command="sudo gcloud compute target-https-proxies update 你的proxy --ssl-certificates 憑證名稱-$(date +%Y-%m-%d)" --zone=LoadBalancer的區域

# 關機
sudo gcloud compute instances stop dehydrated的機器 --zone=跑dehydrated的機器的Zone

如果不知道你的proxy, 可以跑gcloud compute target-https-proxies list去看.

# start get ssl instance
sudo gcloud compute instances start {the-instance-that-run-dehydrated} --zone={the-instance-located}

# run dehydrated in the instance
sudo gcloud compute ssh {the-instance-that-run-dehydrated} --command="sudo dehydrated -c" --zone={the-instance-located}

# generate certificate to gcp
# certificate name with date string for distinguishable
sudo gcloud compute ssh {the-instance-that-run-dehydrated} --command="sudo gcloud compute ssl-certificates create cert-name-$(date +%Y-%m-%d) --certificate /etc/dehydrated/certs/{your-domain}/fullchain.pem --private-key /etc/dehydrated/certs/{your-domain}/privkey.pem" --zone={the-instance-located}

# update the certificate in gcp load balancer
# if dont know target-https-proxies, you can run
# gcloud compute target-https-proxies list
# to check it
sudo gcloud compute ssh {the-instance-that-run-dehydrated} --command="sudo gcloud compute target-https-proxies update {your-https-proxy} --ssl-certificates cert-name-$(date +%Y-%m-%d)" --zone={the-https-zone}

# shutdown instance
sudo gcloud compute instances stop {the-instance-that-run-dehydrated} --zone={the-instance-located}


Comments

comments powered by Disqus