惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CXSECURITY Database RSS Feed - CXSecurity.com
V
Visual Studio Blog
aimingoo的专栏
aimingoo的专栏
博客园_首页
C
Check Point Blog
T
Threatpost
SecWiki News
SecWiki News
宝玉的分享
宝玉的分享
AWS News Blog
AWS News Blog
博客园 - 三生石上(FineUI控件)
Scott Helme
Scott Helme
The Register - Security
The Register - Security
Cyberwarzone
Cyberwarzone
C
Cyber Attacks, Cyber Crime and Cyber Security
Know Your Adversary
Know Your Adversary
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
P
Proofpoint News Feed
I
InfoQ
WordPress大学
WordPress大学
A
Arctic Wolf
T
Threat Research - Cisco Blogs
大猫的无限游戏
大猫的无限游戏
J
Java Code Geeks
A
About on SuperTechFans
P
Palo Alto Networks Blog
博客园 - Franky
I
Intezer
T
Tenable Blog
S
Secure Thoughts
Project Zero
Project Zero
S
Securelist
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
H
Heimdal Security Blog
Google Online Security Blog
Google Online Security Blog
The Cloudflare Blog
云风的 BLOG
云风的 BLOG
Security Latest
Security Latest
M
MIT News - Artificial intelligence
Martin Fowler
Martin Fowler
H
Hackread – Cybersecurity News, Data Breaches, AI and More
B
Blog
MongoDB | Blog
MongoDB | Blog
Forbes - Security
Forbes - Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
MyScale Blog
MyScale Blog
The Last Watchdog
The Last Watchdog
F
Fortinet All Blogs
雷峰网
雷峰网
V2EX - 技术
V2EX - 技术

陈少文的网站

巨变与机遇的未来十年 Kubernetes 平台管理软件压力测试方案 使用镜像部署 Hexo 静态页面 终于等到你 - GitHub 镜像仓库服务(ghcr.io) 一起来学 Go --(6)Interface 一起来学 Go --(5)Goroutine 和 Channel 什么是函数式编程 如何在 Kubernetes 集群集成 Kata 柯里化与偏函数 使用 PyGithub 自动创建 Label 软件产品是团队能力的输出 Helm 2 、Helm 3 比较 IoT 变现 Kubernetes 中的 DNS 服务 国内的 Helm 镜像源 Harbor 使用自签证书支持 Https 访问 DevOps 工具链之 Prow 如何使用 kfctl 安装 Kubeflow VS Code 无法下载 Go 插件的工具包 工程师更应具有服务精神 你不知道的 Docker 使用技巧 使用 Docker 运行 Tensorflow 论中国 什么是左移 如何清空 Git 仓库全部历史记录 一禅小和尚 有风吹过厨房 时间的玫瑰 如何在 CentOS 安装 GPU 驱动 开发 Tips(19) 使用 Velero 备份 Kubernetes 集群 Kubernetes Cheat Sheet 开发 Tips(18) 如何构建一个 Java 工程 开发 Tips(17) KubeSpray 安装 Kubernetes 报错 ip in ansible_all_ipv4_addresses 基于 Kubernetes 和 Jenkins 搭建自动化测试系统 在 Kubernetes 上动态创建 Jenkins Slave 使用 Jenkins 进行服务拨测 开发 Tips(16) Kubernetes 签发 Ingress 证书及日常故障运维 Kubernetes 中 Deployment 的基本操作 Kubernetes 中的证书 如何使用 KubeBuilder 开发一个 Operator Kubernetes 1.6.0 安装问题汇总 镜像管理工具 -- Harbor 开发 Tips(15) Docker 如何拉取镜像 开发 Tips(14) 使用 Helm 安装 harbor 开发 Tips(13) 使用 S2I 构建云原生应用 在 Kubernetes 中使用 emptyDir、hostPath、localVolume 开发 Tips(12) 开发 Tips(11) 代码质量分析工具 SonarQube 使用 Kubeadm 安装 Kubernetes 集群 一起来学 Go --(4)常用函数 Kubernetes 中的 Ceph Kubernetes 之 Volumes Kubernetes 之 Labels、Selectors 开发 Tips(10) 开源正在重构商业模式 Kubernetes 之网络 Kubernetes 之 API 使用 Helm 和 Operator 快速部署 Prometheus Kubernetes 复杂有状态应用管理框架 -- Operator Kubernetes 的包管理器 -- Helm 一起来学 Go --(3)Go Modules 如何一步一步地优化博客方案 kubectl 实用指南 Kubernetes 中的基本概念 搭建远程 Kubernetes 开发环境 大公司和小公司的 ToB 思路 开发 Tips(9) Go 入门指南 一起来学 Go --(2)数据与逻辑结构 如何预防 Web 富文本中的 XSS 攻击 django-xss-cleaner 云工作时代 一起来学 Go --(1)背景与特点 SaaS 开发团队的不同阶段 你不知道的 Git 使用技巧 输出既服务 微服务设计 继续奔跑 开发 Tips(8) 从账户安全到二次验证 Django 性能之数据库查询优化 Django 性能之分库分表 敏捷开发之研发流程 打造一致性的团队 开发 Tips(7) Pytest 进阶学习之 Mock PaaS 部署之 buildpack Go 开发配置 领域输出才是 PaaS 的核心竞争力 Pytest 入门学习 开发 Tips(6) 如何使用 Jenkins、Docker、GitLab 搭建 Django 自动化部署流程
Kubevela 下的多集群应用
微信公众号 · 2021-09-17 · via 陈少文的网站

