0
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?

Minikube × Kubernetes × SkaffoldでPHP+MariaDBの開発環境を構築

Last updated at Posted at 2025-03-21

Minikubeで開発環境を作成する

前提条件

私の環境はWindows10です。

ツールのダウンロード

minikubeを以下からインストールしてください:
https://minikube.sigs.k8s.io/docs/start/

minikubeにはvirtualboxドライバーを使います。
以下からvirtualboxをインストールしてください:
http://virtualbox.org/wiki/Downloads

Gitも使用します。以下からGitをインストールしてください:
https://git-scm.com/downloads

skaffoldも以下からインストールしてください:
https://skaffold.dev/docs/install/

そしてkubectlも以下からインストールします:
https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/

(chocoやscoopを使うと簡単にインストールできます)

インストール確認

それぞれのツールをインストール後、PowerShellでminikubeにアクセスできるか確認しましょう。

PowerShellを開いて次のコマンドを実行:

minikube version

出力例:

minikube version: v1.35.0
commit: dd5d320e41b5451cdf3c01891bc4e13d189586ed-dirty

こんな感じになるはず。
cap.PNG

次にGitのバージョン確認:

git -v

出力例:

git version 2.47.1.windows.2

テストプロジェクトの作成

次のようにディレクトリを作成:

cd Documents
mkdir projects
cd projects
mkdir test-project
cd test-project

このプロジェクトはminikubeのクラスターで動かします。

Minikubeクラスターの起動

用語解説

  • コンテナとは?
    アプリケーションとその依存関係をまとめた軽量な分離環境です。様々な環境間で一貫性を保てます。

  • ポッドとは?
    Kubernetesにおける最小のデプロイ単位で、1つ以上のコンテナを内包します。

  • クラスターとは?
    複数のワーカーノードがポッドを実行する、Kubernetesの最上位構成です。

クラスター起動

以下のコマンドで起動:

minikube start --driver=virtualbox

※Dockerドライバーを使う場合は次のようにマウントするフォルダを指定しつつ起動できます:

minikube start --mount --mount-string="$HOME:/src" --driver=docker

ただし、virtualboxではこれは使用できません(でもDocker Desktopと違って無料です)
UbuntuなどのLinux系はDockerを無料で使えるので試してみてください。仕組み上仕方ないのですが、Dockerは爆速なのに対してvirtualboxは遅いのでイライラします。
Windows/MacはDockerを使うならDocker desktopになっちゃうので、とりあえずvirtualboxでいきます。

Kubernetesのインストール確認

minikube経由でkubernetes(kubectl)を確認します。
kubectlを直接使えることも確かめておきます。

minikube kubectl -- version
kubectl -- version

出力例:

Client Version: v1.32.0  
Kustomize Version: v5.5.0  
Server Version: v1.32.0

ポッドの作成(PHP, Nginx, MariaDB)

まずIngressを有効にします:

minikube addons enable ingress

次に以下の内容を php-mariadb.yaml に保存します。
このファイルにはポッド内のコンテナ定義が含まれています。
このファイルの改行コードは「CRLF」ではなく「LF」にしてください。

以下が php-mariadb.yaml の内容です:

# MariaDBのDeployment
apiVersion: apps/v1
kind: Deployment
metadata:
  # Deploymentの名前
  name: mariadb
  # Deploymentを区別するためのラベル
  labels:
    app: mariadb
spec:
  # MariaDBインスタンスの数
  replicas: 1
  selector:
    # Podのためのmatch label
    matchLabels:
      app: mariadb
  template:
    metadata:
      labels:
        app: mariadb
    spec:
      containers:
        - name: mariadb
          # MariaDBのためのDocker image
          image: mariadb:11.3
          # MariaDBの動くport
          ports:
            - containerPort: 3306
          # MariaDBの環境変数
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "rootpassword"
            - name: MYSQL_DATABASE
              value: "mydatabase"
            - name: MYSQL_USER
              value: "myuser"
            - name: MYSQL_PASSWORD
              value: "mypassword"
          # MariaDB data storageのボリュームマウンティング
          volumeMounts:
            - name: mariadb-storage
              mountPath: /var/lib/mysql
      # volumeの定義
      volumes:
        - name: mariadb-storage
          emptyDir: {}
---
# MariaDB Service
apiVersion: v1
kind: Service
metadata:
  # MariaDBサービス名
  name: mariadb
spec:
  ports:
    - port: 3306
  selector:
    # MariaDB podに接続するためのセレクター
    app: mariadb
---
# PHPのWebアプリ用のDeployment
apiVersion: apps/v1
kind: Deployment
metadata:
  # Deployment名
  name: php-app
  # PHPのdeploymentを区別するためのラベル
  labels:
    app: php-app
