乐趣区

关于kubernetes:基于-KubeVela-的-GitOps-交付

作者|董天欣(雾雾)
审核 & 校对:溪洋、海珠
编辑 & 排版:雯燕

KubeVela 是一个简略、易用、且高可扩大的云原生利用治理和交付平台,能让开发人员方便快捷地在 Kubernetes 上定义与交付古代微服务利用,无需理解任何 Kubernetes 基础设施相干的细节。

KubeVela 背地的 OAM 模型人造解决了利用构建过程中对简单资源的组合、编排等治理问题,同时也将前期的运维策略模型化,这意味着 KubeVela 能够联合 GitOps 治理简单大规模利用,收敛因为团队与零碎规模增长导致的零碎复杂度问题。

什么是 GitOps

它的核心思想是将利用零碎所需的基础架构和利用配置申明性形容寄存在 Git 仓库中,并配合一个自动化流程,使每次仓库被更新后,自动化过程都能逐步将环境更新到最新配置。

这样的形式容许开发人员通过间接更改 Git 仓库中的代码和配置来主动部署利用,应用 GitOps 的形式能够为利用研发带来诸多价值,例如:

• 进步生产效率。通过主动的继续部署可能放慢均匀部署工夫,减少开发效率。
• 升高开发人员部署的门槛。通过推送代码而非容器配置,开发人员能够不须要理解 Kubernetes 的外部实现,便能够轻易部署。
• 使变更记录可追踪。通过 Git 来治理集群,能够使每一次更改都可追踪,增强了审计跟踪。
• 可通过 Git 的回滚 / 分支性能来复原集群。

KubeVela 与 GitOps

KubeVela 作为一个申明式的利用交付管制立体,人造反对以 GitOps 的形式来应用,并使用户更显著地感触到由 GitOps 带来的好处,和端到端的利用交付与治理体验,包含:

• 利用交付工作流(CD 流水线):即:KubeVela 反对在 GitOps 模式中形容过程式的利用交付,而不只是简略的申明终态;
• 解决部署过程中的各种依赖关系和拓扑构造;
• 在现有各种 GitOps 工具的语义之上提供对立的下层形象,简化利用交付与治理过程;
• 对立进行云服务的申明、部署和服务绑定;
• 提供开箱即用的交付策略(金丝雀、蓝绿公布等);
• 提供开箱即用的混合云 / 多云部署策略(搁置规定、集群过滤规定等);
• 在多环境交付中提供 Kustomize 格调的 Patch 来形容部署差别,而无需学习任何 Kustomize 自身的细节;
• ……

在本文中,咱们次要解说间接应用 KubeVela 在 GitOps 模式下进行交付的步骤。

GitOps 工作流

GitOps 工作流分为 CI 和 CD 两个局部:

• CI(Continuous Integration):继续集成对业务利用进行代码构建、构建镜像并推送至镜像仓库。目前有许多成熟的 CI 工具,如开源我的项目罕用的 GitHub Action、Travis 等,以及企业中罕用的 Jenkins、Tekton 等。在本文中,咱们应用 GitHub Action 来实现 CI 这一步,当然你也能够应用别的 CI 工具来代替,KubeVela 围绕 GitOps 能够对接任意工具下的 CI 流程。
• CD(Continuous Delivery):继续部署会自动更新集群中的配置,如将镜像仓库中的最新镜像更新到集群中。目前次要有两种计划的 CD:
1)Push-Based:Push 模式的 CD 次要是通过配置 CI 流水线来实现的,这种形式须要将集群的拜访秘钥共享给 CI,从而使得 CI 流水线可能通过命令将更改推送到集群中,能够参考咱们之前发表的博客:应用 Jenkins + KubeVela 实现利用的继续交付(详见文末相干链接)。
2)Pull-Based:Pull 模式的 CD 会在集群中监听仓库(代码仓库或者配置仓库)的变动,并且将这些变动同步到集群中。与 Push 模式相比,Pull-Based 由集群被动拉取更新,从而防止了秘钥裸露的问题。这也是本文介绍的核心内容。

