k8s之HPA,命名空间资源限制
HPA(Horizontal Pod Autoscaling)Pod 水平自动伸缩,Kubernetes 有一个 HPA 的资源,HPA 可以根据 CPU 利用率自动伸缩一个 Replication Controller、Deployment 或者Replica Set 中的 Pod 数量。
一、HPA 的相关知识
HPA(Horizontal Pod Autoscaling)Pod 水平自动伸缩,Kubernetes 有一个 HPA 的资源,HPA 可以根据 CPU 利用率自动伸缩一个 Replication Controller、Deployment 或者Replica Set 中的 Pod 数量。
(1)HPA 基于 Master 上的 kube-controller-manager 服务启动参数 horizontal-pod-autoscaler-sync-period 定义的时长(默认为30秒),周期性的检测 Pod 的 CPU 使用率。
(2)HPA 与之前的 RC、Deployment 一样,也属于一种 Kubernetes 资源对象。通过追踪分析 RC 控制的所有目标 Pod 的负载变化情况,来确定是否需要针对性地调整目标Pod的副本数,这是HPA的实现原理。
(3)metrics-server 也需要部署到集群中, 它可以通过 resource metrics API 对外提供度量数据。
二、部署 HPA 及运用
2.1 部署 metrics-server
●metrics-server:是kubernetes集群资源使用情况的聚合器,收集数据给kubernetes集群内使用,如kubectl、hpa、scheduler等。
//在所有 Node 节点上传 metrics-server.tar 镜像包到 /opt 目录
cd /opt/
docker load -i metrics-server.tar
//使用 helm install 安装 metrics-server
mkdir /opt/metrics
cd /opt/metrics
helm repo remove stable
helm repo add stable https://charts.helm.sh/stable
或
helm repo add stable http://mirror.azure.cn/kubernetes/charts
我使用的第二种
helm repo update
vim metrics-server.yaml
args:
- --logtostderr
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP
image:
repository: k8s.gcr.io/metrics-server-amd64
tag: v0.3.2
//使用 helm install 安装 metrics-server
helm install metrics-server stable/metrics-server -n kube-system -f metrics-server.yaml
kubectl get pods -n kube-system | grep metrics-server
#部署完毕后,可以通过命令来监视pod的资源占用
kubectl top pods
kubectl top nodes
2.2 部署 HPA
//在所有节点上传 hpa-example.tar 镜像文件到 /opt 目录
hpa-example.tar 是谷歌基于 PHP 语言开发的用于测试 HPA 的镜像,其中包含了一些可以运行 CPU
密集计算任务的代码。
cd /opt
docker load -i hpa-example.tar
docker images | grep hpa-example
HPA伸缩的测试演示
创建用于测试的 Pod 资源,并设置请求资源为 cpu=200m
vim hpa-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
run: php-apache
name: php-apache
spec:
replicas: 1
selector:
matchLabels:
run: php-apache
template:
metadata:
labels:
run: php-apache
spec:
containers:
- image: gcr.io/google_containers/hpa-example
name: php-apache
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
resources:
requests:
cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
name: php-apache
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: php-apache
kubectl apply -f hpa-pod.yaml
创建HPA控制器,进行资源的限制,伸缩管理
使用 kubectl autoscale 命令创建 HPA 控制器,设置 cpu 负载阈值为请求资源的 50%,指定最少负载节点数量为 1 个,最大负载节点数量为 10 个
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
需要等一会儿,才能获取到指标信息 TARGETS
kubectl get hpa
创建一个测试客户端容器
kubectl run -it load-generator --image=busybox /bin/sh
//增加负载
# while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
打开一个新的窗口,查看负载节点数目
kubectl get hpa -w
以上可以看到经过压测,负载节点数量最大上升到 10 个,并且 cpu 负载也随之下降。
如果 cpu 性能较好导致负载节点上升不到 10 个,可再创建一个测试客户端同时测试:
kubectl run -i --tty load-generator1 --image=busybox /bin/sh
# while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
HPA 扩容的时候,负载节点数量上升速度会比较快;但回收的时候,负载节点数量下降速度会比较慢。
原因是防止在业务高峰期时因为网络波动等原因的场景下,如果回收策略比较积极的话,K8S集群可能会认为访问流量变小而快速收缩负载节点数量,而仅剩的负载节点又承受不了高负载的压力导致崩溃,从而影响业务。
三、命名空间的资源限制
命名空间资源限制的配置字段:ResourceQuota
kubectl explain ResourceQuota
Kubernetes对资源的限制实际上是通过cgroup来控制的,cgroup是容器的一组用来控制内核如何运行进程的相关属性集合。针对内存、CPU 和各种设备都有对应的 cgroup。
默认情况下,Pod 运行没有 CPU 和内存的限额。这意味着系统中的任何 Pod 将能够像执行该 Pod 所在的节点一样, 消耗足够多的 CPU 和内存。
一般会针对某些应用的 pod 资源进行资源限制,这个资源限制是通过 resources 的 requests 和 limits 来实现。requests 为创建 Pod 时初始要分配的资源,limits 为 Pod 最高请求的资源值。
示例:
spec:
containers:
- image: xxxx
imagePullPolicy: IfNotPresent
name: auth
ports:
- containerPort: 8080
protocol: TCP
resources:
limits: #定义容器可以使用的最大资源量
cpu: "2"
memory: 1Gi
requests: #容器启动时希望保证的最小资源量
cpu: 250m
memory: 250Mi
资源限制 - 命名空间
3.1 计算资源配额
apiVersion: v1
kind: ResourceQuota #使用 ResourceQuota 资源类型
metadata:
name: compute-resources
namespace: spark-cluster #指定命令空间
spec:
hard:
pods: "20" #设置 Pod 数量最大值
requests.cpu: "2" #允许Pod请求的CPU总量不超过2个单位
requests.memory: 1Gi #允许Pod请求的内存总量不超过1GB
limits.cpu: "4" #允许Pod的CPU使用上限总和不超过4个单位
limits.memory: 2Gi #允许Pod的内存使用上限总和不超过2GB
也就是说为已创建的命名空间sapark-cluster进行计算资源限制。首先限制在该命名空间最大的pod
数量为20个,预留cpu总量为 2 核 ,预留内存总量为 1G,最大cpu总量为 4 核,最大内存总量为 2G。
3.2 配置对象数量配额限制
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
namespace: spark-cluster
spec:
hard:
configmaps: "10" #设置了最多允许10个ConfigMap对象。ConfigMaps用于存储非机密型的数据
persistentvolumeclaims: "4" #设置 pvc 数量最大值
replicationcontrollers: "20" #设置 rc 数量最大值
# RC是Kubernetes 1.6之前的控制器,用于维持指定数量的Pod副本。
# 在Kubernetes 1.7版本后,推荐使用Deployment替代
secrets: "10" #设置了最多允许10个Secret对象
services: "10" #设置了最多允许10个Service对象
services.loadbalancers: "2" #设置了最多允许2个LoadBalancer类型的Service
上述为例,该配置是对namespace中所存在的资源对象进行限制。
如果Pod没有设置requests和limits,则会使用当前命名空间的最大资源;如果命名空间也没设置,则会使用集群的最大资源。
K8S 会根据 limits 限制 Pod 使用资源,当内存超过 limits 时 cgruops 会触发 OOM。
这里就需要创建 LimitRange 资源来设置 Pod 或其中的 Container 能够使用资源的最大默认值
apiVersion: v1
kind: LimitRange #使用 LimitRange 资源类型
metadata:
name: mem-limit-range
namespace: test #可以给指定的 namespace 增加一个资源限制
spec:
limits:
- default: #default 即 limit 的值
memory: 512Mi
cpu: 500m
defaultRequest: #defaultRequest 即 request 的值
memory: 256Mi
cpu: 100m
type: Container #类型支持 Container、Pod、PVC
这意味着在test
命名空间中,如果没有在Pod或容器的定义中显式指定资源请求和限制,那么Kubernetes将自动应用上述的默认值。例如,如果一个Pod没有指定其容器的CPU和内存请求和限制,那么容器的CPU请求将默认为100m,CPU限制为500m,内存请求为256MiB,内存限制为512MiB。
- LimitRange 关注的是资源的规范和标准化,确保资源请求和限制合理,避免资源浪费和不足。
- ResourceQuota 关注的是资源的总量控制,确保整个命名空间的资源使用不超过预定的配额,实现资源的合理分配和管理。
更多推荐
所有评论(0)