1,000ノードクラスタの負荷状況
多数のノードが含まれるクラスタでの負荷状況を確認するため、aws の環境を使って、1,000ノードのTungstenFabricクラスタを試してみている。
台数が多く、ansible-deployer だと構築に時間がかかったため、今回は以下のリンク先に従って、 kube-manager, vRouter のモジュールについては、kubernetes の機能を使って配布するようにした。
https://github.com/Juniper/contrail-ansible-deployer/wiki/Provision-Contrail-Kubernetes-Cluster-in-Non-nested-Mode
AMIについては、引き続き CentOS7.5 (ami-3185744e) を使用し、インスタンスタイプは、TungstenFabric controller, k8s master については、m3.xlarge (4vCPU, 16GB mem) 各1台, k8s node については、m3.medium (1vCPU, 4GB mem) 1,000台、を使用している。
1. TungstenFabric controller の構築
以下のリンクと同様、 ansible-deployer でインストールを行う。
http://aaabbb-200904.hatenablog.jp/entry/2019/02/10/222958
instance.yaml は、以下のように、controller 1台だけを指定している。(k8s_master, kube-managerは削除)
provider_config: bms: ssh_user: root ssh_public_key: /root/.ssh/id_rsa.pub ssh_private_key: /root/.ssh/id_rsa domainsuffix: local ntpserver: ntp.nict.jp instances: bms1: provider: bms roles: config_database: config: control: analytics: webui: ip: 172.31.xx.xx contrail_configuration: CONTAINER_REGISTRY: opencontrailnightly CONTRAIL_VERSION: latest KUBERNETES_CLUSTER_PROJECT: {} JVM_EXTRA_OPTS: "-Xms128m -Xmx1g" global_configuration:
2. k8s master の構築
以下のリンクに従い、kubeadm を使った k8s master の構築を実施している。
https://github.com/Juniper/contrail-docker/wiki/Provision-Contrail-CNI-for-Kubernetes#faqs
# cd # cat install-k8s-packages.sh bash -c 'cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOF' setenforce 0 yum install -y kubelet kubeadm kubectl docker systemctl enable docker && systemctl start docker systemctl enable kubelet && systemctl start kubelet echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables swapoff -a # bash install-k8s-packages.sh # kubeadm init ※ 以下のようなコマンドが表示されるのでひかえておく kubeadm join 172.31.18.113:6443 --token we70in.mvy0yu0hnxb6kxip --discovery-token-ca-cert-hash sha256:13cf52534ab14ee1f4dc561de746e95bc7684f2a0355cb82eebdbd5b1e9f3634 # mkdir -p $HOME/.kube # cp -i /etc/kubernetes/admin.conf $HOME/.kube/config # chown $(id -u):$(id -g) $HOME/.kube/config
3. k8s node の構築
上記のスクリプトは k8s node でも実行し、その後、 kubeadm join を実施する必要がある。
並列で処理を実行するため、今回は GNU parallel と ssh を使用した。
まず、aws 内のノードについて、private ip の一覧を取得する。 (TungstenFabric controller, k8s master の ip は手動で削っておく)
$ pip install awscli $ aws configure (access key, secret key, region 等を入力 (必要に応じて、 IAM から作成)) $ aws ec2 describe-instances --query 'Reservations[*].Instances[*].PrivateIpAddress' --output text | tr '\t' '\n' > /tmp/aaa.txt
その後、上記のリストを k8s master のインスタンスに送り、以下のようなコマンドで k8s node での実行を行う。(/tmp/aaa.pem は、EC2 インスタンス立ち上げ時に指定した pem ファイル)
※ 10-15分程度で完了した
yum -y install epel-release yum -y install parallel ulimit -n 4096 cat aaa.txt | parallel -j1000 scp -i /tmp/aaa.pem -o StrictHostKeyChecking=no install-k8s-packages.sh centos@{}:/tmp cat aaa.txt | parallel -j1000 ssh -i /tmp/aaa.pem -o StrictHostKeyChecking=no centos@{} chmod 755 /tmp/install-k8s-packages.sh cat aaa.txt | parallel -j1000 ssh -i /tmp/aaa.pem -o StrictHostKeyChecking=no centos@{} sudo /tmp/install-k8s-packages.sh cat aaa.txt | parallel -j1000 ssh -i /tmp/aaa.pem -o StrictHostKeyChecking=no centos@{} sudo kubeadm join 172.31.18.113:6443 --token we70in.mvy0yu0hnxb6kxip --discovery-token-ca-cert-hash sha256:13cf52534ab14ee1f4dc561de746e95bc7684f2a0355cb82eebdbd5b1e9f3634
4. vRouter の展開
上記が完了した後、 k8s master 上で以下を発行し、vRouter の展開を行う。(余分なコストがかかるのを防ぐため、kubectl apply 直前までは、k8s node を立ち上げる前に実施した方がよいかもしれない)
# cd # yum -y install git # git clone https://github.com/Juniper/contrail-container-builder.git # cd /root/contrail-container-builder/kubernetes/manifests # vi ../../common.env (以下を追記) CONTRAIL_CONTAINER_TAG=latest CONTRAIL_REGISTRY=opencontrailnightly # ./resolve-manifest.sh contrail-non-nested-kubernetes.yaml > cni-vrouter.yaml ※ 手動で以下の修正を行う (1. Null になってしまう行を削除, 2. k8s master の ip が入ってしまう部分の一部を TungstenFabric controller の ip で置き換え) --- cni-vrouter.yaml.orig 2019-03-17 21:17:25.218399040 +0900 +++ cni-vrouter.yaml 2019-03-17 21:19:40.744368162 +0900 @@ -11,36 +11,20 @@ namespace: kube-system data: AUTH_MODE: {{ AUTH_MODE }} - KEYSTONE_AUTH_HOST: {{ KEYSTONE_AUTH_HOST }} - KEYSTONE_AUTH_ADMIN_TENANT: "{{ KEYSTONE_AUTH_ADMIN_TENANT }}" - KEYSTONE_AUTH_ADMIN_USER: "{{ KEYSTONE_AUTH_ADMIN_USER }}" - KEYSTONE_AUTH_ADMIN_PASSWORD: "{{ KEYSTONE_AUTH_ADMIN_PASSWORD }}" - KEYSTONE_AUTH_ADMIN_PORT: "{{ KEYSTONE_AUTH_ADMIN_PORT }}" - KEYSTONE_AUTH_URL_VERSION: "{{ KEYSTONE_AUTH_URL_VERSION }}" - ANALYTICS_API_VIP: {{ ANALYTICS_API_VIP }} - ANALYTICS_NODES: {{ ANALYTICS_NODES }} - ANALYTICSDB_NODES: {{ ANALYTICSDB_NODES }} + ANALYTICS_NODES: TungstenFabric controller IP + ANALYTICSDB_NODES: TungstenFabric controller IP CLOUD_ORCHESTRATOR: {{ CLOUD_ORCHESTRATOR }} - CONFIG_API_VIP: {{ CONFIG_API_VIP }} - CONFIG_NODES: {{ CONFIG_NODES }} - CONFIGDB_NODES: {{ CONFIGDB_NODES }} - CONTROL_NODES: {{ CONTROL_NODES }} - CONTROLLER_NODES: {{ CONTROLLER_NODES }} + CONFIG_NODES: TungstenFabric controller IP + CONFIGDB_NODES: TungstenFabric controller IP + CONTROL_NODES: TungstenFabric controller IP + CONTROLLER_NODES: TungstenFabric controller IP LOG_LEVEL: {{ LOG_LEVEL }} METADATA_PROXY_SECRET: {{ METADATA_PROXY_SECRET }} - RABBITMQ_NODES: {{ RABBITMQ_NODES }} + RABBITMQ_NODES: TungstenFabric controller IP RABBITMQ_NODE_PORT: "{{ RABBITMQ_NODE_PORT }}" - ZOOKEEPER_NODES: {{ ZOOKEEPER_NODES }} + ZOOKEEPER_NODES: TungstenFabric controller IP ZOOKEEPER_PORTS: "{{ ZOOKEEPER_PORTS }}" ZOOKEEPER_PORT: "{{ ZOOKEEPER_PORT }}" - KUBERNETES_CLUSTER_NETWORK: "{{ KUBERNETES_CLUSTER_NETWORK }}" - KUBERNETES_CLUSTER_NAME: {{ KUBERNETES_CLUSTER_NAME }} - KUBERNETES_POD_SUBNETS: {{ KUBERNETES_POD_SUBNETS }} - KUBERNETES_IP_FABRIC_SUBNETS: {{ KUBERNETES_IP_FABRIC_SUBNETS }} - KUBERNETES_SERVICE_SUBNETS: {{ KUBERNETES_SERVICE_SUBNETS }} - KUBERNETES_IP_FABRIC_FORWARDING: "{{ KUBERNETES_IP_FABRIC_FORWARDING }}" - KUBERNETES_IP_FABRIC_SNAT: "{{ KUBERNETES_IP_FABRIC_SNAT }}" - KUBERNETES_PUBLIC_FIP_POOL: "{{ KUBERNETES_PUBLIC_FIP_POOL }}" --- apiVersion: v1 kind: ConfigMap # kubectl apply -f cni-vrouter.yaml
うまく適用されると、以下のように、1,000台の vRouter がクラスタに追加されるはずである。
クラスタの状態
クラスタが立ち上がってから、各ノードのリソースを見てみたところ、TungstenFabric controller, k8s master で、以下のように CPU 使用率が高い状況になっていた。
※ TungstenFabric controller では、contrail-collector, redis 等、analytics の負荷が高く、k8s master では kube-apiserver, etcd の負荷が高くなった。
安定して稼働させるには、リソースの追加割り当てや、controller/analytics のスケールアウトなど、追加の考慮が必要かもしれない。
TungstenFabric controller, analytics: top - 12:13:59 up 43 min, 1 user, load average: 5.77, 12.05, 7.24 Tasks: 153 total, 1 running, 152 sleeping, 0 stopped, 0 zombie %Cpu(s): 22.0 us, 16.9 sy, 0.0 ni, 60.3 id, 0.0 wa, 0.0 hi, 0.7 si, 0.1 st KiB Mem : 15233672 total, 7091360 free, 3899712 used, 4242600 buff/cache KiB Swap: 0 total, 0 free, 0 used. 10779720 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 21165 root 20 0 1035220 333448 10996 S 48.2 2.2 3:26.06 contrail-collec 18891 root 20 0 906588 249180 7524 S 31.9 1.6 0:09.03 node 12763 polkitd 20 0 243412 189736 1668 S 28.6 1.2 2:45.55 redis-server 19410 root 20 0 1375424 108644 12148 S 14.3 0.7 1:40.42 contrail-dns 18864 root 20 0 810588 165356 7196 S 13.0 1.1 0:05.14 node 19448 root 20 0 2167860 1.0g 13732 S 10.6 7.0 10:04.95 contrail-contro 11985 root 20 0 776036 94764 35204 S 3.0 0.6 2:38.34 dockerd 15803 root 20 0 248324 40180 5332 S 2.3 0.3 0:27.72 python k8s master: top - 12:14:09 up 43 min, 1 user, load average: 11.84, 12.30, 8.06 Tasks: 133 total, 1 running, 132 sleeping, 0 stopped, 0 zombie %Cpu(s): 87.2 us, 6.6 sy, 0.1 ni, 3.5 id, 0.2 wa, 0.0 hi, 2.4 si, 0.0 st KiB Mem : 15233672 total, 8167188 free, 4032788 used, 3033696 buff/cache KiB Swap: 0 total, 0 free, 0 used. 10702748 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 11583 root 20 0 2999520 2.7g 37840 S 309.3 18.6 38:35.47 kube-apiserver 5854 root 20 0 10.3g 520460 181348 S 47.5 3.4 1:50.44 etcd 18836 root 20 0 481984 350196 27724 S 17.6 2.3 0:19.61 kube-controller 11211 root 20 0 1572404 74628 31760 S 3.7 0.5 0:52.85 kubelet 18460 root 20 0 209628 119648 13428 S 2.7 0.8 0:08.79 kube-scheduler 10663 root 20 0 1280720 60912 16316 S 0.7 0.4 1:12.93 dockerd-current 377 root 20 0 145808 88372 87852 S 0.3 0.6 0:42.88 systemd-journal
一方、メモリ, disk については、数台での小規模なクラスタと比べて、大きな違いは見られなかった。
※ analyticsdb を有効化している場合、こちらも大きくリソースを使う可能性が高いため注意
TungstenFabric controller, analytics: [root@ip-172-31-13-135 ~]# free -h total used free shared buff/cache available Mem: 14G 4.3G 6.1G 17M 4.1G 9.7G Swap: 0B 0B 0B [root@ip-172-31-13-135 ~]# [root@ip-172-31-13-135 ~]# [root@ip-172-31-13-135 ~]# df -h / Filesystem Size Used Avail Use% Mounted on /dev/xvda1 20G 4.3G 16G 22% / [root@ip-172-31-13-135 ~]# k8s master: [root@ip-172-31-18-113 ~]# free -h total used free shared buff/cache available Mem: 14G 3.5G 7.9G 105M 3.2G 10G Swap: 0B 0B 0B [root@ip-172-31-18-113 ~]# [root@ip-172-31-18-113 ~]# df -h / Filesystem Size Used Avail Use% Mounted on /dev/xvda1 20G 3.6G 17G 18% / [root@ip-172-31-18-113 ~]#