kubernetesでDrupal環境構築

  •  
 
ズィスト に投稿

kubernetesでDrupal環境構築

前提条件

ホストOS上にUTMをインストールして仮想環境を作成した。 その仮想環境上でkubernetesをデプロイした。使用した環境は以下である。

  • ホストOS
    • macOS Monterey(CPU M1)
  • 仮想化ソフト
    • UTM
  • ゲストOS
    • centos7
  • コンテナ型仮想環境
    • Docker 20.10.22
  • kubernetes環境
    • minikube v1.21.0

kubernetesとは

kubernetesはk8sと略されることが多い。頭文字のkと末尾のsを除くと8文字になるためk8sと呼ばれている。 k8sはコンテナオーケストレーションツールでコンテナの監視や管理を実施している。 具体的にできることは以下である。

  • アクセス数が増加した場合に水平スケーリングの実施
  • サービスが正常に動いているかどうかを監視し、停止した場合は再起動を実施
  • サービスを止めずにサービスの更新(ローリングアップデート)

k8sの構造

k8sをデプロイするとクラスターが展開される。 クラスターの中にはmaster nodeとworker nodeが存在する。 master nodeではworker nodeの管理(作成・削除・監視等)を実施している。 worker nodeではコンテナ化したアプリケーションを実行している。

リソース

k8sは様々なものをリソースとして扱っている。今回使用するリソースについて紹介する。

使用するリソース

使用するリソースはワークロード、サービス、ストレージに分けることができる。

ワークロード

  • Pod
    • k8sにおける最小単位
    • 1つ以上のアプリケーションコンテナを実行する
  • ReplicaSet
    • podの集合
    • 常に使用するPod数を定義する。
    • 公式ドキュメントではDeploymentを使用することを推奨している。
  • Deployment
    • ReplicaSetの集合
    • Podを定義した状態に保つ
    • 世代管理をしているため過去のバージョンに戻す等のロールバックが可能になる

上記のリソースを図にまとめると以下のようなる。
ワークロード

サービス

  • Service
    • ネットワークに公開する。
    • DNSの機能を持つ
    • L4ロードバランサーの役割を持つ
      • L4ロードバランサーはトランスポート層(プロトコルやポート等の情報)で負荷分散を実施する。
  • Ingress
    • ネットワークに公開する
    • DNSの機能はない
    • L7ロードバランサーの役割を持つ
      • L7ロードバランサーはアプリケーション層(URL等)で負荷分散を実施する。

上記のリソースを図にまとめると以下のようなる。
サービス

ストレージ

  • PersustebtVolumeClaim
    • ストレージ(PersistentVolume)を要求する
  • PersistentVolume
    • ストレージを確保する

上記のストレージを図にまとめると以下のようなる。
ストレージ

実際にDrupalを構築してみる

k8sのリソースを作成する場合はマニフェストファイルと呼ばれるymlファイルが必要になる。

マニフェストファイルについて

マニフェストファイルは以下のような内容で記載する。

apiVersion: apps/v1
kind: Deployment
metadata:
  ...
spec:
  ...

リソースによって記載する内容が異なるが、共通となる内容は以下の4つである。

  • kind
    • 作成するリソースを指定する。
  • apiVersion
    • 使用するリソースおよびkubernetesのバージョンによって異なる。
    • APIリファレンス に記載がある。
    • 例えばリソースがPodの場合は以下のように表示される。
      APIリファレンス
    • ApiVersionでは{Group/Version}と指定するため「core/v1」と表すことができる。また、Groupがcoreの場合は省略することができるため「v1」となる。
  • metadata
    • リソースの名前などのメタ情報を記載する。
  • spec
    • 使用するリソースによって記載内容が異なる。
    • 詳細は公式ドキュメントを参照

今回使用したマニフェストファイル

今回用意したマニフェストファイルは以下の2ファイルとなる。

