gceでふつうのLB構成

[前回記事](https://qiita.com/holy_road_ss/items/d83285a641a474a05dd0)の2.のほうをやってる前提。
(VPCとサブネットを自前で作ってあると説明が楽というだけの話ではありますが)

## 最初に
この記事の通りにやらなかったら疎通できないとかそういうことはありません。
あと筆者はSS取るのをものすごく面倒くさがるためstringオンリーのストロングスタイルです。

## やること
プライベートサブネットに浮かぶwebサーバ(外部IPなし)にLB通してhttp(s)アクセスしたい。したくてたまらない。
LB種類はHTTP(s)負荷分散。
GKEの場合だと色々と変わってくるようなのでそれはまたやる時にということで。

## ひつようなもの
・どめいん(主にGCP発行SSL証明書利用のため)
・インターネッツに出ていないwebサーバ1つ
・webサーバ操作用のインターネッツに出ている踏み台サーバ1つ
・NATサーバ(当該記事では話を簡単にするためにCloud NAT使います)

## どめいん(Cloud DNS他)
GCPでラクチンにSSL証明書をLBにぶちこむためにはドメイン必要なので、まずその設定をします。
※GCPのSSL証明書はLet’s Encryptなので、OV以上の認証がポリシーとして要る場合は別なところで取得する必要有

### どうせだしドメインもgoogleで取ろうかな？
なんやCloud DNSで取れへんのかい、って別所で言ったら教えてもらいました。
[google domains](https://domains.google/intl/ja_jp/)で取るのがよろしいかと。
DNSSECも使えるしね。

### ドメインAWSのRoute53なんやが
サブドメ移譲しましょう。
Route53管理のドメインがbar.comだとします。

まず、適当にサブドメ決めます。foo.bar.comとしましょう。
Cloud DNSでゾーン名を決めたら(これは特に名前解決に影響しないので、わかりやすい名前にしときましょう)、DNS名をfoo.bar.comと設定します。DNSSECはRoute53で取ったドメインの場合キーの設定が出来ないので恐らくﾑﾘﾝﾇ
なのでオフにします。

作成して詳細見てTTL300秒くらいにしてNSレコードの値コピったら、今度はRoute53側のbar.comのレコードセットにfoo.bar.comのNSレコードを作成、値はさっきコピーしたgcp側NSレコードの値をペーストします。変な改行とかスペース入ってたら直しておきましょう。

あとはLBの設定終わるころにはなんとかなってます。

### お名前です
ぐぐれ。つか↑の手順とそんなかわらんて

## 踏み台サーバ
今回疎通したいwebサーバはインターネット上におらんので、初期状態だと誰も触れない電脳の孤島です。
なので仲介をしてくれるサーバを1つ立てます。
といっても、前回記事で認証鍵設定しているならやることはほぼなく、

1. 外部IPありでインスタンスを1つ作る。ファイアウォールルールは前回記事同様自IPだけを通すようにしておく。
2. ssh接続したら、カレントユーザ(ログインユーザ)のhomeディレクトリ下の`.ssh`の中に秘密鍵を放り込む。

で終わります。秘密鍵の設置の仕方はGCE特有のものではないので別途ぐぐってください。
めっちゃ雑にいうと、コピペして権限を0600にすれば終わります。

## Cloud NAT
電脳の孤島がインターネットとよろしくやるためにはやっぱり仲介役が必要です。
先ほどの踏み台サーバはssh専用と捉えましょう。
で、前まではGCPでNAT構成取ろうとすると自前構築の必要があったようですが、今はマネージドサービスがあります。
もちろん、自前で構築してもかまいません。[公式ドキュメントにあるくらいです](https://cloud.google.com/vpc/docs/special-configurations#multiple-natgateways)

Cloud NATの設定は迷うところはないとは思いますが、
リージョンはwebサーバと同じ、
cloud routerが必須なので新規作成する必要がある(NAT設定画面から作れます)
IP範囲はカスタムにしてwebサーバを置くサブネットを設定
※GKEの場合セカンダリを使う必要があるようですが今回は無視

設定をミスっていなければ作成した瞬間疎通します。
注意点としては、外部IPが振られているインスタンスの場合、対象サブネット内にあってもNAT経由で通信しないことくらいですかね。

## webサーバ
ファイアウォールルールでさっき作った踏み台サーバのIPもしくはタグからのSSH接続とhttp接続(80)を許可しておきます。
作成時、外部IPはなしで。
また、nginx導入の説明を少しでも短くしたいがためにcentos8を選びます。

起動次第、踏み台サーバからssh接続します。
Cloud NATの設定が済んでいれば既にインターネットに出れる状態になっているかと思うので、疎通の邪魔になる可能性があるものを殺してnginxをぶちこみます。

具体的には

```bash
sudo su -
setenforce 0
systemctl stop firewalld
dnf -y update
dnf install -y nginx
systemctl start nginx
```
この脳ミソ使ってない感あふれるコマンドをたたき込みましょう。
どうせ疎通終わったら殺すし。

一応補足しますと、これstop/startしたりrebootしたりするとSELINUXとfirewalldは復活します。
運用時はポリシーにあわせて切るなり設定するなりしましょう。
あとnginxはもしちゃんと運用するのであれば最低限server_tokensをoffるのと、keepaliveの設定をGCP推奨値にしときましょう。
[参考1(公式)](https://cloud.google.com/load-balancing/docs/https/#timeouts_and_retries)
[参考2](https://blog.percy.io/tuning-nginx-behind-google-cloud-platform-http-s-load-balancer-305982ddb340)
SSLがらみの設定は当該記事ではLB-サーバ間はHTTPで通信するので考えません。

ここまでやったら踏み台からこのwebサーバの内部IPをcurlでぶったたき、nginxの初期ページが返却されるか確認しておきます。
返ってこなかった場合何かミスってるので見直しましょう。
レスポンスがやけに遅い場合は大体ファイアウォールルールをミスってます。

## ヘルスチェック用の穴をあけておく
LBからwebサーバにヘルスチェックを飛ばすためのポートに対してアクセス許可を出します。
順番前後しても問題はありませんが、事前に開けておくとよりスムーズです。
[ここ](https://cloud.google.com/load-balancing/docs/health-checks?hl=ja#fw-rule)を参考にファイアウォールルールを作り、webサーバが対象となるようにタグを張ります。
この記事を書いた時点では、

```
35.191.0.0/16
130.211.0.0/22
209.85.152.0/22
209.85.204.0/22 
```

これでいけました。ポートは後述するヘルスチェック設定に合わせる必要がありますが、webサーバだし普通にtcp:80でよろしいかと。

## インスタンスグループ
インスタンステンプレートから作成しても良いのですが、今回は疎通確認がメインなので既存のインスタンスを使う方式でいきます。
GCEメニューからインスタンスグループ選択して非マネージドインスタンスのほうを選び、適当に名前決めます。
リージョン/ゾーンはwebサーバ用インスタンスがあるリージョン/ゾーンとそろえます。
VPC/サブネットも同様に。
ミスってなければVM インスタンス のところのグレーアウトが解除されてインスタンス選択可能になってるはずなので選択します。なお、グループだけ先に作って後でインスタンス足すのも出来るので、この辺の順番はさほど気にしなくても問題ありません。

## LB
ロードバランサって書いてくれればいいのに、何故か「負荷分散」というメニュー名(ネットワークサービスにあります)なことに毒づき、作成・HTTP(S) 負荷分散 を選択します。通信はインターネットからVMで。

バックエンドサービスを作成します。
名前決めてインスタンスグループをさっき作ったものに設定したらあと全部デフォルトでかまいません。
CDNは使用しない。
ヘルスチェックは新規作成し、名前だけ決めたらやっぱりデフォルトのままでOKです。

ホストとパスのルールはバックエンド作成が完了した時点で恐らくデフォルトルールが出来てるはずなので、それの確認だけで大丈夫。

フロントエンドは適当に名前を決め、HTTPSを選択します。
IP部分はデフォルトで。勿論、固定IPを振ってもかまいません。なんなら、お使いのISPがIPv6対応してるならIPv6にしちゃっても良いんじゃないかな！
ポートはHTTPS選択した時点で443以外選べないと思います。
証明書は新規作成からGoogle 管理の証明書を作成する を選択し、ドメインは最初の方で設定したドメインを入れます。当該記事の例だとfoo.bar.comですね。
他はデフォルトで大丈夫です。

ここまでやったら作成を押下します。
作成押下後、LBのダッシュボードで下部に正常0/1ってなってる部分があるかと思います。
ヘルスチェック用の通信許可をミスっていなければ、5分ー10分もすれば1/1になるはず。
ならない場合何かミスってる可能性があります。

## 再びCloud DNS
最初の方で作ったゾーンに対してレコードセットを追加します。
LB作成時、フロントエンドのIPでv4ならAレコード、v6ならAAAAレコード、DNS名は証明書作ったときのドメインと一致させます。当該記事の例だとfoo.bar.comで変わりないので空欄のままです。
値はLBのダッシュボードまたはフロントエンド部分で表示されるIPを設定します。

あとはしばらく待ってればLBのダッシュボードに表示されてるIP部分の横のSSLの状態に緑チェックが入るかと思います。
5分から10分くらいで済むかと。逆に10分くらいたってもチェック済みにならない場合なんかミスってる恐れがあります。

## 疎通
ここまで全てつつがなく終えれば、当該記事の例でいくと`https://foo.bar.com`をブラウザで叩けばnginxの初期ページが返ってくるかと思います。お疲れ様でした。

## 閲覧しぼり(任意)
GCPのLBにはタグの付与が出来ないため、LBそのものにファイアウォールルールを適用することが出来ません。
IPでの制限をかけたい場合、ネットワーキングメニューのネットワークセキュリティ内にあるCloud Armorを利用する必要があります。
存在することを知ってしまえば設定方法は99%迷いませんが、1ポリシー+1ルールで多分最低6$です。
1ルールに設定できるIPは5個までで、1ルール追加するごとに1$かかります。
ゲホ。

## 最後に
運用する予定がないなら作ったものは消しておきましょう。おかねかかるし。