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 ~]#