6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Webアプリ構築カレンダーAdvent Calendar 2023

Day 25

【Day 25】Skaffoldで起動する

Last updated at Posted at 2023-12-24

はじめに

スライド26.png


2023年アドベントカレンダー最終日です。

昨日と今日で、k8sの環境をskaffoldで作っています。

本日は立ち上げの最後までいきます。

各Dockerfileの作成

各サービスを立ち上げるためのDockerfileを作成します。

ディレクトリ構造のイメージとしてはこのような感じです

.
├── api
├── bff
├── dockers
|   ├── api
|   |   └── Dockerfile
|   ├── bff
|   |   └── Dockerfile
|   ├── db
|   |   ├── init.sql
|   |   └── Dockerfile
|   └── web
|       └── Dockerfile
└── web

Web

WebはNext.jsで動きます。

nodejsのイメージを使い、buildしてから、startするような形が良いでしょう

dockers/web/Dockerfile
FROM node:21-alpine3.17

WORKDIR /life-sync-web

COPY ./web /life-sync-web

RUN npm install && npm run build

CMD ["npm", "run", "start"]

BFF

BFFはNestJSで動きます。

nodejsのイメージを使い、prodモードで起動するようにstart:prodしようと思います

dockers/bff/Dockerfile
FROM node:21-alpine3.17

WORKDIR /life-sync-bff

COPY ./bff /life-sync-bff

RUN npm install

CMD ["npm", "run", "start:prod"]

API

APIはRustで動きます。

nodejsのイメージを使い、cargo runします。

dockers/api/Dockerfile
FROM rust:1.73-buster

WORKDIR /life-sync-api

COPY ./api /life-sync-api

CMD ["cargo", "run"]

DB

DBはpostgresqlで動かします。
起動後に、init.sqlを動かしたいので、Dockerfileを作っていきます

dockers/db/init.sql
CREATE TABLE blog (
    id UUID PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    author VARCHAR(255) NOT NULL,
    body TEXT NOT NULL,
    created_at VARCHAR(255) NOT NULL
);
dockers/db/Dockerfile
FROM postgres:16

COPY ./dockers/db/init.sql /docker-entrypoint-initdb.d/

Skaffold

Skaffoldとは、Googleによって開発されたKubernates開発のためのコマンドラインツールです。

Skaffoldについては私が所属するUzabaseの先輩が書いた素晴らしい記事があるので、こちらをお読みください

Skaffold.yaml

Skaffold.yamlを作成しました。

skaffold.yaml
apiVersion: skaffold/v2beta19
kind: Config
build:
  artifacts:
    - image: life-sync-web
      context: .
      docker:
        dockerfile: ./dockers/web/Dockerfile
    - image: life-sync-bff
      context: .
      docker:
        dockerfile: ./dockers/bff/Dockerfile
    - image: life-sync-api
      context: .
      docker:
        dockerfile: ./dockers/api/Dockerfile
    - image: life-sync-db
      context: .
      docker:
        dockerfile: ./dockers/db/Dockerfile
deploy:
  kubectl:
    manifests:
      - k8s/web/*.yaml
      - k8s/bff/*.yaml
      - k8s/api/*.yaml
      - k8s/db/*.yaml
portForward:
  - resourceType: service
    resourceName: life-sync-web
    namespace: default
    port: 3000
    localPort: 3000
  - resourceType: service
    resourceName: life-sync-bff
    namespace: default
    port: 3000
    localPort: 4000
  - resourceType: service
    resourceName: life-sync-api
    namespace: default
    port: 3000
    localPort: 8000
  - resourceType: service
    resourceName: life-sync-db
    namespace: default
    port: 5432
    localPort: 5432

上から順に、

  1. DockerImageを指定して
  2. deployのためのmanifestファイルの場所を指定して
  3. portを開放する

といった感じです

manifestファイル

.
├── api
├── bff
├── dockers
├── k8s
|   ├── api
|   |   ├── deployment.yaml
|   |   └── service.yaml
|   ├── bff
|   |   ├── deployment.yaml
|   |   └── service.yaml
|   ├── db
|   |   ├── service.yaml
|   |   └── statefulset.yaml
|   └── web
|   |   ├── deployment.yaml
|   |   └── service.yaml
└── web

Web

deployment.yaml
k8s/web/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: life-sync-web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: life-sync-web
  template:
    metadata:
      labels:
        app: life-sync-web
    spec:
      containers:
        - name: life-sync-web
          image: life-sync-web:latest
          ports:
            - containerPort: 3000
service.yaml
k8s/web/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: life-sync-web
spec:
  selector:
    app: life-sync-web
  ports:
    - protocol: TCP
      port: 3000
      targetPort: 3000
  type: LoadBalancer

BFF

deployment.yaml
k8s/bff/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: life-sync-bff
spec:
  replicas: 1
  selector:
    matchLabels:
      app: life-sync-bff
  template:
    metadata:
      labels:
        app: life-sync-bff
    spec:
      containers:
        - name: life-sync-bff
          image: life-sync-bff:latest
          ports:
            - containerPort: 3000
service.yaml
k8s/bff/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: life-sync-bff
spec:
  selector:
    app: life-sync-bff
  ports:
    - protocol: TCP
      port: 3000
      targetPort: 3000
  type: LoadBalancer

API

deployment.yaml
k8s/api/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: life-sync-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: life-sync-api
  template:
    metadata:
      labels:
        app: life-sync-api
    spec:
      containers:
        - name: life-sync-api
          image: life-sync-api:latest
          ports:
            - containerPort: 3000
service.yaml
k8s/api/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: life-sync-api
spec:
  selector:
    app: life-sync-api
  ports:
    - protocol: TCP
      port: 3000
      targetPort: 3000
  type: LoadBalancer

DB

service.yaml
k8s/db/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: life-sync-db
spec:
  ports:
  - protocol: TCP
    port: 5432
    targetPort: 5432
  selector:
    app: life-sync-db
  type: ClusterIP
statefulset.yaml
k8s/db/statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: life-sync-db
spec:
  serviceName: life-sync-db
  replicas: 1
  selector:
    matchLabels:
      app: life-sync-db
  template:
    metadata:
      labels:
        app: life-sync-db
    spec:
      containers:
        - name: life-sync-db
          image: life-sync-db:latest
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_DB
              value: life-sync
            - name: POSTGRES_USER
              value: postgres_user
            - name: POSTGRES_PASSWORD
              value: postgres_password

起動

これで起動してみます!

今回の設定とは別で各サービスで他サービスを指定している個所をENVに移行したり、CORSの設定をしたりしました。本題とはずれるので省略しました。

skaffold dev

起動ができました。

image.png

直接DBに入り、データをいくつか入れてみました。

データ投入方法

psqlを利用して、直接アクセスしました。

psql -h localhost -p 5432 -U postgres_user -W -d life-sync

好みに合わせて、A5M2や、DBeaverなどのGUIツールを入れてもいいでしょう

ちゃんと表示されました👍

image.png

最後に・アドベントカレンダーを振り返って

去年は一貫性の無いアドベントカレンダーを走りましたが、今年は一つのアプリを構築してみました。
そのため、ユーザーストーリーデザインWebの実装BFFの実装APIの実装各種テスト・モックK8s環境構築といったWebアプリケーションを作る上で必要な一通りの実装を触ることができました。

(実際にクラウド上にデプロイするとなると、もう少しネットワーク関係やセキュリティ面でやることはあるでしょう)

25個の記事を書くのは大変でしたが、楽しかったです

来年も頑張るぞ!

image.png

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?