HPA
HPA的全称为Horizontal Pod Autoscaling,它可以根据当前pod资源的使用率(如CPU、磁盘、内存等),进行副本数的动态的扩容与缩容,以便减轻各个pod的压力。当pod负载达到一定的阈值后,会根据扩缩容的策略生成更多新的pod来分担压力,当pod的使用比较空闲时,在稳定空闲一段时间后,还会自动减少pod的副本数量
前提条件:系统应该能够获取当前Pod的资源使用情况(意思是可以执行 kubectl top pod命令,并且能够得到反馈信息)
heapster:这个组件之前是集成在k8s集群的,不过在1.12版本之后就被移除了。如果还想使用此功能,应该部署metricServer这个k8s集群资源使用情况的聚合器
要是想实现自动扩容缩容的功能,还需要部署heapster服务,而这个服务集成在Prometheus的MetricServer服务中,也就是说需要部署Prometheus服务,但是我们也可以直接部署heapster服务
实现Pod的扩容与缩容示例
因为heapster集成在MetricServer服务中,所以首先部署这个服务
1、首先安装MerticServer服务,从Github上克隆项目
[root@master ~]# git clone https://github.com/kubernetes-incubator/metrics-server.git
2、修改yaml文件
[root@master ~]# vim metrics-server/deploy/kubernetes/metrics-server-deployment.yaml
image: k8s.gcr.io/metrics-server-amd64:v0.3.1 #更换镜像版本
//在44行添加
command:
- /metrics-server
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP
3、下载metrics-server镜像k8s.gcr.io/metrics-server-amd64:v0.3.1(因为国内无法访问k8s.gcr.io,所以采用以下办法)
pull-google-container 工具脚本
[root@master ~]# vim pull-google.sh
image=$1
echo $1
img=`echo $image | sed 's/k8s\.gcr\.io/anjia0532\/google-containers/g;s/gcr\.io/anjia0532/g;s/\//\./g;s/ /\n/g;s/_/-/g;s/anjia0532\./anjia0532\//g' | uniq | awk '{print ""$1""}'`
echo "docker pull $img"
docker pull $img
echo "docker tag $img $image"
docker tag $img $image
[root@master ~]# chmod +x pull-google.sh && cp pull-google.sh /usr/local/bin/pull-google-container
[root@master ~]# pull-google-container k8s.gcr.io/metrics-server-amd64:v0.3.1
4、将镜像打包发给k8s各个节点
[root@master ~]# docker save > metrics-server-amd64.tar k8s.gcr.io/metrics-server-amd64:v0.3.1
[root@master ~]# scp metrics-server-amd64.tar node01:/root
[root@master ~]# scp metrics-server-amd64.tar node02:/root
[root@node01 ~]# docker load < metrics-server-amd64.tar
[root@node02 ~]# docker load < metrics-server-amd64.tar
5、运行yaml文件
[root@master ~]# kubectl apply -f metrics-server/deploy/kubernetes/
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
serviceaccount/metrics-server created
deployment.apps/metrics-server created
service/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
[root@master ~]# kubectl get pod -n kube-system
metrics-server-849dcc6bb4-hr5xp 1/1 Running 0 13s
6、验证
[root@master ~]# kubectl top node
error: metrics not available yet #这里等一会就行
[root@master ~]# kubectl top pod -n kube-system metrics-server-849dcc6bb4-hr5xp
NAME CPU(cores) MEMORY(bytes)
metrics-server-849dcc6bb4-hr5xp 1m 13Mi
[root@master ~]# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master 56m 2% 1145Mi 66%
node01 12m 0% 478Mi 27%
node02 11m 0% 452Mi 26%
这里,我们使用一个测试镜像,这个镜像基于php-apache制作的docker镜像,包含了一些可以运行cpu密集计算任务的代码(模拟压力测试)
[root@master ~]# kubectl run php-apache --image=mirrorgooglecontainers/hpa-example:latest --requests=cpu=200m --expose --port=80
[root@master ~]# kubectl get deployments.
NAME READY UP-TO-DATE AVAILABLE AGE
php-apache 1/1 1 1 33s
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
php-apache-794cdd478f-l9kxn 1/1 Running 0 6m27s
[root@master ~]# kubectl top pod php-apache-794cdd478f-l9kxn
NAME CPU(cores) MEMORY(bytes)
php-apache-794cdd478f-l9kxn 0m 9Mi
创建HPA控制器
[root@master ~]# kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
horizontalpodautoscaler.autoscaling/php-apache autoscaled
[root@master ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 10 1 2m1s
限制cpu使用率不能超过50%,最少有一个Pod,最多有10个
实时监控Pod的状态
[root@master ~]# kubectl get pod -w
NAME READY STATUS RESTARTS AGE
php-apache-794cdd478f-l9kxn 1/1 Running 0 40m
创建一个应用,用来不停的访问我们刚刚创建的php-apache的svc资源
[root@master ~]# kubectl run -i --tty load-generator --image=busybox /bin/sh
进入Pod内,执行此命令用来模拟访问php-apache的svc资源
#对Pod进行死循环请求
/ # while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
运行一段时间后查看pod的数量变化
NAME READY STATUS RESTARTS AGE
load-generator-7d549cd44-xm98c 1/1 Running 1 25m
php-apache-867f97c8cb-4r6sk 1/1 Running 0 19m
php-apache-867f97c8cb-4rcpk 1/1 Running 0 13m
php-apache-867f97c8cb-5pbxf 1/1 Running 0 16m
php-apache-867f97c8cb-8htth 1/1 Running 0 13m
php-apache-867f97c8cb-d94h9 0/1 ContainerCreating 0 13m
php-apache-867f97c8cb-drh52 1/1 Running 0 18m
php-apache-867f97c8cb-f67bs 0/1 ContainerCreating 0 17m
php-apache-867f97c8cb-nxc2r 1/1 Running 0 19m
php-apache-867f97c8cb-vw74k 1/1 Running 0 39m
php-apache-867f97c8cb-wb6l5 0/1 ContainerCreating 0 15m
当停止死循环请求后,也并不会立即减少pod数量,会等一段时间后减少pod数量,防止流量再次激增。
至此,pod副本数量的自动扩缩容就实现了
[root@master ~]# kubectl get hpa -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 106%/50% 1 10 8 50m
php-apache Deployment/php-apache 102%/50% 1 10 8 50m
php-apache Deployment/php-apache 93%/50% 1 10 8 51m
php-apache Deployment/php-apache 87%/50% 1 10 8 51m
php-apache Deployment/php-apache 82%/50% 1 10 8 51m
php-apache Deployment/php-apache 77%/50% 1 10 8 51m
php-apache Deployment/php-apache 68%/50% 1 10 8 52m
php-apache Deployment/php-apache 61%/50% 1 10 8 52m
资源限制
以下只是yaml文件中的一段,并不是整个yaml文件
基于Pod
kubernetes对资源的限制实际上是通过cgroup来控制的,cgroup是容器的一组用来控制内核如何运行进程的相关属性集合,针对内存、cpu和各种设备都有对应的cgroup
默认情况下,Pod运行没有cpu和内存的限额,这意味着系统中的任何Pod将能够想执行该Pod所在的节点一样,消耗足够多的cpu和内存,一般会针对某些应用的pod资源进行资源限制,这个资源限制通过resources的requeste和limits来实现
[root@master ~]# vim cgroup-pod.yaml
spec:
containers:
- name: xxx
imagePullPolicy: Always
image: xxx
ports:
- protocol: TCP
containerPort: 80
resources:
limits:
cpu: "4"
memory: 2Gi
requests:
cpu: 260m
memory: 260Mi
requests:要分配的资源,limits为最高请求的资源值。可以简单的理解为初始值和最大值
基于名称空间
1)计算资源配额
[root@master ~]# vim compute-resources.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
spec:
hard:
pods: "20"
requests.cppu: "20"
requests.memory: 100Gi
limits.cpu: "40"
limits.memory: 200Gi
2)配置对象数量配额限制
[root@master ~]# vim object-counts.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
spec:
hard:
configmaps: "10"
persistentvolumeclaims: "4"
replicationcontrollers: "20"
secrets: "10"
service.loadbalancers: "2"
3)配置CPU和内存的LimitRange
[root@master ~]# vim limitRange.yaml
apiVersion: v1
kind: LimiRange
metadata:
name: mem-limit-range
spec:
limits:
- default:
memory: 50Gi
cpu: 5
defaultRequest:
memory: 1Gi
cpu: 1
type: Container
default即limit的值
defaultRequest即request的值