Author | Dong Tianxin (Wu Wu)

Review & proofread: Xiyang, Haizhu

Editing & Typesetting: Wen Yan

KubeVela is a simple, easy-to-use, and highly scalable cloud native application management and delivery platform that enables developers to quickly and easily define and deliver modern microservices applications on Kubernetes without needing to know any Kubernetes infrastructure-related details.

The OAM model behind KubeVela naturally solves the management problems of the combination and arrangement of complex resources in the process of application construction, and also models the later operation and maintenance strategy, which means that KubeVela can combine GitOps to manage complex large-scale applications. Convergence of system complexity problems due to team and system size growth.

What is a GitOps

Its core idea is to store declarative descriptions of the infrastructure and application configuration required by the application system in a Git repository, along with an automated process that gradually updates the environment to the latest configuration each time the repository is updated.

This approach allows developers to automatically deploy applications by directly changing the code and configuration in the Git repository. Using GitOps brings a lot of value to application development, such as:

• Improve productivity. Speed up average deployment times and increase development efficiency through automated continuous deployment. • Lower the barriers to developer deployment. By pushing code instead of container configuration, developers can easily deploy Kubernetes without needing to know about its internal implementation. • Make change records traceable. Managing the cluster with Git makes every change traceable, enhancing the audit trail. • Clusters can be recovered using Git’s rollback/branch capabilities.

KubeVela and GitOps

As a declarative application delivery control plane, KubeVela naturally supports the use of GitOps and enables users to more clearly experience the benefits of GitOps and the end-to-end application delivery and management experience, including:

• Application delivery workflow (CD pipeline) : KubeVela supports describing procedural application delivery in GitOps mode rather than simply declaring the end state; • Handle dependencies and topologies during deployment; • Simplify application delivery and management by providing a unified upper level abstraction over the semantics of existing GitOps tools; • Unified declaration, deployment and service binding of cloud services; • Provide out-of-the-box delivery strategies (Canary, Blue and green releases, etc.); • Provide hybrid cloud/multi-cloud deployment strategies (placement rules, cluster filtering rules, etc.) out of the box; • Provide Kustomize-style patches in multi-environment delivery to describe deployment differences without learning any details of Kustomize itself; •…

In this article, we focus on the steps to deliver directly using KubeVela in GitOps mode.

GitOps workflow

The GitOps workflow is divided into CI and CD:

• Continuous Integration (CI) : Builds code for business applications, builds images, and pushes them to the image repository. At present, there are many mature CI tools, such as GitHub Action and Travis commonly used in open source projects, and Jenkins and Tekton commonly used in enterprises. In this article, we use GitHub Action to do this step. Of course, you can use other CI tools instead. KubeVela can interconnect CI processes with any tool around GitOps. • Continuous Delivery (CD) : Continuous deployment automatically updates cluster configurations. For example, the latest images in the image repository are updated to the cluster. At present, there are mainly two kinds of CD schemes: 1) push-based: CD in Push mode is accomplished mainly by configuring CI pipeline, which requires sharing the access key of the cluster with CI so that THE CI pipeline can Push changes to the cluster by command. Please refer to our previous blog: Continuous delivery of the application using Jenkins + KubeVela (see related links at the end of this article). 2) Pull-based: A Pull mode CD listens for changes in the repository (code repository or configuration repository) in the cluster and synchronizes these changes to the cluster. Compared with Push mode, pull-based cluster actively pulls updates, thus avoiding the problem of secret key exposure. This is the core of this article.

There are two types of person-oriented delivery, which we will introduce separately:

  1. For platform administrators and O&M personnel, you can update the configuration file in the warehouse to update the infrastructure configuration in the cluster, such as the dependency software, security policy, storage, and network configuration.
  2. For the delivery of terminal developers, once the user’s code is merged into the application code warehouse, it will automatically trigger the update of the application in the cluster, which can be more efficient to complete the iteration of the application. Combined with KubeVela’s grayscale release, traffic allocation, multi-cluster deployment and other functions, it can form a more powerful automatic release ability.

Delivery for platform administrators/O&M personnel

As shown in the figure, for platform administrators/operations personnel, they don’t need to care about the application code, so they only need to prepare a Git repository and deploy the KubeVela configuration file. Subsequent configuration changes for the application and infrastructure can be done by directly updating the Git repository. Make every configuration change traceable.

Preparing the configuration warehouse

Refer to sample Repository 1 for configuration details (see related links at the end of this article).

In this example, we will deploy a MySQL database software as the project infrastructure and a business application that uses the database. The configuration repository directory structure is as follows:

