Komposeを使ってdocker-compose.ymlからk8sマニフェストファイルを作成する

## はじめに

この記事の環境は以下のGitHubにあります。
https://github.com/bocci-farm/docker-rails

## インストール

```console
% brew install kompose
```

## 元になるdocker-composeを作成

versionは"3"や"3.8", "3.9"だと後のkomposeの工程でエラーになったので"3.7"にしています。

```yaml:docker-compose.yml
version: "3.7"
services:
  db:
    image: boccifarm/mysql:8.0.23
    build:
      context: ./docker/db/
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - 3306:3306
      - 33060:33060
    volumes:
      - type: volume
        source: db
        target: /var/lib/mysql
  app:
    image: boccifarm/rails:6.1.3-ruby3.0.0-alpine3.13
    build:
      context: ./app/
      dockerfile: ../docker/app/Dockerfile
    environment:
      RAILS_DATABASE_HOST: db
      RAILS_DATABASE_USERNAME: root
      RAILS_DATABASE_PASSWORD: password
    ports:
      - 3000:3000
    depends_on:
      - db
  web:
    image: boccifarm/nginx:1.18.0-alpine
    build:
      context: ./docker/web/
    ports:
      - 80:80
    depends_on:
      - app
volumes:
  db:
```

## まずはdocker-composeが正常に起動することを確認

```console
% DOCKER_BUILDKIT=1 COMPOSE_DOCKER_CLI_BUILD=1 docker-compose build
% docker-compose up -d
```

ブラウザから確認します。
http://localhost/
![スクリーンショット 2021-03-05 15.54.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1177074/51b98f37-51f9-1e3f-a3a3-661b4415f345.png)

問題なければdocker-composeを落としておきます。

```
% docker-compose stop
```

## komposeを使ってk8sマニフェストファイルを作成

```console
% mkdir -p k8s/overlays/local
% kompose convert --volumes hostPath -o k8s/overlays/local
```

## k8sマニフェストファイルの編集

作成されるのはあくまで雛形なので自分の環境に合うように微調整します。

### hostPathのpathにdocker volumeを指定する

こうすることでdocker-composeで使用していたdocker volumeを共用できます。

```yaml:k8s/overlays/local/db-deployment.yaml
 41       volumes:
 42         - hostPath:
 43             path: docker-rails_db  # <= docker volumeに変更
```

### ローカルのイメージを使用するようにimagePullPolicy: Neverを追加

imagePullPolicy: Neverを設定するとローカルにあるイメージを使うように強制できます。

```yaml:k8s/overlays/local/app-deployment.yaml
 34           image: boccifarm/rails:6.1.3-ruby3.0.0-alpine3.13
 35           imagePullPolicy: Never  # <= 追加
```

```yaml:k8s/overlays/local/db-deployment.yaml
 31           image: boccifarm/mysql:8.0.23
 32           imagePullPolicy: Never  # <= 追加
```

```yaml:k8s/overlays/local/web-deployment.yaml
 27         - image: boccifarm/nginx:1.18.0-alpine
 28           imagePullPolicy: Never  # <= 追加
```

### serviceのTypeをNodePortにする

ローカル環境なのでserviceのTypeをNodePortにします。
今回はweb(nginx)だけ外からアクセスできればいいので、web-service.yamlのみ編集します。

```yaml:k8s/overlays/local/web-service.yaml
 11 spec:
 12   ports:
 13     - name: "80"
 14       port: 80
 15       targetPort: 80
 16   selector:
 17     io.kompose.service: web
 18   type: NodePort  # <= 追加
```

## k8sの起動

```console
% kubectl apply -f k8s/overlays/local
% kubectl get po,deploy,svc
NAME                       READY   STATUS    RESTARTS   AGE
pod/app-b75844fb8-24fqx    1/1     Running   0          17s
pod/db-9cb76c59d-tvmtq     1/1     Running   0          17s
pod/web-785bb88999-nkxkd   1/1     Running   0          17s

NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/app   1/1     1            1           17s
deployment.apps/db    1/1     1            1           17s
deployment.apps/web   1/1     1            1           17s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)              AGE
service/app          ClusterIP   10.102.65.9      <none>        3000/TCP             17s
service/db           ClusterIP   10.98.6.248      <none>        3306/TCP,33060/TCP   17s
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP              16d
service/web          NodePort    10.110.198.177   <none>        80:31427/TCP         17s
```

ブラウザから確認します。ポートはNodePort(今回は31427)を指定します。
http://localhost:31427/
![スクリーンショット 2021-03-05 16.22.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1177074/3402252d-3b47-7b7a-c811-e43a841c9df7.png)

以上