VPSに乗せていたappを自宅のオンプレに移す試み(mysqlを稼働させる)

スポンサーリンク
DB

はじめに

今回はDB部分を稼働させます。

まだ、DB稼働させていなかったんか!ってツッコミはあるかもしれませんが、ちゃんと稼働させていませんでした。(てへぺろ)

当然ですが、アプリケーションにはデータのやり取りがあるので、今回のゴールはデータのやり取りができるところまで実装していきます。

ポイントとしては、

  • k8s上でのボリュームデータの扱い
  • パスワードの扱い(Secretを使用する)
  • 正規化のためにサイドカー構成にする

です。

実装前に

実装前に今回の実装する必要があることについてまとめておきます。

おうちk8s上にDBを乗せる上での考慮は以下の3つです。

  • k8s上でのボリュームデータの扱いを考慮する
  • パスワードの扱いを考慮する
  • 正規化のためにサイドカー構成にする

です。

1つずつ見ていきましょう。

k8s上でのボリュームデータの扱い

まず、docker-composeではvolumeとして以下のような設定をしていました。

    volumes:
      - ./db/dml:/tmp/dml
      - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql

これと同等のことをk8sでするにはvolumeを使用すればいいだけなのかというとそういう訳でもないです。

dmlの方はDBにインプットするデータで、肥大していく且つ更新していく必要があるデータになります。

このため、

  • dml⇒volume
  • init.sql⇒ConfigMap

としていきます。

パスワードの扱い(Secretを使用する)

DBで扱うパスワードにはセキュリティ的な観点でSecretを使用するようにします。

正規化のためにサイドカー構成にする

元々のdocker composeを使用した構成ではスクリプトを用意して、DBの中身を更新する際に正規化をしていました。

それをおうちk8sではどうするかと言うと、サイドカー構成にして、pythonコンテナを用意し、そこからmysqlにアクセスし、正規化を行うようにします。

そのデータをDjangoのbackend podからアクセスし、データを読み込むという構成になります。

以下のようになるという事です。

実際の実装内容

実際の実装内容は以下のようになります。

configmap.yamlの中身

configmap.yamlには設定ファイルとして用意する内容を記載します。

僕の場合は、init.sqlの内容と、my.cnfの設定を書いています。

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-config
data:
  my.cnf: |
    [mysqld]
    local-infile=1
    [mysql]
    local-infile=1

---

apiVersion: v1
kind: ConfigMap
metadata:
  name: db-init-configmap
data:
  init.sql: |
      -- ★init.sqlに書く内容を記載
      CREATE DATABASE IF NOT EXISTS test_db;

      set password for root@localhost = 'root';
      CREATE USER IF NOT EXISTS 'test_user'@'%' IDENTIFIED BY 'xxx_passwd';
      ALTER USER 'test_user'@'%' IDENTIFIED BY 'xxx_passwd';

      GRANT ALL PRIVILEGES ON test_db.* TO 'test_user'@'%';
      GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO test_user;
・・・【略】・・・

secret.yamlの中身

dataの値はdeployment.yamlの中で使用します。

apiVersion: v1
kind: Secret
metadata:
  name: sql-secret
type: Opaque
data:
  # パスワードをbase64でエンコードした値
  mysql_root_password: crrrdA==
  mysql_password: ZGphbssssttttTTA==

deployment.yamlの中身

この下に一つ一つの説明を記載しておきます。

apiVersion: apps/v1
・・・【略】・・・
spec:
  selector:
    matchLabels:
      app: {{ .Values.dbDeployment.labels.app }}
  strategy:
    type: {{ .Values.dbDeployment.strategy }}
  template:
    metadata:
      labels:
        app: {{ .Values.dbDeployment.labels.app }}
    spec:
      containers:
        - name: {{ .Values.dbDeployment.containerName }}
          image: {{ .Values.dbDeployment.image }}          
          args:
            {{- range .Values.dbDeployment.args }}
            - {{ . }}
            {{- end }}
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: sql-secret
                  key: mysql_root_password
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: sql-secret
                  key: mysql_password
            - name: MYSQL_USER
              value: {{ .Values.dbDeployment.env.MYSQL_USER }}
            - name: TZ
              value: {{ .Values.dbDeployment.env.TZ }}
            - name: MYSQL_DATABASE
              value: {{ .Values.dbDeployment.env.MYSQL_DATABASE }}
          ports:
            - containerPort: {{ .Values.dbDeployment.containerPort }}
              name: mysql
          volumeMounts:
            - name: mysql-dml
              mountPath: {{ .Values.dbDeployment.mountDmlPath }}
            - name: sql-init-config
              mountPath: /docker-entrypoint-initdb.d
            - name: mysql-config-volume
              mountPath: /etc/mysql/conf.d/my.cnf
              subPath: my.cnf
        - name: python-runner
          image: python:3.10
          volumeMounts:
            - name: mysql-dml
              mountPath: /data
          command: ["sh", "-c"]
          args:
            - |
              apt-get update && apt-get install -y default-mysql-client
              until mysqladmin ping -h localhost --silent; do sleep 1; done
              python3 /data/python_codes/exec_1nf_season_spot.py
              python3 /data/python_codes/exec_1nf_season_food_2.py
      volumes:
        - name: mysql-dml
          persistentVolumeClaim:
            claimName: {{ .Values.dbDeployment.pvcName }}
        - name: sql-init-config
          configMap:
              name: db-init-configmap
              items:
                - key: init.sql
                  path: init.sql
        - name: mysql-config-volume
          configMap:
            name: mysql-config

envのところで上記で設定したsecret.yamlのパスワードが使用されています。

          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: sql-secret
                  key: mysql_root_password
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: sql-secret
                  key: mysql_password

volumeはconfigmap.yamlで設定した値に加えて、実際にマウントしたファイル群もあります。

マウントするデータは実際のDBに入る値などです。

      volumes:
        - name: mysql-dml
          persistentVolumeClaim:
            claimName: {{ .Values.dbDeployment.pvcName }}
        - name: sql-init-config
          configMap:
              name: db-init-configmap
              items:
                - key: init.sql
                  path: init.sql
        - name: mysql-config-volume
          configMap:
            name: mysql-config

サイドカー用のpythonコンテナを用意しています。

こちらが正規化するpythonコードが書かれたコードを実行します。

pythonコードは別途自分で用意する必要があります。

        - name: python-runner
          image: python:3.10
          volumeMounts:
            - name: mysql-dml
              mountPath: /data
          command: ["sh", "-c"]
          args:
            - |
              apt-get update && apt-get install -y default-mysql-client
              until mysqladmin ping -h localhost --silent; do sleep 1; done
              python3 /data/python_codes/exec_1nf_season_spot.py
              python3 /data/python_codes/exec_1nf_season_food_2.py

以上で、おうちk8sのDB部分の設定が完了です。

最後に

データを扱うところだから大事にいきたいところですね。

タイトルとURLをコピーしました