• Clusters/contains the KubeVela GitOps configuration for the cluster, and the user needs to manually deploy the files in clusters/ into the cluster. This is a one-time control operation, and once done, KubeVela automatically listens for file changes in the repository and automatically updates the configuration in the cluster. Yaml will listen for changes to all applications under apps/, and Clusters /infra.yaml will listen for changes to all infrastructure under Infrastructure /. • The apps/ directory contains all configurations for the business application, in this case a business application that uses a database. • Infrastructure/contains some infrastructure-related configurations and policies, in this case the MySQL database.

├ ─ ─ apps │ └ ─ ─ my - app. The yaml ├ ─ ─ clusters │ ├ ─ ─ apps. The yaml │ └ ─ ─ infra. Yaml └ ─ ─ proceeds └ ─ ─ mysql. The yamlCopy the code

KubeVela recommends using the directory structure above to manage your GitOps repository. Clusters/hold the associated KubeVela GitOps configuration and need to be manually deployed to the cluster, apps/ and Infrastructure/hold your application and infrastructure configuration, respectively. By separating the application from the base configuration, you can better manage your deployment environment and isolate the impact of application changes.

Clusters/directory

First, let’s look at the clusters directory, which is also the configuration directory for KubeVela’s initialization operation with GitOps.

Take Clusters /infra.yaml as an example:

apiVersion: core.oam.dev/v1beta1 kind: Application metadata: name: infra spec: components: - name: Database -config type: kustomize properties: repoType: git # https://github.com/FogDong/KubeVela-GitOps-Infra-Demo # if it is a private warehouse, also need to link the git secret # secretRef: PullInterval: 10m git: # Listen for branch changes Main # Listen for changing paths to the file path:./infrastructure in the repositoryCopy the code

Yaml apps. Yaml is almost identical to infra. Yaml, except that it listens to different file directories. In apps.yaml, the value of properties.path is changed to./apps, indicating that file changes under the apps/ directory are being listened for.

The GitOps management profile in the Cluster folder needs to be manually deployed to the cluster once and for all during initialization, after which KubeVela will automatically listen for and update the profile in the apps/ and Infrastructure/directories periodically.

Apps/directory

The apps/ directory houses the application configuration file, which is a simple application that configures database information and Ingress. The application will connect to a MySQL database and simply start the service. In the default service path, the current version number is displayed. In the /db path, the information in the current database is listed.

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
Copy the code

This is an application that uses KubeVela’s built-in component type WebService, which is bound to Ingress operation features. By declaring operation and maintenance capabilities in the application, the underlying Deployment, Service, and Ingress can be brought together in a single file, making it easier to manage the application.

Infrastructure/directory

The infrastructure/ directory holds some of the infrastructure configuration. Here we deploy a mysql cluster using mysql Controller (see the link at the end of this article).

Note that make sure you have a secret in your cluster and declare the MySQL password via ROOT_PASSWORD.

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: SecretName: mysql-secretCopy the code

In this MySQL application, we use the capabilities of KubeVela workflow. The workflow is divided into two steps. The first step is to deploy the MySQL Controller. When the Controller is successfully deployed and running correctly, the second step will start deploying the MySQL cluster.

Deploy the files in the clusters/ directory

After the above files were configured and stored in the Git repository, we needed to manually deploy the KubeVela GitOps configuration file in the Clusters/directory in the cluster.

First, you deploy clusters/infra.yaml in the cluster. You can see that it automatically pulls up the MySQL deployment file in the infrastructure/ directory in the cluster:

kubectl apply -f clusters/infra.yaml
Copy the code
$ vela ls APP COMPONENT TYPE TRAITS PHASE HEALTHY STATUS CREATED-TIME infra database-config kustomize running healthy 2021-09-26 2021-09-26 20:48:9 +0800 CST mysql mysql -Controller helm Running Healthy 2021-09-26 20:48:11 +0800 CST ├ ─ 0800 CST ├ ─ 0800 CST  raw running healthy 2021-09-26 20:48:11 +0800 CSTCopy the code

Next, deploy in a cluster

Yaml, and you can see that it automatically pulls up the application deployment file in the apps/ directory:

kubectl apply -f clusters/apps.yaml
Copy the code
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 20:48:11 2021-09-26 + 0800 CSTCopy the code

At this point, we automatically pull up the application and database in the cluster by deploying the KubeVela GitOps configuration file.

Curl app Ingress: curl app Ingress: Curl app Ingress: Curl app Ingress: Curl app Ingress

$ 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: $curl -h "Host:testsvc.example.com" http://<ingress-ip>/db User: KubeVela Description: It's a test UserCopy the code

