Opensourcetechブログ

OpensourcetechによるNGINX/Kubernetes/Zabbix/Neo4j/Linuxなどオープンソース技術に関するブログです。

Deploymentの耐障害性(自動復旧)とオートスケーリング(kubernetes)


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


改めて、実際にやってみることの大事さを知った検証でした。

Opensourcetech by Takahiro Kujirai