LoginSignup
4
3

More than 3 years have passed since last update.

kubernetes上にLNMP環境を構築した際のメモ

Posted at

前回の記事にてminikube環境を構築した。

その後、Kubernetesのチュートリアルを一通りこなした後、勉学のためLNMPスタックの構築を実施した際のメモ。

実行環境

前回記事と同様のため省略

構築する環境外観

こちらの記事(Docker × PHP7.3 × Laravel環境作ってみた)の環境構築手順を参考とさせていただき、最終的にこんな感じの構成を目指す。

なお、本記事ではLaravelの構築については触れない。

構築するKubernetesオブジェクトについてのおさらい

ここで、構築にて使用するkubernetesオブジェクトについて簡単に説明する。

Pod

Kubernetesの中で最小のオブジェクト。

アプリケーションを実行する際の項目 (コンテナ、ストレージ、ネットワークIP、実行オプション) をカプセル化したもの。

今回は一つのPodにつき、一つのコンテナイメージが実行されるようにする。

Node

Podが動作する環境。複数のPodを動作させることが可能。

今回は特に操作しない。

Namespace

クラスタの仮想的な分割機能。

今回は特に操作せず、defaultを使用。

Deployment

デプロイするアプリケーション (Pod) について、レプリケーション数、ローリングアップデートなどの制御を実施する。

Service

実行されているPodへのアクセス経路を提供する。

PodのIPアドレスは一意でないため、アクセスにはService名の指定が必要となる。

また、Podへのアクセス方式にはいくつか種類があり、今回は以下を使用する。

  • ClusterIP: 外部疎通性のないアクセス方式。クラスタの内部IPを作成する。
  • NodePort: 外部疎通性のあるアクセス方式。Nodeの指定ポートへのアクセスをコンテナに転送する。

ConfigMap

アプリケーションの設定データを管理する。

あとで更新が必要などの理由から、コンテナイメージに内包したくない設定については、こちらで持つようにする。

PersistentVolume (PV)

アプリケーションが使用できる、独立した永続化ストレージ。

PersistentVolumeClaim (PVC)

アプリケーションがPVを利用する際に経由される。

環境の構築作業

以下の手順で構築した。

nginx環境の構築

まず、PV, PVC, ConfigMapの構築から行う。こちらを行わずDeploymentの構築を実施すると失敗となった。

ConfigMapの作成

今回、nginx-phpポッド間の通信をservice経由とするので、nginxのdefault.confをコンテナに内包させずConfigMapとする。

default.confを以下のように記載。この際、phpポッドへのアクセスにservice名とPort:9000を指定する。

server {
  listen 80;

  root  /var/www/public/;
  index index.php;

  location / {
    try_files $uri $uri/ /index.php$is_args$args;
  }

  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    # php serviceに送信する設定にする。
    fastcgi_pass   lnmp-php-service:9000;
    fastcgi_index  index.php;

    include        fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param  PATH_INFO $fastcgi_path_info;
  }
}
$ kubectl create configmap nginx-config --from-file={ホスト上のnginx.confの配置されているパス}

PV, PVCの作成

続いてPV, PVCの構築を行う。

今回、nginxポッドがphpアプリケーションを公開するため、ストレージはphpポッドと共有する。

ということでマニュフェストファイルを、lnmp-php-server-persistentvolumeclaim.yamlとして作成。

# PV
kind: PersistentVolume
apiVersion: v1
metadata:
  name: php-server-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    # とりあえず100Miくらいの容量で試す
    storage: 100Mi
  # ホストないに作成したストレージへ、Kubernetes nodeがアクセスする際の制約事項
  # 今回は、単一のnodeのみに書き込み/読み込みを可能とする設定とした
  accessModes:
    - ReadWriteOnce
  hostPath:
    # ホストマシンのどこにストレージを割り当てるか
    path: '/root/src/lnmp/server'
---
# PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: php-server-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Mi

コマンドを実行してpv, pvcを作成。

$ kubectl apply -f lnmp-php-server-persistentvolumeclaim.yaml

以下のkubectlコマンドから、作成されていることが確認できた。

$ kubectl get pv
NAME                   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                         STORAGECLASS   REASON   AGE
php-server-pv-volume   100Mi      RWO            Retain           Bound    default/php-server-pv-claim   manual                  5d20h
$ kubectl get pvc
NAME                  STATUS   VOLUME                 CAPACITY   ACCESS MODES   STORAGECLASS   AGE
php-server-pv-claim   Bound    php-server-pv-volume   100Mi      RWO            manual         5d20h

deploymentを作成

次に、deploymentを作成する。

マニュフェストファイルを、lnmp-nginx-deployment.yamlとして作成。

# Deployment設定
apiVersion: apps/v1
kind: Deployment
metadata:
  name: lnmp-nginx-deployment
  labels:
    app: lnmp
spec:
  # レプリケーション設定、今回は1台のみの構成とする
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      # 配置するnginxコンテナ
      containers:
      - name: lnmp-nginx-deployment
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-persistent-storage
          mountPath: /var/www
        # default.conf共有パス
        - name: nginx-config
          # default.confの配置先
          mountPath: /etc/nginx/conf.d
      volumes:
        # nginxの永続化ボリューム
        - name: nginx-persistent-storage
          persistentVolumeClaim:
            claimName: php-server-pv-claim
        # nginx設定のinject
        - name: nginx-config
          configMap:
            name: nginx-config
            items:
            - key: default.conf
              # マウントしたボリュームのmountPath配下に、どういう階層で登録されるかを記載
              path: default.conf
              mode: 0777

