GraphQLの旅(1) Kubernetes上でPrisma/PostgreSQLによるGraphQL開発

# Prisma/PostgreSQLをKubernetes上に起動する

### 目的：PrismaでGraphQLサーバを楽に構築したい。環境はDockerじゃなくKubernetes！

Prismaでは、GraphQLのエンドポイントやデータベースのスキーマを自動で作成してくれます。

参考：　Prismaの位置づけはDevelopment toolだと思う

![graphql.png](https://qiita-image-store.s3.amazonaws.com/0/96277/615d9dde-4ec8-6bba-9bf8-3900ad87145b.png)

この力をKubernetesでも活用したい、と思ったらデータベースインスタンス構築部分は現状docker-composeのみに対応。

今回はこれをKubernetes上に構築します。
[本家ドキュメント](https://www.prisma.io/docs/tutorials/cluster-deployment/kubernetes-aiqu8ahgha)には MySQLをKubernetesに構築する例がございます。

今回は、個人的な趣味でPostgreSQLをデータベースに使用します。

方針

- prisma initでdocker-compose.yamlが出力される。
- これをKomposeでkubernetes用Yamlに変換。

## Prismaインストール

```
# Prismaのインストール
npm install -g prisma
```

## 新規Prismaプロジェクト作成

```
$ prisma init graphql-psql-k8s

  You can set up Prisma for local development (based on docker-compose)
  Use existing database      Connect to existing database
❯ Create new database        Set up a local database using Docker

? What kind of database do you want to deploy to?
  MySQL             MySQL compliant databases like MySQL or MariaDB
❯ PostgreSQL        PostgreSQL database

Created 3 new files:

  prisma.yml           Prisma service definition
  datamodel.graphql    GraphQL SDL-based datamodel (foundation for database)
  docker-compose.yml   Docker configuration file

Next steps:

  1. Open folder: cd graphql-psql-k8s
  2. Start your Prisma server: docker-compose up -d
  3. Deploy your Prisma service: prisma deploy
  4. Read more about Prisma server:
     http://bit.ly/prisma-server-overview
```

フォルダに入ってみる。

```
cd graphql-psql-k8s/
```

内部構造はこんな感じ。

```
.
├── datamodel.graphql
├── docker-compose.yml
└── prisma.yml
```

## Komposeを使ってKubernetes用に変換

[Kompose](https://github.com/kubernetes/kompose)はdocker-composeファイルからkubernetesファイルを作るツールで、Kubernetesのサブプロジェクトです。

Linuxの場合は下記でインストールします。

```
curl -L https://github.com/kubernetes/kompose/releases/download/v1.15.0/kompose-linux-amd64 -o kompose
chmod +x kompose
sudo mv ./kompose /usr/local/bin/kompose
```

Komposeを使って、先ほど作成したPrismaフォルダ内でファイル変換を実施します。

```
$ mkdir k8s
$ kompose convert -f docker-compose.yml -o k8s
INFO Kubernetes file "k8s/prisma-service.yaml" created
INFO Kubernetes file "k8s/postgres-deployment.yaml" created
INFO Kubernetes file "k8s/postgres-persistentvolumeclaim.yaml" created
INFO Kubernetes file "k8s/prisma-deployment.yaml" created
```

そうするとk8sフォルダ内に`.yaml`ファイル群が作成されています。

今回は`k8s/prisma-service.yaml`を下記のように変更し、PrismaにNodePort方式でアクセスします。

```
- type: ClusterIP
+ type: NodePort
  port:
+   nodePort: 30432 (Kubernetesが許可したポート範囲で空いている任意のポート番号を指定)
```

また、postgresにserviceができていないので、追加します。

```
echo << EOS > k8s/postgres-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  type: ClusterIP
  ports:
  - name: "5432"
    port: 5432
    targetPort: 5432
  selector:
    io.kompose.service: postgres
status:
  loadBalancer: {}
EOS
```

## Kubernetesを整備

kubernetesにPrismaを起動するためのnamespaceを作ります。これは本家ドキュメントと同じです。

そのあと、デプロイ先としてprismaというnamespaceを規定にしておきます。

```
kubectl create namespace prisma
kubectl config set-context <current-context名> --namespace=prisma 
Context <current-context名> modified.
```



## Databaseを起動

もともとdocker-compose用に作られたPostgreSQL/Prisma起動はしなくてよいです。
そのかわり、下記を実施。

```
# docker-compose up -dはしなくてよい
$ kubectl create -f ./k8s
deployment.extensions/postgres created
persistentvolumeclaim/postgres created
deployment.extensions/prisma created
service/postgres created
service/prisma created
```

ここまで来て、`kubectl get pod`で問題なくprismaが起動したようなら、`<kubernetesのIP>:<prismaのnodePort>`にブラウザでアクセスします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/96277/e5b809cb-7c99-1c38-2d6d-49d07cf28e39.png)

## Prismaの設定ファイルを変更

`prisma.yaml`を変更し、Kubernetes内のprismaのserviceに宛先を変更します。

```
endpoint: http://<kubernetesのIP>:<prismaのnodePort>
```

## Prisma起動（データベースにスキーマをインストール）

```
$ prisma deploy
Creating stage default for service default ✔
Deploying service `default` to stage `default` to server `default` 8.2s

Changes:

  User (Type)
  + Created type `User`
  + Created field `id` of type `GraphQLID!`
  + Created field `name` of type `String!`
  + Created field `updatedAt` of type `DateTime!`
  + Created field `createdAt` of type `DateTime!`

Applying changes 5.7s
```

## 結果：Prismaにアクセス

下記のように、Prismaの`schama.graphql`で指定されているスキーマ(Users)がちゃんとPostgreSQLとPrisma上で構築されていて、GraphQLが試せることがわかります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/96277/4a7d611a-3bf2-0f8d-08f2-87bf3935cfc2.png)

### その他参考

[単純にdocker-composeで起動するなら](https://qiita.com/Hiroyuki_OSAKI/items/2c81369bf6d3006e3f74)