共计 5652 个字符,预计需要花费 15 分钟才能阅读完成。
作者 | 张杰(冰羽)
起源 | 阿里巴巴云原生公众号
背景
在注释开始之前,咱们先回顾一下单元化部署的概念和设计理念。在边缘计算场景下,计算节点具备很显著的地区散布属性,雷同的利用可能须要部署在不同地区下的计算节点上。以 Deployment 为例,如下图所示,传统的做法是先将雷同地区的计算节点设置成雷同的标签,而后创立多个 Deployment,不同 Deployment 通过 NodeSelectors 选定不同的标签,从而实现将雷同的利用部署到不同地区的需要。
然而随着地区散布越来越多,使得运维变得越来越简单,具体表现在以下几个方面:
- 当镜像版本升级,须要批改大量相干的 Deployment 的镜像版本配置。
- 须要自定义 Deployment 的命名标准来表明雷同的利用。
- 短少一个更高的视角对这些 Deployment 进行对立治理和运维。运维的复杂性随着利用和地区散布增多呈现线性增长。
基于以上需要和问题,openyurt 的 yurt-app-manager 组件提供的单元化部署(UnitedDeployment)通过更上档次的形象,对这些子的 Deployment 进行对立治理:主动创立 / 更新 / 删除,从而大幅简化了运维复杂度的问题。
yurt-app-manager 组件:
https://github.com/openyurtio/yurt-app-manager
如下图所示:
单元化部署(UnitedDeployment)对这些 Workload 进行了更高层次的形象,UnitedDeployment 蕴含两个次要配置:WorkloadTemplate 和 Pools。workloadTemplate 格局能够是Deployment 也能够是Statefulset。Pools 是一个列表,每个列表都有一个 Pool 的配置,每个 Pool 都有它的 name、replicas 和 nodeSelector 配置。通过 nodeSelector 能够抉择一组机器,因而在边缘场景下 Pool 咱们能够简略的认为它代表了某个地区下的一组机器。应用WorkloadTemplate + Pools 的定义,咱们能够很容易的将一个 Deployment 或者 Statefulset 利用散发到不同的地区中去。
上面是一个具体的 UnitedDeployment 例子:
apiVersion: apps.openyurt.io/v1alpha1
kind: UnitedDeployment
metadata:
name: test
namespace: default
spec:
selector:
matchLabels:
app: test
workloadTemplate:
deploymentTemplate:
metadata:
labels:
app: test
spec:
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- image: nginx:1.18.0
imagePullPolicy: Always
name: nginx
topology:
pools:
- name: beijing
nodeSelectorTerm:
matchExpressions:
- key: apps.openyurt.io/nodepool
operator: In
values:
- beijing
replicas: 1
- name: hangzhou
nodeSelectorTerm:
matchExpressions:
- key: apps.openyurt.io/nodepool
operator: In
values:
- hangzhou
replicas: 2
UnitedDeployment 控制器的具体逻辑如下:
用户定义了一个 UnitedDeployment CR , CR 里定义了一个 DeploymentTemplate 和两个 Pool。
- 其中 DeploymentTemplate 格局为一个 Deployment 格局定义,本例子中应用的 Image 为 nginx:1.18.0。
- Pool1 的 name 为 beijing, replicas=1,nodeSelector 为 apps.openyurt.io/nodepool=beijing。代表 UnitedDeployment 控制器将要创立一个子的 Deployment,replicas 为 1,nodeSelector 为 apps.openyurt.io/nodepool=beijing,其余的配置继承自 DeploymentTemplate 配置。
- Pool2 的 name 为 hangzhou,replicas=2, nodeSelector 为 apps.openyurt.io/nodepool=hangzhou,代表 UnitedDeployment 控制器将要创立一个子的 Deployment,replicas 为 2,nodeSelector 为 apps.openyurt.io/nodepool=hangzhou,其余的配置继承自 DeploymentTemplate 配置。
UnitedDeployment 控制器检测到 name 为 test 的 UnitedDeployment CR 实例被创立后,会首先依据 DeploymentTemplate 里的配置生成一个 Deployment 的模板对象,依据 Pool1 和 Pool2 的配置和 Deployment 的模板对象,别离生成 name 前缀为 test-hangzhou- 和 test-beijing- 的两个 deployment 资源对象,这两个 Deployment 资源对象有本人的 nodeselector 和 replica 配置。这样通过应用 workloadTemplate+Pools 的模式,能够将 workload 散发到不同的地区,而无需用户保护大量的 Deployment 资源。
UnitedDeployment 所解决的问题
UnitedDeployment 通过一个单元化部署实例就能够主动保护多个 Deployment 或者 Statefulset 资源,每个 Deployment 或者 Statefulset 资源都遵循对立的命名标准。同时还能实现 Name、NodeSelectors 和 Replicas 等的差异化配置。能极大地简化用户在边缘场景下的运维复杂度。
新的需要
UnitedDeployment 能满足用户的大部分需要,然而在咱们进行推广和客户落地以及在与社区同学探讨的过程中,逐步发现在一些非凡场景下,UnitedDeployment 提供的性能还显得有点有余,例如如下场景:
- 利用镜像降级时候,用户打算先在在某个节点池中做验证,如果验证胜利,再在所有节点池中全量更新公布。
- 为了放慢镜像拉取速度,用户可能在不同节点池中搭建本人的公有镜像仓库,因而同一个利用在每个节点池下的镜像名会不一样。
- 不同的节点池下服务器数量,规格,以及业务拜访压力不统一,因而同一个利用在不同节点池下 pod 的 cpu,内存等配置会不一样。
- 同一个利用在不同节点池下可能会应用不同的 configmap 资源。
这些需要促使了 UnitedDeployment 须要提供针对每个 Pool 做一些个性化配置的性能,容许用户依据不同节点池下的理论状况做一些个性化的配置,比方镜像、pod 的 request 和 limit 等等。为了最大化的提供灵活性,通过探讨咱们决定在 Pool 里减少 Patch 的字段,容许用户自定义 Patch 内容,然而须要遵循 Kubernetes 的 strategic merge patch 标准,其行为与咱们罕用的 kubectl patch 有点相似。
pool 里新增 patch,示例如下:
pools:
- name: beijing
nodeSelectorTerm:
matchExpressions:
- key: apps.openyurt.io/nodepool
operator: In
values:
- beijing
replicas: 1
patch:
spec:
template:
spec:
containers:
- image: nginx:1.19.3
name: nginx
patch 里定义的内容,须要遵循 Kubernetes 的 strategic merge patch 标准,如果用过 kubectl patch 的同学就很容易的晓得 patch 内容如何书写,具体能够参照应用 kubectl patch 更新 Kubernetest api 对象。
接下来咱们演示一下 UnitedDeployment patch 的应用。
个性演示
1. 环境筹备
- 提供一个 K8s 集群或者 OpenYurt 集群,集群里至多 2 台节点。一台节点 label 为:apps.openyurt.io/nodepool=beiing, 另一台节点 label 为:apps.openyurt.io/nodepool=hangzhou。
- 集群里须要装置 yurt-app-manager 组件。
yurt-app-manager 组件:
https://github.com/openyurtio/yurt-app-manager
2. 创立 UnitedDeployment 实例
cat <<EOF | kubectl apply -f -
apiVersion: apps.openyurt.io/v1alpha1
kind: UnitedDeployment
metadata:
name: test
namespace: default
spec:
selector:
matchLabels:
app: test
workloadTemplate:
deploymentTemplate:
metadata:
labels:
app: test
spec:
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- image: nginx:1.18.0
imagePullPolicy: Always
name: nginx
topology:
pools:
- name: beijing
nodeSelectorTerm:
matchExpressions:
- key: apps.openyurt.io/nodepool
operator: In
values:
- beijing
replicas: 1
- name: hangzhou
nodeSelectorTerm:
matchExpressions:
- key: apps.openyurt.io/nodepool
operator: In
values:
- hangzhou
replicas: 2
EOF
实例中 workloadTemplate 应用了 Deployment 模板,其中 name 为 nginx 的镜像为 nginx:1.18.0。同时拓扑里定义了两个 pool:beijing 和 hangzhou,replicas 数目别离为 1 和 2。
3. 查看 UnitedDeployment 创立的 Deployment
# kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
test-beijing-rk8g8 1/1 1 1 6m4s
test-hangzhou-kfhvj 2/2 2 2 6m4s
能够看到 yurt-app-manager 控制器创立了两个 Deployment,散布对应 beijing 和 hangzhou 的 pool,Deployment 的命名标准以 {UnitedDeployment name}-{pool name} 为前缀。查看这两个 Deployment 配置咱们能够发现,Replicas 和 Nodeselector 继承了对应的每个 Pool 的配置,而其余的配置则继承了 workloadTemplate 模板的配置。
4. 查看对应创立的 Pod
# kubectl get pod
NAME READY STATUS RESTARTS AGE
test-beijing-rk8g8-5df688fbc5-ssffj 1/1 Running 0 3m36s
test-hangzhou-kfhvj-86d7c64899-2fqdj 1/1 Running 0 3m36s
test-hangzhou-kfhvj-86d7c64899-8vxqk 1/1 Running 0 3m36s
能够看到创立了 1 个 name 前缀为 test-beijing 的 pod,2 个 name 前缀为 test-hangzhou 的 pod。
5. 应用 patch 能力做差异化配置
应用 kubectl edit ud test 命令为 beijing 的 pool 减少 patch 字段,patch 里的内容是批改 name 为 nginx 的 container 镜像版本为:nginx:1.19.3。
格局如下:
- name: beijing
nodeSelectorTerm:
matchExpressions:
- key: apps.openyurt.io/nodepool
operator: In
values:
- beijing
replicas: 1
patch:
spec:
template:
spec:
containers:
- image: nginx:1.19.3
name: nginx
6. 查看 Deploy 实例配置
从新查看前缀为 test-beijing 的 Deployment,能够看到 container 的镜像配置曾经变成了 1.19.3。
kubectl get deployments test-beijing-rk8g8 -o yaml
总结
通过 UnitedDeployment 的 workloadTemplate + Pools 的模式,能够将 workload 通过继承的模板的形式疾速散发到不同的地区。在加上 Pool 的 patch 能力,在继承模板的配置的同时还能提供更灵便的差异化配置,基本上曾经能够满足大部分客户在边缘场景下非凡的需要。
如果您对于 OpenYurt 有任何疑难,欢送应用钉钉搜寻群号(31993519)退出钉钉交换群。