4,872ノードでの負荷状況
前回に続いて、4,872ノードでの負荷状況を確認してみている。
http://aaabbb-200904.hatenablog.jp/entry/2019/03/17/222320
※ 本来は kubernetes クラスタの最大数である、5,000ノードで検証したかったのだが、実機で試したときは このノード数しか起動できなかった、、
https://kubernetes.io/ja/docs/setup/cluster-large/
環境は GCP を使い、インスタンスイメージとしては、CentOS7 (centos-7-v20190312, CentOS7.6) を使用している。
controller兼analytics, k8s master を1台ずつ用意し、インスタンスタイプとしては、n1-highcpu-64 (64vCPU, 58GM mem, 30GB disk)を使用した。
vRouter としては、n1-standard-1 (1vCPU, 3.75GB mem, 10GB disk) を使用した。
手順は基本的に前回と同じだが、変更点として、global ip の数を節約するため、今回は controller/analytics, k8s master の2台にのみ、global ip を割り当て、vRouter のノードについては、private ip のみを割り当てる構成とした。 (default のサブネットは /20 となっており、5,000 ip が入りきらないため、別のVPC を作成し、10.0.0.0/9 を割り当てている) ただし、vRouterノードも、モジュールインストールのためにインターネットにアクセスする必要があるため、CloudNAT (ネットワークサービス > CloudNAT) を追加で作成するようにしている。
また、元々の設定だと、途中で、cassandra がスローダウンする動作となったため、以下のように heap size の最大値を20GBに変更し、事象を回避している。
JVM_EXTRA_OPTS: "-Xms128m -Xmx20g"
他に、前回と比べて追加したコマンドを列記しておく。
# kubectl label node instance-group-2-m2cq node-role.opencontrail.org/config= cni-vrouter.yaml の適用後、contrail-kube-manager を起動するために実施 (instance-group-2-m2cq には k8s master の node名を入力する) ※ upstream の変更に追随するため # pip install google-cloud $ gcloud init $ gcloud auth login $ gcloud --format="value(networkInterfaces[0].networkIP)" compute instances list GCP instances の ip をダンプするために使用 ※ parallel -j 5000 にすると、実行ノードのメモリが枯渇したため、-j 3000, -j 2000 の2回に分けて実施した ipの差分は以下で取得: $ cat (インスタンスipをダンプしたファイルを全て列記) | sort | uniq -c | grep ' 1 ' | awk '{print $2}'
起動後、以下のように、4,872台の vRouter が登録される動作となった。
※ interface数は本来、4,878 (vRouter ごとに1, coredns x 2, この時起動していた cirros x2, default で作成される k8s service: kubernetes API, kube-dns) となるはずだったのだが、確認時は、なぜかこの値から変化しなかった、、(analytics-api の応答では、正しく4,878で出力されている、後述)
負荷状況としては、controller兼analytics では、以下のように control が最も多くの cpu / mem を使用する動きとなった。
特に、メモリ使用量は前回と比べて大きく上昇しており、30GB を使用する動作となっている。
この状態でも、cirros への ip 払いだし、等は、問題なく実施できていたので、基本的な動作は継続できていたようである。
top - 16:01:05 up 1:17, 2 users, load average: 62.04, 44.99, 35.31 Tasks: 572 total, 2 running, 570 sleeping, 0 stopped, 0 zombie %Cpu(s): 65.6 us, 6.5 sy, 0.0 ni, 27.4 id, 0.0 wa, 0.0 hi, 0.4 si, 0.0 st KiB Mem : 59192668 total, 11975852 free, 42433520 used, 4783296 buff/cache KiB Swap: 0 total, 0 free, 0 used. 15865188 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 19347 root 20 0 35.2g 31.1g 13688 S 3199 55.1 505:42.00 contrail-contro 21052 root 20 0 7336100 2.2g 10960 S 1020 4.0 336:58.27 contrail-collec 19339 root 20 0 5990856 562944 12160 S 286.5 1.0 110:07.13 contrail-dns 21051 root 20 0 559792 259616 6464 R 92.7 0.4 10:36.47 python 10429 polkitd 20 0 890380 854872 1668 S 52.8 1.4 9:47.83 redis-server 13024 polkitd 20 0 34.5g 161112 3816 S 18.2 0.3 22:18.44 beam.smp 9538 root 20 0 3179672 113380 35224 S 7.6 0.2 4:27.13 dockerd 19290 root 20 0 246400 40248 5284 S 2.3 0.1 0:42.96 python 21044 root 20 0 246404 40192 5284 S 2.3 0.1 0:40.39 python $ free -h total used free shared buff/cache available Mem: 56G 40G 11G 9.8M 4.6G 15G Swap: 0B 0B 0B $ df -h . ファイルシス サイズ 使用 残り 使用% マウント位置 /dev/sda1 30G 5.2G 25G 18% / $ curl 172.16.1.18:8081/analytics/uves/vrouters | python -m json.tool | grep -w href | wc -l % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1065k 100 1065k 0 0 3268k 0 --:--:-- --:--:-- --:--:-- 3279k 4872 $ curl 172.16.1.18:8081/analytics/uves/virtual-machines | python -m json.tool | grep -w href | wc -l % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 768 100 768 0 0 230k 0 --:--:-- --:--:-- --:--:-- 375k 4 $ curl 172.16.1.18:8081/analytics/uves/virtual-machine-interfaces | python -m json.tool | grep -w href | wc -l % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1495k 100 1495k 0 0 6018k 0 --:--:-- --:--:-- --:--:-- 6006k 4878 ※ 4872(vRouter vhost0)+4(k8s pod: coredns, cirros x 2)+2(defaultで作成される k8s service: kubernetes, kube-dns)
k8s master は、前回と同じく、 kube-apiserver/etcd が最も多くの cpu / mem を使用する動作となった。
top - 15:55:01 up 1:11, 2 users, load average: 27.01, 24.74, 21.02 Tasks: 610 total, 2 running, 608 sleeping, 0 stopped, 0 zombie %Cpu(s): 31.2 us, 2.5 sy, 0.0 ni, 65.3 id, 0.2 wa, 0.0 hi, 0.8 si, 0.0 st KiB Mem : 59192676 total, 41605700 free, 15398320 used, 2188656 buff/cache KiB Swap: 0 total, 0 free, 0 used. 42949840 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 20248 root 20 0 19.0g 10.6g 39724 S 1653 18.7 292:06.02 kube-apiserver 9460 root 20 0 11.0g 1.6g 620208 S 359.3 2.8 54:45.80 etcd 20705 root 20 0 1406768 1.1g 30552 S 245.4 2.0 32:05.66 kube-controller 20410 root 20 0 385024 105376 5992 S 12.6 0.2 2:20.30 python 20257 root 20 0 635832 555136 15836 S 8.9 0.9 8:46.33 kube-scheduler 9107 root 20 0 5875912 92168 17240 S 3.0 0.2 4:51.77 kubelet 3285 root 0 -20 0 0 0 S 1.0 0.0 0:11.79 kworker/0:1H # free -h total used free shared buff/cache available Mem: 56G 14G 39G 66M 2.1G 40G Swap: 0B 0B 0B # df -h . Filesystem Size Used Avail Use% Mounted on /dev/sda1 30G 4.7G 26G 16% / # kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES cirros1 1/1 Running 0 77s 10.47.255.250 instance-group-2-4197 <none> <none> cirros2 1/1 Running 0 73s 10.47.255.249 instance-group-2-k7sr <none> <none>
今回、かなり多くの台数を controller/analytics に追加してみたのだが、実際のところ、ここまで多くのノードを1クラスタにおさめる必要があるのか、という議論はあり、管理を分離する、という意味では、アプリケーションごとに kubernetes クラスタを立てた方がよいかもしれない。
ただ、kubernetes クラスタを複数立てると、その間で連携を行うような操作が難しくなる。
この場合、TungstenFabric のように、多数のノードを1つのクラスタにいれておき、必要に応じて、アプリケーションごとのネットワーク分離の有効・無効を切り替える (policy 等も活用可能)、という動作の方がよいかもしれない。