Kubernetes で Lumen を動かす
Google Container Engine (GKE) で Kubernetes を使って Lumen を動かしたときの手順メモ。
今回は ReplicationController で pod を 3 個立ててみました。
Docker イメージの作成
1 個の pod 内で nginx と php-fpm の 2 つのコンテナを起動させます。そのための Docker イメージを作成します。
nginx の Dockerfile
FROM nginx:latest MAINTAINER takaya030 ADD server.conf /etc/nginx/conf.d/server.conf
server.conf
同じ pod のコンテナは同じホストで起動するので php-fpm を localhost:9000 で参照する設定にしています。
server {
listen 80 default;
server_name _;
root /webapp/public;
index index.php index.html index.htm;
charset utf-8;
access_log off;
error_log off;
rewrite ^(.+)/$ $1;
location / {
# try_files $uri $uri/ /index.php$is_args$args;
try_files $uri /index.php?$query_string;
}
location ~ ^/index.php$ {
fastcgi_pass localhost:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
nginx イメージのビルド
$ docker build -t gcr.io/my_project_id/lumen_nginx .
php-fpm + lumen の Dockerfile
k8s_lumen フォルダはこちらで作成した Lumen の実行環境になります。
FROM php:7-fpm MAINTAINER takaya030 RUN apt-get update \ && apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng12-dev libmcrypt-dev \ && docker-php-ext-install pdo_mysql mysqli mbstring gd iconv mcrypt RUN mkdir /webapp COPY k8s_lumen /webapp
php-fpm イメージのビルド
$ docker build -t gcr.io/my_project_id/lumen_php7 .
イメージを Container Registry へ push
$ gcloud docker push gcr.io/my_project_id/lumen_nginx $ gcloud docker push gcr.io/my_project_id/lumen_php7
ReplicationController の作成
rc-k8slumen.yaml
apiVersion: v1 kind: ReplicationController metadata: name: k8slumen spec: replicas: 3 selector: app: weblumen template: metadata: name: k8slumen labels: app: weblumen spec: containers: - name: nginx image: gcr.io/my-project-id/lumen_nginx ports: - containerPort: 80 - name: lumen image: gcr.io/my-project-id/lumen_php7 ports: - containerPort: 9000
ReplicationController の作成
$ kubectl create -f rc-k8slumen.yaml replicationcontroller "k8slumen" created
ReplicationController の作成確認
$ kubectl get rc NAME DESIRED CURRENT AGE k8slumen 3 3 27s
service の作成
service-k8slumen.yaml
apiVersion: v1 kind: Service metadata: name: lumentest spec: ports: - port: 80 targetPort: 80 selector: app: weblumen type: LoadBalancer
service の作成
$ kubectl create -f service-k8slumen.yaml service "lumentest" created
service の作成確認
$ kubectl get services NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes 10.3.240.1 <none> 443/TCP 7m lumentest 10.3.255.153 80/TCP 17s
動作確認
この状態で pod が 3 個起動しています。
$ kubectl get pods -l app=weblumen -o wide NAME READY STATUS RESTARTS AGE NODE k8slumen-5r9jc 2/2 Running 0 1m gke-cluster-1-default-pool-a58af72c-3ais k8slumen-itl2h 2/2 Running 0 1m gke-cluster-1-default-pool-a58af72c-yx7i k8slumen-xfed2 2/2 Running 0 1m gke-cluster-1-default-pool-a58af72c-4rtd
service を作成してから 1 分程経過するとグローバルIP (EXTERNAL-IP) が割り当てられるので、 http://EXTERNAL-IP にブラウザでアクセスして以下のように表示されれば成功です。
ロードバランスされているので、ブラウザをリロードした際、前回と別の pod にリクエストしたときは以下のように Server IP が変化します。
フェイルオーバー(failover)の検証
試しに pod を一つ削除してみます。
$ kubectl delete pod k8slumen-5r9jc pod "k8slumen-5r9jc" deleted
kubernetes が pod の減少を検知して自動で pod を立ち上げます。
pod のリストを見ると新しい pod が追加されているのが分かります。
$ kubectl get pods -l app=weblumen -o wide NAME READY STATUS RESTARTS AGE NODE k8slumen-itl2h 2/2 Running 0 31m gke-cluster-1-default-pool-a58af72c-yx7i k8slumen-w468c 2/2 Running 0 12s gke-cluster-1-default-pool-a58af72c-3ais k8slumen-xfed2 2/2 Running 0 31m gke-cluster-1-default-pool-a58af72c-4rtd
後始末
service、ReplicationController の削除
ReplicationController を削除すれば pod も自動で削除されます
$ kubectl delete -f service-k8slumen.yaml service "lumentest" deleted $ kubectl delete -f rc-k8slumen.yaml replicationcontroller "k8slumen" deleted