Kubevela 目前处于 1.1 版本。通常,我们认为 1.x 的版本是相对稳定的,可以尝试引入生产。在不断地跟踪和学习过程中,也感受到 Kubevela 的一些好的地方,这是一篇小结性的文档。

1. Kubevela 能解决什么问题

  • 面向平台开发者

需要区分几个角色: 开发、运维、运维开发。开发面向的是业务需求,运维面向的是业务稳定,运维开发面向的是效率。运维开发提供各种各样的工具,打通开发和运维之间的壁垒,既要快速满足业务上线。又要保障业务稳定。

Kubevela 对开发和运维并没有太大吸引力,却能让运维开发耳目一新。因为,Kubevela 能显著提升团队的平台水平,直达主流梯队。

  • 应用生命周期的管理

Kubevela 提供了管理应用生命周期的解决方案,应用的定义 applications,部署 appdeployments ,版本管理 applicationrevisions,回滚 approllouts,灰度 traits、approllouts。利用这些 CRD 对象,能够覆盖很大一部分业务需求。

  • 应用负载和特性的组件化

Component 提供的是负载的定义,比如 Deployment、CloneSet。Trait 提供的是特征的定义,比如 Ingress、Istio。通过这两种抽象,Kubevela 允许平台的开发者能够组装、定制适合自己业务的平台。

而 Workflow 提供的编排能力,给集成各种云原生组件增添了更多可能,甚至能延展到 CICD 领域。

2. 多集群下应用面临的挑战

  • 统一的视角

在面向应用的平台上,切换集群是一个非常糟糕的用户体验。我们需要的不是在每个集群上部署一套管理服务,然后通过修改数据源,查看不同集群上的数据。

我们应该以应用为中心,集群只是应用的一个属性,而不能将应用归属于某个集群。统一视角就是希望能够提供给用户一个 UI,包含完整的应用描述、所在运行时、实时服务画像等信息。

  • 应用的定义

世界上,没有两个平台团队对应用的定义是一样的。

一个应用应该包含哪些属性,哪些特征,对哪些字段进行哪些限制,很多的细节需要推敲和考虑。当然你也可以选择背负技术债务,将问题延后解决,快速交付几个版本。但却也是道阻且长,越来越难。

每个团队在定义应用时,都会附带一些业务属性。自救是不可能的,繁杂的业务需求不会给平台的开发者喘息之机。

因此,OAM 的出现是个机会,有机会统一应用生命周期管理 (ALM)。虽前有 Kubernetes Applications 死在了沙滩,但 Kubevela 犹如黑夜星光,给人无限希望。

  • 分批发布

分批发布有两个维度,单个集群中的多副本应用,多个集群中的同一个应用。

单个集群上的多副本,不会一次性更新,而是需要分批发布。这个过程,称之为 rollout,是一个逐步放量的过程。

多个集群或者多个区域的服务,在更新时,也需要观察时间,而不能一把就 show hand。

3. AppDeployment 下的多集群应用

这里主要是以 AppDeployment 作为主要对象,将应用在多个集群上进行发布。

  • 在主集群上添加多个子集群

需要在同一个 kubeconfig 配置多个集群的 context,然后按照官方文档操作即可。这里添加了两个集群 prod-cluster-1 和 prod-cluster-2 。下面是查看集群的命令:

1
2
3
4
5
kubectl get clusters.core.oam.dev

