ブログに戻る

Ubuntu 18.04のKubernetesクラスターにPHPアプリケーションをデプロイする

Ubuntu 18.04のKubernetesクラスターにPHPアプリケーションをデプロイする

Kubernetes(k8sとしても知られる)は、オープンソースのオーケストレーションシステムです。これにより、ユーザーは最小限のダウンタイムでコンテナ化されたアプリケーションをデプロイ、スケール、管理できます。このチュートリアルでは、PHPアプリケーションをKubernetesクラスターにデプロイする方法を学びます。

Nginxは、PHPアプリケーションの実行中にPHP-FPMへのプロキシとして動作します。これら2つのサービスを単一のコンテナで管理することは困難なプロセスです。Kubernetesは、これらを2つの異なるコンテナで管理するのに役立ち、手間を省きます。また、ユーザーがコンテナを再利用できるようにし、PHP/Nginxの新しいバージョンごとにコンテナイメージを構築することを心配する必要をなくします。

アプリケーションとプロキシサービスを2つの別々のコンテナで実行します。このチュートリアルでは、ローカルストレージを使用して永続ボリューム(PV)および永続ボリュームクレーム(PVC)を作成する方法についても説明します。その後、このPVCを使用して、設定ファイルとコードをコンテナイメージの外部に保持します。このチュートリアルを完了すると、プロキシサーバーを必要とする他のアプリケーションに対してNginxイメージを再利用できるようになります。これは、イメージを再構築する代わりに、設定を渡すことで実現できます。