serviceを作成

つづいて、serviceを作成する。

マニュフェストファイルを、lnmp-nginx-service.yamlとして作成。

apiVersion: v1
kind: Service
metadata:
  name: lnmp-nginx-service
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
  - port: 80
    targetPort: 80

以下コマンドを実行し、デプロイを実施。

$ kubectl apply -f lnmp-nginx-deployment.yaml
$ kubectl apply -f lnmp-service-deployment.yaml

これでnginxの構築は完了。この時点でnginxサーバーのポートは確認できるけど、index.phpを配置していないので502エラーになる。

mysql環境の構築

こちらも引き続き構築していく。

ConfigMapのデプロイ

mysql設定ファイル、my.cnfをConfigMapとする。なお、これは元記事のものをそのまま使用する。

$ kubectl create configmap mysql-config --from-file={ホスト上のmy.cnfの配置されているパス}

PV, PVCの作成

元記事同様、mysqlのデータディレクトリをマウントするPV, PVCを作成。

kind: PersistentVolume
apiVersion: v1
metadata:
  name: mysql-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    # とりあえず5Gでマウントする
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    # プルパスで記載しないとエラーになった
    path: '/root/src/lnmp/mysql/db/data'
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

deploymentを作成

nginxの場合と同様、以下のマニュフェストファイルを作成し、デプロイ。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: lnmp-mysql-deployment
  labels:
    app: lnmp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: lnmp
  template:
    metadata:
      labels:
        app: lnmp
    spec:
      containers:
      - name: lnmp-mysql-deployment
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: root
        - name: MYSQL_DATABASE
          value: test_db
        - name: TZ
          value: 'Asia/Tokyo'
        ports:
        - containerPort: 3306
        args:
        - mysqld
        - --character-set-server=utf8mb4
        - --collation-server=utf8mb4_unicode_ci
        volumeMounts:
        # mysqlストレージ用パス
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
        # my.cnf共有パス
        - name: mysql-config
          # my.cnfの配置先
          mountPath: /etc/mysql/conf.d
      volumes:
      # mysqlの永続化ボリューム
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim
      # mysql設定のinject
      - name: mysql-config
        configMap:
          name: mysql-config
          items:
          - key: my.cnf
            # マウントしたボリュームのmountPath配下に、どういう階層で登録されるかを記載
            path: my.cnf
            mode: 0644

serviceを作成

こちらもnginxの場合と同様のマニュフェストファイルを作成しデプロイする。

ただし、mysqlへの通信はクラスタ内ポッド間でのみ行われるので、Service.spec.typeNodePortではなくClusterIPとしている。

apiVersion: v1
kind: Service
metadata:
  name: lnmp-mysql-service
spec:
  selector:
    app: lnmp
  type: ClusterIP
  ports:
  - port: 3306
    targetPort: 3306

php環境の構築

deploymentを作成

phpコンテナをデプロイする。

デプロイするphpイメージは元記事のDockerfileから作成する。

コンテナイメージを毎回dockerhubから取得しようとしてエラーとなっていたため、コンテナ取得タイミングをIfNotPresentとした。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: lnmp-php-deployment
  labels:
    app: lnmp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: lnmp
  template:
    metadata:
      labels:
        app: lnmp
    spec:
      containers:
      - name: lnmp-php-deployment
        image: laravel
        # なんかdockerhubから取ろうとしてた
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9000
        volumeMounts:
          - name: php-persistent-storage
            mountPath: /var/www
      volumes:
      # サーバーログ出力先(nginxと共有)
      - name: php-persistent-storage
        persistentVolumeClaim:
          claimName: php-server-pv-claim

また、PV, PVCはnginxポッドと共有する。

serviceを作成

nginxポッドがアクセスするサービスを作成する。

こちらもクラスタ内ポッド間でのみの通信となるため、Service.spec.typeClusterIPとしている。

apiVersion: v1
kind: Service
metadata:
  name: lnmp-php-service
spec:
  selector:
    app: lnmp
  type: ClusterIP
  ports:
  - port: 9000
    protocol: TCP

php環境の動作確認

この段階でLNMP環境にアクセスできることを確認する。

nginxのdefault.confに従い、phpポッドの/var/www/public/に、index.phpを配置してみる。

nginx, phpポッドに割り当てた/root/src/lnmp/serverに以下の内容のindex.phpを配置する。

<h1>kubenetes-php</h1>
<p>Served by Nginx</p>
<?php phpinfo();?>

この状態でnginxサーバーにアクセスしてみる。

$ kubectl get services/lnmp-nginx-service
NAME                 TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
lnmp-nginx-service   NodePort   10.98.216.9   <none>        80:32626/TCP   11d```

Podのアクセス先が32626ポートだと確認できた。

http://localhost:32626へブラウザからアクセスする。

phpの情報が出た!!

元記事ではLaravelアプリケーションの構築までを実施していたが、長くなってしまうので一旦ここまで。

4
3
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
4
3