在实际生产系统中,我们经常会遇到某个服务需要扩容的场景,也可能会遇到由于资源紧张或者工作负载降低而需要减少服务实例数量的场景。此时我们可以利用 Deployment/RC 的Scale机制来完成这些工作。
Kubernetes对Pod的扩容和缩容操作提供了手动
和自动
两种模式,手动模式通过执行kubectl scale
命令对一个 Deployment/RC 进行Pod副本数量的设置,即可一键完成。自动模式则需要用户根据某个性能指标或者自定义业务指标
,并指定Pod副本数量的范围
,系统将自动在这个范围内根据性能指标的变化进行调整。
1. 手动扩容和缩容模式
以 Deployment nginx为例:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
已运行的Pod副本数量为3个:
$ kubectl get pods | grep nginx
nginx-deployment-76bf4969df-2zgwr 1/1 Running 0 4m15s
nginx-deployment-76bf4969df-fmcz2 1/1 Running 0 4m15s
nginx-deployment-76bf4969df-t7zrs 1/1 Running 0 4m15s
通过kubectl scale
命令可以将Pod副本数量从初始的3个更新为5个:
$ kubectl scale deployment nginx-deployment --replicas 5
deployment.extensions/nginx-deployment scaled
将--replicas
设置为比当前Pod副本数量更小的数字,系统将会“杀掉”一些运行中的Pod,以实现应用集群缩容:
$ kubectl scale deployment nginx-deployment --replicas=1
deployment.extensions/nginx-deployment scaled
2. 自动扩容和缩容模式
从Kubernetes v1.1 版本开始,新增了名为Horizontal Pod Autoscaler(HPA)
的控制器,用于实现基于CPU使用率进行自动Pod扩容和缩容的功能。
HPA控制器基于Master的kube-controller-manager
服务启动参数--horizontal-pod-autoscaler-sync-period
定义的时长(默认30s),周期性地检测目标Pod的CPU使用率,并在满足条件时对 Deployment/RC 或 Deployment 中的Pod副本数量进行调整,以符合用户定义的平均Pod CPU使用率。
Pod CPU使用率来源于Heapster
和Metric-Server
组件,所以需要预先安装好Heapster
和Metric-Server
,安装过程参考:
Kubernetes heapster监控插件安装
Kubernetes Metrics Server安装
创建HPA时可以使用kubectl autoscale
命令进行快速创建或者使用yaml配置文件进行创建。
在创建HPA之前,需要已经存在一个 Deployment/RC 对象,并且该 Deployment/RC 中的Pod必须定义 resources.requests.cpu
的资源请求值,如果不设置该值,则Heapster
将无法收集到该Pod的CPU使用情况,会导致HPA无法正常工作。
下面通过为一个Deployment设置HPA,然后使用一个客户端对其进行压力测试,对HPA的用法进行示例。
以php-apache的Deployment为例,设置cpu request为200m,未设置limit上限的值:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: php-apache
spec:
replicas: 1
template:
metadata:
name: php-apache
labels:
app: php-apache
spec:
containers:
- name: php-apache
image: siriuszg/hpa-example
resources:
requests:
cpu: 200m
ports:
- containerPort: 80
在创建一个php-apache的Service,供客户端访问:
apiVersion: v1
kind: Service
metadata:
name: php-apache
spec:
ports:
- port: 80
selector:
app: php-apache
接下来为Deployment “php-apache” 创建一个HPA控制器,在1和10之间调整Pod的副本数量,以使得平均Pod CPU使用率维持在50%。
使用kubectl autoscale
命令进行创建:
kubectl autoscale deployment php-apache --min=1 --max=10 --cpu-percent=50
或者通过yaml配置文件来创建HPA,需要在scaleTargetRef
字段指定需要管理的 Deployment/RC 的名字,然后设置minReplicas
、maxReplicas
和targetCPUUtilizationPercentage
参数:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1beta1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 50
查看已创建的HPA:
$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache <unknown>/50% 1 10 1 47s
然后,创建一个busybox Pod,用于对php-apache服务发起压力测试的请求:
apiVersion: v1
kind: Pod
metadata:
name: busybox
spec:
containers:
- name: busybox
image: busybox
command: ["sleep", "3600"]
登录busybox容器,执行一个无限循环的wget命令来访问php-apache服务:
while true; do wget -q -O- http://php-apache > /dev/null; done
3. 遇到的问题
通过kubectl get hpa
命令查看HPA状态时,TARGETS状态为unknown。
通过kubectl describe hpa
查看HPA详细信息:
# kubectl describe hpa
Name: php-apache
Namespace: default
Labels: <none>
Annotations: <none>
CreationTimestamp: Sat, 05 Oct 2019 18:50:34 +0800
Reference: Deployment/php-apache
Metrics: ( current / target )
resource cpu on pods (as a percentage of request): <unknown> / 50%
Min replicas: 1
Max replicas: 10
Deployment pods: 1 current / 0 desired
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True SucceededGetScale the HPA controller was able to get the target's current scale
ScalingActive False FailedGetResourceMetric the HPA was unable to compute the replica count: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedGetResourceMetric 4s (x11 over 2m35s) horizontal-pod-autoscaler unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io)
Warning FailedComputeMetricsReplicas 4s (x11 over 2m35s) horizontal-pod-autoscaler failed to get cpu utilization: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io)
可以看到failed to get cpu utilization: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io)
。
原因可能是:
- 配置资源限额时拼写错误,致使资源限额添加失败。
- Metrics Server未安装。
解决方案:
- 修正资源限额配置。
- Kubernetes Metrics Server安装
等待一段时间后,观察HPA控制器收集到的Pod CPU使用率:
$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 2156%/50% 1 10 1 47s