Rancherを使ってGKEにKEDAを簡単導入

# はじめに

Microsoftの年次開発者会議「Build 2019」でKEDAが発表されました。
KEDAはKnativeと同じようなKubernetes上にサーバーレス環境を構築するサービスになります。
今回はドキュメントに従い、環境構築から動作確認まで行いますが、AzureではなくGCPに構築したいと思います。

# KEDA

Gitnubのリポジトリはこちら

https://github.com/kedacore/keda

<img width="672" alt="スクリーンショット 2019-05-18 13.40.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/2b09f9fc-121b-5c82-2ba0-63c7d3a3569b.png">

まだまだこれからのプロジェクトだと思いますが、Kubernetes上でイベントドリブンなサーバーレスは非常に楽しみなプロダクトなので、きっとこれから伸びてくると思います。

### トリガーにできるイベント

- RabbitMQ Queues
- Kafka topics
- Azure Storage Queues
- Azure Service Bus Queues
- Azure Service Bus Topics

Azure以外で使おうと思うと、今の所RabbitMQとKafkaの２つ。今回はRabbitMQで検証します。

# 構築するもの

- GKEクラスタ
- Rancher
- KEDA(Helm)
- RabbitMQ(Helm)
- サンプルアプリ

# 構築

## GKEクラスタ

大阪に住んでいるので、大阪リージョン！
サブネットも事前に大阪リージョンで作成しています。

```
gcloud container clusters create <クラスタ名> --cluster-version=latest \
--machine-type=n1-standard-2 \
--num-nodes=1 --enable-autoscaling --min-nodes=1 --max-nodes=3 \
--network=<VPC名> --subnetwork=<サブネット名> \
--disk-size=50GB \
--enable-autorepair \
--enable-cloud-logging \
--enable-cloud-monitoring \
--zone=asia-northeast2-b \
--node-locations=asia-northeast2-a,asia-northeast2-b,asia-northeast2-c \
--addons=HttpLoadBalancing,HorizontalPodAutoscaling \
--preemptible
```

## Rancher

今回、必要なプロダクトはHelmでデプロイするため、Kubernetesの管理にRancherを使用します。
RancherはHelmのカタログから簡単にデプロイできますし、カタログの追加も簡単なので、楽チン。

ここのQuickStart(Dockerはインストール済みの前提)
https://github.com/rancher/rancher

## Rancherにクラスタをインポート

Add Clusterを選択

<img width="1257" alt="スクリーンショット 2019-05-17 21.23.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/0afb4dc8-d8bc-5d80-459d-5b774a91e68d.png">

Importを選択して、ClusterNameを入れる

<img width="1247" alt="スクリーンショット 2019-05-17 21.23.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/a6d4bbe5-3e9a-75f6-a908-1bb37c6a8920.png">

表示されたコマンドをローカルのコンソールから実行
なお、２行目、３行目はどちらかでよい（Rancherをドメイン取ってちゃんとしたTLS通信しているなら２行目、IPアドレスでのアクセスなどでオレオレ認証なら3行目）

## KEDAのデプロイ

Global→Tools→Catalogsからカタログのセットアップ画面を開き、HelmStableを有効化する。また、AddCatalogを押す

<img width="1255" alt="スクリーンショット 2019-05-17 19.55.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/774993ea-8cce-6eb2-69ba-ebc0640f658e.png">

### KEDAのカタログを追加する

Catalog URL : https://kedacore.azureedge.net/helm

<img width="987" alt="スクリーンショット 2019-05-17 19.56.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/94ef01e1-8e8a-f77b-1741-971debdce5fd.png">

### KEDAとRabbitMQをデプロイする

画面に左上のプルダウン（初期はGlobal）から、クラスタ名→Defaultと選択
Appsを開き、Launchをクリック

### KEDA

デフォルトでインストール

<img width="1246" alt="スクリーンショット 2019-05-17 19.56.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/2028542d-ec31-67f1-4a43-c1e860e0250d.png">

### RabbitMQ

デフォルトでインストール

<img width="1248" alt="スクリーンショット 2019-05-17 20.03.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/4a0c7c8d-f137-dddf-de10-66a1004bdb84.png">

### クラスタにKEDAとRabbitMQが追加されたことを確認

<img width="1243" alt="スクリーンショット 2019-05-17 20.06.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/6717e3e4-d312-addb-7479-67311dd53fd5.png">

<img width="979" alt="スクリーンショット 2019-05-17 20.06.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/058957a0-6cca-66ac-8505-ea568471add5.png">

<img width="980" alt="スクリーンショット 2019-05-17 20.07.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/7526c6ff-6fca-b267-4452-b21887cbb10d.png">

## サンプルアプリの導入

ドキュメントに沿って導入していきます。

Githubからclone

