【四日目】最小限の構成でdocker-composeからKubernetesにデプロイする勉強会

# 概要

表題の勉強会を行った四日目の内容を記載します。全日の内容は以下のまとめページをご覧ください。

[【まとめ】最小限の構成でdocker-composeからKubernetesにデプロイする勉強会] (https://qiita.com/tamoco/items/5a5ffb448d59b3b03831/)


# 四日目のできたこと

- Kubernetes
  - deployment.ymlの作成
  - service.ymlの作成

# 四日目の内容

これまでは`docker-compose`でコンテナを作成し、それらを`GitLab CI/CD`でコンテナイメージを作成するところまでできました。四日目では作成したコンテナイメージを元に`kubernetes`で動作させます。

## まずkubenernetesとは？

以下のページを参考に勉強します。

[Kubernetesとは？仕組みと構造をわかりやすく解説します] (https://www.kagoya.jp/howto/rentalserver/kubernetes/)

規模の大きいDockerの管理や自動化をするような仕組みでありコンテナの運用を充填としたモノであるのがイメージしやすいと思います。
逆に`docker-compose`はソースから動作環境を準備したりすることに使われることが多く、負荷分散や冗長構成などの運用となった場合は`AWS`などのサービスに頼ったりすることが多かったりするのではないでしょうか。
他のサービスによる運用でもよいのですが、せっかくベンダーに依存しないコンテナを使っているなら運用も依存したくないから、`Kubernetes`のような仕組みができたかもしれません。

## 動作環境

ローカルの`kubernetes`を使います。動作環境は以下のとおりです。

- Windows 10
- docker-for-windows
- docker desktop 2.3.0.3

今回は`docker desktop`の`kubernetes`を使用し、初期の`Node`を使用します。以下のように`context`が設定されているか確認します。

```bash
$ kubectl config get-contexts
CURRENT   NAME                   CLUSTER          AUTHINFO                                  NAMESPACE
*         docker-desktop         docker-desktop   docker-desktop
```

## deployment.ymlの作成

まずは`deployment`を作成します。すでに作成されたイメージを元にしています。
この時点ではコンテナのイメージはパブリックの状態にしてあります。
`deployment`が定義の内容を元に`pod`を作成します。

■ deployment.yaml

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: express-app
  labels:
    app: express-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: express-app
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: express-app
    spec:
      containers:
      - image: registry.gitlab.com/tamoco-mocomoco/k8s-test/express
        name: express-app
        ports:
        - containerPort: 3000
          name: express-app
```

`delopyment.yml`を`apply`することで常に`deployment`が定義に書いている内容を維持するようになります。

```bash
 kubectl apply -f deployment.yaml
```

`deployment`によって作成された`pod`を確認します。`replicas: 2`となっているため`pod`は２つ作成されます。

```bash
$ kubectl get po
NAME                           READY   STATUS    RESTARTS   AGE
express-app-7dc6d9dbcd-jpbzm   1/1     Running   0          47s
express-app-7dc6d9dbcd-mb5jj   1/1     Running   0          47s
```

上記で維持すると記載されていました。これはもし`pod`が予期しない状態で削除された場合でも`deployment`が定義された状態を維持しようとするので`pod`が作り直されます。試しに`pod`を削除してみます。

```bash
$ kubectl delete po express-app-7dc6d9dbcd-jpbzm
pod "express-app-7dc6d9dbcd-jpbzm" deleted
```

もう一度`pod`を確認すると先ほど削除されたモノとは別の`pod`が作成されていることがわかります。

```bash
$ kubectl get po
NAME                           READY   STATUS    RESTARTS   AGE
express-app-7dc6d9dbcd-mb5jj   1/1     Running   0          3m
express-app-7dc6d9dbcd-wt6m6   1/1     Running   0          16s
```

## service.ymlの作成

ポートの転送などは`service`で行います。今回は`NodePort`を使用しています。`Ingress`とかが良いとかは一旦は置いておきます。

■ service.yml

```yaml
apiVersion: v1
kind: Service
metadata:
  name: express-app
spec:
  type: NodePort
  selector:
    app: express-app
  ports:
    - name: "http-port"
      protocol: "TCP"
      port: 80
      targetPort: 3000
```

`service.yml`を`apply`します。

```bash
$ kubectl apply -f service.yaml
service/express-app created
```

`service`を確認してみます。

```bash
$ kubectl get svc
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
express-app   NodePort    10.98.216.204   <none>        80:30948/TCP   38s
```

以下のURLにアクセスすることで動作していることが確認できます。転送されているポート番号は`service`を作り直すと変わるのでご注意ください。

```bash
http://localhost:30948/
```

# 作成したモノを削除する

以下のコマンドで削除します。`deployment`を削除していないとダッシュボードなどでコンテナや`pod`を削除しても作り直されたりします。

```bash
$ kubectl delete deployment express-app
deployment.apps "express-app" deleted

$ kubectl delete svc express-app
service "express-app" deleted
```

# 四日目を振り返って

実際に動作させることを目標に`kubernetes`の触りの部分をやりました。`pod`が作り直されるところを確認すると、運用することに重点されていることが何となく感じられたと思います。これをdocker-compose＋他の仕組みを自分たちで作ろうとするとタイヘンかと・・・。
今回の場合はアプリの元になったイメージが公開されていることを前提にしています。非公開にした場合の内容は五日目に続きます。