Google Kubernetes Engine（GKE）+ HTTPロードバランサでwebアプリケーションを公開する

# Google Kubernetes Engine（GKE）とKubernetes
Google Kubernetes Engine（GKE）とはGCPのサービスの1つで、
Kubernetesとはコンテナ化されたアプリケーションのデプロイ、管理、スケーリングを管理するシステムのこと。（※詳細は今回は省略）

# GKE + HTTPロードバランサでアプリケーションを公開しよう

基本的な流れは下記の通り。
環境構築経験がほぼない自分は、下記の流れを何度も実行しながらではないと理解できなかった。
余計な設定などが含まれていそうなので、理解しながら加筆修正していきたい。

## 1. インスタンスの作成

**デフォルトリージョンの設定**

```
gcloud config set compute/region {region}
```

**デフォルトゾーンの設定**

```
gcloud config set compute/zone {zone}
```

**インスタンスの作成**

```
gcloud compute instances create {vm-name} 
       --machine-type {machine-type}
```

## 2. Kubernetes Serviceクラスタの作成
### Kubernetesクラスタとは
Kubernetesクラスタとは、コンテナ化されたアプリケーションを実行するためのノードグループのこと。（※ノードとはアプリケーションを実行しているマシンのこと）
Kubernetesクラスタはマスターノードと1つ以上のノードで構成される。

**Kubernetesクラスタの作成**

```
gcloud container clusters create {cluster-name}
```

**Kubernetesクラスタの認証情報の取得**

```
gcloud container clusters get-credentials {cluster-name}
```

**アプリケーションをKubernetesクラスタにデプロイ**

```
kubectl create deployment {object-name} 
       --image={container-image}
```

**Kubernetes Serviceの作成**
Kubernetes Serviceはアプリケーションを外部公開できるようにするためのサービスのこと。

```
kubectl expose deployment {object-name} 
       --type=LoadBalancer 
       --port {port}
```

`type=LoadBalancer`を指定することでHTTPロードバランサを利用できる

サービスの状態確認は`kubectl get service`
問題なければアプリケーションが外部公開される。

## 3. HTTPロードバランサを設定する

**インスタンステンプレートの作成**

```
gcloud compute instance-templates create {template-name}
       --region={region}
       --network=default
       --subnet=default
       --tags=allow-health-check
       --image-family=debian-9
       --image-project=debian-cloud
       --metadata-from-file=startup-script={script}
```

`metadata-from-file` には起動スクリプトを指定できるので、
ソフトウェアのインストール、更新の実行、サービスの有効化などのタスクを定義する。
例えば下記のようなnginxを利用するためのシェルスクリプトを作成し、
それを `metadata-from-file` に指定する。

```
cat << EOF > startup.sh
#! /bin/bash
apt-get update
apt-get install -y nginx
service nginx start
sed -i -- 's/nginx/Google Cloud Platform - '"\$HOSTNAME"'/' /var/www/html/index.nginx-debian.html
EOF
```

**ターゲットプールの作成**
ターゲットプールとは、ロードバランサが転送するインスタンスをグループ化するもの。
ターゲットプールによって複数のインスタンスに1ヶ所からアクセスできるようになる。

```
gcloud compute target-pools create {pool-name}
```


**マネージドインスタンスグループの作成**
マネージドインスタンスグループによって、
先ほど作成したインスタンステンプレートに設定された通りのインスタンスを
指定した`size`だけ立ち上げる。

マネージドインスタンスグループは同一ゾーンだけでなく、
同一リージョン内の複数ゾーンのインスタンスを含むことも可能。
後者（リージョンマネージドインスタンスグループ）の場合は
ゾーンをまたがった負荷分散ができる。

```
gcloud compute instance-groups managed create {instance-group-name} 
       --base-instance-name {instance-name}
       --template {template-name} 
       --size {size} 
       --target-pool {pool-name}
       --zone {zone}
```

**ファイアウォールルールの作成**

```
gcloud compute firewall-rules create {fw-rules-name} 
       --allow {protocol}:{port}
```

**ロードバランサの作成**

```
gcloud compute forwarding-rules create {lb-name}
       --region {region}
       --target-pool {pool-name}
       --ports={port}
```

**ヘルスチェックの作成**

```
gcloud compute http-health-checks create {health-check-name}
```

**ポート番号に名前を指定**
インスタンスグループにポート番号を設定する。
これによってバックエンドサービスにも同一のポート番号が設定される。

```
gcloud compute instance-groups managed
       set-named-ports {instance-group-name}
       --named-ports {protocol}:{port}
```

**バックエンドサービスの作成**
ヘルスチェックはバックエンドサービスに追加することで動作する。

```
gcloud compute backend-services create {backend-name}
       --protocol HTTP 
       --http-health-checks {health-check-name} 
       --global
```

**バックエンドサービスにマネージドインスタンスグループを追加**

```
gcloud compute backend-services add-backend {backend-name} 
       --instance-group {instance-group-name} 
       --instance-group-zone {zone} 
       --global
```


**URLマップの作成**
デフォルトで接続するバックエンドサービスを設定するもの。

```
gcloud compute url-maps create {map-name}
       --default-service {backend-name}
```


**ターゲットHTTPプロキシの作成**
転送ルールとURLマップをつなげるもの。
URLマップに受信リクエストを振り分ける。

```
gcloud compute target-http-proxies create {proxy-name}
       --url-map {map-name}
```

**転送ルールの作成**
IPアドレスをロードバランサやターゲットHTTPプロキシに紐づけるもの。

```
gcloud compute forwarding-rules create {rule-name}
       --global
       --target-http-proxy {proxy-name}
       --ports {ports}
```

`kubectl get service`でサービスの状態を確認する。
お疲れさまでした！