UCS+OpenKruise实现多云混合节点部署UnitedDeployment负载
【摘要】 一、背景客户针对多云容灾考虑,想结合集群跨云场景和K8S集群OpenKruise能力,满足对集群高级应用运维能力的同时,提高应用程序的可用性和稳定性OpenKruise:https://openkruise.ioOpenKruise核心能力和工作原理:https://bbs.huaweicloud.com/blogs/417777华为云UCS:https://support.huaweic...
一、背景
客户针对多云容灾考虑,想结合集群跨云场景和K8S集群OpenKruise能力,满足对集群高级应用运维能力的同时,提高应用程序的可用性和稳定性
OpenKruise:https://openkruise.io
OpenKruise核心能力和工作原理:https://bbs.huaweicloud.com/blogs/417777
华为云UCS:https://support.huaweicloud.com/productdesc-ucs/ucs_productdesc_0001.html
二、方案简介
本文展示在UCS纳管多云集群的场景下,跨云部署OpenKruise特有的workload(以UnitedDeployment为例),方案步骤如下:
- 配置联邦kubectl,分别为集群联邦管理面及成员集群安装Kruise插件。
- 利用UCS联邦的PropagationPolicy,将负载按权重部署在成员集群中。
- 利用openkruise的多区域管理能力,使负载按规则部署在ecs节点及CCI上。
整体架构如下:
- PropagationPolicy:是UCS中控制如何在不同集群之间传播资源的策略。具体来说,PropagationPolicy决定了在应用程序部署期间,哪些资源需要在不同的集群之间复制。
- PropagationPolicy的策略有:复制分发模式和权重分发模式,由于客户需求为各集群部署实例数不同,所以采用权重分发模式
- PropagationPolicy官方文档:https://karmada.io/zh/docs/next/userguide/scheduling/propagate-dependencies
- Virtual-Kubelet:是kubernetes集群的插件,作为一种虚拟的kubelet用来连接Kubernetes集群和其他平台的API。Virtual Kubelet的主要场景是将Kubernetes API扩展到无服务器的容器平台(如CCI)。
- UnitedDeployment:在一个 Kubernetes 集群中可能存在不同的 node 类型,比如多个可用区、或不同的节点技术(比如 Virtual kueblet)等,这些不同类型的 node 上有 label/taint 标识。 UnitedDeployment 控制器可以提供一个模板来定义应用,并通过管理多个 workload 来匹配不同的区域。
三、准备工作
3.1 配置已加入舰队CCE集群的kubectl工具
通过kubectl连接集群:https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html
步骤1 进入CCE集群->点击kubectl旁的”配置”按钮(连接信息已添加公网地址)
步骤2 下载config文件->将文件放在能够连接到集群API的节点的/$HOME/.kube/
mkdir -p $HOME/.kube
mv -f test-ucs-kubeconfig.yaml $HOME/.kube/config
步骤3 根据使用场景,按需切换kubectl的访问模式
内网接入:
kubectl config use-context internal
公网接入:
kubectl config use-context external
----结束
3.2 登录舰队下需要部署UnitedDeployment类型工作负载的集群安装openkruise
须知:
在1.25集群中,节点如果选择的是docker运行时,会导致该节点上的kruise-daemon安装失败。具体原因如下:
- 由于开源的K8S在1.25版本已经不再默认支持docker运行时了,1.25集群是通过:kubelet --> cri-dockerd (kubelet使用cri接口对接cri-dockerd) --> docker --> containerd的方式继续使用docker运行时的,kubelet不是对接的docker-shim,而是cri-dockerd。由于节点上没有docker-shim,kruise-daemon探测到运行时为docker,但找不到docker-shim,pod会启动失败。
步骤1 通过helmv3安装openkruise
helm repo add openkruise https://openkruise.github.io/charts
helm repo update
helm install kruise openkruise/kruise
----结束
3.3 为CCE集群安装vk插件
由于kruise-daemon使用了hostnetwork类型(CCI不支持)的网络,会显示部署在VK节点(CCI)上失败。将kruise-daemon容忍全部污点配置去除,这样kruise-daemon会忽略VK节点。
步骤1 进入集群->插件中心->CCE突发弹性引擎 点击安装
----结束
四、集群联邦UCS下发UnitedDeployment工作负载
4.1 配置对接联邦管理面kubectl工具
步骤1 CCE集群已加入舰队,开启集群联邦
集群联邦官方文档:https://support.huaweicloud.com/usermanual-ucs/ucs_01_0018.html
步骤2 获取联邦kubeconfig文件,并配置对接UCS
进入该舰队->点击舰队基本信息中的"kubectl"按钮->点击项目名称"cn-north-4"->选择虚拟私有云->选择子网->选择有效期(最高5年)->点击下载
匹配UCS界面选择,在北京四region的、上方指定虚拟私有云的、指定子网下的ecs节点上安装kubectl工具->将获取的kubeconfig文件改名为config放到/$home/.kube/
mkdir -p $HOME/.kube
mv -f kubeconfig.json $HOME/.kube/config
步骤3 切换kubectl的访问模式
kubectl config use-context federation
步骤4 验证是否配置成功
kubectl get cluster
----结束
4.2 为联邦控制面安装openkruise
步骤1 通过helm v3 安装 openkruise,由于需要对Chart.yaml进行修改,所以需要将Chart包下载下来
wget https://github.com/openkruise/charts/releases/download/kruise-1.5.1/kruise-1.5.1.tgz
tar -xvf kruise-1.5.1.tgz
vim ./kruise/Chart.yaml
#将 kubeVersion: '>= 1.16.0-0' 这一行删除,helm安装时获取不到UCS联邦的kubeVersion,会安装失败
helm install kruise ./kruise
步骤2 部署自定义资源解释器,使用户能够在联邦管理侧get命令获取到UnitedDeployment的status字段
kubectl apply -f customizations.yaml
apiVersion: config.karmada.io/v1alpha1
kind: ResourceInterpreterCustomization
metadata:
name: declarative-configuration-UnitedDeployment
spec:
target:
apiVersion: apps.kruise.io/v1alpha1
kind: UnitedDeployment
customizations:
replicaResource:
luaScript: >
local kube = require("kube")
function GetReplicas(obj)
replica = obj.spec.replicas
requirement = kube.accuratePodRequirements(obj.spec.template)
return replica, requirement
end
replicaRevision:
luaScript: >
function ReviseReplica(obj, desiredReplica)
obj.spec.replicas = desiredReplica
return obj
end
statusAggregation:
luaScript: >
function AggregateStatus(desiredObj, statusItems)
if statusItems == nil then
return desiredObj
end
if desiredObj.status == nil then
desiredObj.status = {}
end
if desiredObj.metadata.generation == nil then
desiredObj.metadata.generation = 0
end
generation = desiredObj.metadata.generation
replicas = 0
readyReplicas = 0
updatedReplicas = 0
for i = 1, #statusItems do
if statusItems[i].status ~= nil and statusItems[i].status.observedGeneration ~= nil and statusItems[i].status.observedGeneration ~= '' then
generation = statusItems[i].status.observedGeneration
end
if statusItems[i].status ~= nil and statusItems[i].status.replicas ~= nil then
replicas = replicas + statusItems[i].status.replicas
end
if statusItems[i].status ~= nil and statusItems[i].status.readyReplicas ~= nil then
readyReplicas = readyReplicas + statusItems[i].status.readyReplicas
end
if statusItems[i].status ~= nil and statusItems[i].status.updatedReplicas ~= nil then
updatedReplicas = updatedReplicas + statusItems[i].status.updatedReplicas
end
if statusItems[i].status ~= nil and statusItems[i].status.currentRevision ~= nil then
currentRevision =statusItems[i].status.currentRevision
end
end
desiredObj.status.observedGeneration = generation
desiredObj.status.replicas = replicas
desiredObj.status.readyReplicas = readyReplicas
desiredObj.status.updatedReplicas = updatedReplicas
desiredObj.status.currentRevision = currentRevision
return desiredObj
end
dependencyInterpretation:
luaScript: >
local kube = require("kube")
function GetDependencies(desiredObj)
template = {}
if desiredObj.spec.template.statefulSetTemplate ~= nil then
template = desiredObj.spec.template.statefulSetTemplate.spec.template
end
if desiredObj.spec.template.advancedStatefulSetTemplate ~= nil then
template = desiredObj.spec.template.advancedStatefulSetTemplate.spec.template
end
if desiredObj.spec.template.cloneSetTemplate ~= nil then
template = desiredObj.spec.template.cloneSetTemplate.spec.template
end
if desiredObj.spec.template.deploymentTemplate ~= nil then
template = desiredObj.spec.template.deploymentTemplate.spec.template
end
refs = kube.getPodDependencies(template, desiredObj.metadata.namespace)
return refs
end
----结束
4.3 通过联邦kubectl下发UnitedDeployment
官方文档:https://openkruise.io/zh/docs/user-manuals/UnitedDeployment
步骤1 在联邦侧删除openkruise默认安装webhook资源,UCS控制面不需要校验,否则会被webhook拦截,下发请求失败。
kubectl delete ValidatingWebhookConfiguration kruise-validating-webhook-configuration
kubectl delete MutatingWebhookConfiguration kruise-mutating-webhook-configuration
步骤2 通过联邦kubectl创建UnitedDeployment工作负载
UnitedDeployment 所管理的负载会按照subsets中定义的topology和replicas进行部署,
topology中的replicas要按百分比进行实例数的分配(如下实现效果为在ecs节点上部署50%实例,剩余部署到CCI)
kubectl apply -f xxx.yaml
apiVersion: apps.kruise.io/v1alpha1
kind: UnitedDeployment
metadata:
name: sample-ud
spec:
#总的实例数
replicas: 6
revisionHistoryLimit: 10
selector:
matchLabels:
app: sample
template:
# statefulSetTemplate or advancedStatefulSetTemplate or cloneSetTemplate or deploymentTemplate
statefulSetTemplate:
metadata:
labels:
app: sample
spec:
selector:
matchLabels:
app: sample
template:
metadata:
labels:
app: sample
spec:
containers:
- image: swr.cn-north-4.myhuaweicloud.com/testapp/nginx:v2
name: nginx
resources:
limits:
cpu: 50m
memory: 50Mi
requests:
cpu: 50m
memory: 50Mi
topology:
# 实例部署的区域
subsets:
- name: subset-a
nodeSelectorTerm:
matchExpressions:
- key: type
operator: NotIn
values:
- virtual-kubelet
# 部署50%实例到非VK虚拟节点上
replicas: 50%
- name: subset-b
nodeSelectorTerm:
matchExpressions:
- key: type
operator: In
values:
- virtual-kubelet
# 注意此处写replicas占比或实例数,代表剩余的都在subset-b上部署
tolerations:
# 容忍VK节点上的污点
- key: virtual-kubelet.io/provider
operator: Exists
updateStrategy:
manualUpdate:
partitions:
subset-a: 0
subset-b: 0
type: Manual
步骤3 定义PropagationPolicy,通过按自动义权重比例将负载分发到不同集群中
kubectl apply -f pp.yaml
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: ud-propagation
spec:
# 资源选择器
resourceSelectors:
- apiVersion: apps.kruise.io/v1alpha1
# 资源的类型
kind: UnitedDeployment
name: sample-ud
placement:
replicaScheduling:
# 传播到舰队集群成员时副本的调度策略
# 副本调度类型分为2种:Duplicate,复制模式,复制相同的副本数到成员集群;Divided,权重模式,按权重将副本分配到成员集群
replicaSchedulingType: Divided
# 复制分区首选项,当replicaSchedulingType为Divided的时候,replicaDivisionPreference有两种选择:Weighted(权重)和 Aggregated(自动均衡)
replicaDivisionPreference: Weighted
weightPreference:
# 静态权重列表
staticWeightList:
- targetCluster:
# 集群名
clusterNames:
- idc1
weight: 1
- targetCluster:
# 集群名
clusterNames:
- test-ucs
weight: 2
----结束
五、验证
步骤 1查看负载被成功下发到各个集群
步骤 2查看负载被成功下发到各个集群
使用联邦管理面的kubectl 获取UnitedDeployment的状态
----结束
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)