Skip to content

Instantly share code, notes, and snippets.

@skaji
Last active September 15, 2019 03:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skaji/ab038fa9cf8ca4059ab64bf4f1ea7c39 to your computer and use it in GitHub Desktop.
Save skaji/ab038fa9cf8ca4059ab64bf4f1ea7c39 to your computer and use it in GitHub Desktop.

概要

HorizontalPodAutoscalerを設定したDeploymentをリリースしている最中に、pod数が想定外に増えることがある。これの原因を知りたい。

環境

  • Amazon EKS Kubernetes Version 1.14
  • metrics-server v0.3.4

事象の再現

以下のDeployment, HorizontalPodAutoscalerが書かれたmanifest test.yamlを用意する。

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test
  name: test
  namespace: default
spec:
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
      annotations:
        createdAt: 'FIXME'
    spec:
      containers:
        - image: alpine:3.10.2
          imagePullPolicy: IfNotPresent
          name: test
          args:
            - ash
            - -c
            - |
              trap exit TERM
              while :; do
                sleep 1
              done
          readinessProbe:
            exec:
              command:
                - "true"
            initialDelaySeconds: 10
          resources:
            requests:
              cpu: 100m
---
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: test
  namespace: default
spec:
  minReplicas: 2
  maxReplicas: 6
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: test
  metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: 100

step0

2つターミナルを用意し、test podとtest hpaを監視しておく。

# terminal1 (pod監視)
❯ while :; do date; kubectl get pod --sort-by=.metadata.creationTimestamp | grep -E '^test-'; sleep 3; done
# terminal2 (hpa監視)
❯ while :; do date; kubectl get hpa test --no-headers; sleep 3; done

step1

test.yamlを適用しtest pod, test hpaを作る。(FIXMEを現在時刻に置き換えて何度もpodを作れるようにしている)

# terminal3
❯ sed -e "s/FIXME/$(date +%s)/" test.yaml | kubectl apply -f -

step2

terminal2 (hpa監視)でTARGETSが<unknown>から1%などに変わるまで待つ。

...
Sat Sep 14 09:23:04 JST 2019
test   Deployment/test   <unknown>/100%   2     6     0     1s
Sat Sep 14 09:23:07 JST 2019
test   Deployment/test   <unknown>/100%   2     6     0     4s
Sat Sep 14 09:23:10 JST 2019
test   Deployment/test   <unknown>/100%   2     6     0     7s
...
...
Sat Sep 14 09:24:04 JST 2019
test   Deployment/test   1%/100%   2     6     2     62s
Sat Sep 14 09:24:08 JST 2019
test   Deployment/test   1%/100%   2     6     2     65s

step3

test.yamlを再び適用する。

❯ sed -e "s/FIXME/$(date +%s)/" test.yaml | kubectl apply -f -

step4

terminal1 (pod監視)を見ると、pod数が2から増えていることがわかる。

Sat Sep 14 09:29:15 JST 2019
test-6dd788c59b-t4fwb                                  1/1     Running     0          58s
test-6dd788c59b-g9zll                                  1/1     Running     0          43s
test-6dd788c59b-xvwbr                                  1/1     Running     0          20s

事象の再現の注意

  • step0 ~ step4をやってpodが増えなかった場合、kubectl delete -f test.yamlで一度削除してから再び試せる。
  • 上記のtest.yamlは、実際に事象が起きるプロダクションのmanifestを、なるべく簡単にしたものである。
  • readinessProbeは単に"true"を実行となっているが、実際のプロダクションmanifestではhttpGetでのprobeである。
  • readinessProbeを抜くと事象が再現しにくくなる様子。
@skaji
Copy link
Author

skaji commented Sep 15, 2019

もっと簡素化できたので以下の変更をした。

  • pythonのimageをalpineに変更
  • preStop削除
  • deployment.spec.replicas削除

@skaji
Copy link
Author

skaji commented Sep 15, 2019

よく調べると

  • (a) 素早くpodがTERMINATEする。(sigtermを受け取ってすぐTERMIATEするようにするなど)
  • (b) なかなかpodがREADYにならない。(readinessProbeにがなかなかOKにならない or initialDelaySecondsが長め など)

の2条件が満たされるとき、podが増えやすいとわかった。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment