GKE 中配置 Pod 的垂直伸缩
原文:Configuring vertical pod autoscaling
在 GKE 1.11.3 中提供了 Pod 垂直伸缩功能的 Beta 版本。这一功能在未来可能会收取费用,没有提供 SLA 以及过期策略,也有可能发生不向后兼容的更改。
本文阐述如何在 GKE 中配置 Pod 的垂直伸缩,该功能包含对 Pod 的 CPU 和内存申请进行调整的能力。
概述
可以配置 VerticalPodAutoscaler CRD来对容器的CPU以及内存需求进行分析和调整。
开始之前
开始这一任务之前,首先要完成以下步骤:
- 确认开启了 GKE API
- 安装 Cloud SDK
设置缺省的 Project ID
gcloud config set project [PROJECT_ID]
如果运行的是 zonal 集群,设置缺省的 compute zone:
gcloud config set compute/zone [COMPUTE_ZONE]
如果运行的是 regional 集群,设置缺省的 compute region:
gcloud config set compute/region [COMPUTE_REGION]
更新
gcloud
到最新版本:gcloud components update
为集群启用 Pod 的垂直自动伸缩功能
可以使用下面的命令创建包含 Pod 垂直自动伸缩功能的新集群:
gcloud beta container clusters create [CLUSTER_NAME] \
--enable-vertical-pod-autoscaling
[CLUSTER_NAME]
就是该集群的名称。
如果要给现有集群启用 Pod 垂直自动伸缩功能,可以用下列命令:
cloud beta container clusters update [CLUSTER-NAME] \
--enable-vertical-pod-autoscaling
[CLUSTER_NAME]
就是该集群的名称。
获取资源推荐
下面的练习中会创建一个 VerticalPodAutoscaler,其中的 updateMode
设置为 Off
。接下来创建一个包含两个 Pod 的 Deployment,每个 Pod 包含一个容器。当 Pod 创建时,VerticalPodAutoscaler 会分析容器的 CPU 和内存需要,并将推荐设置保存在 status
字段中。VerticalPodAutoscaler 在这一过程中不会对运行中的容器采取任何更新资源需求的措施。
VerticalPodAutoscaler 的配置如下:
apiVersion: autoscaling.k8s.io/v1beta1
kind: VerticalPodAutoscaler
metadata:
name: my-rec-vpa
spec:
selector:
matchLabels:
purpose: try-recommend
updatePolicy:
updateMode: "Off"
将代码保存为 my-rec-vpa.yaml
并创建该资源:
kubectl create -f my-rec-vpa.yaml
Deployment 的代码如下:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-rec-deployment
labels:
purpose: try-recommend
spec:
replicas: 2
template:
metadata:
labels:
purpose: try-recommend
spec:
containers:
- name: my-rec-container
image: nginx
上述代码中并未设置 CPU 和内存的请求数量。而 Deployment 中的 Pod,具有标签 purpose: try-recommend
,符合 VerticalPodAutoscaler 的 selector
中定义的选择标准,因此是会受到管理的。
将上述代码命名为 my-rec-deployment.yaml
,创建对象:
kubectl create -f my-rec-deployment.yaml
稍候片刻,查看 VirticalPodAutoscaler:
kubectl get vpa my-rec-vpa --output yaml
会显示 CPU 和内存资源的推荐设置:
...
recommendation:
containerRecommendations:
- containerName: my-rec-container
lowerBound:
cpu: 25m
memory: 262144k
target:
cpu: 25m
memory: 262144k
upperBound:
cpu: 7931m
memory: 8291500k
...
现在看到了推荐的 CPU 和内存请求了,可以选择删除 Deployment,加入 CPU 和内存请求的相关内容,并重新启动。
自动更新资源
接下来的练习会创建一个 Deployment ,其中包含两个 Pod,每个 Pod 包含一个容器,容器请求 100m 的 CPU 以及 50M 的内存。然后创建一个 VerticalPodAutoscaler 对象,自动对 CPU 和内存的请求进行修正。
下面是该 Deployment 的代码:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-deployment
labels:
purpose: try-auto-requests
spec:
replicas: 2
template:
metadata:
labels:
purpose: try-auto-requests
spec:
containers:
- name: my-container
image: k8s.gcr.io/ubuntu-slim:0.1
resources:
requests:
cpu: 100m
memory: 50Mi
command: ["/bin/sh"]
args: ["-c", "while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done"]
把上述代码保存为文件 my-deployment.yaml
,并创建对象:
kubectl create -f my-deployment.yaml
列出运行中的 Pod:
kubectl get pods
输出内容中包含了 my-deployment
中的 Pod:
NAME READY STATUS RESTARTS AGE
my-deployment-cbcdd49fb-d6bf9 1/1 Running 0 8s
my-deployment-cbcdd49fb-th288 1/1 Running 0 8s
为了后续方便,记录下 Pod 名称。
这个 Deployment 申请的 CPU 和内存非常小,所以可能提供更多资源会给这一 Deployment 带来更好的效果。
下面代码用于创建一个 VerticalPodAutoscaler
:
apiVersion: autoscaling.k8s.io/v1beta1
kind: VerticalPodAutoscaler
metadata:
name: my-vpa
spec:
selector:
matchLabels:
purpose: try-auto-requests
updatePolicy:
updateMode: "Auto"
这段代码中的 selector
字段中声明,所有带有标签 purpose: try-auto-requests
的 Pod 都会受其影响。
updateMode
字段取值为 Auto
,代表 VerticalPodAutoscaler 会更新 Pod 的 CPU 和内存请求,也就是说 VerticalPodAutoscaler 会删除 Pod、调整 CPU 和内存申请,然后启动一个新 Pod。
把代码保存为 my-vpa.yaml
,并创建该资源:
kubectl create -f my-vpa.yaml
几分钟之后,再次查看 Pod:
kubectl get pods
会看到 Pod 名称已经发生了变化,如果没有,请隔一段时间再次查看。
获取一个新 Pod 的信息:
kubectl get pod [POD_NAME] --output yaml
输出内容中,会看到 VerticalPodAutoscaler 提高了内存和 CPU 的设置。还会看到注解中也发生了更新:
apiVersion: v1
kind: Pod
metadata:
annotations:
vpaUpdates: 'Pod resources updated by my-vpa: container 0: cpu capped to node
capacity, memory capped to node capacity, cpu request, memory request'
...
spec:
containers:
...
resources:
requests:
cpu: 510m
memory: 262144k
...
查看一下 VerticalPodAutoscaler 的详情:
kubectl get vpa my-vpa --output yaml
输出内容中显示了三组对 CPU 和内存申请的建议:lowerBound
、target
和 upperBound
:
...
recommendation:
containerRecommendations:
- containerName: my-container
lowerBound:
cpu: 536m
memory: 262144k
target:
cpu: 587m
memory: 262144k
upperBound:
cpu: 27854m
memory: "545693548"
target
的含义是,该容器使用 587m 的 CPU 和 262144 KB 的内存会获得更好的运行效果。
VerticalPodAutoscaler 会使用 lowerBound
和 upperBound
来决定是否重新创建 Pod,如果一个 Pod 申请的资源少于 lowerBound
或者大于 upperBound
,就会被 VerticalPodAutoscaler 删除并使用 target
推荐的规格进行重建。
Selector 不可重叠
VerticalPodAutoscaler 包含了一个 selector
字段,用来决定该对象的影响范围。如果创建了不止一个的 VerticalPodAutoscaler
,要保证其 selector 不能发生重叠。
例如下面的两个 VerticalPodAutoscaler:
...
kind: VerticalPodAutoscaler
metadata:
name: my-vpa-1
spec:
selector:
matchLabels:
app: metrics
department: engineering
...
...
...
kind: VerticalPodAutoscaler
metadata:
name: my-vpa-2
spec:
selector:
matchLabels:
department: engineering
...
带有 app: metrics
和 department: engineering
标签的 Pod 会被两个对象同时管理,会引发问题。