【メンテナンス告知:2025/12/05 15~17時】メンテナンス中はサイトの閲覧ができなくなりますのでご了承下さい。

コンテナDB実践シリーズ④:アプリコンテナからDBコンテナへの接続

はじめに

前回は、StatefulSetと永続ボリューム(PV/PVC)を使い、データが消えないDBコンテナを起動しました。

しかし、データベースはアプリケーションから接続されて初めて価値があります。そのため今回はアプリコンテナとDBコンテナの接続方法を学びます。

前提条件

  • Kubernetesで、Pod同士をどうやって通信させるのか仕組みを知りたい方
  • DBコンテナを立てることはできたが使用出来ていない状態の方

アプリコンテナとDBコンテナを接続するための基本概念

コンテナ同士を接続する方法はいくつかありますが、Kubernetesでは推奨される接続方法が決まっており、単純な接続方法ではうまくいきません。特にDB接続では、ポート番号や認証情報(Secret)をアプリコンテナに適切に渡す必要があるほか、DBコンテナの動的なスケーリングや再起動によるIPアドレスの変動が接続安定性の課題となります。

このような固有の課題を解決するためには、Kubernetesのネットワーク層におけるServiceやDNSの仕組みを理解することが重要です。この記事では、DB接続における安定性を向上させるために、ServiceとDNSの利用方法に焦点を当て、その役割や実践的な活用法を解説します。

直接接続の問題点

最も単純な接続方法は、DBコンテナ(Pod)のIPアドレスを調べ、アプリの設定ファイルに直接記述する方式です。しかし、この方法には致命的な問題があります。Podは再起動するとIPアドレスが変わってしまうという点です。ノードの障害、設定変更による再デプロイ、負荷分散による再スケジューリングなどの問題が発生すると、古いPodは破棄され、新しいPodが作られます。この時、IPアドレスは変わってしまいます。

直接接続ではDBが再起動するたびにアプリの設定ファイルを書き換え、再起動しなければならず手間がかかります。

Serviceの仕組み

Kubernetesでは、PodのIPアドレスが変動する問題を解決するために「Service」というリソースを利用します。Serviceは一意の名前を持ち、内部DNSを介してアクセス可能です。これにより固定的なDNS名を提供することができ、アプリケーションはこのDNS名を使用して安定した通信を実現できます。

KubernetesのDNSの仕組み

Serviceを利用することで、PodのIPアドレスが変わる問題を解決できます。しかし、ServiceのIPアドレスをアプリケーションに設定する手間が残ります。この問題を解決するのがKubernetesのDNSです。通常、DNSはドメイン名とIPアドレスを対応させる役割を持っています。一方、Kubernetesクラスターには専用のDNSサーバーが標準で組み込まれており、Service名とIPアドレスを対応づける機能を提供します。Kubernetesでは、Serviceを作成すると、そのサービス名とIPアドレスの対応が自動的にDNSサーバーに登録されます。

この仕組みによりKubernetesでのPod間の接続は完全修飾ドメイン名(<Service名>.<Namespace名>.svc.cluster.local)を使用して実現できます。サービス名とネームスペース名を指定することで、Pod間通信が可能になります。

また、本記事ではDNSの仕組みの理解のために完全修飾ドメイン名を使用していますが、同じネームスペース内に存在するアプリケーションからServiceに接続する際にはサービス名だけで接続が出来ます。

YAMLファイルの作成例

これまで、アプリコンテナとデータベースコンテナの接続方法について解説しました。ここからは、具体的なYAMLファイルの例を示し、ServicesやKubernetesのDNSをどのように設定するのかについて解説します。

DBコンテナ側の設定

DBコンテナの設定(接続されるコンテナ)

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: "mysql-service"
  replicas: 1 
  selector:
    matchLabels:
      app.kubernetes.io/name: mysql # (A) Serviceはこのラベルを基準にPodを探す。
  template:
    metadata:
      labels:
        app.kubernetes.io/name: mysql # (A) Serviceに見つけてもらうためのラベル。
    spec:
      containers:
        - name: mysql-container
          image: mysql:8.0
          env:
            # ... 省略 ...
          ports:
            - containerPort: 3306 # (B) このPodが待ち受けるポート。ServiceのtargetPortと一致させる。
  volumeClaimTemplates:
    - metadata:
      name: mysql-storage
      spec:
        accessModes: [ "ReadWriteOnce" ]
        storageClassName: "standard" 
        resources:
          requests:
            storage: 1Gi

Serviceの設計(接続の窓口)

apiVersion: v1
kind: Service
metadata:
  name: mysql-service # KubernetesのDNSに登録される名前。この名前を使って他のコンテナからアクセス可能になる。
spec:
  selector:
    app.kubernetes.io/name: mysql # (A) このラベルを持つPodを探す。
  ports:
    - protocol: TCP
      port: 3306 # クライアントが接続するポート番号。
      targetPort: 3306 # (B) Podのコンテナが待ち受けているポート。StatefulSetのcontainerPortと一致させる。
  • metadata.name: mysql-service :サービス名がKubernetesのDNSに登録されます。このサービス名とネームスペース名があれば他のコンテナから接続ができます。
  • selector:Serviceが接続先のPodを決定するためのラベルセレクターです。ここでは、`app.kubernetes.io/name: mysql` というラベルが付けられたPodを対象とします。このラベルセレクターを使用してServiceは指定されたラベルを持つすべてのPodに接続します。
  • port: 3306:クライアントが接続するポート番号です。アプリケーションはこのポートに向けて通信します。
  • targetPort: 3306:Serviceが受け取った通信を転送するPodの内部ポート番号です。ここでは3306 番ポートに転送されます。

アプリコンテナ側の設定

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress # Podの識別用ラベル。
spec:
  # ... 省略 ...
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
      - image: wordpress:6.2.1-apache
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: mysql-service.default.svc.cluster.local # 完全修飾ドメイン名を使用してDNSで解決する。
      # ... 省略(DBのパスワードやユーザーの設定) ...
        - name: DB_PORT 
          value: "3306"
  • value: mysql-service:Serviceの名前を元にDNSを使ってIPアドレスを解決し、そのIPアドレスに対して接続を試みるための設定です。

おわりに

今回は、ServiceとDNSを活用したコンテナ同士の接続方法について解説しました。これらの技術を利用することで、PodのIPアドレスが変動しても影響を受けることなく、安定した接続を実現できます。 

次回からは、Kubernetes内部のデータベースコンテナを外部に公開する方法について、2回にわたり解説していきます。

参考文献

https://kubernetes.io/docs/concepts/services-networking/service/

https://kubernetes.io/ja/docs/concepts/services-networking/dns-pod-service/

https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

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