Google Container Engine (GKE) のモニタリングについてのメモ
Cloud Monitoring の有効化
GKE でコンテンナクラスタを作成するときに "Cloud Monitoring を有効にする" にチェックを入れます。
初回は StackDriver のユーザー登録を行った後、使用可能になります。
2016年7月23日現在、BETA期間中につき無料で使用できます。
Google Container Engine (GKE) のモニタリングについてのメモ
GKE でコンテンナクラスタを作成するときに "Cloud Monitoring を有効にする" にチェックを入れます。
初回は StackDriver のユーザー登録を行った後、使用可能になります。
2016年7月23日現在、BETA期間中につき無料で使用できます。
Google Container Engine (GKE) で Kubernetes を使って Lumen を動かしたときの手順メモ。
今回は ReplicationController で pod を 3 個立ててみました。
1 個の pod 内で nginx と php-fpm の 2 つのコンテナを起動させます。そのための Docker イメージを作成します。
FROM nginx:latest MAINTAINER takaya030 ADD server.conf /etc/nginx/conf.d/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;
}
}
$ docker build -t gcr.io/my_project_id/lumen_nginx .
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
$ docker build -t gcr.io/my_project_id/lumen_php7 .
$ gcloud docker push gcr.io/my_project_id/lumen_nginx $ gcloud docker push gcr.io/my_project_id/lumen_php7
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
$ kubectl create -f rc-k8slumen.yaml replicationcontroller "k8slumen" created
$ kubectl get rc NAME DESIRED CURRENT AGE k8slumen 3 3 27s
apiVersion: v1 kind: Service metadata: name: lumentest spec: ports: - port: 80 targetPort: 80 selector: app: weblumen type: LoadBalancer
$ kubectl create -f service-k8slumen.yaml service "lumentest" created
$ 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 が変化します。
試しに 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
nginx + php-fpm で Lumen を動かす記事の続編です。
最新版の Lumen をインストールして実行してみたらバージョン番号のテキストが表示されました。あの白い画面の Welcome Page が無いとチョット寂しいので Lumen 5.2 で作ってみました。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class WelcomeController extends Controller { public function index( Request $request ) { $client_ip = $request->ip(); $server = $request->server(); // $_SERVER return view('welcome', ['server' => $server, 'client_ip' => $client_ip]); } }
<?php /* |-------------------------------------------------------------------------- | Application Routes |-------------------------------------------------------------------------- | | Here is where you can register all of the routes for an application. | It is a breeze. Simply tell Lumen the URIs it should respond to | and give it the Closure to call when that URI is requested. | */ $app->get('/', [ 'uses' => 'WelcomeController@index', ]);
<!DOCTYPE html> <html> <head> <title>Lumen</title> <link href='//fonts.googleapis.com/css?family=Lato:100' rel='stylesheet' type='text/css'> <style> body { margin: 0; padding: 0; width: 100%; height: 100%; color: #B0BEC5; display: table; font-weight: 100; font-family: 'Lato'; } .container { text-align: center; display: table-cell; vertical-align: middle; } .content { text-align: center; display: inline-block; } .title { font-size: 96px; margin-bottom: 40px; } .quote { font-size: 24px; } .info { font-size: 48px; } </style> </head> <body> <div class="container"> <div class="content"> <div class="title">Lumen.</div> <div class="info">Hostname: {{ gethostname() }}</div> <div class="info">Server IP: {{ $server['SERVER_ADDR'] }}</div> <div class="info">Client IP: {{ $client_ip }}</div> @if ( array_key_exists('X-Forwarded-For', $server) ) <div class="info">X-Forwarded-For: {{ $server['X-Forwarded-For'] }}</div> @elseif ( array_key_exists('HTTP_X_FORWARDED_FOR', $server) ) <div class="info">HTTP_X_FORWARDED_FOR: {{ $server['HTTP_X_FORWARDED_FOR'] }}</div> @elseif ( array_key_exists('REMOTE_ADDR', $server) ) <div class="info">REMOTE_ADDR: {{ $server['REMOTE_ADDR'] }}</div> @endif </div> </div> </body> </html>
lumen │ docker-compose.yml │ ├─nginx │ Dockerfile │ server.conf │ └─php7 Dockerfile k8s_lumen/
lumen/php7/k8s_lumen は下記コマンドでインストールされた Lumen の実行環境に上記ソースコードを適用したものになります。
$ composer create-project --prefer-dist laravel/lumen k8s_lumen
nginx: build: ./nginx ports: - "80:80" links: - php7 php7: build: ./php7
FROM nginx:latest MAINTAINER takaya030 ADD server.conf /etc/nginx/conf.d/server.conf
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 lumen_php7_1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
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
$ cd lumen
$ docker-compose build
$ cd lumen $ docker-compose up -d
web ブラウザで http://192.168.99.100/ にアクセスして下の画像のように表示されるか確認。
Lumen 5.2 でコントローラのルートの namespace が App\Http\Controllers に変更されていたのでメモ
app/Http/routes.php
<?php $app->get('/', [ 'uses' => 'App\Http\Controllers\WelcomeController@index', ]);
上のコードを Lumen の最新版(5.2)で実行したとき発生したエラー
[2016-06-25 04:01:55] lumen.ERROR: ReflectionException: Class App\Http\Controllers\App\Http\Controllers\WelcomeController does not exist in /webapp/vendor/illuminate/container/Container.php:734
Lumen 5.1 では Controller のルートは namespace 無しだったが、5.2 では 'App\Http\Controllers' になったらしい。
以下のように変更したら無事動きました。
<?php $app->get('/', [ 'uses' => 'WelcomeController@index', ]);
ちなみに Controller のデフォルト namespace は bootstrap/app.php で定義されている。
Lumen 5.1 の bootstrap/app.php 84行目
<?php /* |-------------------------------------------------------------------------- | Load The Application Routes |-------------------------------------------------------------------------- | | Next we will include the routes file so that they can all be added to | the application. This will provide all of the URLs the application | can respond to, as well as the controllers that may handle them. | */ require __DIR__.'/../app/Http/routes.php';
Lumen 5.2 の bootstrap/app.php 85行目
<?php /* |-------------------------------------------------------------------------- | Load The Application Routes |-------------------------------------------------------------------------- | | Next we will include the routes file so that they can all be added to | the application. This will provide all of the URLs the application | can respond to, as well as the controllers that may handle them. | */ $app->group(['namespace' => 'App\Http\Controllers'], function ($app) { require __DIR__.'/../app/Http/routes.php'; });
Lumen 5.1
$ php artisan --version Laravel Framework version Lumen (5.1.6) (Laravel Components 5.1.*)
Lumen 5.2
$ php artisan --version Laravel Framework version Lumen (5.2.7) (Laravel Components 5.2.*)
Google Container Engine (GKE) で Kubernetes を使って nginx + php-fpm を動かしたときの手順メモ
今回は 1 個の pod 内で nginx と php-fpm の 2 つのコンテナを起動させます。そのための Docker イメージを作成します。
FROM nginx:latest MAINTAINER takaya030 ADD server.conf /etc/nginx/conf.d/server.conf
同じ pod のコンテナは同一ホストで起動するので php-fpm を localhost:9000 で参照する設定にしています。
server { listen 80 default; server_name _; root /var/www/html; index index.php index.html index.htm; charset utf-8; access_log off; error_log off; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ ^/index.php$ { fastcgi_pass localhost:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
$ docker build -t gcr.io/my_project_id/k8sphp_nginx .
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 COPY index.php /var/www/html/
<?php phpinfo();
$ docker build -t gcr.io/my_project_id/k8sphp_php7 .
$ gcloud docker push gcr.io/my_project_id/k8sphp_nginx $ gcloud docker push gcr.io/my_project_id/k8sphp_php7
apiVersion: v1 kind: Pod metadata: name: k8sphp labels: app: webphp spec: containers: - name: nginx image: gcr.io/my-project-id/k8sphp_nginx ports: - containerPort: 80 - name: php-fpm image: gcr.io/my-project-id/k8sphp_php7 ports: - containerPort: 9000
$ kubectl create -f pod-k8sphp.yaml pod "k8sphp" created
$ kubectl get pods NAME READY STATUS RESTARTS AGE k8sphp 2/2 Running 0 34s
apiVersion: v1 kind: Service metadata: name: phptest spec: ports: - port: 80 targetPort: 80 selector: app: webphp type: LoadBalancer
$ kubectl create -f service-k8sphp.yaml service "phptest" created
$ kubectl get services NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes 10.3.240.1 <none> 443/TCP 45m phptest 10.3.242.13 80/TCP 25s
service を作成してから 1 分程経過するとグローバルIP (EXTERNAL-IP) が割り当てられるので、 http://EXTERNAL-IP にブラウザでアクセスして以下のように表示されれば成功です。
service、pod の削除
$ kubectl delete -f service-k8sphp.yaml service "phptest" deleted $ kubectl delete -f pod-k8sphp.yaml pod "k8sphp" deleted
GKE に作成したクラスタに kubectl を使って Docker コンテナを単体起動したときの手順メモ
今回は nginx の Docker Hub 公式イメージをそのまま使います。
$ docker pull nginx $ docker tag nginx gcr.io/my_project_id/nginx $ gcloud docker push gcr.io/my_project_id/nginx
my_project_id にハイフンが含まれている場合、アンダースコアに置き換えて下さい。
push されたイメージは GKE のコンソールで確認できます。
GKE のコンソールからコンテナクラスタを作成します。
今回はこのような内容で作成しました。Cluster size がノード数になります。
作成ボタンを押してから数分後にクラスタが作成されます。
$ kubectl run hello-nginx --image=gcr.io/my-project-id/nginx:laest --port=80
外部からアクセス可能にするため下記コマンドを実行
$ kubectl expose deployment hello-nginx --type="LoadBalancer"
数分待つとコンテナにグローバル IP が割り当てられます。
$ kubectl get service hello-nginx NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-nginx 10.3.243.148 130.211.xxx.xx 80/TCP 7m
EXTERNAL-IP がコンテナのグローバル IP になります。
web ブラウザで http://EXTERNAL-IP を開いて以下の通りに表示されば成功です。
gcloud の config にクラスタの情報が登録されていないのが原因です。
以下の操作で登録します。
$ gcloud config set project my-project-id $ gcloud config set compute/zone us-central1-b $ gcloud config set container/cluster cluster-1 $ gcloud container clusters get-credentials cluster-1 Fetching cluster endpoint and auth data. kubeconfig entry generated for cluster-1. $ gcloud config list Your active configuration is: [default] [compute] region = us-central1 zone = us-central1-b [container] cluster = cluster-1 ...
kubectl version で Server Version が表示されていれば、サーバーと通信できています。
$ kubectl version Client Version: version.Info{Major:"1", Minor:"2", GitVersion:"v1.2.4", GitCommit:"3eed1e3be6848b877ff80a93da3785d9034d0a4f", GitTreeState:"clean"} Server Version: version.Info{Major:"1", Minor:"2", GitVersion:"v1.2.4", GitCommit:"3eed1e3be6848b877ff80a93da3785d9034d0a4f", GitTreeState:"clean"}
Windows版 Google Cloud SDK では Kubernetes (kubectl) が動かないため、Docker コンテナ にインストールしたときの手順メモ
gcloud を動作させるために Python 2.7 が必要なため、Docker Hub の公式イメージを流用して作成
# gcloud shell # FROM python:2.7 MAINTAINER takaya030 RUN apt-get update && apt-get install -y openssh-server sudo RUN mkdir /var/run/sshd RUN echo 'root:root' | chpasswd RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config # SSH login fix. Otherwise user is kicked off after login RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile # create login user RUN useradd -d /home/gcp -m -s /bin/bash gcp RUN echo gcp:****gcp | chpasswd RUN echo 'gcp ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"]
$ docker build -t takaya030/gcloud .
$ docker run -d -it -p 2222:22 --hostname gcsh --name gcp_gcsh_1 takaya030/gcloud
$ ssh -p 2222 gcp@192.168.99.100 ※パスワードは '****gcp'
$ curl https://sdk.cloud.google.com | bash
今回は /home/gcp/google-cloud-sdk/ にインストールした。
インストール後、直ちにコマンドのパスを有効にしたい場合は以下のコマンドを入力
$ source .bashrc
$ gcloud init
$ gcloud components update kubectl $ which kubectl /home/gcp/google-cloud-sdk/bin/kubectl