LoginSignup
46
34

More than 5 years have passed since last update.

Kubernetesで作るPHPの開発環境

Last updated at Posted at 2017-12-22

グレンジ Advent Calendar 2017 24日目担当の 石川 です.
株式会社グレンジで,サーバサイドエンジニアをしています.

概要

Minikubeを利用したPHPのローカル環境構築について解説します.
Minikubeは,Kubernetesをローカルで実行するためのツールです.
Kubernetesは,コンテナ化されたアプリケーションをマネージするためのオープンソフトウェアです.
また,今回の記事は,Macを利用して検証した記事です.
他環境の方は,ところどころ読み替えて下さい.

準備

VirtualBoxのインストール

今回は,Minikubeの実行環境にVirtualBoxを利用します.
Download VirtualBoxOS X hostsのリンクからVirtualBoxをダウンロードして,インストールします.

gcloudのインストール

kubectlKubernetesを利用するためのコマンド)を利用するために,gcloudをインストールし,更にkubectlコマンドをインストールします.

bashを利用している方は,zshbashに変更して実行して下さい.

$ curl https://sdk.cloud.google.com | zsh

$ exec -l $SHELL

$ gcloud init

上記で,gcloudコマンドはインストールされました.
今,インストールされている.gcloudのコンポーネントリストを確認します.

$ gcloud components list

Your current Cloud SDK version is: 180.0.1
The latest available version is: 180.0.1

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                  Components                                                 │
├───────────────┬──────────────────────────────────────────────────────┬──────────────────────────┬───────────┤
│     Status    │                         Name                         │            ID            │    Size   │
├───────────────┼──────────────────────────────────────────────────────┼──────────────────────────┼───────────┤
│ Not Installed │ App Engine Go Extensions                             │ app-engine-go            │  97.7 MiB │
│ Not Installed │ Cloud Bigtable Command Line Tool                     │ cbt                      │   4.0 MiB │
│ Not Installed │ Cloud Bigtable Emulator                              │ bigtable                 │   3.5 MiB │
│ Not Installed │ Cloud Datalab Command Line Tool                      │ datalab                  │   < 1 MiB │
│ Not Installed │ Cloud Datastore Emulator                             │ cloud-datastore-emulator │  17.7 MiB │
│ Not Installed │ Cloud Datastore Emulator (Legacy)                    │ gcd-emulator             │  38.1 MiB │
│ Not Installed │ Cloud Pub/Sub Emulator                               │ pubsub-emulator          │  33.2 MiB │
│ Not Installed │ Emulator Reverse Proxy                               │ emulator-reverse-proxy   │  14.5 MiB │
│ Not Installed │ Google Container Local Builder                       │ container-builder-local  │   3.7 MiB │
│ Not Installed │ Google Container Registry's Docker credential helper │ docker-credential-gcr    │   2.2 MiB │
│ Not Installed │ gcloud Alpha Commands                                │ alpha                    │   < 1 MiB │
│ Not Installed │ gcloud Beta Commands                                 │ beta                     │   < 1 MiB │
│ Not Installed │ gcloud app Java Extensions                           │ app-engine-java          │ 118.4 MiB │
│ Not Installed │ gcloud app PHP Extensions                            │ app-engine-php           │  21.9 MiB │
│ Not Installed │ gcloud app Python Extensions                         │ app-engine-python        │   6.2 MiB │
│ Not Installed │ kubectl                                              │ kubectl                  │  12.2 MiB │
│ Installed     │ BigQuery Command Line Tool                           │ bq                       │   < 1 MiB │
│ Installed     │ Cloud SDK Core Libraries                             │ core                     │   7.5 MiB │
│ Installed     │ Cloud Storage Command Line Tool                      │ gsutil                   │   3.3 MiB │
└───────────────┴──────────────────────────────────────────────────────┴──────────────────────────┴───────────┘
To install or remove components at your current SDK version [180.0.1], run:
  $ gcloud components install COMPONENT_ID
  $ gcloud components remove COMPONENT_ID

To update your SDK installation to the latest version [180.0.1], run:
  $ gcloud components update

kubectlはデフォルトでは,インストールされていません.
gcloud components install COMPONENT_IDで必要なコンポーネントをインストールできるので,下記のように実行してkubectlをインストールします.

$ gcloud components install kubectl

Minikube

Minikubeのインストール

$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.22.3/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/

※記事を書いた時点では,v0.24.1が最新ですが,意図した通りに動かない部分があったので,minikubeのバージョンを意図的に落としています.

また,brewを利用した下記のようなインストール方法もあります.

