kubernetes上でAPIを動かしてみよう

システムの運用とかをやっているとkubernetes(略してk8s)を触る機会があると思います。というか大抵のシステムはk8s上で動いていると思います。そのためシステムを運用するにはk8sを扱えることがとても重要だと思います。ちなみに僕は学生時代k8sを触ったこともなく、「なにそれ？」状態だったので、運用の仕事についたときかなり苦労しました（笑）

本記事ではまだシステム運用をやったことがない方に向けたチュートリアルとして以下のページで作ったAPIをk8sで動かして遊んでみたいと思います。

https://qiita.com/hiro949/items/d0146c7a0bbe5889a6f8

ここの`tax.py`と`dockerfile`の２つがあれば大丈夫です。
ちなみに必要なパッケージのインストールに`brew`を使っていて基本的にMacユーザーを想定しています。

# k8sって何？

システムを使ってくれるお客さんが増えると送られるリクエスト数が増えてシステムの処理が追い付かなくなりパンクしてしまう可能性があります。(１つのコンテナをk8sではポッドというものに入れて使います。)　そこで、ポッドを複数用意して処理を分担させてこれを回避します。k8sは各ポッドの負荷に応じてポッドの個数を自動で増減してくれるミドルウェアになっています。

k8sの基本的な構成要素は以下のようなものがあります。

| コンポーネント| 役目 |
|:--:|:-:|
| pod | docker コンテナ１個が動いている |
| deployment | podの個数を管理する |
| service | リクエストを各podにうまく割り振る |
| namespace | pod,deploy,serviceなどのコンポーネントをまとめたもの |

他にもsecret,cronjob,configmapなど色々な機能のコンポーネントがありますが(実際これらもよく使う)、基本的には上表のものを覚えればいいかなと思います。

# マニフェスト(k8sの設定ファイル)

まずk8sのマニフェストファイル(k8sの各コンポーネントの設定を書いたもの)を作成します。

```tax-api.yaml
apiVersion: v1
kind: Namespace
metadata:
    name: sample-ns

---
apiVersion: v1
kind: Service
metadata:
    namespace: sample-ns
    name tax-svc
spec:
    type: LoadBalancer
    selector:
        app: tax-svc
    ports:
    - port: 80
        targetPort: 5000

---
apiVersion: apps/v1
kind: Deployment
metadata: 
    namespace sample-ns
    name tax-deploy
spec:
    replicas: 2
    selector:
        matchLabels:
            app: tax-api
        template:
            metadata:
                labels:
                    app: tax-api
            spec:
                containers:
                    - name: tax-api
                        image: tax-api:v1
                        ports:
                        - containerPort: 5000
                        resources:
                            limits:
                                cpu: 200m
                                memory: 256Mi
                            requests:
                                cpu: 100m
                                memory: 128Mi
```

Podの設定がない？と思われるかもしれませんが、podはdeploymentが自動的に作ってくれので大丈夫です。

# パッケージのインストール

次にk8sをローカルで試すパッケージ：minikubeとk8sを操作するコマンド：kubectlをインストールします。

```
brew install minikube
brew install kubectl
```

# システムの立ち上げ

次にdocker desktopを起動してターミナルで

```
minikube start
```

を実行します。

docker desktopのダッシュボードを見るとminikubeというコンテナができていると思います。このコンテナはk8sを使える仮想環境になっていてここでシステムを展開していきます。

まず、docker imageを保存するregistoryをminikubeに指定します。(minikubeコンテナにはregistoryも用意されています)

```
eval $(minikube docker-env)
```

次にここにdockerimageを作って保存します。

```
docker build -t tax-api:v1
```

（ちゃんとできたか`docker images`で確認しましょう。）

次に

```
kubectl config get-contexts
```

でkubecltで操作するk8sがminikubeで動いているものになっているか確認します。
もし違うk8sが選ばれていたら

```
kubectl config use-context minikube
```

でminikubeを選び直しましょう。

ではtax-apiのservice,deploymentなどを立ち上げたいと思います。

```
kubectl apply -f tax-api.yaml
```

ちゃんと展開されているか次のコマンドで確認しましょう。

```
kubectl get all -n sample-ns
```

最後にリクエストを投げてみましょう。普通はnginxなどのサービスを別途k8s上に立ち上げるのですが、minikubeは次のコマンドでサービスを展開する機能がついているのでそれを使います。

```
minikube service tax-svc -n sample-ns
```

２つアクセス先の表が出力されると思うので、別のターミナルから２つ目の表のURLにリクエストを送ってみます。

```
curl -X POST -H 'Content-Type: application/json' -d '{"amount":100}' {表のURL}/calc
```

最後にお片付けは、

```
minikube stop
```

でコンテナを止めれば大丈夫です。