MacでKubernatesを試してみた

# 概要
dockerは軽く使ったことがあるので多少の理解はあるのですが、dockerと同じだけkubernetesも目にするのでその部分の理解も深めたいと思い学習の記録を残します

# dockerとkubernetesの違い
どちらもコンテナという技術に関連があるもの達です
(`コンテナ`とはアプリケーションとその実行に必要なもの（ライブラリや設定）をまとめて「軽量な箱（Container）」にしたもの)

まずはそれぞれどういった違いがあるか理解しておきます

## docker
コンテナ化されたアプリケーションを構築、共有、および実行するために使用するツールのこと
コンテナイメージの作成などを行う

## kubernetes
コンテナをたくさん管理・運用・自動化するためのオーケストレーションツールのこと
直接コンテナを作るわけではなく、たくさんのコンテナをまとめて管理し、ヘルスチェックやオートスケーリング、障害時の自己修復などを自動でやってくれる

## ざっくり表でまとめるとこんなイメージのようです

| 項目 | docker | kubernetes |
| :---: | :---: | :---: |
| 役割 | コンテナを作成・実行 | コンテナを大量にまとめて管理・自動化 |
| 規模感 | 単体または少数のコンテナ | 大量のコンテナ・サーバー群 |
| 使い方 | コンテナを手動・単純管理 | コンテナ群を自動・大規模運用 |
| 依存 | 単独で動く | コンテナランタイム（dockerなど）が必要 |

# kubernetesで何ができるか
ざっくりと違いを理解したところで実際にkubernetesではどういうことができるか調べました

ここでは実際にローカル環境でkubernetesを触ってみたいと思います

## Kubernetesだけで FastAPI + PostgreSQL を立ち上げてみる
ローカルPC上でkubernetesを扱うには`minikube`というものが必要になるみたいです

```sh
brew install minikube
```

以下のコマンドでkubernetesクラスターを起動できます
(クラスター＝リソースを管理する集合体)
```sh
minikube start
```

| リソース | 説明 | 用語 |
| :---: | :---: | :---: |
| Deployment (FastAPI, Postgres) | FastAPI, Postgresコンテナを起動・管理する | Deployment |
| Service (FastAPI, Postgres) | FastAPI, Postgresのアクセス口を作る | Service |

今回の基本構成はこんな感じです
DeploymentやServiceがその名の通りの役割を担っています

PostgresのDeployementとServiceを作ってみます

- Deployment

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:14
        env:
        - name: POSTGRES_DB
          value: "testdb"
        - name: POSTGRES_USER
          value: "user"
        - name: POSTGRES_PASSWORD
          value: "password"
        ports:
        - containerPort: 5432
```

- Service

```yml
apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  selector:
    app: postgres
  ports:
    - protocol: TCP
      port: 5432
      targetPort: 5432
```

作成した内容のデプロイするためのコマンドは以下の内容です

```sh
kubectl apply -f postgres-deployment.yaml
kubectl apply -f postgres-service.yaml
```

ちなみにデプロイした内容の確認は以下でできます

| 実行内容 | コマンド |
| :---: | :---: |
| Pod一覧の確認 | kubectl get pods |
| Deployment一覧の確認 | kubectl get deployments |
| Service一覧の確認 | kubectl get services |
| リソース内容の確認 | kubectl describe [リソース種類] [リソース名] |

続けてFastAPIの内容です

- Deployment

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: fastapi
spec:
  replicas: 1
  selector:
    matchLabels:
      app: fastapi
  template:
    metadata:
      labels:
        app: fastapi
    spec:
      containers:
        - name: fastapi
          image: tiangolo/uvicorn-gunicorn-fastapi:python3.9
          ports:
            - containerPort: 80
          env:
            - name: MODULE_NAME
              value: "main"
```

- Service

```yml
apiVersion: v1
kind: Service
metadata:
  name: fastapi
spec:
  selector:
    app: fastapi
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: NodePort
```

作成した内容のデプロイするためのコマンドは以下の内容です

```sh
kubectl apply -f fastapi-deployment.yaml
kubectl apply -f fastapi-service.yaml
```

起動後に、`minikube service fastapi`を実行するとブラウザが開かれてFastAPIのレスポンスがページに表示されます

コマンドの内容としては、kubernetesクラスタ内部のServiceのIP/Portに直接リクエスト転送（トンネル）してくれるみたいです、便利

## 実験
せっかくリソース立ててみたので、何かしらkubernetes特有の挙動を試してみたいと思います
違いを調べた際に「障害時の自己修復などを自動でやってくれる」という情報があったので、それを試します

どうすれば再現できるかというとpodを削除すると、deploymentで指定したreplicasの数値に合わせてpodが自動で起動されるようです

### 確認手順
1. 現在動いているpodの確認
まず、現在実行中のpodの名前を確認します

    ```sh
    kubectl get pods
    ```

1. podを削除
次に、以下のコマンドを実行して確認したpodを削除します

    ```sh
    kubectl delete pod <POD名>
    ```

1. podの復旧を確認
podを削除すると、kubernetesが新しいPodを自動的に作成してくれます
以下のコマンドを実行し、リアルタイムでpodの状況を監視してみます
(-wオプションは、Podの変化を監視するためのオプション)
    
    ```sh
    kubectl get pods -w
    ```

    Podが削除されると同時に、新しいPodが作成される様子が表示されます


    ```sh
    fastapi-fb5d4f848-j8cmc     1/1     Terminating   0          30s
    fastapi-fb5d4f848-ws9kh     0/1     Pending       0          0s
    fastapi-fb5d4f848-ws9kh     0/1     Pending       0          0s
    fastapi-fb5d4f848-ws9kh     0/1     ContainerCreating   0          0s
    fastapi-fb5d4f848-j8cmc     0/1     Completed           0          31s
    fastapi-fb5d4f848-j8cmc     0/1     Completed           0          31s
    fastapi-fb5d4f848-j8cmc     0/1     Completed           0          31s
    fastapi-fb5d4f848-ws9kh     1/1     Running             0          1s
    ```

# おわりに
以上で、一旦kuernetesの学習記録としては以上にしたいと思います
まだまだ、しれていないことがあると思うので、引き続き学習を続けていければと思います