LinuCエヴァンジェリストの鯨井貴博@opensourcetechです。
はじめに
今回は、kubernetesのDeploymentの耐障害性(自動復旧)とオートスケーリングを検証してみます。
なお、kubernetesは以下の記事で作成したクラスターを使っています。
DualStack(IPv4 & IPv6)のkubernetesクラスター構築(v1.26.00・ubuntu22.04)
https://www.opensourcetech.tokyo/entry/20230314/1678782139
検証すること
検証する内容は、以下の通りです。
・Deploymentの耐障害性(自動復旧)
→ Deploymentで起動されるPodがダウンした際の挙動確認
・オートスケーリング
→ スケールアウト(Pod数の増加)する際の挙動確認
→スケールイン(Pod数の減少)する際の挙動確認
Deploymentの耐障害性(自動復旧)
ではまず、Deploymentの耐障害性(自動復旧) からやってみます。
なお、使用するService(type:LoadBalancer)は以下の記事で作成したMetalLBが必要になるので予め用意する、もしくはNodePortを使うようにしてください。
MetalLBとService(type:LoadBalancer)による外部クライアントへのサービス公開(kubernetes v1.26.00 on ubuntu22.04)
では、DeploymentとServiceのデプロイ。
kubeuser@master01:~/autoscaling$ ls
deployment.yaml hpa.yaml
kubeuser@master01:~/autoscaling$ cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hpa-nginx
spec:
replicas: 4
selector:
matchLabels:
run: hpa-nginx
template:
metadata:
labels:
run: hpa-nginx
spec:
containers:
- name: hpa-nginx
image: nginx:latest
ports:
- containerPort: 80
resources:
limits:
cpu: 100m
requests:
cpu: 50m
---
apiVersion: v1
kind: Service
metadata:
name: hpa-nginx
labels:
run: hpa-nginx
spec:
ports:
- port: 80
selector:
run: hpa-nginx
type: LoadBalancer
kubeuser@master01:~/autoscaling$ kubectl apply -f deployment.yaml --dry-run=client
deployment.apps/hpa-nginx created (dry run)
service/hpa-nginx created (dry run)
kubeuser@master01:~/autoscaling$ kubectl apply -f deployment.yaml
deployment.apps/hpa-nginx created
service/hpa-nginx created
kubeuser@master01:~/autoscaling$ kubectl get deployments,pods
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/hpa-nginx 4/4 4 4 42s
deployment.apps/nginx 2/2 2 2 12d
deployment.apps/nginx2 1/1 1 1 12d
NAME READY STATUS RESTARTS AGE
pod/hpa-nginx-668b69fd79-9qqpb 1/1 Running 0 41s
pod/hpa-nginx-668b69fd79-k7d2q 1/1 Running 0 41s
pod/hpa-nginx-668b69fd79-pzxdl 1/1 Running 0 41s
pod/hpa-nginx-668b69fd79-v5bjk 1/1 Running 0 41s
pod/nginx-6cbc9bb4f5-jm8mr 1/1 Running 0 12d
pod/nginx-6cbc9bb4f5-pfhfz 1/1 Running 0 12d
pod/nginx2-f96cfc57b-vnsfm 1/1 Running 0 12d
pod/webserver-master01 1/1 Running 0 9d
kubeuser@master01:~/autoscaling$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hpa-nginx LoadBalancer 10.1.114.112 192.168.1.53 80:31842/TCP 68s
kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 21d
nginx LoadBalancer 10.1.55.116 192.168.1.51 80:30267/TCP 12d
hpa-nginxという名前のDeployment・Pod(4つ)・Serviceが作成されました。
では、続いて耐障害性の確認ということで、
Podを手動で削除すると自動復旧するか確認してみます。
kubeuser@master01:~/autoscaling$ kubectl get pods -w NAME READY STATUS RESTARTS AGE hpa-nginx-668b69fd79-9qqpb 1/1 Running 0 4m9s hpa-nginx-668b69fd79-k7d2q 1/1 Running 0 4m9s hpa-nginx-668b69fd79-pzxdl 1/1 Running 0 4m9s hpa-nginx-668b69fd79-v5bjk 1/1 Running 0 4m9s . . . kubectl delete pods hpa-nginx-668b69fd79-9qqpb --forceでPodを強制的に削除 ※別のターミナルで実施しています . . . hpa-nginx-668b69fd79-9qqpb 1/1 Terminating 0 4m45s hpa-nginx-668b69fd79-9qqpb 1/1 Terminating 0 4m45s hpa-nginx-668b69fd79-xnqfx 0/1 Pending 0 0s hpa-nginx-668b69fd79-xnqfx 0/1 Pending 0 0s hpa-nginx-668b69fd79-xnqfx 0/1 ContainerCreating 0 1s hpa-nginx-668b69fd79-xnqfx 0/1 ContainerCreating 0 4s hpa-nginx-668b69fd79-xnqfx 1/1 Running 0 8s
Pod(hpa-nginx-668b69fd79-9qqpb)を強制的に削除したあと、代わりのPod(hpa-nginx-668b69fd79-xnqfx)が起動され自動復旧しています。
オートスケーリング
続いてオートスケーリングの検証です。
大量のHTTPリクエストを投げつけて、負荷が増加するにつれPodが増加、
負荷が減少するにつれPodが減少するか確認します。
※負荷は、Apache Benchを使ってかけます。
まずオートスケーリングするためのリソース(HorizontalPodAutoscaler)をデプロイします。
※CPU負荷によって、Podが最大10までスケールアウトされる
kubeuser@master01:~/autoscaling$ ls
deployment.yaml hpa.yaml
kubeuser@master01:~/autoscaling$ cat hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: hpa-nginx
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: hpa-nginx
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
kubeuser@master01:~/autoscaling$ kubectl apply -f hpa.yaml --dry-run=client
horizontalpodautoscaler.autoscaling/hpa-nginx created (dry run)
kubeuser@master01:~/autoscaling$ kubectl apply -f hpa.yaml
horizontalpodautoscaler.autoscaling/hpa-nginx created
kubeuser@master01:~/autoscaling$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hpa-nginx Deployment/hpa-nginx <unknown>/50% 1 10 0 6s
kubeuser@master01:~/autoscaling$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hpa-nginx Deployment/hpa-nginx 0%/50% 1 10 4 37s
まだ負荷をかけていない(アクセスがない状態)なので、スケールアウト/スケールインの基準となるCPU使用率は0%となっています。
では、Apache Benchによる負荷をかけていきましょう。
c:\xampp\apache\bin>ab.exe -n 100000 -c 100 http://192.168.1.53/
This is ApacheBench, Version 2.3 <$Revision: 1901567 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.1.53 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests
Server Software: nginx/1.23.4
Server Hostname: 192.168.1.53
Server Port: 80
Document Path: /
Document Length: 615 bytes
Concurrency Level: 100
Time taken for tests: 379.038 seconds
Complete requests: 100000
Failed requests: 0
Total transferred: 84800000 bytes
HTML transferred: 61500000 bytes
Requests per second: 263.83 [#/sec] (mean)
Time per request: 379.038 [ms] (mean)
Time per request: 3.790 [ms] (mean, across all concurrent requests)
Transfer rate: 218.48 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 3 19.1 0 1024
Processing: 9 375 202.8 334 3403
Waiting: 0 240 187.5 225 2387
Total: 12 379 204.0 339 3404
Percentage of the requests served within a certain time (ms)
50% 339
66% 357
75% 367
80% 378
90% 423
95% 472
98% 1343
99% 1390
100% 3404 (longest request)
上記Apache Benchによるアクセスによって、Podの数が増加します。
kubeuser@master01:~/autoscaling$ kubectl get hpa -w NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE hpa-nginx Deployment/hpa-nginx 0%/50% 1 10 4 2m36s hpa-nginx Deployment/hpa-nginx 34%/50% 1 10 4 3m15s hpa-nginx Deployment/hpa-nginx 75%/50% 1 10 4 3m31s hpa-nginx Deployment/hpa-nginx 68%/50% 1 10 6 3m46s hpa-nginx Deployment/hpa-nginx 54%/50% 1 10 6 4m1s hpa-nginx Deployment/hpa-nginx 30%/50% 1 10 6 4m16s hpa-nginx Deployment/hpa-nginx 34%/50% 1 10 6 4m31s hpa-nginx Deployment/hpa-nginx 50%/50% 1 10 6 4m46s hpa-nginx Deployment/hpa-nginx 42%/50% 1 10 6 5m16s hpa-nginx Deployment/hpa-nginx 38%/50% 1 10 6 5m31s hpa-nginx Deployment/hpa-nginx 47%/50% 1 10 6 5m46s hpa-nginx Deployment/hpa-nginx 63%/50% 1 10 6 6m1s hpa-nginx Deployment/hpa-nginx 36%/50% 1 10 8 6m16s hpa-nginx Deployment/hpa-nginx 39%/50% 1 10 8 6m31s hpa-nginx Deployment/hpa-nginx 29%/50% 1 10 8 6m47s hpa-nginx Deployment/hpa-nginx 28%/50% 1 10 8 7m2s hpa-nginx Deployment/hpa-nginx 35%/50% 1 10 8 7m17s hpa-nginx Deployment/hpa-nginx 32%/50% 1 10 8 7m32s hpa-nginx Deployment/hpa-nginx 37%/50% 1 10 8 7m47s hpa-nginx Deployment/hpa-nginx 29%/50% 1 10 8 8m2s hpa-nginx Deployment/hpa-nginx 28%/50% 1 10 8 8m17s hpa-nginx Deployment/hpa-nginx 39%/50% 1 10 8 8m32s hpa-nginx Deployment/hpa-nginx 26%/50% 1 10 8 8m47s hpa-nginx Deployment/hpa-nginx 32%/50% 1 10 8 9m2s hpa-nginx Deployment/hpa-nginx 28%/50% 1 10 8 9m17s hpa-nginx Deployment/hpa-nginx 12%/50% 1 10 8 9m32s hpa-nginx Deployment/hpa-nginx 0%/50% 1 10 8 9m48s
kubeuser@master01:~$ kubectl get pods -w NAME READY STATUS RESTARTS AGE hpa-nginx-668b69fd79-k7d2q 1/1 Running 0 17m hpa-nginx-668b69fd79-pzxdl 1/1 Running 0 17m hpa-nginx-668b69fd79-v5bjk 1/1 Running 0 17m hpa-nginx-668b69fd79-xnqfx 1/1 Running 0 12m nginx-6cbc9bb4f5-jm8mr 1/1 Running 0 12d nginx-6cbc9bb4f5-pfhfz 1/1 Running 0 12d nginx2-f96cfc57b-vnsfm 1/1 Running 0 12d webserver-master01 1/1 Running 0 9d hpa-nginx-668b69fd79-4cb2g 0/1 Pending 0 0s hpa-nginx-668b69fd79-4cb2g 0/1 Pending 0 0s hpa-nginx-668b69fd79-fjxg2 0/1 Pending 0 0s hpa-nginx-668b69fd79-4cb2g 0/1 ContainerCreating 0 0s hpa-nginx-668b69fd79-fjxg2 0/1 Pending 0 0s hpa-nginx-668b69fd79-fjxg2 0/1 ContainerCreating 0 0s hpa-nginx-668b69fd79-4cb2g 0/1 ContainerCreating 0 2s hpa-nginx-668b69fd79-fjxg2 0/1 ContainerCreating 0 2s hpa-nginx-668b69fd79-fjxg2 1/1 Running 0 5s hpa-nginx-668b69fd79-4cb2g 1/1 Running 0 6s hpa-nginx-668b69fd79-gmbcn 0/1 Pending 0 0s hpa-nginx-668b69fd79-dwt7h 0/1 Pending 0 0s hpa-nginx-668b69fd79-gmbcn 0/1 Pending 0 0s hpa-nginx-668b69fd79-dwt7h 0/1 Pending 0 0s hpa-nginx-668b69fd79-gmbcn 0/1 ContainerCreating 0 0s hpa-nginx-668b69fd79-dwt7h 0/1 ContainerCreating 0 0s hpa-nginx-668b69fd79-gmbcn 0/1 ContainerCreating 0 1s hpa-nginx-668b69fd79-dwt7h 0/1 ContainerCreating 0 2s hpa-nginx-668b69fd79-gmbcn 1/1 Running 0 5s hpa-nginx-668b69fd79-dwt7h 1/1 Running 0 6s
最終的には8Podまで増加しました。
続いて、アクセスがなくなりPodが減少していく様子をみてみましょう。
kubeuser@master01:~/autoscaling$ kubectl get hpa -w NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE . . . hpa-nginx Deployment/hpa-nginx 0%/50% 1 10 7 11m hpa-nginx Deployment/hpa-nginx 0%/50% 1 10 7 13m hpa-nginx Deployment/hpa-nginx 0%/50% 1 10 6 13m hpa-nginx Deployment/hpa-nginx 0%/50% 1 10 6 14m hpa-nginx Deployment/hpa-nginx 0%/50% 1 10 5 14m hpa-nginx Deployment/hpa-nginx 0%/50% 1 10 2 14m hpa-nginx Deployment/hpa-nginx 0%/50% 1 10 1 14m
kubeuser@master01:~$ kubectl get pods -w . . . hpa-nginx-668b69fd79-gmbcn 1/1 Terminating 0 5m16s hpa-nginx-668b69fd79-gmbcn 1/1 Terminating 0 5m17s hpa-nginx-668b69fd79-gmbcn 0/1 Terminating 0 5m19s hpa-nginx-668b69fd79-gmbcn 0/1 Terminating 0 5m19s hpa-nginx-668b69fd79-gmbcn 0/1 Terminating 0 5m19s hpa-nginx-668b69fd79-dwt7h 1/1 Terminating 0 7m32s hpa-nginx-668b69fd79-dwt7h 1/1 Terminating 0 7m32s hpa-nginx-668b69fd79-dwt7h 0/1 Terminating 0 7m33s hpa-nginx-668b69fd79-dwt7h 0/1 Terminating 0 7m34s hpa-nginx-668b69fd79-dwt7h 0/1 Terminating 0 7m34s hpa-nginx-668b69fd79-4cb2g 1/1 Terminating 0 10m hpa-nginx-668b69fd79-4cb2g 1/1 Terminating 0 10m hpa-nginx-668b69fd79-4cb2g 0/1 Terminating 0 10m hpa-nginx-668b69fd79-4cb2g 0/1 Terminating 0 10m hpa-nginx-668b69fd79-4cb2g 0/1 Terminating 0 10m hpa-nginx-668b69fd79-pzxdl 1/1 Terminating 0 28m hpa-nginx-668b69fd79-fjxg2 1/1 Terminating 0 10m hpa-nginx-668b69fd79-v5bjk 1/1 Terminating 0 28m hpa-nginx-668b69fd79-pzxdl 1/1 Terminating 0 28m hpa-nginx-668b69fd79-v5bjk 1/1 Terminating 0 28m hpa-nginx-668b69fd79-fjxg2 1/1 Terminating 0 10m hpa-nginx-668b69fd79-pzxdl 0/1 Terminating 0 28m hpa-nginx-668b69fd79-pzxdl 0/1 Terminating 0 28m hpa-nginx-668b69fd79-pzxdl 0/1 Terminating 0 28m hpa-nginx-668b69fd79-fjxg2 0/1 Terminating 0 10m hpa-nginx-668b69fd79-fjxg2 0/1 Terminating 0 10m hpa-nginx-668b69fd79-fjxg2 0/1 Terminating 0 10m hpa-nginx-668b69fd79-v5bjk 0/1 Terminating 0 28m hpa-nginx-668b69fd79-v5bjk 0/1 Terminating 0 28m hpa-nginx-668b69fd79-v5bjk 0/1 Terminating 0 28m hpa-nginx-668b69fd79-xnqfx 1/1 Terminating 0 24m hpa-nginx-668b69fd79-xnqfx 1/1 Terminating 0 24m hpa-nginx-668b69fd79-xnqfx 0/1 Terminating 0 24m hpa-nginx-668b69fd79-xnqfx 0/1 Terminating 0 24m hpa-nginx-668b69fd79-xnqfx 0/1 Terminating 0 24m
最終的には、HorizontalPodAutoscalerリソースで定義した最小Pod数1まで減少しました。
おわりに
今回Deploymentの耐障害性(自動復旧)とオートスケーリング(スケールアウト/スケールイン)を試してみましたが、挙動としてはイメージ通りでした。
しかしやってみなければ分からなかった細かい挙動の違いを確認することができました。
具体的には、以下。
・Pod数の変化:Deploymentで定義した4つ → CPU負荷増加で8つ → CPU負荷減少で1つ
・どのようなタイミングでPodの増減が起こるのか
増加はすぐ、減少は数分(3分程度で始まり6分程度で収束完了)かかる
・Podの数は、HorizontalPodAutoscalerリソースで定義した最大Pod数/最大Pod数の間で制御される
・HorizontalPodAutoscalerリソースは、定義したCPU使用率(閾値)を超えたらPodを増やし、閾値内に収まる(or 最大Pod数に達する)までPodを増加させる
※以下のログで様子が分かりますね!
kubeuser@master01:~/autoscaling$ kubectl get hpa -w NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE hpa-nginx Deployment/hpa-nginx 0%/50% 1 10 4 2m36s hpa-nginx Deployment/hpa-nginx 34%/50% 1 10 4 3m15s hpa-nginx Deployment/hpa-nginx 75%/50% 1 10 4 3m31s hpa-nginx Deployment/hpa-nginx 68%/50% 1 10 6 3m46s hpa-nginx Deployment/hpa-nginx 54%/50% 1 10 6 4m1s hpa-nginx Deployment/hpa-nginx 30%/50% 1 10 6 4m16s hpa-nginx Deployment/hpa-nginx 34%/50% 1 10 6 4m31s hpa-nginx Deployment/hpa-nginx 50%/50% 1 10 6 4m46s hpa-nginx Deployment/hpa-nginx 42%/50% 1 10 6 5m16s hpa-nginx Deployment/hpa-nginx 38%/50% 1 10 6 5m31s hpa-nginx Deployment/hpa-nginx 47%/50% 1 10 6 5m46s hpa-nginx Deployment/hpa-nginx 63%/50% 1 10 6 6m1s hpa-nginx Deployment/hpa-nginx 36%/50% 1 10 8 6m16s
改めて、実際にやってみることの大事さを知った検証でした。