前提条件
- 已创建Kubernetes集群。
- Kubernetes集群连通性正常。
- 已创建虚拟节点VNode。
创建虚拟节点VNode
从云容器引擎创建的虚拟节点,在弹性容器实例(简称ECI)中也能查看到,由ECI根据使用情况计费,仅支持在ECI开放的资源池创建虚拟节点,ECI开放的资源池请以ECI官网为准。
1、登录云容器引擎控制台,在左侧导航栏选择集群,单击集群名,进入集群页面。
2、点击左侧菜单节点管理 -> 节点,打开节点列表页面。
3、单击创建虚拟节点按钮,进入创建虚拟节点页面。
4、选择可用区后,标签与污点可不需要额外添加,点击确定按钮,提交会自动返回节点列表页面。
5、创建的虚拟节点,在集群列表中的实例规格会显示为“virtual-kubelet”,配置显示为“CG”,类型为“virtual-kubelet”。
安装cubevk-profile插件
1、登录云容器引擎控制台,在左侧导航栏选择集群,单击集群名,进入集群页面。
2、选择左侧菜单插件 -> 插件市场,找到cubevk-profile插件,单击安装,在安装弹出框,选择1.0.3版本,单击“安装”。
Pod调度到ECI
云容器引擎提供了两种方式将Pod调度到ECI上运行,手工调度与自动调度方式。
1、手工调度
方式一:为pod添加 ccse.ctyun.cn/vnode=true 的Label,将Pod调度到ECI上运行。
方式二:创建一个Namespace并添加 ccse.ctyun.cn/vnode=true 的Label,则该Namespace下的所有Pod将调度到ECI上运行。
2、自动调度
cubevk-profile支持的调度策略如下:
策略 说明 fair 公平调度,由kube-scheduler决定调度到标准Node或VNode。 normalNodeOnlyPod 只会调度到标准Node。 normalNodePrefer 优先调度到标准Node,标准Node资源不足时允许调度到VNode。 virtualNodeOnlyPod 只会调度到VNode。
创建Selector来配置Pod的调度策略
创建Pod时,系统会按照Selector配置去匹配Pod,Selector Label能够匹配上的Pod,会自动调度到ECI,并自动添加相应的Annotation和Label,Selector的YAML配置模板如下:
apiVersion: eci.ctyun.cn/v1
kind: Selector
metadata:
name: test-auto-virtual-node
spec:
objectLabels:
matchLabels:
app: nginx
effect:
annotations:
ccse.ctyun.cn/eci-image-cache: "true"
labels:
eci-schedulable: "true"
policy:
virtualNodeOnly: {}
priority: 99
spec中的相关参数说明如下:
名称 描述 objectLabels.matchLabels 要匹配的Pod Label。 namespaceLabels.matchLabels 要匹配的Namespace Label。 effect.annotations 要添加的Annotation。 effect.labels 要添加的Label。 policy 调度策略。支持以下几种:fair、nromalNodeOnly、normalNodePrefer、virtualNodeOnly。 priority 优先级。存在多个Selector且发生冲突时,优先级高的Selector会生效。数值越大,表示该Selector优先级越高。
说明objectLabels和namespaceLabels中,至少要选择一个配置。如果同时配置了两者,则Pod需要同时匹配两者。
调度失败再次自动调度到VNode
默认开启调度失败再次自动调度到VNode功能,当集群中真实节点(即ECS节点)计算资源不足时,将Pod调度到虚拟节点。即在Pod调度时,如果没有匹配的node节点,会把调度失败的Pod重新调度到ECI上。
可设置环境变量VNODE_AUTO_SCALER来关闭调度失败再次调度到VNode功能:
...
env:
- name: VNODE_AUTO_SCALER
value: "true"
...
3、手工调度配置示例
配置示例一:配置Pod Label
为pod添加ccse.ctyun.cn/vnode=true的Label,cubevk-profile会为该pod添加VNode Toleration和NodeSelector,将Pod调度到ECI上运行。
准备测试Pod的yaml文件:
apiVersion: v1
kind: Pod
metadata:
name: test-nginx-manual-virtual
labels:
ccse.ctyun.cn/vnode: "true" #添加特定Label
spec:
containers:
- name: nginx
image: lengbuleng/nginx:1.14.2
ports:
- containerPort: 80
配置示例二:配置Namespace Label
创建一个Namespace并添加ccse.ctyun.cn/vnode=true的Label,cubevk-profile会为该Namespace下的pod添加VNode Toleration和NodeSelector,则该Namespace下的所有Pod将调度到ECI上运行。
创建命名空间:
kubectl create ns vk
给命名空间添加特定标签:
kubectl label ns vk ccse.ctyun.cn/vnode="true"
准备测试Pod的yaml文件:
apiVersion: v1
kind: Pod
metadata:
name: test-nginx-manual-virtual-ns
namespace: vk #指定添加了特定Label的Namespace
spec:
containers:
- name: nginx
image: lengbuleng/nginx:1.14.2
ports:
- containerPort: 80
4、自动调度配置示例
配置示例一:virtualNodeOnly调度
创建以下Selector,cubevk-profile会为带有app: nginx Label的Pod添加VNode Toleration和NodeSelector,同时添加effect中定义的Annotation和Label到Pod。
创建selector自定义资源对象,selector-virtual.yaml的内容如下:
apiVersion: eci.ctyun.cn/v1
kind: Selector
metadata:
name: test-auto-virtual-node
spec:
objectLabels:
matchLabels:
app: nginx
effect:
annotations:
ccse.ctyun.cn/eci-image-cache: "true"
labels:
eci-schedulable: "true"
policy:
virtualNodeOnly: {}
创建selector资源对象:
kubectl apply -f selector-virtual.yaml
准备测试Pod的yaml文件,nginx-virtual.yaml的内容如下:
apiVersion: v1
kind: Pod
metadata:
name: test-nginx-auto-virtual
labels:
app: nginx
spec:
containers:
- name: nginx
image: lengbuleng/nginx:1.14.2
ports:
- containerPort: 80
创建pod:
kubectl apply -f nginx-normal.yaml
配置示例二:normalNodePrefer调度
创建以下Selector,首先kube-scheduler默认只会调度pod到标准节点;当标准节点资源不足时导致调度失败时,cubevk-profile会为带有app: nginx-normal Label的Pod添加VNode Toleration,再次由kube-scheduler决定调度,同时添加effect中定义的Annotation和Label到Pod。
创建selector自定义资源对象,selector-normal.yaml的内容如下:
apiVersion: eci.ctyun.cn/v1
kind: Selector
metadata:
name: test-auto-virtual-node-normal
spec:
objectLabels:
matchLabels:
app: nginx-normal
effect:
annotations:
ccse.ctyun.cn/eci-image-cache: "true"
labels:
eci-schedulable: "true"
policy:
normalNodePrefer: {}
配置示例三:fair调度
创建以下Selector,cubevk-profile会为带有app: nginx-fair Label的Pod添加VNode Toleration,由kube-scheduler决定调度,同时添加effect中定义的Annotation和Label到Pod。
创建selector自定义资源对象,selector-fair.yaml的内容如下:
apiVersion: eci.ctyun.cn/v1
kind: Selector
metadata:
name: test-auto-virtual-node-fair
spec:
objectLabels:
matchLabels:
app: nginx-fair
effect:
annotations:
ccse.ctyun.cn/eci-image-cache: "true"
labels:
eci-schedulable: "true"
policy:
fair: {}
配置示例四:normalNodeOnly调度
不需创建selector,默认情况下kube-scheduler只会调度pod到标准节点;也可以创建以下Selector,cubevk-profile会为带有app: nginx-ecs Label的Pod添加effect中定义的Annotation和Label,由kube-scheduler决定调度。
创建selector自定义资源对象,selector-ecs.yaml的内容如下:
apiVersion: eci.ctyun.cn/v1
kind: Selector
metadata:
name: test-nginx-ecs
spec:
objectLabels:
matchLabels:
app: nginx-ecs
effect:
annotations:
ccse.ctyun.cn/image-cache: "true"
labels:
ccse-ecs: "true"
policy:
normalNodeOnly: {}
5、调度失败再次自动调度到虚拟节点示例
步骤一:在安装cubevk-profile插件时,添加环境变量VNODE_AUTO_SCALER="true",不添加环境变量默认为开启,关闭需修改VNODE_AUTO_SCALER="false"。例如使用helm安装插件时,修改values.yaml:
...
vnodeAutoScaler: "true"
..
步骤二:确认节点资源使用情况。
当真实节点计算资源不足时,cubevk-profile才会将创建失败的Pod自动调度到虚拟节点上。验证pod调度失败再次自动调度到虚拟节点的效果前,可以先确认节点资源使用情况。假设采用的示例环境如下:
真实节点:1台ECS,名称为master(4 vCPU 8 GiB内存),已部署1个deployment,CPU请求接近100%。
虚拟节点:1个,名称为vnd-0002,未部署工作负载。
步骤三:部署deployment。
准备YAML文件,deployment-autoscaler.yaml的内容示例如下,配置副本数(replicas)为2,每个副本的容器声明了4 vCPU 8 GiB的计算资源:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-autoscaler
labels:
app: nginx-autoscaler
spec:
replicas: 2
selector:
matchLabels:
app: nginx-autoscaler
template:
metadata:
labels:
app: nginx-autoscaler
spec:
containers:
- name: nginx
image: lengbuleng/nginx:1.14.2
ports:
- containerPort: 80
resources:
requests:
cpu: 4
memory: 8G
创建deployment:
kubectl create -f deployment-autoscaler.yaml
步骤四:确认Pod调度情况。
查看Pod运行情况:
kubectl get pods -o wide
返回示例如下,可以看到步骤三创建的Pod均运行在虚拟节点上:
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-autoscaler-7cf75fcc46-pss4s 0/1 ProviderFailed 0 19s <none> vnd-0002 <none> <none>nginx-deployment-autoscaler-7cf75fcc46-vhj9k 0/1 ProviderFailed 0 19s <none> vnd-0002 <none> <none>
查看Pod的事件信息,查看名为nginx-deployment-autoscaler-7cf75fcc46-pss4s的Pod的信息:
kubectl describe pod nginx-deployment-autoscaler-7cf75fcc46-pss4s
返回示例如下,在Events中可以看到由于真实节点计算资源不足,kube-scheduler通过cubevk-profile把Pod调度到了虚拟节点上:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 2m40s default-scheduler 0/3 nodes are available: 1 Insufficient cpu, 1 Insufficient memory, 2 node(s) had untolerated taint {virtual-kubelet.io/provider: cube-eci}. preemption: 0/3 nodes are available: 1 No preemption victims found for incoming pod, 2 Preemption is not helpful for scheduling..
Normal Scheduled 2m39s default-scheduler Successfully assigned default/nginx-deployment-autoscaler-7cf75fcc46-pss4s to vnd-0002
Warning ProviderCreateFailed 2m29s vnd-0002/pod-controller Post "https://198.20.2.70:30010/api/openApi/paas/ordervm/api/paas/placeOrder": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Normal ProviderCreateSuccess 2m20s vnd-0002/pod-controller Create pod in provider successfully