例: Redisを使用したPHPのゲストブックアプリケーションのデプロイ
このチュートリアルでは、KubernetesとDockerを使用した、シンプルなマルチティアのウェブアプリケーションのビルドとデプロイの方法を紹介します。この例は、以下のコンポーネントから構成されています。
- ゲストブックのエントリーを保存するための、シングルインスタンスのRedisマスター
- 読み込みデータ配信用の、複数のレプリケーションされたRedisインスタンス
- 複数のウェブフロントエンドのインスタンス
目標
- Redisのマスターを起動する。
- Redisのスレーブを起動する。
- ゲストブックのフロントエンドを起動する。
- フロントエンドのServiceを公開して表示を確認する。
- クリーンアップする。
始める前に
Kubernetesクラスターが必要、かつそのクラスターと通信するためにkubectlコマンドラインツールが設定されている必要があります。 このチュートリアルは、コントロールプレーンのホストとして動作していない少なくとも2つのノードを持つクラスターで実行することをおすすめします。 まだクラスターがない場合、minikubeを使って作成するか、 以下のいずれかのKubernetesプレイグラウンドも使用できます:
バージョンを確認するには次のコマンドを実行してください:kubectl version
.Redisのマスターを起動する
ゲストブックアプリケーションでは、データを保存するためにRedisを使用します。ゲストブックはRedisのマスターインスタンスにデータを書き込み、複数のRedisのスレーブインスタンスからデータを読み込みます。
RedisのマスターのDeploymentを作成する
以下のマニフェストファイルは、シングルレプリカのRedisのマスターPodを実行するDeploymentコントローラーを指定しています。
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: redis-master
labels:
app: redis
spec:
selector:
matchLabels:
app: redis
role: master
tier: backend
replicas: 1
template:
metadata:
labels:
app: redis
role: master
tier: backend
spec:
containers:
- name: master
image: registry.k8s.io/redis:e2e # or just image: redis
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 6379
マニフェストファイルをダウンロードしたディレクトリ内で、ターミナルウィンドウを起動します。
redis-master-deployment.yaml
ファイルから、RedisのマスターのDeploymentを適用します。kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-deployment.yaml
Podのリストを問い合わせて、RedisのマスターのPodが実行中になっていることを確認します。
kubectl get pods
結果は次のようになるはずです。
NAME READY STATUS RESTARTS AGE redis-master-1068406935-3lswp 1/1 Running 0 28s
次のコマンドを実行して、RedisのマスターのPodからログを表示します。
kubectl logs -f POD-NAME
備考:
POD-NAMEの部分を実際のPodの名前に書き換えてください。RedisのマスターのServiceを作成する
ゲストブックアプリケーションは、データを書き込むためにRedisのマスターと通信する必要があります。そのためには、Serviceを適用して、トラフィックをRedisのマスターのPodへプロキシしなければなりません。Serviceは、Podにアクセスするためのポリシーを指定します。
apiVersion: v1
kind: Service
metadata:
name: redis-master
labels:
app: redis
role: master
tier: backend
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redis
role: master
tier: backend
次の
redis-master-service.yaml
から、RedisのマスターのServiceを適用します。kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-service.yaml
Serviceのリストを問い合わせて、RedisのマスターのServiceが実行中になっていることを確認します。
kubectl get service
The response should be similar to this:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 1m redis-master ClusterIP 10.0.0.151 <none> 6379/TCP 8s
備考:
このマニフェストファイルは、redis-master
という名前のServiceを、前に定義したラベルにマッチする一連のラベル付きで作成します。これにより、ServiceはネットワークトラフィックをRedisのマスターのPodへとルーティングできるようになります。Redisのスレーブを起動する
Redisのマスターは1つのPodですが、レプリカのRedisのスレーブを追加することで、トラフィックの需要を満たすための高い可用性を持たせることができます。
RedisのスレーブのDeploymentを作成する
Deploymentはマニフェストファイル内に書かれた設定に基づいてスケールします。ここでは、Deploymentオブジェクトは2つのレプリカを指定しています。
もし1つもレプリカが実行されていなければ、このDeploymentは2つのレプリカをコンテナクラスター上で起動します。逆に、もしすでに2つ以上のレプリカが実行されていれば、実行中のレプリカが2つになるようにスケールダウンします。
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: redis-slave
labels:
app: redis
spec:
selector:
matchLabels:
app: redis
role: slave
tier: backend
replicas: 2
template:
metadata:
labels:
app: redis
role: slave
tier: backend
spec:
containers:
- name: slave
image: gcr.io/google_samples/gb-redisslave:v3
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: GET_HOSTS_FROM
value: dns
# Using `GET_HOSTS_FROM=dns` requires your cluster to
# provide a dns service. As of Kubernetes 1.3, DNS is a built-in
# service launched automatically. However, if the cluster you are using
# does not have a built-in DNS service, you can instead
# access an environment variable to find the master
# service's host. To do so, comment out the 'value: dns' line above, and
# uncomment the line below:
# value: env
ports:
- containerPort: 6379
redis-slave-deployment.yaml
ファイルから、RedisのスレーブのDeploymentを適用します。kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-deployment.yaml
Podのリストを問い合わせて、RedisのスレーブのPodが実行中になっていることを確認します。
kubectl get pods
結果は次のようになるはずです。
NAME READY STATUS RESTARTS AGE redis-master-1068406935-3lswp 1/1 Running 0 1m redis-slave-2005841000-fpvqc 0/1 ContainerCreating 0 6s redis-slave-2005841000-phfv9 0/1 ContainerCreating 0 6s
RedisのスレーブのServiceを作成する
ゲストブックアプリケーションは、データを読み込むためにRedisのスレーブと通信する必要があります。Redisのスレーブが発見できるようにするためには、Serviceをセットアップする必要があります。Serviceは一連のPodに対する透過的なロードバランシングを提供します。
apiVersion: v1
kind: Service
metadata:
name: redis-slave
labels:
app: redis
role: slave
tier: backend
spec:
ports:
- port: 6379
selector:
app: redis
role: slave
tier: backend
次の
redis-slave-service.yaml
ファイルから、RedisのスレーブのServiceを適用します。kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-service.yaml
Serviceのリストを問い合わせて、RedisのスレーブのServiceが実行中になっていることを確認します。
kubectl get services
結果は次のようになるはずです。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 2m redis-master ClusterIP 10.0.0.151 <none> 6379/TCP 1m redis-slave ClusterIP 10.0.0.223 <none> 6379/TCP 6s
ゲストブックのフロントエンドをセットアップして公開する
ゲストブックアプリケーションには、HTTPリクエストをサーブするPHPで書かれたウェブフロントエンドがあります。このアプリケーションは、書き込みリクエストに対してはredis-master
Serviceに、読み込みリクエストに対してはredis-slave
Serviceに接続するように設定されています。
ゲストブックのフロントエンドのDeploymentを作成する
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: frontend
labels:
app: guestbook
spec:
selector:
matchLabels:
app: guestbook
tier: frontend
replicas: 3
template:
metadata:
labels:
app: guestbook
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google-samples/gb-frontend:v4
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: GET_HOSTS_FROM
value: dns
# Using `GET_HOSTS_FROM=dns` requires your cluster to
# provide a dns service. As of Kubernetes 1.3, DNS is a built-in
# service launched automatically. However, if the cluster you are using
# does not have a built-in DNS service, you can instead
# access an environment variable to find the master
# service's host. To do so, comment out the 'value: dns' line above, and
# uncomment the line below:
# value: env
ports:
- containerPort: 80
frontend-deployment.yaml
ファイルから、フロントエンドのDeploymentを適用します。kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
Podのリストを問い合わせて、3つのフロントエンドのレプリカが実行中になっていることを確認します。
kubectl get pods -l app=guestbook -l tier=frontend
結果は次のようになるはずです。
NAME READY STATUS RESTARTS AGE frontend-3823415956-dsvc5 1/1 Running 0 54s frontend-3823415956-k22zn 1/1 Running 0 54s frontend-3823415956-w9gbt 1/1 Running 0 54s
フロントエンドのServiceを作成する
適用したredis-slave
およびredis-master
Serviceは、コンテナクラスター内部からのみアクセス可能です。これは、デフォルトのServiceのtypeがClusterIPであるためです。ClusterIP
は、Serviceが指している一連のPodに対して1つのIPアドレスを提供します。このIPアドレスはクラスター内部からのみアクセスできます。
もしゲストの人にゲストブックにアクセスしてほしいのなら、フロントエンドServiceを外部から見えるように設定しなければなりません。そうすれば、クライアントはコンテナクラスターの外部からServiceにリクエストを送れるようになります。Minikubeでは、ServiceをNodePort
でのみ公開できます。
備考:
一部のクラウドプロバイダーでは、Google Compute EngineやGoogle Kubernetes Engineなど、外部のロードバランサーをサポートしているものがあります。もしクラウドプロバイダーがロードバランサーをサポートしていて、それを使用したい場合は、type: NodePort
という行を単に削除またはコメントアウトして、type: LoadBalancer
のコメントアウトを外せば使用できます。apiVersion: v1
kind: Service
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
# comment or delete the following line if you want to use a LoadBalancer
type: NodePort
# if your cluster supports it, uncomment the following to automatically create
# an external load-balanced IP for the frontend service.
# type: LoadBalancer
ports:
- port: 80
selector:
app: guestbook
tier: frontend
frontend-service.yaml
ファイルから、フロントエンドのServiceを提供します。kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml
Serviceのリストを問い合わせて、フロントエンドのServiceが実行中であることを確認します。
kubectl get services
結果は次のようになるはずです。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE frontend NodePort 10.0.0.112 <none> 80:31323/TCP 6s kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 4m redis-master ClusterIP 10.0.0.151 <none> 6379/TCP 2m redis-slave ClusterIP 10.0.0.223 <none> 6379/TCP 1m
フロントエンドのServiceをNodePort
経由で表示する
このアプリケーションをMinikubeやローカルのクラスターにデプロイした場合、ゲストブックを表示するためのIPアドレスを見つける必要があります。
次のコマンドを実行すると、フロントエンドServiceに対するIPアドレスを取得できます。
minikube service frontend --url
結果は次のようになるはずです。
http://192.168.99.100:31323
IPアドレスをコピーして、ブラウザー上でページを読み込み、ゲストブックを表示しましょう。
フロントエンドのServiceをLoadBalancer
経由で表示する
もしfrontend-service.yaml
マニフェストをtype: LoadBalancer
でデプロイした場合、ゲストブックを表示するためのIPアドレスを見つける必要があります。
次のコマンドを実行すると、フロントエンドServiceに対するIPアドレスを取得できます。
kubectl get service frontend
結果は次のようになるはずです。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE frontend ClusterIP 10.51.242.136 109.197.92.229 80:32372/TCP 1m
外部IPアドレス(EXTERNAL-IP)をコピーして、ブラウザー上でページを読み込み、ゲストブックを表示しましょう。
ウェブフロントエンドをスケールする
サーバーがDeploymentコントローラーを使用するServiceとして定義されているため、スケールアップやスケールダウンは簡単です。
次のコマンドを実行すると、フロントエンドのPodの数をスケールアップできます。
kubectl scale deployment frontend --replicas=5
Podのリストを問い合わせて、実行中のフロントエンドのPodの数を確認します。
kubectl get pods
結果は次のようになるはずです。
NAME READY STATUS RESTARTS AGE frontend-3823415956-70qj5 1/1 Running 0 5s frontend-3823415956-dsvc5 1/1 Running 0 54m frontend-3823415956-k22zn 1/1 Running 0 54m frontend-3823415956-w9gbt 1/1 Running 0 54m frontend-3823415956-x2pld 1/1 Running 0 5s redis-master-1068406935-3lswp 1/1 Running 0 56m redis-slave-2005841000-fpvqc 1/1 Running 0 55m redis-slave-2005841000-phfv9 1/1 Running 0 55m
次のコマンドを実行すると、フロントエンドのPodの数をスケールダウンできます。
kubectl scale deployment frontend --replicas=2
Podのリストを問い合わせて、実行中のフロントエンドのPodの数を確認します。
kubectl get pods
結果は次のようになるはずです。
NAME READY STATUS RESTARTS AGE frontend-3823415956-k22zn 1/1 Running 0 1h frontend-3823415956-w9gbt 1/1 Running 0 1h redis-master-1068406935-3lswp 1/1 Running 0 1h redis-slave-2005841000-fpvqc 1/1 Running 0 1h redis-slave-2005841000-phfv9 1/1 Running 0 1h
クリーンアップ
DeploymentとServiceを削除すると、実行中のPodも削除されます。ラベルを使用すると、複数のリソースを1つのコマンドで削除できます。
次のコマンドを実行すると、すべてのPod、Deployment、Serviceが削除されます。
kubectl delete deployment -l app=redis kubectl delete service -l app=redis kubectl delete deployment -l app=guestbook kubectl delete service -l app=guestbook
結果は次のようになるはずです。
deployment.apps "redis-master" deleted deployment.apps "redis-slave" deleted service "redis-master" deleted service "redis-slave" deleted deployment.apps "frontend" deleted service "frontend" deleted
Podのリストを問い合わせて、実行中のPodが存在しないことを確認します。
kubectl get pods
結果は次のようになるはずです。
No resources found.
次の項目
- ゲストブックアプリケーションに対するELKによるロギングとモニタリング
- Kubernetesの基本のインタラクティブチュートリアルを終わらせる
- Kubernetesを使って、MySQLとWordpressのためにPersistent Volumeを使用したブログを作成する
- サービスとアプリケーションの接続についてもっと読む
- リソースの管理についてもっと読む