The cluster autoscaler works with self-built Kubernetes cluster on Huaweicloud ECS and specified Huaweicloud Auto Scaling Groups It runs as a Deployment on a worker node in the cluster. This README will go over some of the necessary steps required to get the cluster autoscaler up and running.
-
Download Project
Get the latest
autoscaler
project and download it to${GOPATH}/src/k8s.io
.This is used for building your image, so the machine you use here should be able to access GCR. Do not use a Huawei Cloud ECS.
-
Go environment
Make sure you have Go installed in the above machine.
-
Docker environment
Make sure you have Docker installed in the above machine.
Execute the following commands in the directory of autoscaler/cluster-autoscaler
of the autoscaler project downloaded previously.
The following steps use Huawei SoftWare Repository for Container (SWR) as an example registry.
-
Build the
cluster-autoscaler
binary:make build-in-docker
-
Build the docker image:
docker build -t {Image repository address}/{Organization name}/{Image name:tag} .
For example:
docker build -t swr.cn-north-4.myhuaweicloud.com/{Organization name}/cluster-autoscaler:dev .
Follow the
Pull/Push Image
section ofInteractive Walkthroughs
under the SWR console to find the image repository address and organization name, and also refer toMy Images
->Upload Through Docker Client
in SWR console. -
Login to SWR:
docker login -u {Encoded username} -p {Encoded password} {SWR endpoint}
For example:
docker login -u cn-north-4@ABCD1EFGH2IJ34KLMN -p 1a23bc45678def9g01hi23jk4l56m789nop01q2r3s4t567u89v0w1x23y4z5678 swr.cn-north-4.myhuaweicloud.com
Follow the
Pull/Push Image
section ofInteractive Walkthroughs
under the SWR console to find the encoded username, encoded password and swr endpoint, and also refer toMy Images
->Upload Through Docker Client
in SWR console. -
Push the docker image to SWR:
docker push {Image repository address}/{Organization name}/{Image name:tag}
For example:
docker push swr.cn-north-4.myhuaweicloud.com/{Organization name}/cluster-autoscaler:dev
-
For the cluster autoscaler to function normally, make sure the
Sharing Type
of the image isPublic
. If the cluster has trouble pulling the image, go to SWR console and check whether theSharing Type
of the image isPrivate
. If it is, clickEdit
button on top right and set theSharing Type
toPublic
.
Please see installation here
For example:
-
OS: CentOS 8
-
Note: The following example should be run on ECS that has access to the Google Container Registry (GCR)
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch 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 exclude=kubelet kubeadm kubectl EOF
sudo setenforce 0 sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes sudo systemctl enable --now kubelet
Please see installation here
For example:
-
OS: CentOS 8
-
Note: The following example should be run on ECS that has access to the Google Container Registry (GCR)
sudo yum install -y yum-utils sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo sudo yum install docker-ce docker-ce-cli containerd.io sudo systemctl start docker
Create a Kubeadm.yaml file with the following content:
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 1.2.3.4
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
imagePullPolicy: IfNotPresent
name: node
taints: null
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.k8s.io
kind: ClusterConfiguration
kubernetesVersion: 1.22.0
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
scheduler: {}
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: cgroupfs
note: replace the advertiseAddress to your ECS ip address
kubeadm init --config kubeadm.yaml
Modify these two files, Comment out line - --port=0
:
sudo vim /etc/kubernetes/manifests/kube-controller-manager.yaml
sudo vim /etc/kubernetes/manifests/kube-scheduler.yaml
Restart Kubelet service
systemctl restart kubelet.service
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubeadm token create --ttl 0
Generate a token that never expires. Remember this token since it will be used later.
Get hash key. Remember the key since it will be used later.
openssl x509 -in /etc/kubernetes/pki/ca.crt -noout -pubkey | openssl rsa -pubin -outform DER 2>/dev/null | sha256sum | cut -d' ' -f1
-
Launch a new ECS instance, and install Kubeadm, Kubectl and docker.
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF sudo yum install -y kubeadm kubectl --disableexcludes=kubernetes sudo yum install -y yum-utils sudo yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sudo yum install docker-ce docker-ce-cli containerd.io
-
Create a script to join the new instance into the k8s cluster.
cat <<EOF >/etc/rc.d/init.d/init-k8s.sh #!bin/bash #chkconfig: 2345 80 90 setenforce 0 swapoff -a sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config yum install -y kubelet sudo systemctl enable --now kubelet systemctl start docker systemctl enable docker.service kubeadm join --token $TOKEN $API_Server_EndPoint --discovery-token-ca-cert-hash sha256:$HASHKEY EOF
Replace the $TOKEN with the one created above.
Replace the $API_Server_EndPoint, this could be find in the context file.
cat ~./.kube/config # server: https://192.168.0.239:6443 # the API_Server_EndPoint is 192.168.0.239:6443
-
Add this script into chkconfig, to let it run automatically after the instance is started.
chmod +x /etc/rc.d/init.d/init-k8s.sh chkconfig --add /etc/rc.d/init.d/init-k8s.sh
-
Copy
~/.kube/config
from a control plane (previously referred to as master) node to this ECS~./kube/config
to setup kubectl on this instance. -
Go to Huawei Cloud
Image Management
Service and click onCreate Image
. Select typeSystem disk image
, select your ECS instance asSource
, then give it a name and then create. -
Remember this ECS instance ID since it will be used later.
- Follow the Huawei cloud instruction to create an AS Group.
- Create an AS Configuration, and select private image which we just created. Make sure the AS Configuration with EIP automatically assign.
- While creating the
AS Configuration
, add the following script intoAdvanced Settings
.Replace the $ECS_INSTANCE_ID#!bin/bash IDS=$(ls /var/lib/cloud/instances/) while true do for ID in $IDS do if [ $ID != $ECS_INSTANCE_ID ]; then /usr/bin/kubectl --kubeconfig ~/.kube/config patch node $HOSTNAME -p "{\"spec\":{\"providerID\":\"$ID\"}}" fi done sleep 30 done
- Bind the AS Group with this AS Configuration
The autoscaler needs a ServiceAccount
which is granted permissions to the cluster's resources and a Secret
which
stores credential (AK/SK in this case) information for authenticating with Huawei cloud.
Examples of ServiceAccount
and Secret
are provided in examples/cluster-autoscaler-svcaccount.yaml
and examples/cluster-autoscaler-secret.yaml. Modify the Secret
object yaml file with your credentials.
The following parameters are required in the Secret object yaml file:
-
as-endpoint
Find the as endpoint for different regions here,
For example, for region
cn-north-4
, the endpoint isas.cn-north-4.myhuaweicloud.com
-
ecs-endpoint
Find the ecs endpoint for different regions here,
For example, for region
cn-north-4
, the endpoint isecs.cn-north-4.myhuaweicloud.com
-
project-id
Follow this link to find the project-id: Obtaining a Project ID
-
access-key
andsecret-key
Create and find the Huawei cloud access-key and secret-key required by the Secret object yaml file by referring to Access Keys and My Credentials.
An example deployment file is provided at examples/cluster-autoscaler-deployment.yaml.
Change the image
to the image you just pushed, the cluster-name
to the cluster's id and nodes
to your
own configurations of the node pool with format
{Minimum number of nodes}:{Maximum number of nodes}:{Node pool name}
The above parameters should match the parameters of the AS Group you created.
More configuration options can be added to the cluster autoscaler, such as scale-down-delay-after-add
, scale-down-unneeded-time
, etc.
See available configuration options here.
-
Log in to a machine which can manage the cluster with
kubectl
.Make sure the machine has kubectl access to the cluster.
-
Create the Service Account:
kubectl create -f cluster-autoscaler-svcaccount.yaml
-
Create the Secret:
kubectl create -f cluster-autoscaler-secret.yaml
-
Create the cluster autoscaler deployment:
kubectl create -f cluster-autoscaler-deployment.yaml
Now the cluster autoscaler should be successfully deployed on the cluster. Check it by executing
kubectl get pods -n kube-system
To see whether it functions correctly, deploy a Service to the cluster, and increase and decrease workload to the Service. Cluster autoscaler should be able to autoscale the AS Group to accommodate the load.
A simple testing method is like this:
-
Create a Service: listening for http request
-
Create HPA policy for pods to be autoscaled
- Install metrics server by yourself and create an HPA policy
by executing something like this:
The above command creates an HPA policy on the deployment with target average cpu usage of 10%. The number of pods will grow if average cpu usage is above 10%, and will shrink otherwise. The
kubectl autoscale deployment [Deployment name] --cpu-percent=10 --min=1 --max=20
min
andmax
parameters set the minimum and maximum number of pods of this deployment.
- Install metrics server by yourself and create an HPA policy
by executing something like this:
-
Generate load to the above service
Example tools for generating workload to an http service are:
- Use
hey
command - Use
busybox
image:kubectl run --generator=run-pod/v1 -it --rm load-generator --image=busybox /bin/sh # send an infinite loop of queries to the service while true; do wget -q -O- {Service access address}; done
Feel free to use other tools which have a similar function.
- Use
-
Wait for pods to be added: as load increases, more pods will be added by HPA
-
Wait for nodes to be added: when there's insufficient resource for additional pods, new nodes will be added to the cluster by the cluster autoscaler
-
Stop the load
-
Wait for pods to be removed: as load decreases, pods will be removed by HPA
-
Wait for nodes to be removed: as pods being removed from nodes, several nodes will become underutilized or empty, and will be removed by the cluster autoscaler
Interested in Cluster Autoscaler on Huawei Cloud? Want to talk? Have questions, concerns or great ideas?
Please reach out to us at shiqi.wang1@huawei.com
.