NAME             AGE
prod-cluster-1   57d
prod-cluster-2   57d
  • 定义 Application 应用

需要提前定义 components 和 traits,下面是应用的定义:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: cluster-test-app-cloneset
  namespace: default
  annotations:
    app.oam.dev/revision-only: "true"
spec:
  components:
    - name: helloworld-cloneset
      type: cloneset
      properties:
        image: oamdev/helloworld-python:v1
        env:
          - name: "TARGET"
            value: "KubeVela-v1"
        port: 8080
      traits:
        - type: expose-nodeport
          properties:
            ports:
              - protocol: "TCP"
                port: 80

由于有 app.oam.dev/revision-only: "true" 的 Annotations,因此相关的资源并不会被创建。我们在此只是定义应用,并不需要创建相应的负载。

  • 修改应用的版本,产生不同的应用版本

为了更加逼近生产环境,我们修改上面 Application 的参数,比如:环境变量、镜像版本等,产生不同的应用版本。

1
2
3
4
5
6
kubectl get applicationrevisions.core.oam.dev

NAME                  AGE
cluster-test-app-v1   57d
cluster-test-app-v2   57d
cluster-test-app-v3   57d

最终,分发到各个集群上的应用版本,由此产生。这些版本,大致相同而有细微差异,类似日常应用更新。

  • AppDeployment 多集群分发应用

AppDeployment 提供了一个更加贴近用户对应用理解的视角。应用不仅包含的是对应用的定义,还有对运行时的选择。这里将 cluster-test-app-v1 部署到 prod-cluster-1 集群,设置 3 个副本数量;而将 cluster-test-app-v2 部署到 prod-cluster-2 集群,设置 4 个副本数量。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: core.oam.dev/v1beta1
kind: AppDeployment
metadata:
  name: cross-cluster-app
  namespace: default
spec:
  appRevisions:
    - revisionName: cluster-test-app-v1
      placement:
        - clusterSelector:
            labels:
              env: stage
            name: prod-cluster-1
          distribution:
            replicas: 3

    - revisionName: cluster-test-app-v2
      placement:
        - clusterSelector:
            labels:
              env: production
            name: prod-cluster-2
          distribution:
            replicas: 4

4 Workflow 下的多集群应用

Workflow 是 Kubevela 近期版本新增的一个特性,在这里主要用来生成 OCM 需要的跨集群资源对象。

4.1 配置 Open Cluster Management (OCM)

  • 使用 vela 命令安装 Open Cluster Management
1
vela addon enable ocm-cluster-manager
  • 在主集群上添加多个子集群

需要在同一个 kubeconfig 配置多个集群的 context。在 dev1 集群上,添加 dev2 集群的 kubeconfig。

1
2
3
4
5
kubectl config get-contexts

CURRENT   NAME           CLUSTER              AUTHINFO                NAMESPACE
*         dev1-context   dev1.cluster.local   dev1-kubernetes-admin
          dev2-context   dev2.cluster.local   dev2-kubernetes-admin
  • 配置环境变量

使用 dev1(主集群) 管理 dev2(子集群) 。在主集群上,执行命令:

1
2
3
4
export HUB_CLUSTER_NAME=dev1
export MANAGED_CLUSTER_NAME=dev2
export CTX_HUB_CLUSTER=dev1-context
export CTX_MANAGED_CLUSTER=dev2-context
  • 查找添加子集群的 Token

在主集群上,执行命令:

1
2
3
clusteradm get token

xxxxxxxxxxxxxx

取出其中的 token 值,Base64 反解码,可以得到一个有效的 hub-token 值。

  • 添加子集群

这里的 hub-apiserver 就是主集群的 kube-apiserver 的访问地址。在主集群上,执行命令:

1
clusteradm join --context ${CTX_MANAGED_CLUSTER} --hub-token xxxxxxxxxxxxxx --hub-apiserver https://1.1.1.1:6443 --cluster-name ${MANAGED_CLUSTER_NAME}
  • 接受新的集群添加请求

在主集群上,执行命令:

1
clusteradm accept --clusters dev2
  • 查看被管理的集群

在主集群上,执行命令:

1
2
3
4
kubectl get managedcluster

NAME   HUB ACCEPTED   MANAGED CLUSTER URLS                JOINED   AVAILABLE   AGE
dev2   true           https://dev1.chenshaowen.com:6443   True     True        3m38s
  • 在被管理的集群上安装 Kubevela rollout

在子集群上,执行命令:

