慣れたら全部で30分かからないぐらいかな。といってもほぼ待ち時間で、GKEの生成を待ってるのに5分ぐらいで、最後の証明書の生成の待ち時間が15分ぐらい。
## 前置き
Private GKEクラスターを立ててみる。まだ、ちゃんとProductionレベルで動かすような設定は勉強してないので、とりあえずおもちゃみたいな気分で。
GCP周りの操作はgcloudとかTerraformとかを使えば良さそうだなーとは思うけど、今回はGUIでやってみることにする。Terraformとかはまた別で勉強しとく。
LoadBalancerはk8sからはコントロールせずに自分で作ろうと思う。なのでk8sはNodePortまでにしておく。LBのライフサイクルはk8sから切り離して考えたいなと思って。
## 準備
- プロジェクトを適当な名前で新しく作成した
buffering-20190901
。最後にプロジェクトごと削除したいから。 - Google Cloud SDKがインストールされてる(gcloudとkubectl使う)
- 課金を有効にしてる
## 手順
こうかな。
- VPCを作る
- GKEを作る
- Cloud NATを設定する
- サンプルアプリをGKEにデプロイする
- LoadBalancer用にFirewallを設定する
- LoadBalancer用にStatic IPを作成する
- Cloud LoadBalancerを作る
## 1. VPCを作る
デフォルトで作成されてるVPCは使わないので削除した。新しく my-vpc
って名前のVPCを作成して、Custom Subnetを東京リージョンに作った。Private Google AccessはOnにしておいた。
## 2. GKEを作る
Highly available
のテンプレートから作った。
- 左側から「Highly available」のテンプレートを選択
- 名前を
my-gke
にした - Regionが
us-central1
になってるのでasia-northeast1
にした - Number of nodes (per zone)が
3
になってるので1
にした。合計で3台動くことになる - 下の方にある「Availability, networking, security, and additional features」の部分をクリックして広げて
- さっき作成したVPCが選ばれてることを確認
- 「Private cluster」にチェックを入れた
- 「Master IP range」には
172.16.0.0/28
を入れておいた - 「Enable master authorized networks」に、Masterへのアクセスを許可するIPを設定した方が良いとは思うんだけど、今回は別にいっかと思ってチェックを外しておいた。
- 「Stackdriver」の「Enable Stackdriver Kubernetes Engine Monitoring」をチェックしておいた(分かってない)
- 「Create」をクリック
これで、5分くらい待てばRegionalでAutoscalingなPrivateクラスターができる。
- Regionalだと、MasterもNodeも複数Zoneに分散した構成になる。
- Autoscalingを有効にすると、NodeのCPU使用率とかによって自動でScale Out/InしてくれるNodePoolになる。
- Privateクラスターは、NodeにGlobalIPを持たせないので外部からのアクセスができない。MasterはGoogleのネットワーク側で管理されていて、外部からのアクセスが可能。
Privateクラスターだと、NodeがGlobalIPを持っていないので、このままだとNodeから外部へのアクセスもできない。ので、Cloud NATを設定する。
## 3. Cloud NATを設定する
東京リージョンを選んで作成する。Cloud Routerがコントロールプレーンとして必要らしいので作成する。
## 4. サンプルアプリをGKEにデプロイする
これで、GKE上にアプリをデプロイできるので、サンプルアプリをデプロイする。サービスは最初に書いたとおり、NodePortにする。
gcloudでログイン
$ gcloud auth login
GKEのクレデンシャルを取得。リージョンやプロジェクト名は gcloud config
で設定してもいい。
$ gcloud container clusters get-credentials my-gke \ --region asia-northeast1 --project bufferings-20190901
これでkubectlがGKEにつながるようになる。
$ kubectl get node NAME STATUS ROLES AGE VERSION gke-my-gke-standard-pool-1-6f5f83d6-vzxn Ready <none> 55m v1.12.8-gke.10 gke-my-gke-standard-pool-1-7cec640a-790g Ready <none> 55m v1.12.8-gke.10 gke-my-gke-standard-pool-1-978f3a3c-6dbc Ready <none> 55m v1.12.8-gke.10
サンプルのアプリをデプロイする。ファイル名は my-nginx.yaml
でいいかな。NodePortには 31380
を指定しといた。自動でアサインしても問題ない。
apiVersion: v1 kind: Service metadata: name: my-nginx-service spec: type: NodePort ports: - name: http protocol: TCP nodePort: 31380 port: 8080 targetPort: 80 selector: app: my-nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx-deployment spec: selector: matchLabels: app: my-nginx replicas: 2 template: metadata: labels: app: my-nginx spec: containers: - name: my-nginx image: nginx:1.7.9 ports: - containerPort: 80
これを適用して
$ kubectl apply -f my-nginx.yaml
service/my-nginx-service created
deployment.apps/my-nginx-deployment created
作成されてることを確認したら
$ kubectl get svc,po NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.201.0.1 <none> 443/TCP 43m service/my-nginx-service NodePort 10.201.1.148 <none> 8080:31380/TCP 9s NAME READY STATUS RESTARTS AGE pod/my-nginx-deployment-5796dcf6c4-bxjw8 1/1 Running 0 9s pod/my-nginx-deployment-5796dcf6c4-rz87d 1/1 Running 0 8s
Port Forwardingで確認しておく
$ kubectl port-forward svc/my-nginx-service 8888:8080 Forwarding from 127.0.0.1:8888 -> 80 Forwarding from [::1]:8888 -> 80
これで、localhost:8888をブラウザで開くとnginxにつながる。
## 5. LoadBalancer用にFirewallを設定する
k8s側でNodePortじゃなくてLBサービスを使えばFirewallも自動で設定してくれるんだけど、自分でLBを作るのでFirewallも自分で設定する必要がある。
### LB → NodePort
さっきNodePortを 31380
にしたからそこへのアクセスを許可する。
次のページに書いてあるように、LBからのアクセスは 130.211.0.0/22
と 35.191.0.0/16
のレンジからのアクセスを許可する。
https://cloud.google.com/load-balancing/docs/https/#firewall_rules
TargetのTagは、既にGKE生成時に自動的に作成されている設定と同じものを入れておいた。
### LB → Health Check
それともうひとつ、LBからNodeへのHealthCheckを許可しないといけない。これは各Nodeのポート 10256
でパスが /healthz
で動いてるので、そこを通す。NodePortのやつに混ぜても良かったんだけど、別で作っておいた。
## 6. LoadBalancer用にStatic IPを予約する
LB用なのでRegionalじゃなくてGlobalで予約する。
「Reserve」ボタンを押すとIPが予約される。
今回僕が予約できたのは 35.244.157.110
だったので、これをLBから使う。LBを作成するときにHTTPSアクセスのための証明書を自動設定したいので、自分で持ってるドメインに登録しておく。
my-gke.shiiba.dev
でこのIPアドレスを登録しておいた。
$ nslookup my-gke.shiiba.dev Server: 127.0.0.53 Address: 127.0.0.53#53 Non-authoritative answer: Name: my-gke.shiiba.dev Address: 35.244.157.110
## 7. Cloud LoadBalancerを作る
ということで、最後にLBを作る。種類は「HTTP(S) Load Balancing」
LBはBackend、Rule、Frontendの3つの設定があって、Frontendがリクエストをインターネットから受ける部分、それをRuleで処理して、Backendに流す、という感じ。
BackendにGKEのNodePortを設定して、FrontendでSSLの設定をする。Ruleは特に設定せずに受けたリクエストを全部GKEに流すことにする。
### Backend
対象はInstance Groupで、PortはNodePortに指定した 31380
。
Regional Clusterにしたので、各ZoneにInstance Groupが作られてる。なので、各ZoneのInstance Groupに対して同じ設定をする。
Backendに対するHealthCheckは新規作成する。これがPort 10256
で、パスが /healthz
### Frontend
HTTPSのフロントエンドを作成する。IPアドレスには、さっき予約したIPアドレスを指定する。
Certificateの部分で「Create a new certificate」を選んで、証明書の作成と管理をGoogleにやってもらうようにする。
ドメインの部分にさっき設定しておいた my-gke.shiiba.dev
を指定しておいた。これで「Let's Encrypt」の証明書発行などをGoogleがやってくれる。
### Create
全部終わったら、Createボタンを押して15分ぐらい待つ。LBが作成されて、証明書のStatusがACTIVEになってから、5分ぐらい待つと、つながるようになる。
(∩´∀`)∩ワーイ
## プロジェクトを削除
楽しんだら忘れずにプロジェクトとDNSの設定を削除しておしまい!