Kubernetes × DB(MySQL / PostgreSQL)徹底入門

はじめに

Kubernetes
コンテナを自動で配置・復旧・スケーリングしてくれる非常に強力な基盤です。

しかし、Kubernetesを学び始めた多くの人が、次の壁にぶつかります。

  • Webアプリ(Node.js / Python)は動かせた
  • でも MySQL / PostgreSQL はどう扱えばいいのか分からない
  • Podが消えたらDBのデータは消えるのでは?
  • 本番でKubernetes上にDBを置いていいのか?

これらは 非常に正しい疑問 です。
なぜなら、DBはKubernetesが最も苦手とする「ステートフル(状態を持つ)」存在だからです。

本記事では、

  • Kubernetesが「状態」をどう扱うのか
  • なぜStatefulSetが必要なのか
  • PersistentVolume / PVCの本当の役割
  • MySQL / PostgreSQLを安全に動かす具体例
  • 実務でやってはいけない設計

までを、文章多め・図を想像しながら理解できる構成で解説します。


そもそもKubernetesはDB向きなのか?

まず最初に、現場目線の結論を明確にします。

結論

  • 学習・検証・小規模構成 → Kubernetes上でDBを動かすのはアリ
  • 重要データ・大規模本番 → マネージドDBを使うことが多い

これは「KubernetesでDBが動かせない」からではありません。
「DBは壊れたときの影響が大きすぎる」 からです。


ステートレスとステートフルの決定的な違い

Kubernetes理解の核心はここです。

ステートレス(Stateless)

例:

  • Node.js API
  • Python Flaskアプリ
  • バッチ処理

特徴:

  • Podが消えても問題ない
  • データは外部(DB)にある
  • 何個起動しても同じ動作

👉 Kubernetesが最も得意な領域


ステートフル(Stateful)

例:

  • MySQL
  • PostgreSQL
  • Redis(永続化あり)

特徴:

  • データを内部に保持する
  • Podが消えるとデータ消失リスク
  • 同じ名前・同じストレージが必要

👉 DBはステートフルの代表格


なぜDeploymentではDBを動かしてはいけないのか

初心者が最初にやりがちなミスがこれです。

kind: Deployment
image: mysql

一見動きます。
しかし 本質的な問題 があります。

  • Podが再作成されるたびに名前が変わる
  • ストレージが紐づかない
  • 再起動でデータが消える可能性

👉 Deploymentは「使い捨て前提」
👉 DBは「同じ存在であり続ける必要がある」

このギャップを埋めるのが StatefulSet です。


StatefulSetとは何か(超重要)

StatefulSetは、ステートフルアプリ専用の仕組みです。

StatefulSetの特徴

  • Pod名が固定される(mysql-0 など)
  • Podとストレージが1対1で紐づく
  • 再作成されても同じIDとして扱われる

👉 「このDBはこのDBであり続ける」
これをKubernetesに理解させるための仕組みです。


データ永続化の要:PV と PVC

ここが一番イメージしづらい部分なので、丁寧に説明します。

PersistentVolume(PV)

  • 実際のディスク領域
  • 「物理的なストレージ」

PersistentVolumeClaim(PVC)

  • 「このくらいのディスクをください」という要求
  • Podは直接PVを触らない

なぜ分かれているのか?

  • インフラ担当とアプリ担当を分離するため
  • ストレージの実装を隠蔽するため

👉 Pod → PVC → PV → ディスク
この間接構造がKubernetesらしさです。


Kubernetes × DB の全体構成イメージ

頭の中では、次のように考えてください。

[ Pod (MySQL) ]
      |
   volumeMount
      |
     PVC
      |
      PV
      |
   実ディスク

Podが消えても
👉 PVCとPVが残っていればデータは消えない


【ハンズオン①】Kubernetes × MySQL(文章多め解説付き)

目的

  • StatefulSetでMySQLを起動
  • Pod削除後もデータが残ることを理解する

MySQL StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:8.4
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: rootpass
            - name: MYSQL_DATABASE
              value: sampledb
          ports:
            - containerPort: 3306
          volumeMounts:
            - name: mysql-data
              mountPath: /var/lib/mysql
  volumeClaimTemplates:
    - metadata:
        name: mysql-data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 5Gi

このYAMLの本質

  • volumeClaimTemplatesPodごとのディスクを自動生成
  • mysql-0必ず同じディスクを使う
  • Podが消えても「中身の人格」は変わらない

データ永続化の確認

kubectl exec -it mysql-0 -- mysql -uroot -prootpass
CREATE TABLE test (id INT);
INSERT INTO test VALUES (1);

Podを削除:

kubectl delete pod mysql-0

👉 再作成後もデータが残る理由
→ ストレージがPodの外にあるから


【ハンズオン②】Kubernetes × PostgreSQL(思想は同じ)

PostgreSQLでも 考え方は完全に同じ です。

  • StatefulSetを使う
  • データディレクトリをvolumeMount
  • PVCで永続化

技術が変わっても、Kubernetesの思想は一貫しています。


アプリ側からの接続設計(重要)

Kubernetesでは Service名 = ホスト名 です。

mysql:3306
postgres:5432

これにより、

  • Podが変わっても
  • IPが変わっても

👉 アプリ側の設定は変えなくてよい


実務で必ず考えるべきこと

  • リソース制限(CPU / メモリ)
  • バックアップ戦略
  • Secretによる認証情報管理
  • マネージドDBとの使い分け

やってはいけない設計(重要)

  • DeploymentでDBを動かす
  • emptyDirを使う
  • バックアップなし
  • 本番でlatestタグ

👉 「動く」と「安全」は別物 です。


まとめ

Kubernetes × MySQL / PostgreSQLは、

  • Kubernetesの本質を理解する最高の教材
  • ステートフル設計の考え方が身につく
  • 本番設計の判断力が養われる

「DBをどう扱うか分かる=Kubernetesを理解した」
と言っても過言ではありません。


投稿日

カテゴリー:

投稿者:

タグ:

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です