基于 KubeVela 的 GitOps 交付( 三 )


$ kubectl get podsNAMEREADYSTATUSRESTARTSAGEmysql-cluster-mysql-04/4Running035mmysql-operator-02/2Running035m通过这种方式,我们可以方便地通过更新 Git 配置仓库中的文件,从而自动化更新集群中的配置 。
面向终端开发者的交付对于终端开发者而言,在 KubeVela Git 配置仓库以外,还需要准备一个应用代码仓库 。在用户更新了应用代码仓库中的代码后,需要配置一个 CI 来自动构建镜像并推送至镜像仓库中 。KubeVela 会监听镜像仓库中的最新镜像,并自动更新配置仓库中的镜像配置,最后再更新集群中的应用配置 。使用户可以达成在更新代码后,集群中的配置也自动更新的效果,代码仓库位于 https://github.com/cnych/KubeVela-GitOps-App-Demo 。

基于 KubeVela 的 GitOps 交付

文章插图
准备代码仓库准备一个代码仓库,里面包含一些源代码以及对应的 Dockerfile 。这些代码将连接到一个 MySQL 数据库,并简单地启动服务 。在默认的服务路径下,会显示当前版本号 。在 /db 路径下,会列出当前数据库中的信息,基本代码如下所示:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {_, _ = fmt.Fprintf(w, "Version: %sn", 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: %vn", err)}for rows.Next() {var username stringvar desc stringerr = rows.Scan(&username, &desc)if err != nil {_, _ = fmt.Fprintf(w, "Scan Error: %vn", err)}_, _ = fmt.Fprintf(w, "User: %s nDescription: %snn", username, desc)}})if err := http.ListenAndServe(":8088", nil); err != nil {panic(err.Error())}我们希望用户改动代码进行提交后,自动构建出最新的镜像并推送到镜像仓库 。这一步 CI 可以通过前面我们讲解的 Jenkins 来实现,基本一致 。
首先为代码仓库创建一个 Webhook , 指向 Jenkins 的触发器地址:
基于 KubeVela 的 GitOps 交付

文章插图
然后在 Jenkins 中创建一个名为 KubeVela-GitOps-App-Demo 的流水线:
基于 KubeVela 的 GitOps 交付

文章插图
并勾选 GitHub hook trigger for GITScm polling 触发器 。
基于 KubeVela 的 GitOps 交付

文章插图
触发器
然后添加如下所示的流水线脚本:
void setBuildStatus(String message, String state) {step([$class: "GitHubCommitStatusSetter",reposSource: [$class: "ManuallyEnteredRepositorySource", url: "https://github.com/cnych/KubeVela-GitOps-App-Demo"],contextSource: [$class: "ManuallyEnteredCommitContextSource", context: "ci/jenkins/deploy-status"],errorHandlers: [[$class: "ChangingBuildStatusErrorHandler", result: "UNSTABLE"]],statusResultSource: [ $class: "ConditionalStatusResultSource", results: [[$class: "AnyBuildResult", message: message, state: state]] ]]);}pipeline {agent {kubernetes {cloud 'Kubernetes'defaultContainer 'jnlp'yaml '''spec:serviceAccountName: jenkinscontainers:- name: golangimage: golang:1.16-alpine3.15command:- cattty: true- name: dockerimage: docker:latestcommand:- cattty: trueenv:- name: DOCKER_HOSTvalue: tcp://docker-dind:2375'''}}stages {stage('Prepare') {steps {script {def checkout = git branch: 'main', url: 'https://github.com/cnych/KubeVela-GitOps-App-Demo.git'env.GIT_COMMIT = checkout.GIT_COMMITenv.GIT_BRANCH = checkout.GIT_BRANCHdef unixTime = (new Date().time.intdiv(1000))def gitBranch = env.GIT_BRANCH.replace("origin/", "")env.BUILD_ID = "${gitBranch}-${env.GIT_COMMIT.substring(0,8)}-${unixTime}"echo "env.GIT_BRANCH=${env.GIT_BRANCH},env.GIT_COMMIT=${env.GIT_COMMIT}"echo "env.BUILD_ID=${env.BUILD_ID}"setBuildStatus("Deploy running", "PENDING");}}}stage('Test') {steps {container('golang') {sh 'GOPROXY=https://goproxy.io CGO_ENABLED=0 GOCACHE=$(pwd)/.cache go test *.go'}}}stage('Build') {steps {withCredentials([[$class: 'UsernamePasswordMultiBinding',credentialsId: 'docker-auth',usernameVariable: 'DOCKER_USER',passwordVariable: 'DOCKER_PASSWORD']]) {container('docker') {sh """docker login -u ${DOCKER_USER} -p ${DOCKER_PASSWORD}docker build -t cnych/kubevela-gitops-demo:${env.BUILD_ID} .docker push cnych/kubevela-gitops-demo:${env.BUILD_ID}"""}}}}}post {success {setBuildStatus("Deploy success", "SUCCESS");}failure {setBuildStatus("Deploy failed", "FAILURE");}}}


推荐阅读