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で出力されている、後述)
f:id:aaabbb_200904:20190402003622p:plain

負荷状況としては、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 等も活用可能)、という動作の方がよいかもしれない。