Fix: optimize gitops doc (#308)
* Fix: optimize gitops doc * Docs: modify the doc * resolve the comments * Optimize the EN ver
|
|
@ -22,28 +22,99 @@ KubeVela as an declarative application delivery control plane can be naturally u
|
|||
|
||||
In this section, we will introduce steps of using KubeVela directly in GitOps approach.
|
||||
|
||||
This article will separate into two perspectives:
|
||||
|
||||
1. For platform administrators/SREs, they can update the config in Git repo. It will trigger automated re-deployment.
|
||||
|
||||
2. For developers, they can update the app source code and then push it to Git. It will trigger building latest image and re-deployment.
|
||||
|
||||
> Note: you can also use it with existing tools such as ArgoCD with similar steps, detailed guides will be added in following releases.
|
||||
|
||||
## Setup
|
||||
## For platform administrators/SREs
|
||||
|
||||
First, setup a Git Repository with `Application` files, some source code and a Dockerfile.
|
||||

|
||||
|
||||
The code is very simple, starting a service and displaying the version in the code. In `Application`, we'll start a `webservice` for the code and add an `Ingress` trait to access.
|
||||
Platform administrators/SREs prepares the Git repo for operational config. Every config config change will be traceable by that. KubeVela will watch the repo and apply changes to the clusters.
|
||||
|
||||
## Setup Config Repository
|
||||
|
||||
> The configuration files are from the [Example Repo](https://github.com/oam-dev/samples/tree/master/9.GitOps_Demo).
|
||||
|
||||
The structure of the config repository looks below:
|
||||
|
||||
* The `clusters/` contains the GitOps config. It will command KubeVela to watch the specified repo and apply latest changes.
|
||||
* The `apps/` contains the Application yaml for deploying the user-facing app.
|
||||
* The `infrastructure/` contains infrastructure tools, i.e. MySQL database.
|
||||
|
||||
```shell
|
||||
├── apps
|
||||
│ └── my-app.yaml
|
||||
├── clusters
|
||||
│ ├── apps.yaml
|
||||
│ └── infra.yaml
|
||||
└── infrastructure
|
||||
└── mysql.yaml
|
||||
```
|
||||
|
||||
> KubeVela recommends using the directory structure above to manage your GitOps repository. `clusters/` holds the associated KubeVela configuration that need to be applied to cluster manually, `apps/` holds your application and `infrastructure/` holds your base configuration. Application-related configurations can be bound with traits. By separating applications from basic configurations, you can manage your deployment environment more reasonably and isolate application changes.
|
||||
|
||||
#### Directory `clusters/`
|
||||
|
||||
`apps.yaml` and `infra.yaml` in `clusters/` are similar. Their difference is to watch different directories.
|
||||
|
||||
Apply the files in `clusters/` manually. They will sync the files in `infrastructure/` and `apps/` dir of the Git repo.
|
||||
|
||||
Below is how the infra.yaml looks like:
|
||||
|
||||
```yaml
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: first-vela-workflow
|
||||
name: infra
|
||||
spec:
|
||||
components:
|
||||
- name: database-config
|
||||
type: kustomize
|
||||
properties:
|
||||
repoType: git
|
||||
# replace it with your repo url
|
||||
url: https://github.com/FogDong/KubeVela-GitOps-Infra-Demo
|
||||
# replace it with your git secret if it's a private repo
|
||||
# secretRef: git-secret
|
||||
# the pull interval time, set to 10m since the infrastructure is steady
|
||||
pullInterval: 10m
|
||||
git:
|
||||
# the branch name
|
||||
branch: main
|
||||
# the path to sync
|
||||
path: ./infrastructure
|
||||
```
|
||||
|
||||
#### Directory `apps/`
|
||||
|
||||
The file in `apps` is a simple application with database information and Ingress. The app serves HTTP service and connects to a MySQL database. In the '/' path, it will display the version in the code; in the `/db` path, it will list the data in database.
|
||||
|
||||
```yaml
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: my-app
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: test-server
|
||||
- name: my-server
|
||||
type: webservice
|
||||
properties:
|
||||
# replace the imagepolicy `default:gitops` with your policy later
|
||||
image: <your image> # {"$imagepolicy": "default:gitops"}
|
||||
image: <your image address> # {"$imagepolicy": "default:apps"}
|
||||
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:
|
||||
|
|
@ -52,11 +123,167 @@ spec:
|
|||
/: 8088
|
||||
```
|
||||
|
||||
We want users to build the image and push it to the image registry after changing the code, so we need to integrate with a CI tool like GitHub Actions or Jenkins to do it. In this example, we use GitHub Actions to build the image. For the code and configuration file, please refer to [Example Repo](https://github.com/oam-dev/samples/tree/master/9.GitOps_Demo).
|
||||
#### Directory `infrastructure/`
|
||||
|
||||
## Create the Git secret
|
||||
The `infrastructure/` contains the config of some infrastructures like database. In the following, we will use [MySQL operator](https://github.com/bitpoke/mysql-operator) to deploy a MySQL cluster.
|
||||
|
||||
After the new image is pushed to the image registry, KubeVela will recognize the new image and update the `Application` file in the Git repository and cluster. Therefore, we need a secret with Git information for KubeVela to commit to the Git repository.
|
||||
> Notice that there must be a secret in your cluster with MySQL password specified in key `ROOT_PASSWORD`.
|
||||
|
||||
```yaml
|
||||
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
|
||||
properties:
|
||||
apiVersion: mysql.presslabs.org/v1alpha1
|
||||
kind: MysqlCluster
|
||||
metadata:
|
||||
name: mysql-cluster
|
||||
spec:
|
||||
replicas: 1
|
||||
# replace it with your secret
|
||||
secretName: mysql-secret
|
||||
|
||||
workflow:
|
||||
steps:
|
||||
- name: deploy-operator
|
||||
type: apply-component
|
||||
properties:
|
||||
component: mysql-controller
|
||||
- name: deploy-mysql
|
||||
type: apply-component
|
||||
properties:
|
||||
component: mysql-cluster
|
||||
```
|
||||
|
||||
#### Apply the files in `clusters/`
|
||||
|
||||
Apply the `infra.yaml` to cluster, we can see that the MySQL in `infrastructure/` is automatically deployed:
|
||||
|
||||
```shell
|
||||
kubectl apply -f clusters/infra.yaml
|
||||
```
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
Apply the `apps.yaml` to cluster, we can see that the application in `apps/` is automatically deployed:
|
||||
|
||||
```shell
|
||||
kubectl apply -f clusters/apps.yaml
|
||||
```
|
||||
|
||||
```shell
|
||||
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
|
||||
```
|
||||
|
||||
`curl` the Ingress of the app, we can see that the current version is `0.1.5` and the application is connected to the database successfully:
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
## Modify the config for GitOps trigger
|
||||
|
||||
After the first deployment, we can modify the files in config repo to update the applications in the cluster.
|
||||
|
||||
Modify the domain of the application's Ingress:
|
||||
|
||||
```yaml
|
||||
...
|
||||
traits:
|
||||
- type: ingress
|
||||
properties:
|
||||
domain: kubevela.example.com
|
||||
http:
|
||||
/: 8089
|
||||
```
|
||||
|
||||
Check the Ingress in cluster after a while:
|
||||
|
||||
```shell
|
||||
NAME CLASS HOSTS ADDRESS PORTS AGE
|
||||
my-server <none> kubevela.example.com <ingress-ip> 80 162m
|
||||
```
|
||||
|
||||
The host of the Ingress has been updated successfully!
|
||||
|
||||
## For developers
|
||||
|
||||

|
||||
|
||||
Developers writes the application source code and push it to a Git repo (aka app repo). Once app repo updates, the CI will build the image and push it to the image registry. KubeVela watches the image registry, and updates the image in config repo. Finally, it will apply the config to the cluster.
|
||||
|
||||
User can update the configuration in the cluster automatically when the code is updated.
|
||||
|
||||
### Setup App Code Repository
|
||||
|
||||
Setup a Git repository with source code and Dockerfile.
|
||||
|
||||
The app serves HTTP service and connects to a MySQL database. In the '/' path, it will display the version in the code; in the `/db` path, it will list the data in database.
|
||||
|
||||
```go
|
||||
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())
|
||||
}
|
||||
```
|
||||
|
||||
In this tutorial, we will setup a CI pipeline using GitHub Actions to build the image and push it to a registry. The code and configuration files are from the [Example Repo](https://github.com/oam-dev/samples/tree/master/9.GitOps_Demo).
|
||||
|
||||
## Create Git Secret for KubeVela committing to Config Repo
|
||||
|
||||
After the new image is pushed to the image registry, KubeVela will be notified and update the `Application` file in the Git repository and cluster. Therefore, we need a secret with Git information for KubeVela to commit to the Git repository. Fill the following yaml files with your password and apply it to the cluster:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
|
|
@ -69,90 +296,76 @@ stringData:
|
|||
password: <your password>
|
||||
```
|
||||
|
||||
## Create the Application that sync with Git
|
||||
## Setup Config Repository
|
||||
|
||||
After completing the basic configuration above, we can create an Application file that syncs with the corresponding Git repository and image registry information:
|
||||
The configuration repository is almost the same as the previous configuration, you only need to add the image registry config to the file. For more details, please refer to [Example Repository](https://github.com/oam-dev/samples/tree/master/9.GitOps_Demo).
|
||||
|
||||
Modify the image field in `my-app` and add annotation `# {"$imagepolicy": "default:apps"}`.
|
||||
Notice that KubeVela will only be able to modify the image field if the annotation is added after the field. `default:apps` is `namespace:application-name` of the application config file.
|
||||
|
||||
```yaml
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: git-app
|
||||
spec:
|
||||
components:
|
||||
- name: gitops
|
||||
type: kustomize
|
||||
properties:
|
||||
repoType: git
|
||||
url: <your github repo address>
|
||||
# your git secret
|
||||
secretRef: my-secret
|
||||
# the interval time to pull from git repo and image registry
|
||||
pullInterval: 1m
|
||||
git:
|
||||
# the specific branch
|
||||
branch: master
|
||||
# the path that you want to listen
|
||||
path: .
|
||||
imageRepository:
|
||||
image: <your image>
|
||||
# if it's a private image registry, use `kubectl create secret docker-registry` to create the secret
|
||||
# secretRef: imagesecret
|
||||
filterTags:
|
||||
# filter the image tag
|
||||
pattern: '^master-[a-f0-9]+-(?P<ts>[0-9]+)'
|
||||
extract: '$ts'
|
||||
# use the policy to sort the latest image tag and update
|
||||
policy:
|
||||
numerical:
|
||||
order: asc
|
||||
# add more commit message
|
||||
commitMessage: "Image: {{range .Updated.Images}}{{println .}}{{end}}"
|
||||
- name: my-server
|
||||
type: webservice
|
||||
properties:
|
||||
image: ghcr.io/fogdong/test-fog:master-cba5605f-1632714412 # {"$imagepolicy": "default:apps"}
|
||||
```
|
||||
|
||||
Apply the file to the cluster and check the `Application` in clusters, we can see that the `git-app` automatically pulls the config from Git Repository and apply the application to the cluster:
|
||||
Add the config of image registry in `apps`, it listens for image updates in the image registry:
|
||||
|
||||
```shell
|
||||
$ vela ls
|
||||
|
||||
APP COMPONENT TYPE TRAITS PHASE HEALTHY STATUS CREATED-TIME
|
||||
first-vela-workflow test-server webservice ingress running healthy 2021-09-10 11:23:34 +0800 CST
|
||||
git-app gitops kustomize running healthy 2021-09-10 11:23:32 +0800 CST
|
||||
```yaml
|
||||
...
|
||||
imageRepository:
|
||||
image: <your image>
|
||||
# if it's a private image registry, use `kubectl create secret docker-registry` to create the secret
|
||||
# secretRef: imagesecret
|
||||
filterTags:
|
||||
# filter the image tag
|
||||
pattern: '^master-[a-f0-9]+-(?P<ts>[0-9]+)'
|
||||
extract: '$ts'
|
||||
# use the policy to sort the latest image tag and update
|
||||
policy:
|
||||
numerical:
|
||||
order: asc
|
||||
# add more commit message
|
||||
commitMessage: "Image: {{range .Updated.Images}}{{println .}}{{end}}"
|
||||
```
|
||||
|
||||
We can `curl` the `Ingress` to see the current version in code:
|
||||
After update the files in `clusters/` to cluster, we can then update the application by modifying the code.
|
||||
|
||||
```shell
|
||||
$ curl -H "Host:testsvc.example.com" http://<your-ip>
|
||||
Version: 0.1.5
|
||||
```
|
||||
## Modify the code
|
||||
|
||||
## Modify the code to trigger automatic deployment
|
||||
|
||||
After the first applying, we can modify the code in Git Repository to apply automatically.
|
||||
|
||||
Change the `Version` to `0.1.6` in code:
|
||||
Change the `Version` to `0.1.6` and modify the data in database:
|
||||
|
||||
```go
|
||||
const VERSION = "0.1.6"
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = fmt.Fprintf(w, "Version: %s\n", VERSION)
|
||||
})
|
||||
if err := http.ListenAndServe(":8088", nil); err != nil {
|
||||
println(err.Error())
|
||||
...
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Commit the change to the Git Repository, we can see that our CI pipelines has built the image and push it to the image registry.
|
||||
|
||||
KubeVela will then listening to the image registry and update the `Application` in Git Repository with the latest image tag. We can see that there is a commit form `kubevelabot`, the commit message is always with a prefix `Update image automatically.` You can use format like `{{range .Updated.Images}}{{println .}}{{end}}` to specify the image name in the `commitMessage` field.
|
||||
KubeVela will listen to the image registry and update the `Application` in Git Repository with the latest image tag.
|
||||
|
||||
We can see that there is a commit form `kubevelabot`, the commit message is always with a prefix `Update image automatically.` You can use format like `{{range .Updated.Images}}{{println .}}{{end}}` to specify the image name in the `commitMessage` field.
|
||||
|
||||

|
||||
|
||||
> Note that the commit from `kubevelabot` will not trigger the pipeline again and since we filter out the commit from KubeVela in CI configuration.
|
||||
> Note that if you want to put the code and config in the same repository, you need to filter out the commit from KubeVela in CI configuration like below to avoid the repeat build of pipeline.
|
||||
>
|
||||
> ```shell
|
||||
> jobs:
|
||||
|
|
@ -160,17 +373,36 @@ KubeVela will then listening to the image registry and update the `Application`
|
|||
> if: "!contains(github.event.head_commit.message, 'Update image automatically')"
|
||||
> ```
|
||||
|
||||
Re-check the `Application` in cluster, we can see that the image of the `Application` has been updated after a while. We can `curl` to `Ingress` to see the current version:
|
||||
Re-check the `Application` in cluster, we can see that the image of the `Application` has been updated after a while.
|
||||
|
||||
```shell
|
||||
$ curl -H "Host:testsvc.example.com" http://<your-ip>
|
||||
> KubeVela polls the latest information from the code and image repo periodically (at an interval that can be customized):
|
||||
> * When the `Application` file in the Git repository is updated, KubeVela will update the `Application` in the cluster based on the latest configuration.
|
||||
> * When a new tag is added to the image registry, KubeVela will filter out the latest tag based on your policy and update it to Git repository. When the files in the repository are updated, KubeVela repeats the first step and updates the files in the cluster, thus achieving automatic deployment.
|
||||
|
||||
We can `curl` to `Ingress` to see the current version and data:
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
The `Version` has been updated successfully! Now we're done with everything from changing the code to automatically applying to the cluster.
|
||||
|
||||
KubeVela polls the latest information from the code and image repo periodically (at an interval that can be customized):
|
||||
* When the `Application` file in the Git repository is updated, KubeVela will update the `Application` in the cluster based on the latest configuration.
|
||||
* When a new tag is added to the image registry, KubeVela will filter out the latest tag based on your policy and update it to Git repository. When the files in the repository are updated, KubeVela repeats the first step and updates the files in the cluster, thus achieving automatic deployment.
|
||||
## Summary
|
||||
|
||||
For platform admins/SREs, they update the config repo to operate the application and infrastructure. KubeVela will synchronize the config to the cluster, simplifying the deployment process.
|
||||
|
||||
For end users/developers, they write the source code, push it to Git, and then re-deployment will happen. It will make CI to build the image. KubeVela will then update the image field and apply the deployment config.
|
||||
|
||||
By integrating with GitOps, KubeVela helps users speed up deployment and simplify continuous deployment.
|
||||
|
After Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 237 KiB After Width: | Height: | Size: 217 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
|
@ -2,7 +2,7 @@
|
|||
title: 基于工作流的 GitOps
|
||||
---
|
||||
|
||||
本案例讲介绍如何在 GitOps 场景下使用 KubeVela, 并介绍这样做的好处是什么。
|
||||
本案例将介绍如何在 GitOps 场景下使用 KubeVela,并介绍这样做的好处是什么。
|
||||
|
||||
## 简介
|
||||
|
||||
|
|
@ -21,28 +21,98 @@ KubeVela 作为一个声明式的应用交付控制平面,天然就可以以 G
|
|||
|
||||
在本文中,我们主要讲解直接使用 KubeVela 在 GitOps 模式下进行交付的步骤。
|
||||
|
||||
交付的模式有以下两种,我们将分别介绍:
|
||||
|
||||
1. 面向平台管理员/运维人员的交付,用户可以通过直接更新仓库中的 KubeVela 配置文件,从而更新集群中的应用。
|
||||
2. 面向终端开发者的交付,用户通过更新应用代码仓库中的代码,从而更新集群中的应用。
|
||||
|
||||
> 提示:你也可以通过类似的步骤使用 ArgoCD 等 GitOps 工具来间接使用 KubeVela,细节的操作文档我们会在后续发布中提供。
|
||||
|
||||
## 准备代码仓库
|
||||
## 面向平台管理员/运维人员的交付
|
||||
|
||||
首先,准备一个 Git 仓库,里面含有一个 `Application` 配置文件,一些源代码以及对应的 Dockerfile。
|
||||

|
||||
|
||||
代码的实现逻辑非常简单,会启动一个服务,并显示对应的 Version 版本。而在 `Application` 当中,我们会通过一个 `webservice` 类型的组件启动该服务,并添加一个 `ingress` 的运维特征以方便访问:
|
||||
如图所示,对于平台管理员/运维人员而言,只需要准备一个 KubeVela Git 配置仓库并部署 KubeVela 配置文件,后续对于应用及基础设施的配置变动,便可通过直接更新 Git 配置仓库来完成,使得每一次配置变更可追踪。
|
||||
|
||||
### 准备配置仓库
|
||||
|
||||
> 具体的配置可参考 [示例仓库](https://github.com/oam-dev/samples/tree/master/9.GitOps_Demo)。
|
||||
|
||||
配置仓库的目录结构如下:
|
||||
|
||||
* `clusters/` 中包含集群中的 KubeVela 配置,用户需要将 `clusters/` 中的文件手动部署到集群中后,KubeVela 便能自动监听配置仓库中的文件变动且自动更新集群中的配置。
|
||||
* `apps/` 目录中包含应用的配置。会被 `clusters/` 中的 `apps.yaml` 自动监听变化。
|
||||
* `infrastructure/` 中包含一些基础架构工具,如 MySQL 数据库。会被 `clusters/` 中的 ` infra.yaml` 自动监听变化。
|
||||
|
||||
|
||||
```shell
|
||||
├── apps
|
||||
│ └── my-app.yaml
|
||||
├── clusters
|
||||
│ ├── apps.yaml
|
||||
│ └── infra.yaml
|
||||
└── infrastructure
|
||||
└── mysql.yaml
|
||||
```
|
||||
|
||||
> KubeVela 建议使用如上的目录结构管理你的 GitOps 仓库。`clusters/` 中存放相关的 KubeVela 配置并需要被手动部署到集群中,`apps/` 和 `infrastructure/` 中分别存放你的应用和基础配置。应用相关的配置可以通过运维特征绑定在应用上,通过把应用和基础配置分开,能够更为合理的管理你的部署环境,隔离应用的变动影响。
|
||||
|
||||
#### `clusters/` 目录
|
||||
|
||||
首先,我们来看下 clusters 目录。
|
||||
|
||||
`apps.yaml` 与 `infra.yaml` 几乎保持一致,只不过监听的文件目录有所区别。
|
||||
将两个文件手动部署到集群中后,KubeVela 将自动监听 `infrastructure/` 以及 `apps/` 目录下的配置文件并定期更新同步。
|
||||
|
||||
```yaml
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: first-vela-workflow
|
||||
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/` 目录
|
||||
|
||||
`apps/` 目录中存放着应用配置文件,这是一个配置了数据库信息以及 Ingress 的简单应用。 该应用将连接到一个 MySQL 数据库,并简单地启动服务。在默认的服务路径下,会显示当前版本号。在 `/db` 路径下,会列出当前数据库中的信息。
|
||||
|
||||
```yaml
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: my-app
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: test-server
|
||||
- name: my-server
|
||||
type: webservice
|
||||
properties:
|
||||
# 在创建完自动部署文件后,将 `default:gitops` 替换为其 namespace 和 name
|
||||
image: <your image> # {"$imagepolicy": "default:gitops"}
|
||||
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:
|
||||
|
|
@ -51,109 +121,248 @@ spec:
|
|||
/: 8088
|
||||
```
|
||||
|
||||
我们希望用户改动代码进行提交后,自动构建出镜像并推送到镜像仓库。这一步 CI 可以通过集成 GitHub Actions、Jenkins 或者其他 CI 工具来实现。在本例中,我们通过借助 GitHub Actions 来完成持续集成。具体的代码文件及配置可参考 [示例仓库](https://github.com/oam-dev/samples/tree/master/9.GitOps_Demo)。
|
||||
#### `infrastructure/` 目录
|
||||
|
||||
## 配置秘钥信息
|
||||
`infrastructure/` 目录下存放一些基础设施的配置。此处我们使用 [mysql controller](https://github.com/bitpoke/mysql-operator) 来部署了一个 MySQL 集群。
|
||||
|
||||
在新的镜像推送到镜像仓库后,KubeVela 会识别到新的镜像,并更新仓库及集群中的 `Application` 配置文件。因此,我们需要一个含有 Git 信息的 Secret,使 KubeVela 向 Git 仓库进行提交。
|
||||
> 注意,请确保你的集群中有一个 secret,并通过 `ROOT_PASSWORD` 声明了 MySQL 密码。
|
||||
|
||||
```yaml
|
||||
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
|
||||
properties:
|
||||
apiVersion: mysql.presslabs.org/v1alpha1
|
||||
kind: MysqlCluster
|
||||
metadata:
|
||||
name: mysql-cluster
|
||||
spec:
|
||||
replicas: 1
|
||||
# 关联 secret 名称
|
||||
secretName: mysql-secret
|
||||
|
||||
workflow:
|
||||
steps:
|
||||
- name: deploy-operator
|
||||
type: apply-component
|
||||
properties:
|
||||
component: mysql-controller
|
||||
- name: deploy-mysql
|
||||
type: apply-component
|
||||
properties:
|
||||
component: mysql-cluster
|
||||
```
|
||||
|
||||
#### 部署 `clusters/` 目录下的文件
|
||||
|
||||
在集群中部署 `infra.yaml`,可以看到它自动在集群中拉起了 `infrastructure` 目录下的 MySQL 部署文件:
|
||||
|
||||
```shell
|
||||
kubectl apply -f clusters/infra.yaml
|
||||
```
|
||||
|
||||
```shell
|
||||
$ 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
|
||||
```
|
||||
|
||||
在集群中部署 `apps.yaml`,可以看到它自动拉起了 `apps/staging` 目录下的应用部署文件:
|
||||
|
||||
```shell
|
||||
kubectl apply -f clusters/apps.yaml
|
||||
```
|
||||
|
||||
```shell
|
||||
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
|
||||
```
|
||||
|
||||
通过 curl 应用的 Ingress,可以看到目前的版本是 0.1.5,并且成功地连接到了数据库:
|
||||
|
||||
```shell
|
||||
$ 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:
|
||||
|
||||
```yaml
|
||||
...
|
||||
traits:
|
||||
- type: ingress
|
||||
properties:
|
||||
domain: kubevela.example.com
|
||||
http:
|
||||
/: 8089
|
||||
```
|
||||
|
||||
经过一段时间后,重新查看集群中的 Ingress:
|
||||
|
||||
```shell
|
||||
NAME CLASS HOSTS ADDRESS PORTS AGE
|
||||
my-server <none> kubevela.example.com <ingress-ip> 80 162m
|
||||
```
|
||||
|
||||
可以看到,Ingress 的 Host 地址已被成功更新。
|
||||
|
||||
## 面向终端开发者的交付
|
||||
|
||||

|
||||
|
||||
如图所示,对于终端开发者而言,在 KubeVela Git 配置仓库以外,还需要准备一个应用代码仓库。在用户更新了应用代码仓库中的代码后,需要配置一个 CI 来自动构建镜像并推送至镜像仓库中。KubeVela 会监听镜像仓库中的最新镜像,并自动更新配置仓库中的镜像配置,最后再更新集群中的应用配置。
|
||||
|
||||
使用户可以达成在更新代码后,集群中的配置也自动更新的效果。
|
||||
### 准备代码仓库
|
||||
|
||||
准备一个代码仓库,里面包含一些源代码以及对应的 Dockerfile。
|
||||
|
||||
这些代码将连接到一个 MySQL 数据库,并简单地启动服务。在默认的服务路径下,会显示当前版本号。在 `/db` 路径下,会列出当前数据库中的信息。
|
||||
|
||||
```go
|
||||
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 来完成持续集成。具体的代码文件及配置可参考 [示例仓库](https://github.com/oam-dev/samples/tree/master/9.GitOps_Demo)。
|
||||
|
||||
### 配置秘钥信息
|
||||
|
||||
在新的镜像推送到镜像仓库后,KubeVela 会识别到新的镜像,并更新仓库及集群中的 `Application` 配置文件。因此,我们需要一个含有 Git 信息的 Secret,使 KubeVela 向 Git 仓库进行提交。部署如下文件,将其中的用户名和密码替换成你的信息:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: my-secret
|
||||
name: git-secret
|
||||
type: kubernetes.io/basic-auth
|
||||
stringData:
|
||||
username: <your username>
|
||||
password: <your password>
|
||||
```
|
||||
|
||||
## 编写自动部署配置文件
|
||||
### 准备配置仓库
|
||||
|
||||
完成了上述基础配置后,我们可以在本地新建一个自动部署配置文件,关联对应的 Git 仓库以及镜像仓库信息:
|
||||
配置仓库与之前的配置大同小异,只需要加上与镜像仓库相关的配置即可。具体配置请参考 [示例仓库](https://github.com/oam-dev/samples/tree/master/9.GitOps_Demo)。
|
||||
|
||||
修改 `my-app` 中的 image 字段,在后面加上 `# {"$imagepolicy": "default:apps"}` 的注释。KubeVela 会通过该注释去修改对应的镜像字段。`default:apps` 是该应用配置文件对应的命名空间和应用名。
|
||||
|
||||
```yaml
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: git-app
|
||||
spec:
|
||||
components:
|
||||
- name: gitops
|
||||
type: kustomize
|
||||
properties:
|
||||
repoType: git
|
||||
# 将此处替换成你的 git 仓库地址
|
||||
url: <your github repo address>
|
||||
# 关联 git secret
|
||||
secretRef: my-secret
|
||||
# 自动拉取配置的时间间隔
|
||||
pullInterval: 1m
|
||||
git:
|
||||
# 指定监听的 branch
|
||||
branch: master
|
||||
# 指定监听的路径
|
||||
path: .
|
||||
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}}"
|
||||
- name: my-server
|
||||
type: webservice
|
||||
properties:
|
||||
image: ghcr.io/fogdong/test-fog:master-cba5605f-1632714412 # {"$imagepolicy": "default:apps"}
|
||||
```
|
||||
|
||||
将上述文件部署到集群中后,查看集群中的应用,可以看到,应用 `git-app` 自动拉取了 Git 仓库中的应用配置并部署到了集群中:
|
||||
修改 `clusters/` 中的 `apps` 配置,该配置会监听仓库中 `apps` 下的应用文件变动以及镜像仓库中的镜像更新:
|
||||
|
||||
```shell
|
||||
$ vela ls
|
||||
|
||||
APP COMPONENT TYPE TRAITS PHASE HEALTHY STATUS CREATED-TIME
|
||||
first-vela-workflow test-server webservice ingress running healthy 2021-09-10 11:23:34 +0800 CST
|
||||
git-app gitops kustomize running healthy 2021-09-10 11:23:32 +0800 CST
|
||||
```yaml
|
||||
...
|
||||
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}}"
|
||||
```
|
||||
|
||||
通过 `curl` 对应的 `Ingress`,可以看到目前的版本是 0.1.5
|
||||
将 `clusters` 中的配置文件更新到集群中后,我们便可以通过修改代码来完成应用的更新。
|
||||
|
||||
```shell
|
||||
$ curl -H "Host:testsvc.example.com" http://<your-ip>
|
||||
Version: 0.1.5
|
||||
```
|
||||
### 修改代码
|
||||
|
||||
## 修改代码
|
||||
|
||||
完成首次部署后,我们可以通过修改 Git 仓库中的代码,来完成自动部署。
|
||||
|
||||
将代码文件中的 `Version` 改为 `0.1.6`:
|
||||
将代码文件中的 `Version` 改为 `0.1.6`,并修改数据库中的数据:
|
||||
|
||||
```go
|
||||
const VERSION = "0.1.6"
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = fmt.Fprintf(w, "Version: %s\n", VERSION)
|
||||
})
|
||||
if err := http.ListenAndServe(":8088", nil); err != nil {
|
||||
println(err.Error())
|
||||
...
|
||||
|
||||
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 来更新代码仓库中的 `Application`。此时,可以看到代码仓库中有一条来自 `kubevelabot` 的提交,提交信息均带有 `Update image automatically.` 前缀。你也可以通过 `{{range .Updated.Images}}{{println .}}{{end}}` 在 `commitMessage` 字段中追加你所需要的信息。
|
||||
而 KubeVela 会通过监听镜像仓库,根据最新的镜像 Tag 来更新代码仓库中的 `Application`。
|
||||
|
||||
此时,可以看到配置仓库中有一条来自 `kubevelabot` 的提交,提交信息均带有 `Update image automatically.` 前缀。你也可以通过 `{{range .Updated.Images}}{{println .}}{{end}}` 在 `commitMessage` 字段中追加你所需要的信息。
|
||||
|
||||

|
||||
|
||||
> 值得注意的是,来自 `kubevelabot` 的提交不会再次触发流水线导致重复构建,因为我们在 CI 配置的时候,将来自 KubeVela 的提交过滤掉了。
|
||||
> 值得注意的是,如果你希望将代码和配置放在同一个仓库,需要过滤掉来自 `kubevelabot` 的提交来防止流水线的重复构建。可以在 CI 中通过如下配置过滤:
|
||||
>
|
||||
> ```shell
|
||||
> jobs:
|
||||
|
|
@ -161,17 +370,37 @@ func main() {
|
|||
> if: "!contains(github.event.head_commit.message, 'Update image automatically')"
|
||||
> ```
|
||||
|
||||
重新查看集群中的应用,可以看到经过一段时间后,`Application` 的镜像已经被更新。通过 `curl` 对应的 `Ingress` 查看当前版本:
|
||||
重新查看集群中的应用,可以看到经过一段时间后,`Application` 的镜像已经被更新。
|
||||
|
||||
```shell
|
||||
$ curl -H "Host:testsvc.example.com" http://<your-ip>
|
||||
> KubeVela 会通过你配置的 `interval` 时间间隔,来每隔一段时间分别从配置仓库及镜像仓库中获取最新信息:
|
||||
> * 当 Git 仓库中的配置文件被更新时,KubeVela 将根据最新的配置更新集群中的应用。
|
||||
> * 当镜像仓库中多了新的 Tag 时,KubeVela 将根据你配置的 policy 规则,筛选出最新的镜像 Tag,并更新到 Git 仓库中。而当代码仓库中的文件被更新后,KubeVela 将重复第一步,更新集群中的文件,从而达到了自动部署的效果。
|
||||
|
||||
|
||||
通过 `curl` 对应的 `Ingress` 查看当前版本和数据库信息:
|
||||
|
||||
```shell
|
||||
$ 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 会通过你配置的 `interval` 时间间隔,来每隔一段时间分别从代码仓库及镜像仓库中获取最新信息:
|
||||
* 当 Git 仓库中的配置文件被更新时,KubeVela 将根据最新的配置更新集群中的应用。
|
||||
* 当镜像仓库中多了新的 Tag 时,KubeVela 将根据你配置的 policy 规则,筛选出最新的镜像 Tag,并更新到 Git 仓库中。而当代码仓库中的文件被更新后,KubeVela 将重复第一步,更新集群中的文件,从而达到了自动部署的效果。
|
||||
## 总结
|
||||
|
||||
通过与 GitOps 的集成,KubeVela 可以帮助用户加速部署应用,更为简洁地完成持续部署。
|
||||
在运维侧,如若需要更新基础设施(如数据库)的配置,或是应用的配置项,只需要修改配置仓库中的文件,KubeVela 将自动把配置同步到集群中,简化了部署流程。
|
||||
|
||||
在研发侧,用户修改代码仓库中的代码后,KubeVela 将自动更新配置仓库中的镜像。从而进行应用的版本更新。
|
||||
|
||||
通过与 GitOps 的结合,KubeVela 加速了应用从开发到部署的整个流程。
|
||||
|
After Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 237 KiB After Width: | Height: | Size: 217 KiB |
|
After Width: | Height: | Size: 94 KiB |