spec:
  # PHPポッドのインスタンス数
  replicas: 1
  selector:
    matchLabels:
      app: php-app
  template:
    metadata:
      labels:
        app: php-app
    spec:
      containers:
        - name: php-app
          # PHPのウェブアプリのインスタンス数
          image: php:8.3-apache
          # PHP/Apacheの動くポート番号
          ports:
            - containerPort: 80
          # Virtualbox内のminikubeがホストマシンとなりますが、そのホストマシンへのマウント設定
          volumeMounts:
            - name: php-app-code
              mountPath: /var/www/html
            - name: apache-config
              mountPath: /etc/apache2/sites-enabled/000-default.conf
              subPath: default
      # ボリューム定義
      volumes:
        - name: php-app-code
          hostPath:
            path: "/mnt/project"
            type: Directory
        - name: apache-config
          configMap:
            name: apache-config
---
# Apacheの設定のコンフィグマップ
apiVersion: v1
kind: ConfigMap
metadata:
  name: apache-config
data:
  default: |
    <VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        <Directory "/var/www/html">
            Options Indexes FollowSymLinks
            AllowOverride All
            Require all granted
            DirectoryIndex index.html index.php
        </Directory>
        ErrorLog /var/log/apache2/error.log
        CustomLog /var/log/apache2/access.log combined
    </VirtualHost>
---
# PHPのウェブアプリ用のService
apiVersion: v1
kind: Service
metadata:
  # Service名
  name: php-app-service
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80
  selector:
    # PHPのPODに接続するためのセレクター
    app: php-app
---
# Ingressのリソース(PHPのウェブアプリに接続するためのNginxのこと。めんどくさい部分を色々初期設定済みにしてくれているのがIngress。別に自分でNginxを位置から定義してクラスターへの入口を作りたい人はそれでもいい)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: php-app-ingress
spec:
  ingressClassName: nginx
  rules:
    - host: localhost
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: php-app-service
                port:
                  number: 80

skaffold.yamlの作成

次の内容を skaffold.yaml として保存します:

apiVersion: skaffold/v4beta12
kind: Config
metadata:
  name: php-mariadb-app
deploy:
  kubectl: {}
manifests:
  rawYaml:
    - php-mariadb.yaml

そうするとtest-projectのなかがこうなるはずです。

キャプチャ.PNG

マウント用ディレクトリ作成

まず、マウント用のディレクトリを作成します:

mkdir mounttest

以下のコマンドでホストとminikubeをマウント接続します:

minikube mount "$Home\\Documents\\projects\\test-project\\mounttest:/mnt/project"

このコマンドはマウント状態を維持するため、このターミナルは開いたままにしておいてください。

以降の作業は別ターミナルを開いて実行します。

skaffoldを使ったデプロイ

以下のコマンドを実行して、開発環境を開始します(test-project ディレクトリで実行):

cd {test-projectのディレクトリ}
skaffold delete
skaffold run --force

これも実行中にログを出力し続けるため、別の作業をする場合はさらに別のターミナルを使いましょう。

環境の動作確認

数分待つと、Kubernetes環境がminikubeクラスター上に構築されます。

次のコマンドでポッドの状態を確認します:

kubectl get pods

出力例:

NAME                      READY   STATUS    RESTARTS   AGE
mariadb-998f96ddb-84kqs   1/1     Running   0          64s
php-app-bf6f77579-454jl   1/1     Running   0          64s

READY がすべて 1/1 であれば、環境は正常に動作しています。
これらは「ポッド(Pod)」と呼ばれます。

例:

  • mariadb-998f96ddb-84kqs(ポッド)
  • php-app-bf6f77579-454jl(ポッド)

それぞれのポッドの中に、.yaml で定義したコンテナが動作しています。
1つのポッドに複数コンテナを含めることも可能です。たとえば、ログ用の「サイドカーコンテナ」を一緒に動かすこともできます。

ポッドのトラブルシューティング

もし READY1/1 にならない場合は、以下でポッドの詳細を確認します:

kubectl describe pod php-app-bf6f77579-454jl

標準出力のログを確認するには:

kubectl logs php-app-bf6f77579-454jl

クラスタ全体のイベントを確認するには:

kubectl get events --sort-by='.metadata.creationTimestamp'

ホストPCからminikubeへアクセス

Ingressでファイルを確認

まずはminikube tunnelをつかっておきます。

minikube tunnel

minikubeはVirtual machine内でk8s環境をつくります。通常はHost PCに直接k8s環境を作りますが、今回は開発用にVirtual machine内にk8sを作りました。このk8s環境にHostからアクセスしようとするとPort forwardなどの対応が必要になっちゃいます。

minikube tunnelをするとアクセスできるようになります。(環境によってはアクセスできないかもなので、その場合はあきらめてkubectlでport forwardingしましょう…)

minikube tunnelは一度実行すると動き続けるので、次の作業は別ターミナルを開いて行います。

IngressのIPを確認します。