drupal.yml
apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: drupal-pvc
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 5Gi
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: drupal-service
    spec:
      ports:
      - name: http
        port: 80
        protocol: TCP
      selector:
        app: drupal
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: drupal
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: drupal
      template:
        metadata:
          labels:
            app: drupal
        spec:
          initContainers:
          - name: inist-site-volume
            image: drupal:10.0.1
            command: ['/bin/bash','-c']
            args: ['cp -r /var/www/html/sites/ /data/; chown www-data:www-data /data/ -R']
            volumeMounts:
            - mountPath: /data
              name: vol-drupal
          containers:
            - name: drupal
              image: drupal:10.0.1
              ports:
              - containerPort: 80
              volumeMounts:
              - name: vol-drupal
                mountPath: /var/www/html/modules
                subPath: modules
              - name: vol-drupal
                mountPath: /var/www/html/profiles
                subPath: profiles
              - name: vol-drupal
                mountPath: /var/www/html/sites
                subPath: sites
              - name: vol-drupal
                mountPath: /var/www/html/themes
                subPath: themes
          volumes:
          - name: vol-drupal
            persistentVolumeClaim:
              claimName: drupal-pvc
    ---
    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: drupal-ing
      annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
    spec:
      rules:
      - http:
          paths:
          - path: /
            backend:
              serviceName: drupal-service
              servicePort: 80
    
mysql.yml
apiVersion: v1
    kind: Service
    metadata:
      name: drupal-mysql-service
    spec:
      ports:
        - name: mysql
          port: 3306
          protocol: TCP
      selector:
        app: drupal-mysql
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: drupal-pvc-mysql
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 5Gi
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: drupal-mysql
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: drupal-mysql
      template:
        metadata:
          labels:
            app: drupal-mysql
        spec:
          containers:
          - name: cont-drupal-mysql
            image: mysql:8.0.31
            ports:
            - name: mysql
              containerPort: 3306
              protocol: TCP
            volumeMounts:
            - mountPath: /var/lib/mysql
              name: vol-drupal-mysql
              subPath: dbdata
            env:
            - name: MYSQL_ROOT_PASSWORD
              value: {database_password}
            - name: MYSQL_DATABASE
              value: drupal-database
          volumes:
          - name: vol-drupal-mysql
            persistentVolumeClaim:
              claimName: drupal-pvc-mysql
    

詳細はkubernetes公式ドキュメントや参考サイトを参照
minikubeでは外部アクセスができないため、ingressを使用して外部アクセスを可能にしている。
上記のマニフェストファイルの解説は後日記載する。

実際にデプロイしてみる

マニフェストファイルがあるディレクトリで以下のコマンドを実行することでデプロイができる。

$kubectl apply -f drupal.yml
$kubectl apply -f mysql.yml

デプロイした後、状態の確認は以下のコマンドで行う。

$kubectl get all
実行結果
NAME                                READY   STATUS    RESTARTS   AGE
    pod/drupal-6f44cdc9db-8k7m2         1/1     Running   1          20h
    pod/drupal-mysql-6b6d8d96b5-v4564   1/1     Running   1          19h
    NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    service/drupal-mysql-service   ClusterIP   10.109.162.198   <none>        3306/TCP   19h
    service/drupal-service         ClusterIP   10.108.32.110    <none>        80/TCP     20h
    service/kubernetes             ClusterIP   10.96.0.1        <none>        443/TCP    46h
    NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/drupal         1/1     1            1           20h
    deployment.apps/drupal-mysql   1/1     1            1           19h
    NAME                                      DESIRED   CURRENT   READY   AGE
    replicaset.apps/drupal-6f44cdc9db         1         1         1       20h
    replicaset.apps/drupal-mysql-678f6d655f   0         0         0       19h
    replicaset.apps/drupal-mysql-6b6d8d96b5   1         1         1       19h
    

ingressやpersistentVolume(pv)等は表示されないため以下のようにリソースを指定する必要がある。

$kubectl get {resource}

上記のコマンドを使用してingressの状態を確認するとingressの外部IPが表示される。webブラウザでこの画面にアクセスするとDrupalのセットアップ画面が表示される。この画面に従ってセットアップを行うことでDrupalを使用することができる。
Databaseの設定に関しては注意が必要である。
Database名はmysql.ymlで指定した「MYSQL_DATABASE」の値、パスワードは「MYSQL_ROOT_PASSWORD」となる。また、Databaseのホストはmysql.ymlのサービスで設定したmetadata.nameの「drupal-mysql-service」となる。

コメントを追加

プレーンテキスト

  • HTMLタグは利用できません。
  • 行と段落は自動的に折り返されます。
  • ウェブページのアドレスとメールアドレスは自動的にリンクに変換されます。
CAPTCHA
この質問はあなたが人間の訪問者であるかどうかをテストし、自動化されたスパム送信を防ぐためのものです。
画像
ワークロード
ストレージ
サービス
APIリファレンス