問題
アプリのCPU負荷
実際ノードのCPU負荷
ちょっと見ったら[なんだそのメトリクス,嘘でしょう!?]っと思った
がそのCPUの高負荷のせいでDatadogやKEDAのがたまには落ちて始まった,それは流石に全然駄目状態になって調べてしかない
秘密のCPU高負荷
もちろんメトリクスは実際事実だった
だってノードで入りてtopを発動してすぐわかるよ
PID PPID USER STAT RSS %RSS CPU %CPU COMMAND
72 2 root RW 0 0.0 0 46.9 [kswapd0]
1543 1 root S 27260 0.6 1 7.4 /usr/bin/kubelet --cloud-provider external --kubeconfig /etc/kubernetes/kubelet/kubeconfig --config /etc/kubernetes/kubelet/config --container-r
1058908 970613 root S 172m 4.4 0 5.1 agent run
1437 1 root S 30908 0.7 0 1.2 /usr/bin/eks-node-monitoring-agent --kubeconfig /etc/kubernetes/eks-node-monitoring-agent/kubeconfig --hostname-override i-07e8366dbe1466107 --c
でもさすがに[kswapd0]が普通のアプリではないよ
Googleで入力してそのような記事でるぞ
kswapdがCPU99%喰ってるのを解消したメモ
https://qiita.com/kawaz/items/bd1c52c8a8fec0f69399
まぁ俺の場合は99%じゃなくてなのにさすがに突然50%負荷上がってぜんぜん良くない
って理由は?
メモーリキャッシュかも
total used free shared buff/cache available
Mem: 3.7G 1.4G 111.1M 664.0K 2.2G 2.1G
Swap: 1024.0M 405.5M 618.5M
現在のWebアプリが多くのメモリを使ってなのでLinuxがキャッシュには色々メモーリを送っている
まぁ普通にそれは問題ならない,だって昔からKubernetesでSwapメモーリ禁止された
でも今年からAWSのOSイメージBottlerocketでSwap追加した
普通のAutoモードでOSイメージもBottlerocketなのでそのような問題が出ていたね
治る方法?
残念ながら普通にEKSのAutoモード使用ながらでEC2の設定変化できないぞ
それにまぁもともとSwapメモーリも一応ノードの安全ためありね
もし本当にOOM状態入ったらノードが完全に死ぬよ
ってどうしてLinuxがSwapを使用している?
ちょっと調べったらAWSのBottlerocketで[vm.swappiness]が200設定された!?
それは実際最大限の設定だった,だからメモーリ十分ありなのにSwapもう使用している
がAutoモードでその設定で普通に変わってできない
だが諦めてはやいぞ!
Kubernetesで[securityContext.privileged: true]設定ありね
もし全ノードでvm.swappinessを変更出来ったらなんとなく問題治ってできる
そのためがDaemonSet使用しかないぞ
もちろん普通にDaemonSetのポッドが完了したらまた作り直すね
そのためにaffinityによってポッドの日程禁止のルール必要
# Do not schedule on nodes that are already configured with current version
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: eks-swap-configured
operator: DoesNotExist
- matchExpressions:
- key: eks-swap-configured
operator: NotIn
values:
- "v1"
もしラベルeks-swap-configuredなければそれとも違うバージョンあり,Kubernetesにをポッドを作って頼む,そしてもしノードにはただしいラベル[eks-swap-configured]を付けったらもう二度もポッド発動出来なくてになる,シンプルね
ではKernel設定変更のポッドを作るぞ
#まずはKernel設定変更
#initContainersが最初から発動している
initContainers:
- name: sysctl-init
image: public.ecr.aws/docker/library/busybox:stable-musl
# 大事な,Kernel設定変更ためはアクセス得るしかない
securityContext:
privileged: true
command: ["/bin/sh", "-c"]
args:
- |
set -e
echo "Applying vm.swappiness=60 on $NODE_NAME/$(hostname)..."
sysctl -w vm.swappiness=60
#initCotnainers終わってノードラベル付けるぞ!
containers:
- name: apply-node-labeler
image: registry.k8s.io/kubectl:v1.34.9
# kubectlによって$NODE_NAMEにはラベル付けて
args:
- label
- node
- "$(NODE_NAME)"
- eks-swap-configured=v1
- --overwrite
env:
#ノードの名前を得って
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
resources:
requests:
cpu: 10m
memory: 16Mi
apply終わったらすぐに確認できるぞ
17:58 $ kubectl exec --stdin --tty datadog-agent-4msvp -- sysctl vm.swappiness
vm.swappiness = 60
17:58 $ kubectl exec --stdin --tty datadog-agent-4msvp -- free -h
total used free shared buff/cache available
Mem: 3.7Gi 1.8Gi 167Mi 1.0Mi 2.0Gi 1.9Gi
Swap: 1.0Gi 104Mi 919Mi
もちろんkswapd0のCPU負荷も落ち着けっている
まぁ正直AWSが草すぎるっと思っているだがAutoモードは便利からすぐに変更出来なくてなのでそのような修正も十分でしょうね. でも将来で必ずAutoモードから変更必要っと思う
ところでKernel設定確認ためノードにはログイン必要はない,ポッドからも確認できるぞ
kswapd0のCPU高負荷を修正TL;DR
DaemonSetによって全ノードでvm.swappinessを変更して!
- DaemonSetのYAML: https://gist.github.com/DoumanAsh/b9703856890e46ebdd20c7a1db612f16
- 便利Terraformモージュル: https://github.com/DoumanAsh/aws-tf/tree/master/modules/aws-eks-config-oneshot-daemon