交付的面向人员有以下两种,咱们将别离介绍:

  1. 面向平台管理员 / 运维人员的基础设施交付,用户能够通过间接更新仓库中的配置文件,从而更新集群中的基础设施配置,如零碎的依赖软件、安全策略、存储、网络等基础设施配置。
  2. 面向终端开发者的交付,用户的代码一旦合并到利用代码仓库,就自动化触发集群中利用的更新,能够更高效的实现利用的迭代,与 KubeVela 的灰度公布、流量调拨、多集群部署等性能联合能够造成更为弱小的自动化公布能力。

面向平台管理员 / 运维人员的交付

如图所示,对于平台管理员 / 运维人员而言,他们并不需要关怀利用的代码,所以只须要筹备一个 Git 配置仓库并部署 KubeVela 配置文件,后续对于利用及基础设施的配置变动,便可通过间接更新 Git 配置仓库来实现,使得每一次配置变更可追踪。

筹备配置仓库

具体的配置可参考 示例仓库 1(详见文末相干链接)。

在本例中,咱们将部署一个 MySQL 数据库软件作为我的项目的基础设施,同时部署一个业务利用,应用这个数据库。配置仓库的目录构造如下:

• clusters/ 中蕴含集群中的 KubeVela GitOps 配置,用户须要将 clusters/ 中的文件手动部署到集群中。这个是一次性的管控操作,执行实现后,KubeVela 便能主动监听配置仓库中的文件变动且自动更新集群中的配置。其中,clusters/apps.yaml 将监听 apps/ 下所有利用的变动,clusters/infra.yaml 将监听 infrastructure/ 下所有基础设施的变动。
• apps/ 目录中蕴含业务利用的所有配置,在本例中为一个应用数据库的业务利用。
• infrastructure/ 中蕴含一些基础设施相干的配置和策略,在本例中为 MySQL 数据库。

├── apps
│   └── my-app.yaml
├── clusters
│   ├── apps.yaml
│   └── infra.yaml
└── infrastructure
    └── mysql.yaml

KubeVela 倡议应用如上的目录构造治理你的 GitOps 仓库。clusters/ 中寄存相干的 KubeVela GitOps 配置并须要被手动部署到集群中,apps/ 和 infrastructure/ 中别离寄存你的利用和基础设施配置。通过把利用和根底配置离开,可能更为正当的治理你的部署环境,隔离由利用变动带来的影响。

clusters/ 目录

首先,咱们来看下 clusters 目录,这也是 KubeVela 对接 GitOps 的初始化操作配置目录。

以 clusters/infra.yaml 为例:

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: infra
spec:
  components:
  - name: database-config
    type: kustomize
    properties:
      repoType: git
      # 将此处替换成你须要监听的 git 配置仓库地址
      url: https://github.com/FogDong/KubeVela-GitOps-Infra-Demo
      # 如果是公有仓库,还须要关联 git secret
      # secretRef: git-secret
      # 主动拉取配置的工夫距离,因为基础设施的变动性较小,此处设置为十分钟
      pullInterval: 10m
      git:
        # 监听变动的分支
        branch: main
      # 监听变动的门路,指向仓库中 infrastructure 目录下的文件
      path: ./infrastructure

apps.yaml 与 infra.yaml 简直保持一致,只不过监听的文件目录有所区别。在 apps.yaml 中,properties.path 的值将改为 ./apps,表明监听 apps/ 目录下的文件变动。

cluster 文件夹中的 GitOps 管控配置文件须要在初始化的时候一次性手动部署到集群中,在此之后 KubeVela 将主动监听 apps/ 以及 infrastructure/ 目录下的配置文件并定期更新同步。

apps/ 目录

apps/ 目录中寄存着利用配置文件,这是一个配置了数据库信息以及 Ingress 的简略利用。该利用将连贯到一个 MySQL 数据库,并简略地启动服务。在默认的服务门路下,会显示以后版本号。在 /db 门路下,会列出以后数据库中的信息。

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: my-app
  namespace: default