前提条件

  1. Kubernetes(k8s)とそのオブジェクトに関する基本的な理解。このガイドを参照して、Kubernetesエコシステムの詳細な概要を確認してください。.
  2. Ubuntu 18.04上で稼働しているKubernetesクラスター。このチュートリアルに従って、kubeadmを使用してKubernetesクラスターを作成します。.
  3. さらに、アプリケーションコードを公開URL(例:GitHub.

ステップ 1: PHP-FPMおよびNginxサービスの作成

このステップでは、PHP-FPMおよびNginxサービスを作成します。サービスは、クラスター内のポッドのセットへのアクセスを提供します。クラスター内に存在するすべてのサービスは、IPアドレスを使用せずに、その名前で相互に通信できます。PHP-FPMサービスとNginxサービスは、それぞれPHP-FPMポッドとNginxポッドへのアクセスを提供します。

PHP-FPMサービスにNginxポッドの検出方法を伝える必要があります。これは、NginxポッドがPHP-FPMポッドのプロキシとして機能するためです。このために、Kubernetes’の自動サービス検出を利用し、人間が読める名前を使用してリクエストをそれぞれのサービスにルーティングします。

サービスを作成するには、YAMLファイル(オブジェクト定義を含む)を作成する必要があります。このYAMLファイルには、少なくとも以下のタグが含まれます:

  1. apiVersion: The Kubernetes API version to which the definition belongs.
  2. kind: The kind of Kubernetes object this YAML file creates. For instance: a service, a job, or a pod.
  3. metadata: The name of the object and the different labels that the user might want to apply to this object are defined under this tag.
  4. spec: This tag contains the object specification of your object, such as ENVs, container image to be used, ports on which the container service will be accessible.
PHP-FPMサービスの作成

To start with, you should create a directory to keep your Kubernetes object definition. Log in to your master node and create a directory named “definitions:”

definitionsディレクトリに移動します:

Next, create your PHP-FPM service file as php_service.yaml file:

After that, set the apiVersion and kind in the php_fpm_service.yaml file:

Name your service as php または php-fpm as it will provide access to your PHP-FPM application:

Label your php service as tier: backend as the PHP application will run behind this service:

A service uses the selector labels to determine which pods to access. Any pod that matches these labels, irrespective of when the pod was created, is serviced. You will learn how to add labels to your pods later in this tutorial.

Include the tier: backend label that assigns your pod into the backend tier, along with app: php-fpm label to indicate that the pod runs a PHP-FPM application. You must add these labels after the metadata section:

Next, you need to declare the port to access this php-fpm service under spec. You can add any port of your choice, but we will use port 9000 in this tutorial:

Once done with the above steps, your php_fpm_service.yaml file will look like this:

Enter Ctrl + O to save the file, then enter Ctrl + X to exit nano.

kubectlコマンドを適用してPHPサービスを作成する

As the object definition for your service is created, run kubectl apply command with -f argument by specifying your php_fpm_service.yaml file:

上記のコマンドの出力は次のようになります:

以下のコマンドを実行して、php-fpmサービスが実行されていることを確認します:

php-fpmサービスが起動して実行されていることを確認できます:

注意: Kubernetesはさまざまなサービスタイプをサポートしています。作成したphp-fpmサービスは、デフォルトのClusterIPサービスタイプを使用します。このタイプのサービスは内部IPを割り当て、Kubernetesクラスター内からのみサービスにアクセスできるようにします。
Nginxサービスの作成

Since your PHP-FPM service is ready now, it is time you create your Nginx service as well. Create and open a new YAML file for this service, called nginx_service.yaml in the editor:

Name this service as nginx as it will target the Nginx pods. This service also belongs in the backend so you should add a tier: backend label to it:

As we did in the php-fpm service, add the selector labels app: nginx and tier: backend to target the pods. Add the default HTTP port 80 to access this service:

The Nginx service can be publicly accessible on the internet from the public IP address. You can add your worker node’s IP as your_public_ip. Add the below lines under spec.externalIPs:

Your nginx_service.yaml file should look like the one below once you complete all of the above steps:

上記の必要なパラメータをすべて追加した後、ファイルを保存して閉じます。

kubectlコマンドを適用してNginxサービスを作成する
上記のコマンドに対して、以下の出力が表示されるはずです:
次に、以下のコマンドを実行して、実行中のすべてのサービスを表示します:
上記のコマンドを実行すると、PHP-FPMとNginxの両方のサービスが起動して実行されていることを確認できるはずです:
実行中のサービスを削除したい場合は、以下のコマンドを実行できることに注意してください:

ステップ 2: ローカルストレージとPersistent Volumeの作成

Kubernetesは、環境用のストレージスペースを作成するのに役立つさまざまなストレージプラグインを提供しています。このステップでは、ローカルのStorageClassを作成する方法と、このStorage Classをさらに使用してPersistent Volumeを作成する方法について説明します。

ローカルストレージの作成

Create a file, say storageClass.yaml, in your editor:

Add kind as "storageClass" and apiVersion as "storage.k8s.io/v1" as follows:

Name this StorageClass as "my-local-storage" and add provisioner and volumeBindingMode as follows:

Save and exit the file and your final storageClass.yaml file should look like this:

次に、以下のようにkubectl createコマンドを実行してStorageClassを作成します:

上記のコマンドを実行すると、以下の出力が表示されるはずです:

ローカルPersistent Volumeの作成

After creating Local Storage, you can create your local Persistent Volume. A Persistent Volume, also known as PV, is the specified-sized block storage that is independent of the life cycle of a pod. A local Persistent Volume is nothing but a local disk or a directory that is available on a Kubernetes cluster node. This local Persistent Volume allows its users to access the local storage by using a local Persistent Volume Claim in a very simple yet portable manner. You can create this local Persistent Volume by using this storage class we just created. Open a file, say persistentVolume.yaml, in your editor:

Give this persistent volume a name, say "my-local-pv":

ローカルPersistent Volumeを作成する際、使用状況に応じてストレージ容量を追加できます。このチュートリアルでは、ストレージに5 Giを使用します:

accessModes、persistentVolumeReclaimPolicyを追加し、storageClass.yamlで使用されているものと同じstorageClassNameを指定します:

注意: persistentVolumeReclaimPolicyは、Persistent Volumeのクレーム(Persistent Volume Claim)が解放されたときに、そのPersistent Volumeに何が起こるかを示します。このパラメータには、Retain、Delete、Recycleの3つの有効なオプションがあります。このコードでは、Retainオプションを使用します。詳細については、こちらのpersistentVolumeReclaimPolicyフィールドを確認してください: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#persistentvolumeclaim-v1-core

Add the local.path for your Persistent Volume as below:

注意: このローカルパス(/mnt/disk/vol)がKubernetesクラスターノード上に存在することを確認してください。

After adding all the required fields, your persistentVolume.yaml file should look like this:

注意: マシンの正しいノード名を使用する必要があります。この場合は、“worker.”です。
ローカルボリュームの準備

Now, we need to prepare a local volume on the “worker” node as we have added in the persistentVolume.yaml file. Run the below commands on the node that you have configured in persistentVolume. In this case, it is “worker” node:

注意: ディレクトリを作成し、上記のように権限を変更するための十分な権限があることを確認してください。そうでない場合は、適切なユーザーでコマンドを実行してください。

Run the below command on the master node where your persistentVolume.yaml file is present:

以下のような出力が表示されるはずです:

ローカルストレージとPersistent Volumeの作成に成功したため、アプリケーションコードと設定ファイルを保持するためのPersistent Volume Claimの作成に進むことができます。

ステップ 3: Persistent Volumeの作成

ポッドの管理やアップデートを行う間、アプリケーションコードを安全に保持する必要があります。このために、前のステップで作成したPersistent Volumeを使用します。これにはPersistentVolumeClaim(PVC)を使用してアクセスします。このPVCは、必要なパスにPVをマウントします。

Open a file, say code_volume.yaml, in your editor:

ファイルに以下のパラメータと値を追加して、PVCの名前をcodeに指定します:

PVCのspecセクションには、以下の項目があります:

  1. accessModes: このフィールドには、以下のようにさまざまな値を指定できます:
    • ReadWriteOnce – 単一のノードに対して、読み取りと書き込みの両方の権限でボリュームをマウントします。
    • ReadOnlyMany – 多数のノードに対して、読み取り専用権限でボリュームをマウントします。
    • ReadWriteMany – 多数のノードに対して、読み取りと書き込みの両方の権限でボリュームをマウントします。
  2. resources: 必要なストレージ容量を定義します。

ローカルストレージは単一のノードにのみマウントされるため、accessModeをReadWriteOnceに設定する必要があります。このチュートリアルでは、アプリケーションコードのごく一部のみを追加するため、ここでは1GBのストレージで十分です。ただし、より大容量のデータやコードを保存したい場合は、要件に応じてstorageパラメータを変更できます。ボリュームが作成されると、ストレージサイズを増やすことはできますが、減らすことはサポートされていないことに注意してください。

次に、Kubernetesクラスターがボリュームへの割り当てに使用するストレージクラスを宣言します。ここでは、前のステップで作成したmy-local-storageストレージクラスをstorageClassNameに使用します。

After completing the above steps, your code_volume.yaml file should look like this:

ファイルを保存して終了します。

PVCの作成

kubectl applyコマンドを実行して、コードPVCを作成します。

オブジェクトが正常に作成され、1GBのPVCをボリュームとしてマウントする準備ができたことを示す、次の出力が表示されるはずです。

次のコマンドを実行して、利用可能なPersistent Volume (PV)を確認できます。

上記コマンドの出力は次のようになります。

Reclaim PolicyとStatusを除く上記のすべてのフィールドは、設定ファイルの概要を示しています。Reclaim Policyは、それにアクセスしているPVCが削除されたときにPVに何が起こるかを定義します。Deleteという値は、KubernetesクラスターおよびストレージインフラストラクチャからPVを削除します。詳細については、Kubernetes PVのドキュメント Reclaim PolicyとStatusを明確に理解するため。

ローカルストレージを使用してPersistent Volumeの作成に成功したため、Deploymentを使用してポッドを作成できるようになりました。

ステップ 4: PHP-FPMアプリケーション用のDeploymentの作成

このステップは、Deploymentを使用してPHP-FPMポッドを作成するのに役立ちます。DeploymentはReplicaSetsを使用して、ポッドの作成、更新、管理を安定して行う方法を提供します。Deploymentは、ポッドを以前のイメージに自動的にロールバックします。

The spec.selector key in the Deployment lists all the labels of the pods it manages. It also uses the template key to create the pods that are required.

このステップでは、次の適用についても紹介します:Init Containers. The Init Containers run few commands before the regular containers that are specified under the pod’s template. Here, the Init Container will use GitHub Gist (https://gist.github.com/) to get a sample index.php file. The contents of the sample file are:

PHP Deploymentの作成

Open a new file named php_deployment.yaml in your editor to create your Deployment:

Now, name the Deployment object PHP as this Deployment will manage your PHP-FPM pods. Add the label tier: backend because the pod will belong to the backend tier:

replicaパラメータを使用して、作成するこのポッドのコピー数を指定します。レプリカ数は、要件や利用可能なリソースによって異なる場合があります。このチュートリアルでは、ポッドのレプリカを1つだけ作成します:

Add app: php and tier:backend labels under selector key that denotes that this Deployment will manage pods that match these two labels:

Now, your pod’s object definition needs a template under your Deployment spec. This template defines the specification that is needed to create your pod. To start with, add the labels that were specified for the php service selector and the matchLabels of the Deployment. Then add app:php and tier:backend under template.metadata.labels:

注意: ポッドは複数のコンテナまたはボリュームを持つことができ、それらを区別するためにそれぞれ異なる名前が必要になります。各ボリュームにマウントパスを指定して、そのボリュームをコンテナに選択的にマウントできます。

まず、コンテナがアクセスするすべてのボリュームを指定する必要があります。アプリケーションコードを保持するためにcodeという名前のPVCを作成したため、このボリュームにcodeという名前を付けます:

次に、ポッド内で実行するイメージとともにコンテナ名を指定します。Dockerストアにはさまざまなイメージが用意されています(https://hub.docker.com/explore/), but in this tutorial, we will use the php:7-fpm image:

次に、コンテナがアクセスする必要があるボリュームをマウントします。このコンテナはPHPコードを実行するため、前のステップで作成したコードボリュームへのアクセスが必要になります。このステップでは、Init Containerを使用してアプリケーションコードをコピーする方法についても説明します。

注意: セットアッププロセスの複雑さに応じて、単一のinitContainerを使用してアプリケーションをビルドするスクリプトを実行するか、コマンドごとに1つのinitContainerを使用することができます。ボリュームがinitContainerにマウントされていることを確認する必要があります。

コードをダウンロードするために、このチュートリアルではbusyboxを備えた単一のInit Containerを使用する方法を説明します。Busyboxは、これを実現するために使用するwgetユーティリティを備えた小さなコンテナです。

First, add your initContainer under spec.template.spec and specify the busybox image:

Then, in order to download the code in the code volume, your Init Container will need access to it. Mount the volume code at the /code path under spec.template.spec.initContainers:

すべてのInit Containerはコマンドを実行する必要があります。このInit Containerはwgetを使用して、コードGithubからダウンロードします。 into the /code directory. You can pass a -O option to give this downloaded file a name, and you can name this file index.php.

注意: Init Containerを使用してサーバーにプルするコードを信頼していることを確認してください。ソースコードを検査して、その動作に問題がないことを確認できます。

In addition, add the below lines under install container in spec.template.spec.initContainers:

After you complete all these steps, your php_deployment.yaml file should look like this:

You can now save the file and exit. Next, create your PHP-FPM Deployment using kubectl apply command:

Deploymentの作成に成功すると、以下のような出力が表示されます。

This Deployment starts by downloading the specified images, then it will request the PersistentVolume from your PersistentVolumeClaim, and then run your initContainers. Once this step is done, the containers will run and mount the volumes to the specified mount point. After completing all these steps your pod will be up and running.

以下のコマンドを実行して、Deploymentを表示できます:

上記のコマンドを実行すると、以下のような出力が表示されます。

You can understand the current state of the Deployment with the help of this output. A Deployment is a controller that maintains the desired state. The DESIRED field specifies that it has 1 replica of the pod named php. The CURRENT field indicates how many replicas of the DESIRED state are running at present. For a healthy pod, this should match the DESIRED state. You can learn more about the remaining fields on the Kubernetes Deployments ドキュメント.

その後、実行中のpodのステータスを確認するには、以下のコマンドを実行します:

このコマンドの出力は、Deploymentを作成してから経過した時間によって異なる場合があります。Deploymentの作成直後に実行した場合、出力は以下のようになります。

説明:

これらの列は、以下のような情報を表しています。

  • Ready: このポッドを実行している現在/要求されたレプリカの数。
  • Status: ポッドのステータス。Init:0/1は、Initコンテナが実行中であり、1個中0個のInitコンテナが実行を完了したことを示します。
  • Restarts: これは、ポッドを起動するためにこのプロセスが再起動された回数を示します。

Your pod can take a few minutes for the status to change to podInitializing depending on the complexity of your startup scripts:

これは、Initコンテナが正常に実行され、現在コンテナが初期化中であることを示しています。

ご覧の通り、ポッドは起動して実行されています。ただし、ポッドが起動しない場合は、デバッグ目的で以下のコマンドを実行できます。

1. ポッドの詳細情報を表示するには:

2.  ポッドのログを表示するには:

注: “kubectl logs” コマンドには複数のオプションがあります。詳細については “kubectl logs –help” コマンドを実行して確認できます。

3. ポッド内の特定のコンテナのログを表示するには:

おめでとうございます!アプリケーションコードのマウントに成功し、PHP-FPMサービスが接続を処理する準備が整いました。同様に、Nginx Deploymentを作成できます。

ステップ 5: Nginx Deploymentの作成

このステップでは、以下を使用してNginxを構成する方法を説明します:ConfigMap. A ConfigMap keeps all your required configurations in a key-value format that will be used in other Kubernetes object definitions. With this approach, you will have the flexibility to reuse or swap the Nginx image with a different version, as and when required. You can update the ConfigMap and it will automatically replicate those changes to any pod that is mounting this ConfigMap.

To begin with, open a nginx_configmap.yaml file in your editor:

Now, name this ConfigMap as nginx-config and add it to tier: backend microservice:

さらに、データをConfigMapに追加できます。configという名前のキーを追加し、すべてのNginx設定ファイルの内容を値として追加します。

Since it is possible for Kubernetes to route requests to the respective hosts for a service, you can enter the name of your PHP-FPM service under the fastcgi_pass parameter instead of its IP address. Add the following lines of code to your nginx_configMap.yaml file:

Once completed, your nginx_configMap.yaml file will look like this:

You can now save and exit the editor. Now execute the kubectl apply the command to create the ConfigMap:

その後、画面に以下のような出力が表示されるはずです:

Nginx Configmapが正常に作成されました。これで、Nginx Deploymentを作成できます。

Nginx Deploymentの作成

To begin with, you can create a new file named nginx_deployment.yaml in the editor:

Name this Deployment nginx and add the tier: backend label to it:

After that, specify the replica count by adding replica field in the Deployment spec and add app: nginx and tier: backend labels to it:

Similarly, add the pod template. Make sure you add the same labels that you had added in the Deployment’s selector.matchLabels. You can add the following:

Give Nginx access to the code PVC that was created earlier by adding the following parameters under spec.template.spec.volumes:

注: PodはConfigMapをボリュームとしてマウントできます。ファイル名とキーを指定することで、その値を内容とするファイルを作成します。このConfigMapを使用するには、キーの内容を保持するファイルの名前へのパスを設定します。キー config からファイル site.conf を作成できます。spec.template.spec.volumes の下に以下を追加します。

警告: ファイルが指定されていない場合、キーの内容が volume’s mountPath を置き換えます。言い換えれば、パスが明示的に指定されていない場合、宛先フォルダ内のすべての内容が失われます。

Now, specify the name, image, and port that you want to use in your pod. Here, we will use nginx:1.7.9 image and port 80. Add them under spec.template.spec section:

Also, mount the code volume at /code as both Nginx and PHP-FPM will need to access the file at the same path:

The nginx-1.7.9 image automatically loads any configuration file under /etc/nginx/conf.d folder. Now, if we mount the config volume in this directory, it will create /etc/nginx/conf.d/site.conf. Add the following under volumeMount section:

After completing all the above step, your nginx_deployment.yaml file should look like this:

これでファイルを保存して終了し、次のコマンドを実行して Nginx Deployment を作成できます。

コマンドが正常に実行されると、次の出力が表示されます。

以下のコマンドを実行することで、すべての Deployment を一覧表示できます。

これで、Nginx と PHP-FPM の両方の Deployment が表示されるはずです。

kubernetes deployment status

さらに、次のコマンドを実行して、上記の両方の Deployment によって管理されている Pod を一覧表示できます。

次のように、両方の Pod が起動して実行されていることがわかります。

kubernetes pod status

この時点で、すべての Kubernetes オブジェクトがアクティブになっているため、ブラウザから Nginx サービスにアクセスできるようになります。

次のコマンドを実行して、サービスを一覧表示します。

Nginx サービスの External IP を書き留めておきます。external ip of nginx Deploy a PHP Application on Kubernetes Cluster with Ubuntu 18.04

Now, using this External IP of Nginx service, you can visit your server by typing http://your_public_ip on your browser. You should be able to see the output of php_info() that confirms that your Kubernetes services are up and running.

結論

このチュートリアルでは、PHP-FPMとNginxサービスを個別に管理するために、2つのサービスをコンテナ化しました。これにより、プロジェクトのスケーラビリティが向上するだけでなく、リソースを効率的に使用できるようになります。また、ローカルストレージとPersistent Volumeを作成してアプリケーションコードをボリュームに保存し、将来的にサービスを簡単にアップデートできるようにする方法についても学びました。これにより、コードのユーザビリティとメンテナンス性が向上しました。

さらに、次の場所にあるDockerおよびKubernetesに焦点を当てた他のチュートリアルもご覧ください:私たちのブログ:

ハッピーコンピューティング!

author

Hark Labs

著者 · CloudSigma

Preslav DobrevはCloudSigmaのクリエイティブデザイナーであり、従来型および革新的なマーケティングチャネルを活用した一貫性のあるビジネスアイデンティティに注力しています。彼は芸術的なビジョンと戦略的マーケティングを融合させ、インパクトのあるブランドナラティブを生み出すことに長けています。

コメント

コメントはまだありません。最初のコメントを投稿しましょう。