Modify the configuration

After the initial deployment, we can update the configuration of the application in the cluster by modifying the configuration in the repository.

Modify the Domain of the Ingress:

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

After a while, look again at the Ingress in the cluster:

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

As you can see, the Host address of Ingress has been successfully updated.

This way, you can easily update the configuration in your cluster automatically by updating the files in your Git configuration repository.

Delivery to end developers

For terminal developers, in addition to the KubeVela Git configuration repository, you need to prepare an application code repository. As shown in the figure, after the user updates the code in the application repository, a CI needs to be configured to automatically build the image and push it to the repository. KubeVela listens for the latest images in the repository, automatically updates the image configuration in the repository, and finally updates the application configuration in the cluster. Enables the user to update the configuration in the cluster automatically when the code is updated.

Prepare the code repository

Prepare a repository containing some source code and corresponding Dockerfiles.

This code will connect to a MySQL database and simply start the service. In the default service path, the current version number is displayed. In the /db path, the information in the current database is listed.

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()) }Copy the code

We want the latest image to be automatically built and pushed to the mirror repository after the user submits the code. This CI step can be achieved by integrating GitHub Actions, Jenkins, or other CI tools. In this case, we do continuous integration by leveraging GitHub Actions. For detailed code files and configurations, refer to Sample Repository 2 (see related links at the end of this article).

Configure the key information

After the new image is pushed to the mirror repository, KubeVela recognizes the new image and updates the Application configuration file in the repository and cluster. Therefore, we need a Secret with Git information for KubeVela to commit to the Git repository. Deploy the following file and replace the username and password with your Git username and password (or Token) :

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

Preparing the configuration warehouse

The configuration of the warehouse is similar to the previous configuration for o&M personnel, except for the configuration related to the mirror warehouse. See sample Repository 1 for details (see related links at the end of this article).

Modify apps.yaml in Clusters /, the GitOps configuration that listens for application file changes under apps/ in the repository and mirror updates in the mirror repository:

. ImageRepository: # image: Kubectl create secret docker-registry = kubectl create secret docker-registry = kubectl create secret docker-registry Pattern: '^master-[a-f0-9]+-(? P<ts>[0-9]+)' extract: $ts' # update policy: numerical: order: asc "Image: {{range .Updated.Images}}{{println .}}{{end}}"Copy the code

Modify the image field in apps/my-app.yaml and comment # {“$imagePolicy “: “default:apps”}. KubeVela uses this comment to update the corresponding mirror field. Default :apps is the namespace and name corresponding to the GitOps configuration above.

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

After updating the file containing the mirror repository configuration in Clusters/to the cluster, we were able to update the application by modifying the code.

Modify the code

Change Version in the code file to 0.1.6 and modify the data in the database:

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) } }Copy the code

Commit the change to the repository, and you can see that the CI pipeline we configured starts building the image and pushing it to the repository.

KubeVela listens to the image repository and updates the my-app app under apps/ in the configuration repository according to the latest image Tag.

Kubevelabot: Automatically Update image Automatically. Prefix. You can also append information to the commitMessage field with {{range.updated.Images} {{println.}}{{end}}.

It is worth noting that if you want to keep code and configuration in the same repository, you need to filter out submissions from Kubevelabot to prevent pipeline duplication. You can filter in CI through the following configuration:

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

Looking back at the application in the cluster, you can see that the image of the application my-app has been updated after some time.

KubeVela will get the latest information from the configuration repository and the mirror repository at intervals based on your configured interval:

• When the configuration 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 mirror repository, 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.

Curl curl curl curl curl curl curl curl curl curl curl curl

$ 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 userCopy the code

The version has been successfully updated! At this point, we’re done with everything from changing the code to automatically deploying to the cluster.

conclusion

On the o&M side, if you need to update the configuration of the infrastructure (such as database) or the configuration items of the application, you only need to modify the files in the configuration repository. KubeVela will automatically synchronize the configuration to the cluster, simplifying the deployment process.

On the r&d side, KubeVela automatically updates the image in the configuration repository after the user modifies the code in the repository. To update the version of the application.

In combination with GitOps, KubeVela speeds up the entire application process from development to deployment.

KubeVela project official homepage and documents!!

Jenkins + KubeVela: kubevela.io/zh/blog/202… 2) Example repository 1: github.com/oam-dev/sam… 3) mysql Controller: github.com/bitpoke/mys… 4) Sample repository 2: github.com/oam-dev/sam…

For more information, please scan the qr code below dingding or search dingding group number (35922870) to join ali Cloud native information exchange group! For more information!