spec:
  components:
    - name: my-server
      type: webservice
      properties:
        image: ghcr.io/fogdong/test-fog:master-cba5605f-1632714412
        port: 8088
        env:
          - name: DB_HOST
            value: mysql-cluster-mysql.default.svc.cluster.local:3306
          - name: DB_PASSWORD
            valueFrom:
              secretKeyRef:
                name: mysql-secret
                key: ROOT_PASSWORD
      traits:
        - type: ingress
          properties:
            domain: testsvc.example.com
            http:
              /: 8088

这是一个应用了 KubeVela 内置组件类型 webservice 的利用,该利用绑定了 Ingress 运维特色。通过在利用中申明运维能力的形式,只需一个文件,便能将底层的 Deployment、Service、Ingress 集合起来,从而更为便捷地治理利用。

infrastructure/ 目录

infrastructure/ 目录下寄存一些基础设施的配置。此处咱们应用 mysql controller(详见文末相干链接)来部署了一个 MySQL 集群。

留神,请确保你的集群中有一个 secret,并通过 ROOT_PASSWORD 申明了 MySQL 明码。

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: mysql
  namespace: default
spec:
  components:
    - name: mysql-controller
      type: helm
      properties:
        repoType: helm
        url: https://presslabs.github.io/charts
        chart: mysql-operator
        version: "0.4.0"
    - name: mysql-cluster
      type: raw
      dependsOn:
        - mysql-controller
      properties:
        apiVersion: mysql.presslabs.org/v1alpha1
        kind: MysqlCluster
        metadata:
          name: mysql-cluster
        spec:
          replicas: 1
          # 关联 secret 名称
          secretName: mysql-secret

在这个 MySQL 利用中,咱们应用了 KubeVela 工作流的能力。工作流分为两个步骤,第一个步骤会去部署 MySQL 的 controller。当 controller 部署胜利且正确运行后,第二个步骤将开始部署 MySQL 集群。

部署 clusters/ 目录下的文件

配置完以上文件并存放到 Git 配置仓库后,咱们须要在集群中手动部署 clusters/ 目录下的 KubeVela GitOps 配置文件。

首先,在集群中部署 clusters/infra.yaml。能够看到它主动在集群中拉起了 infrastructure/ 目录下的 MySQL 部署文件:

kubectl apply -f clusters/infra.yaml
$ vela ls
APP     COMPONENT           TYPE        TRAITS  PHASE   HEALTHY STATUS  CREATED-TIME
infra   database-config     kustomize           running healthy         2021-09-26 20:48:09 +0800 CST
mysql   mysql-controller    helm                running healthy         2021-09-26 20:48:11 +0800 CST
└─      mysql-cluster       raw                 running healthy         2021-09-26 20:48:11 +0800 CST

接着,在集群中部署

clusters/apps.yaml,能够看到它主动拉起了 apps/ 目录下的利用部署文件:

kubectl apply -f clusters/apps.yaml
APP     COMPONENT           TYPE        TRAITS  PHASE   HEALTHY STATUS  CREATED-TIME
apps    apps                kustomize           running healthy         2021-09-27 16:55:53 +0800 CST
infra   database-config     kustomize           running healthy         2021-09-26 20:48:09 +0800 CST
my-app  my-server           webservice  ingress running healthy         2021-09-27 16:55:55 +0800 CST
mysql   mysql-controller    helm                running healthy         2021-09-26 20:48:11 +0800 CST
└─      mysql-cluster       raw                 running healthy         2021-09-26 20:48:11 +0800 CST

至此,咱们通过部署 KubeVela GitOps 配置文件,主动在集群中拉起了利用及数据库。

通过 curl 利用的 Ingress,能够看到目前的版本是 0.1.5,并且胜利地连贯到了数据库:

$ kubectl get ingress
NAME        CLASS    HOSTS                 ADDRESS         PORTS   AGE
my-server   <none>   testsvc.example.com   <ingress-ip>    80      162m
$ curl -H "Host:testsvc.example.com" http://<ingress-ip>
Version: 0.1.5
$ curl -H "Host:testsvc.example.com" http://<ingress-ip>/db
User: KubeVela
Description: It's a test user

批改配置

