前言:
Kubernetes HPA是指k8s水平扩缩容,一般指的是一个部署好的应用指定了请求cpu内存限制,超过这个限制量会自动进行扩容pod。接下来我们亲自试验hpa吧。
准备工作:
在试验之前,我们需要给k8s集群安装指标服务(metrics server)。
如果是Mac环境大家可以直接用brew 安装 helm
brew install helm
再用helm 安装 metrics server。不过需要中途编辑部署文件。加上部分command内容。编辑好后跟vi编辑器一样的。:wq可退出编辑。它会自动帮你重新部署的。
command:
- /metrics-server
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP,Hostname,ExternalIP
- --metric-resolution=30shelm install stable/metrics-server --version 2.11.0 --set registry.cn-shanghai.aliyuncs.com/google_containers/metrics-server-amd64 --generate-name -n kube-system
kubectl edit deployments.apps $(kubectl get deployments -n kube-system|grep metrics-server|awk '{print $1}') -n kube-system
https://github.com/kubernetes-sigs/metrics-server 考虑到部署yaml镜像来源于google。我这边为大家提前准备好了。
默认镜像地址:k8s.gcr.io/metrics-server/metrics-server:v0.3.7
阿里镜像地址:registry.cn-shanghai.aliyuncs.com/k8sgcrio_containers/metrics-server:v0.3.7
部署文件地址:https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.3.7/components.yaml
下载不了的话我贴在下面👇。需要注意的是,里面有个command记得加哦。复制我的准没错!我用的版本1.18以上版本,其他版本可能还是有bug的。如果你们安装不上,可以尝试部署在master节点上,你们要把污点去掉。然后再把每台master节点做个标记。后面可以用nodeSelector进行部署匹配。只有需要部署在master的应用才推荐这样使用,部署好记得再还原污点。执行如下命令:
kubectl taint nodes --all node-role.kubernetes.io/master-
kubectl label nodes master00 node-role=master
kubectl label nodes master01 node-role=master
kubectl label nodes master02 node-role=master
还原污点命令:
kubectl taint nodes master00 node-role.kubernetes.io/master=:NoSchedule
kubectl taint nodes master01 node-role.kubernetes.io/master=:NoSchedule
kubectl taint nodes master02 node-role.kubernetes.io/master=:NoSchedule
components.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: system:aggregated-metrics-reader
labels:
rbac.authorization.k8s.io/aggregate-to-view: "true"
rbac.authorization.k8s.io/aggregate-to-edit: "true"
rbac.authorization.k8s.io/aggregate-to-admin: "true"
rules:
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: metrics-server:system:auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: metrics-server-auth-reader
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:
name: v1beta1.metrics.k8s.io
spec:
service:
name: metrics-server
namespace: kube-system
group: metrics.k8s.io
version: v1beta1
insecureSkipTLSVerify: true
groupPriorityMinimum: 100
versionPriority: 100
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: metrics-server
namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: metrics-server
namespace: kube-system
labels:
k8s-app: metrics-server
spec:
selector:
matchLabels:
k8s-app: metrics-server
template:
metadata:
name: metrics-server
labels:
k8s-app: metrics-server
spec:
serviceAccountName: metrics-server
volumes:
# mount in tmp so we can safely use from-scratch images and/or read-only containers
- name: tmp-dir
emptyDir: {}
containers:
- name: metrics-server
image: registry.cn-shanghai.aliyuncs.com/k8sgcrio_containers/metrics-server:v0.3.7
imagePullPolicy: IfNotPresent
command:
- /metrics-server
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP,Hostname,ExternalIP
- --metric-resolution=30s
args:
- --cert-dir=/tmp
- --secure-port=4443
ports:
- name: main-port
containerPort: 4443
protocol: TCP
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
volumeMounts:
- name: tmp-dir
mountPath: /tmp
#如果有啥问题,可以尝试安装master节点
#nodeSelector:
#node-role: master
---
apiVersion: v1
kind: Service
metadata:
name: metrics-server
namespace: kube-system
labels:
kubernetes.io/name: "Metrics-server"
kubernetes.io/cluster-service: "true"
spec:
selector:
k8s-app: metrics-server
ports:
- port: 443
protocol: TCP
targetPort: main-port
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: system:metrics-server
rules:
- apiGroups:
- ""
resources:
- pods
- nodes
- nodes/stats
- namespaces
- configmaps
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:metrics-server
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:metrics-server
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
开始部署:
[root@client ~]# kubectl apply -f components.yaml
[root@client ~]# kubectl get pods -n kube-system|grep metrics
metrics-server-5987bb5dff-kwzl9 1/1 Running 0 38m
试验:
hpa.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache
spec:
selector:
matchLabels:
run: php-apache
replicas: 1
template:
metadata:
labels:
run: php-apache
spec:
containers:
- name: php-apache
image: registry.cn-shanghai.aliyuncs.com/k8sgcrio_containers/hpa-example
ports:
- containerPort: 80
resources:
limits:
cpu: 500m
requests:
cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
name: php-apache
labels:
run: php-apache
spec:
ports:
- port: 80
selector:
run: php-apache
部署hpa示例
[root@client ~]# kubectl apply -f hpa.yaml
deployment.apps/php-apache created
service/php-apache created
[root@client ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
php-apache-b6968c487-ldmml 1/1 Running 0 55s
[root@client ~]# kubectl top pods
NAME CPU(cores) MEMORY(bytes)
php-apache-b6968c487-ldmml 1m 7Mi
创建水平Pod自动缩放器,参数cpu-percent指的是cpu的百分比。超过%50即扩容1个pod。min是最小pod数,max最大pod数。
创建好,一般要个30s左右才能获取到相关指标。你们可以看到TARGETS栏,会有<unknow>。给它点时间!
[root@client ~]# kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
horizontalpodautoscaler.autoscaling/php-apache autoscaled
[root@client ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache <unknown>/50% 1 10 0 8s
[root@client ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache <unknown>/50% 1 10 0 13s
[root@client ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache <unknown>/50% 1 10 0 15s
[root@client ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 10 1 19s
[root@client ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 10 1 22s
[root@client ~]#
再开一个窗口。我们需要对部署的应用进行请求负载。
[root@client ~]# kubectl run -it --rm load-generator --image=busybox /bin/sh
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
If you don't see a command prompt, try pressing enter.
/ # while true; do wget -q -O- http://php-apache; done
OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!
现在继续查看hpa信息
[root@client ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 251%/50% 1 10 4 6m26s
[root@client ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
load-generator-dbf8dc997-lhjwh 1/1 Running 0 2m48s
php-apache-b6968c487-6kq6g 1/1 Running 0 101s
php-apache-b6968c487-cpbs4 1/1 Running 0 116s
php-apache-b6968c487-kszmp 1/1 Running 0 101s
php-apache-b6968c487-ldmml 1/1 Running 0 12m
[root@client ~]#
大家可以看到Replicas开始增加了,也就是pod数量。TARGES百分比也在增加。这说明负载测试成功了!
接下来暂停负载程序,按住ctrl+c即可。等个五分钟吧!!!然后hpa就自动缩回去。
[root@client ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 10 1 14m
[root@client ~]#