helm repo add kubevela https://charts.kubevela.net/core
helm install vela-rollout  --create-namespace -n vela-system kubevela/vela-rollout

4.2 新建 WorkflowStepDefinition 描述跨集群资源

在主集群使用 Workflow 将跨集群的资源定义在 WorkflowStepDefinition 中。下面是需要用到的资源之一:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
apiVersion: core.oam.dev/v1beta1
kind: WorkflowStepDefinition
metadata:
  name: dispatch-traits
  namespace: vela-system
spec:
  schematic:
    cue:
      template: |
        import ("vela/op")

        comp: op.#Load & {
           component: parameter.component
        }

        apply: op.#Apply & {
            value: {
                apiVersion: "work.open-cluster-management.io/v1"
                kind: "ManifestWork"
                metadata: {
                   namespace: parameter.cluster
                   name: parameter.component + "-traits"
                }
                spec: {
                   workload: manifests : comp.value.auxiliaries
                }
            }
        }


        parameter: {
          component: string
          cluster: string
        }        

其中 ManifestWork 定义了分发到某个集群的配置和资源信息。这里只定义了 dispatch-traits,相应的我们还需要定义 dispatch-comp-rev。

分发资源的过程可以理解为,将待分发的资源打包成主集群上的 ManifestWork 对象,通过 OCM 分发到子集群的 AppliedManifestworks 对象,然后由子集群提取资源进行创建。

4.3 创建应用进行分发

这里使用 Application 在主集群 dev1 上定义一个应用,分发到子集群 dev2 上。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: workflow-rollout-demo
  namespace: default
spec:
  components:
    - name: nginx-server
      externalRevision: nginx-server-v1
      type: webservice
      properties:
        image: nginx:1.20.0
        port: 80
      traits:
        - type: rollout
          properties:
            targetRevision: nginx-server-v1
            targetSize: 2
            rolloutBatches:
              - replicas: 1
              - replicas: 1

  workflow:
    steps:
      - name: dispatch-comp-rev-v1
        type: dispatch-comp-rev
        properties:
          compRev: nginx-server-v1
          cluster: dev2

      - name: dispatchRollout
        type: dispatch-traits
        properties:
          component: nginx-server
          cluster: dev2

在 OCM 多集群应用的场景下,子集群需要部署 Kubevela rollout 组件。因此,Kubevela 能够更精细地控制子集群 rollout 过程,比如滚动过程中每个批次的比例和数量等。

4.4 可能会碰到的问题

  • OCM 在子集群创建资源时报错
E0905 14:36:23.461052       1 base_controller.go:270] "ManifestWorkAgent" controller failed to sync "nginx-server-traits", err: rollouts.standard.oam.dev "nginx-server" is forbidden: User "system:serviceaccount:open-cluster-management-agent:klusterlet-work-sa" cannot get resource "rollouts" in API group "standard.oam.dev" in the namespace "default"

提示是权限不够,在子集群上,直接给 klusterlet-work-sa 绑定了一个 admin 权限。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: admin-ocm
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
subjects:
  - kind: ServiceAccount
    name: klusterlet-work-sa
    namespace: open-cluster-management-agent

5. 总结

本篇主要讨论的是 Kubevela 在多集群下的应用,主要内容如下:

  • 多集群下的应用,不同于单集群,不能简单地切换数据源实现,其对交互设计有更高的要求。多集群应用平台需要有统一的视角,查看应用在多集群下的服务画像,以应用为中心,将集群当做属性,分清主次。
  • AppDeployment 是一个很好的抽象,也能给平台设计一些启发,还能看到一些 KubeFed 的身影。AppDeployment 是以用户视角呈现的多集群应用,但目前对 Workload 的处理粒度太大,面向的是整个 Application,也就是全量删除、更新、创建 Workload。如果用于生产,还需要配合 rollout 进行更新。
  • 借助 Workflow 集成 OCM 下的 Kubevela 多集群应用,更具扩展性,后续也可以换成其他多集群组件,比如 Karmada。利用 OCM 的分发能力,加上子集群上的 Kubevela rollout 组件,我们可以实现分批发布、滚动更新。

实际上,多集群下的应用,不仅仅需要考虑的是对应用描述的分发,更重要的还有负载的滚动更新、资源的统一分配、应用的智能调度、应用的自动扩缩容、服务的状态画像等。Kubevela 针对的是看得见的应用,但支撑起整个应用平台还需要更多底层组件。

6. 参考