```
git clone https://github.com/kedacore/sample-go-rabbitmq
cd sample-go-rabbitmq
```

今回作成したRabbitMQのホスト名・パスワードはサンプルとは異なるので、変更します。

### RancherでRabbitMQのホスト名・パスワードを確認する

Appsからrabbitmqを開くと詳細が確認できます。
ここでまず、namespaceホスト名を確認

<img width="1217" alt="スクリーンショット 2019-05-18 12.35.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/2a1204ad-f410-59ae-854f-63674e1b04cf.png">

パスワードは確認用のkubectlが表示されているので、それをローカルで実行

```
echo "Password      : $(kubectl get secret --namespace rabbitmq rabbitmq -o jsonpath="{.data.rabbitmq-password}" | base64 --decode)"
```

※rabbitmqは環境ごとに異なります

### デプロイ用のyamlを書き換え

パスワードおよび、rabbitmqのnamespace,ホスト名を書き換えます

deploy/deploy-consumer.yaml

'amqp://user:xxxxxx@rabbitmq.rabbitmq.svc.cluster.local:5672'の箇所（２箇所）

```
apiVersion: apps/v1
...
      containers:
      - name: rabbitmq-consumer
        image: jeffhollan/rabbitmq-client:dev
        imagePullPolicy: Always
        command:
          - receive
        args:
          - 'amqp://user:xxxxxx@rabbitmq.rabbitmq.svc.cluster.local:5672'
---
apiVersion: keda.k8s.io/v1alpha1
kind: ScaledObject
...
spec:
  scaleTargetRef:
    deploymentName: rabbitmq-consumer
  pollingInterval: 5   # Optional. Default: 30 seconds
  cooldownPeriod: 30   # Optional. Default: 300 seconds
  maxReplicaCount: 30  # Optional. Default: 100
  triggers:
  - type: rabbitmq
    metadata:
      queueName: hello
      host: 'amqp://user:xxxxx@rabbitmq.rabbitmq.svc.cluster.local:5672'
      queueLength  : '5'
```

deploy/deploy-publisher-job.yaml
同様の箇所を１箇所

なお、こちらはテストツールなので、他にRabbitMQに送信ツールがあればそれでもいいと思います。

```
apiVersion: batch/v1
kind: Job
metadata:
  name: rabbitmq-publish
spec:
  template:
    spec:
      containers:
      - name: rabbitmq-client
        image: jeffhollan/rabbitmq-client:dev
        imagePullPolicy: Always
        command: ["send",  "amqp://user:xxxxxxx@rabbitmq.rabbitmq.svc.cluster.local:5672", "300"]
      restartPolicy: Never
  backoffLimit: 4
```

### デプロイ

```
kubectl apply -f deploy/deploy-consumer.yaml
```

スケールの確認

```
kubectl get deploy -w
```

別タブでテストデプロイ実行

```
kubectl apply -f deploy/deploy-publisher-job.yaml
```

### Podの状況

どんどんPodが増えていき、終わった途端０に落ちるのがわかります。
デフォルトのYAMLではだいたい５秒間隔くらいでPodがスケールしていき、約90sで３０までスケールしました。処理が終わると、すぐに０に落ちました。
この辺りは、deploy-consumer.yamlのScaledObjectに設定が記載されています。（スケールのタイミングや最大Pod数など）

```
$ $ kubectl get deploy -w
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
rabbitmq-consumer   0/0     0            0           5s
rabbitmq-consumer   0/1   0     0     19s
rabbitmq-consumer   0/1   0     0     19s
rabbitmq-consumer   0/1   0     0     19s
rabbitmq-consumer   0/1   1     0     20s
rabbitmq-consumer   1/1   1     1     24s
rabbitmq-consumer   1/4   1     1     29s
rabbitmq-consumer   1/4   1     1     29s
rabbitmq-consumer   1/4   1     1     29s
rabbitmq-consumer   1/4   4     1     29s
rabbitmq-consumer   2/4   4     2     33s
rabbitmq-consumer   3/4   4     3     34s
rabbitmq-consumer   4/4   4     4     36s
...
rabbitmq-consumer   27/30   30    27    87s
rabbitmq-consumer   28/30   30    28    87s
rabbitmq-consumer   29/30   30    29    89s
rabbitmq-consumer   30/30   30    30    92s
rabbitmq-consumer   30/0   30    30    100s
rabbitmq-consumer   30/0   30    30    100s
rabbitmq-consumer   0/0   0     0     100s
```

## まとめ

・Podのスケールがスムーズに行われることが確認できました。
・ドキュメントに従い、GKEにHelmでRabbitMQの環境を構築しましたが、Rancherを使えば簡単に環境準備ができました。

いまのところ、GKEで使えるサンプルはRabbitMQだけですが、これを参考に次はyamlの内容等もう少し追いかけます。