GCP(GKE)でknative(0.5.0)を試す

## Kubernetes(GKE)の準備

### クラスタの作成

gcloudのサンプル
節約のためpreemptibleVMで構築

ちなみに、公式サイトによると、推奨構成はn1-standard-4 max-nodes=10です。。。

```
$gcloud container clusters create sample-cluster --cluster-version=latest \
--machine-type=n1-standard-2 \
--num-nodes=1 --enable-autoscaling --min-nodes=1 --max-nodes=3 \
--disk-size=50GB \
--enable-autorepair \
--enable-cloud-logging \
--enable-cloud-monitoring \
--zone=asia-northeast1-b \
--node-locations=asia-northeast1-a,asia-northeast1-b,asia-northeast1-c \
--addons=HttpLoadBalancing,HorizontalPodAutoscaling \
--preemptible

# 権限付与
$kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user="$(gcloud config get-value core/account)"

```
## knative

2019/04/06時点で最新の0.5.0をインストールします。
サイトにはまだドキュメントが上がっていないため、下記を参考にセットアップします。

https://github.com/knative/docs/blob/master/docs/install/Knative-with-GKE.md

### 必要なAPIの有効化

```
$gcloud services enable \
     cloudapis.googleapis.com \
     container.googleapis.com \
     containerregistry.googleapis.com
```

### istioのデプロイ

```
$kubectl apply --filename 
https://github.com/knative/serving/releases/download/v0.5.0/istio-crds.yaml && \
kubectl apply --filename https://github.com/knative/serving/releases/download/v0.5.0/istio.yaml

# defaultのnamespaceを自動インジェクションにする
$kubectl label namespace default istio-injection=enabled

```
### knativeのデプロイ

```
$kubectl apply --filename https://github.com/knative/serving/releases/download/v0.5.0/serving.yaml \
--filename https://github.com/knative/build/releases/download/v0.5.0/build.yaml \
--filename https://github.com/knative/eventing/releases/download/v0.5.0/release.yaml \
--filename https://github.com/knative/eventing-sources/releases/download/v0.5.0/eventing-sources.yaml \
--filename https://github.com/knative/serving/releases/download/v0.5.0/monitoring.yaml \
--filename https://raw.githubusercontent.com/knative/serving/v0.5.0/third_party/config/build/clusterrole.yaml
```

エラーが出た。

```
unable to recognize "https://github.com/knative/eventing/releases/download/v0.5.0/release.yaml": no matches for kind "ClusterChannelProvisioner" in version "eventing.knative.dev/v1alpha1"
unable to recognize "https://github.com/knative/eventing/releases/download/v0.5.0/release.yaml": no matches for kind "ClusterChannelProvisioner" in version "eventing.knative.dev/v1alpha1"
```

なんか、この辺で議論されてるっぽい。
https://github.com/knative/docs/issues/968

```
$kubectl get pods --namespace knative-serving
$kubectl get pods --namespace knative-build
$kubectl get pods --namespace knative-eventing
$kubectl get pods --namespace knative-sources
$kubectl get pods --namespace knative-monitoring
```

とりあえずpodはできているので、次へ進む

### サンプルアプリの実行

サンプル

```
apiVersion: serving.knative.dev/v1alpha1 # Current version of Knative
kind: Service
metadata:
  name: helloworld-go # The name of the app
  namespace: default # The namespace the app will use
spec:
  runLatest:
    configuration:
      revisionTemplate:
        spec:
          container:
            image: gcr.io/knative-samples/helloworld-go # The URL to the image of the app
            env:
              - name: TARGET # The environment variable printed out by the sample app
                value: "Go Sample v1"
```

上記を適当なファイル名（demo.yaml）などで保存して

```
$kubectl apply -f demo.yaml
```

$kubectl get po で確認するとpodが３つ起動していることがわかる

```
$kubectl get po
NAME                                              READY   STATUS    RESTARTS   AGE
helloworld-go-x2mbk-deployment-848c47f56b-qm6fz   3/3     Running   0          2m28s
```

実行準備

```
#EXTERNAL-IPの確認
$kubectl get svc istio-ingressgateway --namespace istio-system

# DOMAINの確認
$kubectl get route helloworld-go --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain
$export HOST_URL=$(kubectl get route helloworld-go  --output jsonpath='{.status.domain}')
```

実行

```
$curl -H "Host: helloworld-go.default.example.com" http://<EXTERNAL-IP>/
Hello Go Sample v1!
```

しばらくするとPodが見えなくなる

```
$kubectl get po
No resources found.
```

見えなくても、実行できて、かつ実行後はまたPodができてる

```
$curl -H "Host: helloworld-go.default.example.com" http://34.85.24.97/
Hello Go Sample v1!
$kubectl get po
NAME                                              READY   STATUS    RESTARTS   AGE
helloworld-go-x2mbk-deployment-848c47f56b-8p4s8   3/3     Running   0          10s
```

## まとめ

- kubernetes, istio, knative 環境作るだけでも結構なスペックのサーバーが必要。
- このGoのサンプルで、Podが全くない状態からだとレスポンスに4,5秒くらいかかった。
- アプリのyamlがシンプル（DeploymentとServiceがまとまってる、スケールはknativeにまかせるのでreplicaの設定がなさそうなど）

## 所感
- 単一プロジェクトのインフラには向かなくて、例えば全社基盤とか、serverless環境を提供するサービスなんかでないとコスパが悪そうな気がした。
- VPCに閉じた環境のserverlessで4,5秒のゼロスケーリングは魅力。（AWS LambdaのVPC遅い問題の解決の一つになる）

## 次にやること

- knativeが用意しているAPIの仕様を調べる
- 自分で作ったアプリでもやってみる
- サーバースペックを色々変えてゼロスケーリングのパフォーマンス推移を調べる
- IoTCoreからの接続