实现了首次部署后,咱们能够通过批改配置仓库中的配置,来实现集群中利用的配置更新。

批改利用 Ingress 的 Domain:

...
      traits:
        - type: ingress
          properties:
            domain: kubevela.example.com
            http:
              /: 8089

通过一段时间后,从新查看集群中的 Ingress:

NAME        CLASS    HOSTS                 ADDRESS         PORTS   AGE
my-server   <none>   kubevela.example.com  <ingress-ip>    80      162m

能够看到,Ingress 的 Host 地址已被胜利更新。

通过这种形式,咱们能够不便地通过更新 Git 配置仓库中的文件,从而自动化更新集群中的配置。

面向终端开发者的交付

对于终端开发者而言,在 KubeVela Git 配置仓库以外,还须要筹备一个利用代码仓库。如图所示,在用户更新了利用代码仓库中的代码后,须要配置一个 CI 来主动构建镜像并推送至镜像仓库中。KubeVela 会监听镜像仓库中的最新镜像,并自动更新配置仓库中的镜像配置,最初再更新集群中的利用配置。使用户能够达成在更新代码后,集群中的配置也自动更新的成果。

筹备代码仓库

筹备一个代码仓库,外面蕴含一些源代码以及对应的 Dockerfile。

这些代码将连贯到一个 MySQL 数据库,并简略地启动服务。在默认的服务门路下,会显示以后版本号。在 /db 门路下,会列出以后数据库中的信息。

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {_, _ = fmt.Fprintf(w, "Version: %s\n", VERSION)
    })
    http.HandleFunc("/db", func(w http.ResponseWriter, r *http.Request) {rows, err := db.Query("select * from userinfo;")
        if err != nil {_, _ = fmt.Fprintf(w, "Error: %v\n", err)
        }
        for rows.Next() {
            var username string
            var desc string
            err = rows.Scan(&username, &desc)
            if err != nil {_, _ = fmt.Fprintf(w, "Scan Error: %v\n", err)
            }
            _, _ = fmt.Fprintf(w, "User: %s \nDescription: %s\n\n", username, desc)
        }
    })
    if err := http.ListenAndServe(":8088", nil); err != nil {panic(err.Error())
    }

咱们心愿用户改变代码进行提交后,主动构建出最新的镜像并推送到镜像仓库。这一步 CI 能够通过集成 GitHub Actions、Jenkins 或者其余 CI 工具来实现。在本例中,咱们通过借助 GitHub Actions 来实现继续集成。具体的代码文件及配置可参考 示例仓库 2(详见文末相干链接)。

配置秘钥信息

在新的镜像推送到镜像仓库后,KubeVela 会辨认到新的镜像,并更新仓库及集群中的 Application 配置文件。因而,咱们须要一个含有 Git 信息的 Secret,使 KubeVela 向 Git 仓库进行提交。部署如下文件,将其中的用户名和明码替换成你的 Git 用户名及明码(或 Token):

apiVersion: v1
kind: Secret
metadata:
  name: git-secret
type: kubernetes.io/basic-auth
stringData:
  username: <your username>
  password: <your password>

筹备配置仓库

配置仓库与之前面向运维人员的配置大同小异,只须要加上与镜像仓库相干的配置即可。具体配置请参考 示例仓库 1(详见文末相干链接)。

批改 clusters/ 中的 apps.yaml,该 GitOps 配置会监听仓库中 apps/ 下的利用文件变动以及镜像仓库中的镜像更新:

...
  imageRepository:
    # 镜像地址
    image: <your image>
    # 如果这是一个公有的镜像仓库,能够通过 `kubectl create secret docker-registry` 创立对应的镜像秘钥并相关联
    # secretRef: imagesecret
    filterTags:
      # 可对镜像 tag 进行过滤
      pattern: '^master-[a-f0-9]+-(?P<ts>[0-9]+)'
      extract: '$ts'
    # 通过 policy 筛选出最新的镜像 Tag 并用于更新
    policy:
      numerical:
        order: asc
    # 追加提交信息
    commitMessage: "Image: {{range .Updated.Images}}{{println .}}{{end}}"

