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
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
test.yamlを適用しtest pod, test hpaを作る。(FIXMEを現在時刻に置き換えて何度もpodを作れるようにしている)
# terminal3
❯ sed -e "s/FIXME/$(date +%s)/" test.yaml | kubectl apply -f -
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
test.yamlを再び適用する。
❯ sed -e "s/FIXME/$(date +%s)/" test.yaml | kubectl apply -f -
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を抜くと事象が再現しにくくなる様子。
もっと簡素化できたので以下の変更をした。