【Kubernetes】Laravel環境の構築ー後編ー

Kubernetes

Laravel実行環境をKubernetesで実装します。
アプリケーションを詰め込みたいのでイメージを作成してKubernetesでデプロイします。
出来るだけKubernetesで管理したいのでNginxとphp-fpmをコンテナ1つで作成してMariaDBをKubernetesでデプロイします。
コンフィグやマニュフェストが長くなるので前編と後編に分けます。
 ①Dockerイメージ作成
 ②Kubernetesでデプロイ ←ここ

前編は下記になります。

マニフェスト作成

シークレット作成やリソース定義するため下記ファイルを作成します。
kustomization.yaml

secretGenerator:
- name: maria-lara-secret
  literals:
  - root-password=[rootパスワード]
  - database-name=[db名]
  - user-username=[ユーザ名]
  - user-password=[ユーザパスワード]
resources:
  - mariadb-dep.yaml
  - lara-dep.yaml

Laravel実装用のマニフェストを作成します。
lara-dep.yaml
永続ストレージとしてnfsを設定してLaravelプロジェクトを保存します。
また、コンフィグマップで環境変数を設定してます。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: laravel-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany # 複数から読み書き可能
  persistentVolumeReclaimPolicy: Retain # 永続
  storageClassName: slow-lara
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /nfs/laravel
    server: [IPアドレス]
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: laravel-pv-claim
  labels:
    app: laravel-dep
spec:
  accessModes:
    - ReadWriteMany #複数から読み書き可能
  resources:
    requests:
      storage: 5Gi
  storageClassName: slow-lara
---
apiVersion: v1
kind: ConfigMap
metadata:
  creationTimestamp: null
  name: laravel-config
data:
  APP_NAME: Laravel
  APP_ENV: local
  APP_KEY: 'null'
  APP_DEBUG: 'true'
  APP_URL: http://localhost

  DB_CONNECTION: mysql
  DB_HOST: laravel-mariadb
  DB_PORT: '3306'
  DB_DATABASE: [db名]
  DB_USERNAME: [ユーザ名]
  DB_PASSWORD: [パスワード]

  BROADCAST_DRIVER: log
  CACHE_DRIVER: file
  QUEUE_CONNECTION: sync
  SESSION_DRIVER: file
  SESSION_LIFETIME: '120'

  REDIS_HOST: '127.0.0.1'
  REDIS_PASSWORD: 'null'
  REDIS_PORT: '6379'

  MAIL_DRIVER: smtp
  MAIL_HOST: smtp.mailtrap.io
  MAIL_PORT: '2525'
  MAIL_USERNAME: 'null'
  MAIL_PASSWORD: 'null'
  MAIL_ENCRYPTION: 'null'

  AWS_ACCESS_KEY_ID: 'null'
  AWS_SECRET_ACCESS_KEY: 'null'
  AWS_DEFAULT_REGION: us-east-1
  AWS_BUCKET: 'null'

  PUSHER_APP_ID: 'null'
  PUSHER_APP_KEY: 'null'
  PUSHER_APP_SECRET: 'null'
  PUSHER_APP_CLUSTER: mt1

  MIX_PUSHER_APP_KEY: "${PUSHER_APP_KEY}"
  MIX_PUSHER_APP_CLUSTER: "${PUSHER_APP_CLUSTER}"
---
apiVersion: v1
kind: Service
metadata:
  name: laravel-dep
  labels:
    app: laravel-dep
spec:
  ports:
    - port: 8080
      protocol: TCP
      targetPort: 80
  selector:
    app: laravel-dep
    tier: frontend
  #type: NodePort
  type: LoadBalancer # MetalLBで分散しているので
LoadBalancerタイプを設定
  #externalTrafficPolicy: Local
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: laravel-dep
  labels:
    app: laravel-dep
spec:
  selector:
    matchLabels:
      app: laravel-dep
      tier: frontend
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: laravel-dep
        tier: frontend
    spec:
      containers:
      - image: [ユーザ名]/laravel-dep:latest
        name: laravel-dep
        ports:
        - containerPort: 9000
          name: laravel-dep
        envFrom:
          - configMapRef:
              name: laravel-config
        volumeMounts:
        - name: laravel-persistent-storage
          #mountPath: /var/www/portal
          mountPath: /var/www/portal/tmp  # 初回起動時は上書きしてしまうのでpod内でコピーしてnfsに保存
      - image: [ユーザ名]/nginx-dep:latest
        name: nginx-dep
        ports:
        - containerPort: 80
        envFrom:
          - configMapRef:
              name: laravel-config
        volumeMounts:
        - name: laravel-persistent-storage
          mountPath: /var/www/portal
      volumes:
      - name: laravel-persistent-storage
        persistentVolumeClaim:
          claimName: laravel-pv-claim

mariadbのマニフェストを作成します。
mariadb-dep.yaml
永続ストレージとしてnfsを設定してDBデータを保存します。
また、コンフィグマップで環境変数を設定してます。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: laravel-mariadb-pv
  labels:
    type: nfs
spec:
  storageClassName: slow-laravel-maria
  capacity:
    storage: 3Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /nfs/mariadb
    server: [IPアドレス]
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: laravel-mariadb-pv-claim
  labels:
    app: laravel-dep
spec:
  storageClassName: slow-laravel-maria
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 3Gi
---
apiVersion: v1
kind: Service
metadata:
  name: laravel-mariadb
  labels:
    app: laravel-dep
spec:
  selector:
    app: laravel-dep
    tier: backend
  ports:
    - name: laravel-mariadb
      port: 3306
      targetPort: 3306
      protocol: TCP
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: laravel-mariadb
  labels:
    app: laravel-dep
spec:
  selector:
    matchLabels:
      app: laravel-dep
      tier: backend
  replicas: 1
  template:
    metadata:
      labels:
        app: laravel-dep
        tier: backend
    spec:
      containers:
      - name: laravel-db-data
        image: mariadb
        ports:
        - containerPort: 3306
          name: laravel-db-data
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: maria-lara-secret
              key: root-password
        - name: MYSQL_DATABASE
          valueFrom:
            secretKeyRef:
              name: maria-lara-secret
              key: database-name
        - name: MYSQL_USER
          valueFrom:
            secretKeyRef:
              name: maria-lara-secret
              key: user-username
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: maria-lara-secret
              key: user-password
        volumeMounts:
        - name: laravel-mariadb-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
        - name: laravel-mariadb-persistent-storage
          persistentVolumeClaim:
            claimName: laravel-mariadb-pv-claim

本番環境デプロイ

デプロイ

デプロイします。

 kubectl apply -k ./

稼働確認します。
php-fpmのコンテナが2/2でRunningになれば正常に稼働しています。

# kubectl get pod
NAME                                 READY   STATUS    RESTARTS       AGE
laravel-dep-5d9dffe-z4vfj           2/2     Running   0              61m
laravel-mariadb-74e148fz9-qvbhd     1/1     Running   0              61m

php-fpmコンテナに入ります。

kubectl exec -it laravel-dep-5d9dffe-z4vfj --container=laravel-dep /bin/sh

初期フォルダをtmpフォルダに入れているので拡張ファイル含めて移動させます。

cd tmp
mv ./tmp ../
mv ./tmp/.[^.]* ../
cd ..

artisan コマンドでDBのマイグレーション実行します。

php artisan migrate

マニフェスト修正

コンテナから抜けて、マニフェストを修正します。

        - name: laravel-persistent-storage
          mountPath: /var/www/portal
          #mountPath: /var/www/portal/tmp  # 初回起動時は上書きしてしまうのでpod内でコピーしてnfsに保存

マニフェストを適用します。

kubectl apply -k ./

http://[IPアドレス]:8080で接続確認をします。

最後に

ここまで書きましたが、イメージ作成ではアプリケーションのインストールだけにして、Laravelのプロジェクト作成はコンテナ入って作成した方が良いと思いました。
結局、初期構築時にGitクローンやマイグレーション、シーダ実行などしないといけませんので。
実際に開発環境で利用する場合は今回作ったイメージではまだまだ粗削りですので、Mix,ViteのHMRやSSL適用を考慮した設計にする必要があります。