批改 apps/my-app.yaml 中的 image 字段,在前面加上 # {“$imagepolicy”: “default:apps”} 的正文。KubeVela 会通过该正文去更新对应的镜像字段。default:apps 是下面 GitOps 配置对应的命名空间和名称。

spec:
  components:
    - name: my-server
      type: webservice
      properties:
        image: ghcr.io/fogdong/test-fog:master-cba5605f-1632714412 # {"$imagepolicy": "default:apps"}

将 clusters/ 中蕴含镜像仓库配置的文件更新到集群中后,咱们便能够通过批改代码来实现利用的更新。

批改代码

将代码文件中的 Version 改为 0.1.6,并批改数据库中的数据:

const VERSION = "0.1.6"
...
func InsertInitData(db *sql.DB) {stmt, err := db.Prepare(insertInitData)
    if err != nil {panic(err)
    }
    defer stmt.Close()
    _, err = stmt.Exec("KubeVela2", "It's another test user")
    if err != nil {panic(err)
    }
}

提交该改变至代码仓库,能够看到,咱们配置的 CI 流水线开始构建镜像并推送至镜像仓库。

而 KubeVela 会通过监听镜像仓库,依据最新的镜像 Tag 来更新配置仓库中 apps/ 下的利用 my-app。

此时,能够看到配置仓库中有一条来自 kubevelabot 的提交,提交信息均带有 Update image automatically. 前缀。你也能够通过 {{range .Updated.Images}}{{println .}}{{end}} 在 commitMessage 字段中追加你所须要的信息。

值得注意的是,如果你心愿将代码和配置放在同一个仓库,须要过滤掉来自 kubevelabot 的提交来避免流水线的反复构建。能够在 CI 中通过如下配置过滤:

jobs:
publish:
  if: "!contains(github.event.head_commit.message,'Update image automatically')"

从新查看集群中的利用,能够看到通过一段时间后,利用 my-app 的镜像曾经被更新。

KubeVela 会通过你配置的 interval 工夫距离,来每隔一段时间别离从配置仓库及镜像仓库中获取最新信息:

• 当 Git 仓库中的配置文件被更新时,KubeVela 将依据最新的配置更新集群中的利用。
• 当镜像仓库中多了新的 Tag 时,KubeVela 将依据你配置的 policy 规定,筛选出最新的镜像 Tag,并更新到 Git 仓库中。而当代码仓库中的文件被更新后,KubeVela 将反复第一步,更新集群中的文件,从而达到了主动部署的成果。

通过 curl 对应的 Ingress 查看以后版本和数据库信息:

$ kubectl get ingress
NAME        CLASS    HOSTS                 ADDRESS         PORTS   AGE
my-server   <none>   kubevela.example.com  <ingress-ip>    80      162m
$ curl -H "Host:kubevela.example.com" http://<ingress-ip>
Version: 0.1.6
$ curl -H "Host:kubevela.example.com" http://<ingress-ip>/db
User: KubeVela
Description: It's a test user
User: KubeVela2
Description: It's another test user

版本已被胜利更新!至此,咱们实现了从变更代码,到主动部署至集群的全副操作。

总结

在运维侧,如若须要更新基础设施(如数据库)的配置,或是利用的配置项,只须要批改配置仓库中的文件,KubeVela 将主动把配置同步到集群中,简化了部署流程。

在研发侧,用户批改代码仓库中的代码后,KubeVela 将自动更新配置仓库中的镜像。从而进行利用的版本更新。

通过与 GitOps 的联合,KubeVela 减速了利用从开发到部署的整个流程。

戳原文,查看 KubeVela 我的项目官方主页与文档!!

相干链接
1)应用 Jenkins + KubeVela 实现利用的继续交付:
https://kubevela.io/zh/blog/2…
2)示例仓库 1:
https://github.com/oam-dev/sa…
3)mysql controller:
https://github.com/bitpoke/my…
4)示例仓库 2:
https://github.com/oam-dev/sa…

理解更多相干信息,请钉钉扫描下方二维码或搜寻钉钉群号(35922870)退出阿里云原生资讯交换群!获取更多相干资讯!

退出移动版