brew cask install minikube

Minikubeの起動

$ minikube start

ダッシュボードの起動

上手く起動できているか,ダッシュボードを確認してみます.

$ minikube dashboard

kubernetes-dashboard_1.png

minikubeの終了

Minikubeの終了の仕方は,下記の通りです.

$ minikube stop

Dockerのインストール

Docker Community Editionから自分の環境にそってダウンロード,インストールします.

DockerHubアカウント作成

Docker Hubでアカウントを作成しておきます.

アカウントを作成したら,docker loginコマンドで,Docker Hubに作成したアカウントでログインします.

Dockerイメージの作成

Kubernetesで利用するDockerイメージを作成します.
今回は,NginxのイメージとPHPのイメージを利用します.

Nginx

ファイル構成

conf.d/
  myapp.conf
Dockerfile
nginx.conf

nginx.conf

user nginx;
worker_processes 1;
pid /run/nginx.pid;

events {
        worker_connections 768;
}

http {
        sendfile off;
        access_log stdout;
        error_log stderr;

        include /etc/nginx/conf.d/*.conf;
}

include /etc/nginx/conf.d/*.conf;により後述する.myapp.confの設定を読み込ませるようにしています.

myapp.conf

今回作成するPHPファイルをNginxを通して実行させ,結果を返すための設定ファイルです.

server {
  listen 80;
  root /app;

  access_log stdout;
  error_log stderr;

  location ~ \.php$ {
    fastcgi_pass php-fpm-service:9000;
    fastcgi_index index.php;
    fastcgi_param  SCRIPT_FILENAME /app$fastcgi_script_name;
    include fastcgi_params;
  }
}

root /app;では,実行するプログラムのディレクトリを設定しています.
access_log stdout;とすることにより,アクセスログを標準出力しています.Kubernetesでは,標準出力されたログを自動で回収してくれます.
location ~ \.php$ {内で,拡張子がphpに該当するものの場合の処理を記載しています.

fastcgi_passには,名前解決できるアドレスやIPアドレス,UNIXソケットなどを指定することができますが,ここでは,kubernetesで起動するServiceの名前とポート番号(php-fpm-service:9000)を指定しています.

Dockerfile

NginxのDockerイメージを作成するのに利用しています.

FROM nginx:1.13.7

ADD ./nginx.conf /etc/nginx/nginx.conf
RUN rm /etc/nginx/conf.d/default.conf
ADD ./conf.d/ /etc/nginx/conf.d

同じディレクトリにあるnginx.confをイメージ内の/etc/nginx/nginx.confに配置し,デフォルトの設定ファイル(default.conf)を削除した後,conf.dディレクトリの内容を/etc/nginx/conf.dディレクトリに追加しています.

イメージのビルド

上記ファイルを作成したら,Dockerfileのあるディレクトリで下記を実行します.
nginx-advent2017は,DockerHubCreate repositoryで,作成したリポジトリです.

$ docker build -t yasunoriishikawa/nginx-advent2017 .

イメージのpush

先程作成した,Docker HubのリポジトリにDockerイメージをpushします.

$ docker push yasunoriishikawa/nginx-advent2017:latest

PHP

ファイル構成

app/
  index.php
  phpinfo.php
php-fpm.d/
  www.conf
Dockerfile
php-fpm.conf
php.ini

index.php

サンプルプログラムです.

<html>
<head>
    <meta charset="UTF-8">
    <title>グレンジ Advent Calendar 2017</title>

    <style>
        body {
            font-family: Verdana, sans-serif;
            font-size: 14px;
            padding: 40px;
        }
    </style>
</head>
<body>
    <h1>グレンジ Advent Calendar 2017</h1>
    <p>Today is <?php echo date('m/d/Y H:i:s'); ?>.</p>
</body>
</html>

www.conf

アプリケーションのNginxの設定ファイルです.

[www]
user = www-data
group = www-data

listen = 9000
listen.owner = www-data
listen.group = www-data

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

listen = 9000で,listenするポートを指定しています.

Dockerfile

PHPのDockerイメージを作成するのに利用しています.

FROM php:7.2.0-fpm

ADD ./php.ini /usr/local/etc/php/php.ini
ADD ./php-fpm.conf /usr/local/etc/php-fpm.conf
ADD ./php-fpm.d/ /usr/local/etc/php-fpm.d

RUN sed -i "s/;date.timezone =/date.timezone = Asia\/Tokyo/" /usr/local/etc/php/php.ini

ADD app/ /app

基本的には,Nginx同様にファイルを追加していますが,大きな違いとしては,php.iniのtimezoneをAsia/Tokyoに設定しています.

php-fpm.conf

php-fpmの設定ファイルです.

[global]
pid = /var/run/php7-fpm.pid
error_log = stdout
include=/usr/local/etc/php-fpm.d/*.conf

php.ini

内容が大きいので,こちらを参照して下さい.

Kubernetes

Kubernetesを利用して実際に,アプリケーションを実行できるようにします.

構成図

今回作成する環境は,下記のようなイメージになります.

advent2017.png

192.168.99.100は,minikubeが外部からのリクエストを受け付けているIPになります.
※IPは環境によって異なる場合があります.

また,今回はnginxで受けたリクエストをphp-fpmで実行し,その結果を返すようにしています.

リクエストは,nginx-service192.168.99.100:30001を通して受け取り,nginxのPodが,php-fpm-serviceを通じて,php-fpmのPodにリクエストを届け処理した結果をレスポンスとして返します.

用語説明

実際にkubernetesを利用して環境を作成する前に基本的な用語を簡単に説明します.

Pod

1つか複数のコンテナをデプロイする単位.今回は,NginxのコンテナPHP-FPMのコンテナを起動するので,それぞれのPodを作成することになります.

Deployment

Deploymentは,Pod(実際はReplicaSetsもです)を管理しています.DeploymentにPodが利用するイメージ(コンテナ)や,作成するPod(レプリカ)の数などを設定することで,常に指定されたイメージを設定した数だけ保つことができます.

Service

アプリケーションのエンドポイントです.今回は,nginx-servicephp-fpm-serviceという2つのServiceを作成します.
このエンドポイントを利用して,PodPodあるいは外部Podが通信することになります.

main.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30001
    protocol: TCP
  selector:
    app: nginx
---
apiVersion: v1
kind: Service
metadata:
  name: php-fpm-service
  labels:
    app: php-fpm
spec:
  selector:
    app: php-fpm
  ports:
    - protocol: TCP
      port: 9000
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: yasunoriishikawa/nginx-advent2017:latest
        ports:
        - containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: php-fpm
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: php-fpm
    spec:
      containers:
      - name: php-fpm
        image: yasunoriishikawa/phpfpm-advent2017:latest
        ports:
        - containerPort: 9000

imageの部分は,先程作成したDocker Hubのイメージを指定して下さい.

yamlを大別すると下記のような構成になっています.

  • Service
    • nginx-service
    • php-fpm-service
  • Deployment
    • nginx
    • php-fpm

nginx-service(Service)

nginxのNetwork Proxyの役割を設定しています.
selectorapp: nginxと設定されていることで,先で説明したnginxのPodとのネットワークを管理しています.
nodePort: 30001により,ホストでアクセスされる際のポート(外部からアクセスするときに使用するポート)を指定しています.

※ポートはデフォルトで,30000-32767まで利用できます.

php-fpm-service(Service)

php-fpmのNexwork Proxyの役割を設定しています.
基本的には,nginx-serviceと同様の設定ですが,管理対象は,php-fpmのPodであり,外部アクセスの必要性がないので,nodePortは,設定していません.

nginx(Deployment)

nginxサーバのpodを管理しています.
Dockerイメージとして,yasunoriishikawa/nginx-advent2017:latestを利用し,コンテナを80番ポートで起動し,1つのPod(replicas: 1)を管理しています.

php-fpm(Deployment)

php-fpm実行サーバのpodを管理しています.
Dockerイメージとして,yasunoriishikawa/phpfpm-advent2017:latestを利用し,コンテナを9000番ポートで1つのPodを管理しています.

リソースの起動

実際に起動するには,下記のコマンドを実行して下さい.

$ kubectl apply -f main.yaml

確認

http://192.168.99.100:30001/index.phpにアクセスしてみて下さい.
※環境によってIPアドレスが異なることがあります.その際は,$ minikube ipを実行して,自分の環境のIPアドレスを確認してみて下さい.

以下のようなページが表示されていれば,成功です.

result.png

ダッシュボードの確認

$ minikube dashboardで,ダッシュボードを確認すると先程作成した.nginxphpdeploymentpodそして,serviceが作成されていることが分かります.

kubernetes-dashboard_2.png

リソースの停止

$ kubectl delete -f main.yaml

最後に

この記事で利用したプログラムは,GitHubで公開しています.
この記事を読んで頂いた方が,少しでもKubernetesに興味を持っていただければ幸いです.

参考

46
34
1

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
46
34