kubectl get ingress
NAME              CLASS   HOSTS       ADDRESS          PORTS   AGE
php-app-ingress   nginx   localhost   192.168.59.100   80      93

IPは192.168.59.100とわかりました。

ブラウザで http://192.168.59.100 にアクセスすると、 404 エラーが表示されます。
これが表示されれば、Ingress経由で接続できている証拠です。

キャプチャ (1).PNG

今度はこのIPを使って次のように .yaml を修正します:

# Ingress resource for PHP Application
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: php-app-ingress
spec:
  ingressClassName: nginx
  rules:
    - host: 192.168.59.100.nip.io #!!! ここをかえる !!!!
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: php-app-service
                port:
                  number: 80

PHPファイルを作成して動作確認

mounttestindex.php を作成します:

<?php
echo "Hello World!";

ブラウザで次にアクセスします:

http://192.168.59.100.nip.io/

「Hello World!」が表示されれば成功!

キャプチャ (2).PNG

なんで最初は404だったのにIPをlocalhostから192.168.59.100.nip.ioに書き換えるとアクセスできるようになったのでしょうか?
.yaml の中のIngress定義では、最初こうなっていました:

rules:
  - host: localhost

つまりこのIngressルールは「ホスト名が localhost のリクエストだけを処理する」という設定です。

でも、minikube が作った仮想ネットワーク(例:192.168.59.100)は、ホストOSの localhost とは別世界のIPアドレスです。なのでブラウザから 192.168.59.100 にアクセスすると、

Ingressコントローラーが

ホスト名が一致しない (localhostじゃない) から

適用するルールがなくて 404 を返すという状態になります。

なぜ 192.168.59.100.nip.io に変えるとアクセスできるのかというと

rules:
  - host: 192.168.59.100.nip.io

に変更することで、Ingressがこのホスト名を認識して、

「あ、これは自分が担当するホスト名だ!」

と判断して、ルーティング処理してくれるようになるためです。

ここでのキモ
nip.io は無料のDNSサービスで、xxx.xxx.xxx.xxx.nip.io にアクセスすると自動でそのIPに名前解決される。
192.168.59.100.nip.io → DNSが 192.168.59.100 に解決してくれる。
つまり「DNSで名前をつけつつ、Ingressの host 条件にも合う」ということになる。

PHPコードの変更が即時反映されない場合

php.ini に次の設定を追加・変更して、opcache を無効にしてください:

opcache.enable=0
opcache.validate_timestamps=1
opcache.revalidate_freq=0

これで、mounttest フォルダのPHPを変更すれば、kubernetes内のpodに即時反映されるようになります。

MariaDBをホストPCから使う(NodePort)

MariaDBのService定義をNodePortに変更する必要があります。以下は修正済みの php-mariadb.yaml の該当部分です:

# MariaDB Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mariadb
  labels:
    app: mariadb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mariadb
  template:
    metadata:
      labels:
        app: mariadb
    spec:
      containers:
        - name: mariadb
          image: mariadb:11.3
          ports:
            - containerPort: 3306
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "rootpassword"
            - name: MYSQL_DATABASE
              value: "mydatabase"
            - name: MYSQL_USER
              value: "myuser"
            - name: MYSQL_PASSWORD
              value: "mypassword"
          volumeMounts:
            - name: mariadb-storage
              mountPath: /var/lib/mysql
      volumes:
        - name: mariadb-storage
          emptyDir: {}
---
# NodePort Service
kind: Service
apiVersion: v1
metadata:
  name: mariadb
spec:
  type: NodePort
  selector:
    app: mariadb
  ports:
    - port: 3306
      targetPort: 3306
      protocol: TCP
      nodePort: 30036  # 任意のポート番号(例:30000〜32767)

再デプロイ

skaffold run を止めて(Ctrl+C)、以下のコマンドで再デプロイします:

skaffold delete
skaffold run --force

minikube tunnelもやり直したほうがいいかもしれません。

MinikubeのIP確認

minikube ip

出力例:

192.168.59.100

このIPとNodePort(例:30036)を組み合わせてMariaDBにアクセスできます。

例:

192.168.59.100:30036

MariaDBへの接続情報(環境変数)

MariaDBの接続には以下の設定が使われています:

ユーザー名: myuser  
パスワード: mypassword  
データベース: mydatabase  
ルートパスワード: rootpassword  

この情報を使って、ホスト側のMySQLクライアントやDBツール(A5SQLmk2やDBeaverなど)から接続できます。

キャプチャ (3).PNG
(A5SQLmk2から接続した際のキャプチャです)

まとめ

これで、

  • PHPファイルを編集するとリアルタイム反映されるKubernetes環境
  • Ingress経由でアクセス可能なWebサーバ
  • NodePort経由でMariaDBに外部から接続可能

本格的なローカルKubernetes開発環境が完成しました!

おまけリンク集

0
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
0
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?