引き続きk8s学習話。
前回k8sでPodとServiceという概念や、その中で名前やラベルといった抽象的な表現を用いて扱うことを学んだ。
今回は実際にそれを利用してスケールしたりB/Gデプロイ的なことをしてみる。
スケールする
Manifestfile
前回はpodとserviceを単純に1対1揃えたが、今回は以下のようなManifestfileを用意した。
# service.yaml kind: Service apiVersion: v1 metadata: name: http-service labels: app: http-app spec: selector: app: http-app ports: - port: 8080 targetPort: http-port externalIPs: - 192.168.99.100
# pod-blue.yaml apiVersion: v1 kind: Pod metadata: name: http-blue labels: app: http-app color: blue spec: containers: - name: nginx image: nginx:latest ports: - name: http-port containerPort: 80 lifecycle: postStart: exec: command: - /bin/sh - -c - echo "<html><body>blue</body></html>" > /usr/share/nginx/html/index.html
# pod-green.yaml apiVersion: v1 kind: Pod metadata: name: http-green labels: app: http-app color: green spec: containers: - name: nginx image: nginx:latest ports: - name: http-port containerPort: 80 lifecycle: postStart: exec: command: - /bin/sh - -c - echo "<html><body>green</body></html>" > /usr/share/nginx/html/index.html
どちらのpodにも同じapp: html-app
のラベルを付けているが、表示するhtmlをそれぞれ変えている。
動作チェック
ひとまず起動。
$ kubectl create -f pod-blue.yaml -f pod-green.yaml -f service.yaml pod "http-blue" created pod "http-green" created service "http-service" created
適当な回数をリクエストを投げてみると、両方のpodにランダムに疎通されていることが確認できる。
$ for i in $(seq 0 10); do echo $i;curl 192.168.99.100:8080;done 0 <html><body>green</body></html> 1 <html><body>green</body></html> 2 <html><body>green</body></html> 3 <html><body>blue</body></html> 4 <html><body>blue</body></html> 5 <html><body>blue</body></html> 6 <html><body>blue</body></html> 7 <html><body>green</body></html> 8 <html><body>green</body></html> 9 <html><body>green</body></html> 10 <html><body>blue</body></html>
当然、一方のpodを停止すれば、動いている方のみにリクエストが飛ぶ。
$ kubectl delete -f pod-blue.yaml pod "http-blue" deleted $ for i in $(seq 0 10); do echo $i;curl 192.168.99.100:8080;done 0 <html><body>green</body></html> 1 <html><body>green</body></html> 2 <html><body>green</body></html> 3 <html><body>green</body></html> 4 <html><body>green</body></html> 5 <html><body>green</body></html> 6 <html><body>green</body></html> 7 <html><body>green</body></html> 8 <html><body>green</body></html> 9 <html><body>green</body></html> 10 <html><body>green</body></html>
このように、必要に応じてPodだけを増減させることができるわけで、付加に応じてスケールさせるなんてことを実現することができる。
Blue/Greenデプロイ
Manifestfile
先のpod-blue.yaml、pod-green.yamlを利用するような、以下のようなservice-bg.yamlを作成してみる。
# service-bg.yaml kind: Service apiVersion: v1 metadata: name: http-service spec: selector: app: http-app color: green ports: - port: 8080 targetPort: http-port externalIPs: - 192.168.99.100
selectorとしてapp項に加えてcolor項も条件に加えてみる。
動作チェック
先に記述した状態でリクエストを投げると、当然greenの側にだけ通信がいく。
$ for i in $(seq 0 10); do echo $i;curl 192.168.99.100:8080;done 0 <html><body>green</body></html> 1 <html><body>green</body></html> 2 <html><body>green</body></html> 3 <html><body>green</body></html> 4 <html><body>green</body></html> 5 <html><body>green</body></html> 6 <html><body>green</body></html> 7 <html><body>green</body></html> 8 <html><body>green</body></html> 9 <html><body>green</body></html> 10 <html><body>green</body></html>
service-bg.yamlのcolor項をblueに書き換えた上でapplyコマンドで適用すると・・・
$ kubectl apply -f service-bg.yaml Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply service "http-service" configured $ for i in $(seq 0 10); do echo $i;curl 192.168.99.100:8080;done 0 <html><body>blue</body></html> 1 <html><body>blue</body></html> 2 <html><body>blue</body></html> 3 <html><body>blue</body></html> 4 <html><body>blue</body></html> 5 <html><body>blue</body></html> 6 <html><body>blue</body></html> 7 <html><body>blue</body></html> 8 <html><body>blue</body></html> 9 <html><body>blue</body></html> 10 <html><body>blue</body></html>
切り替わることが確認できる。
実用上の話、deployment
さて、サービス運用においては実用上は同じ内容のpodを増減させるという使い方になるだろう。
k8sではpodの上にそのスケール数なんかを管理させる概念も用意していて、古くはreplication controller
というresourceとして扱っていたのだが、最近のバージョンからはpodを管理するreplica set
とそれを更に管理するdeployment
というresourceを用いる、らしい。
前回のpod.yamlに準拠して以下のようなdeployment.yamlを作成した。
# deployment.yaml apiVersion: apps/v1beta1 kind: Deployment metadata: name: http-deploy spec: replicas: 3 template: metadata: labels: app: http-app spec: containers: - name: nginx image: nginx:latest ports: - name: http-port containerPort: 80 volumeMounts: - name: docroot mountPath: /usr/share/nginx/html - name: html image: busybox command: - tail - -f - /dev/null volumeMounts: - name: docroot mountPath: /opt/html lifecycle: postStart: exec: command: - /bin/sh - -c - echo "<html><body>Hello k8s!</body></html>" > /opt/html/index.html volumes: - name: docroot emptyDir: {}
apiVersionに注意。起動する数をreplicasに記述し、template内にpodの内容を記述していく。
動作チェック
起動してみる。
$ kubectl create -f deployment.yaml -f service.yaml deployment "http-deploy" created service "http-service" created
deploymentが作成され
$ kubectl get deploy NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE http-deploy 3 3 3 3 34s
reploca setが生成され
$ kubectl get rs NAME DESIRED CURRENT READY AGE http-deploy-2570210715 3 3 3 1m
replicasの設定値分のpodが起動されていることが確認できる。
$ kubectl get pod NAME READY STATUS RESTARTS AGE http-deploy-2570210715-lf1j3 2/2 Running 0 1m http-deploy-2570210715-s4z8l 2/2 Running 0 1m http-deploy-2570210715-tl63x 2/2 Running 0 1m
deployment.yamlのreplocasを2に変えて適用してみると・・・
$ kubectl apply -f deployment.yaml Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply deployment "http-deploy" configured
実際にpodの数が変化することが分かる。
$ kubectl get pod NAME READY STATUS RESTARTS AGE http-deploy-2570210715-lf1j3 2/2 Running 0 3m http-deploy-2570210715-s4z8l 2/2 Running 0 3m
実用上はこのdeploymentを用いてpodを管理していくのが良いのだと思う。
そんな感じで、k8sの一見するとまどろっこしい概念がなぜ必要だったのかがなんとなく掴めたと思う。
実際にはGKEのNodeを動的に増減させられる機能なんかと組み合わせることで威力を発揮しそうだ。
- 作者: Hideto Saito,Hui-Chuan Chloe Lee,Ke-Jou Carol Hsu
- 出版社/メーカー: Packt Publishing
- 発売日: 2016/06/30
- メディア: Kindle版
- この商品を含むブログを見る