自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用 Jenkins 與 KubeVela 實(shí)現(xiàn)應(yīng)用的持續(xù)交付

開發(fā) 前端
KubeVela 的 Apiserver 則是進(jìn)一步為開發(fā)者提供了使用 HTTP Request 直接操縱 Application 的途徑,使得開發(fā)者即使沒有 Kubernetes 的使用經(jīng)驗(yàn)與集群訪問權(quán)限也可以輕松部署自己的應(yīng)用。接下來我們就以 Jenkins 為基礎(chǔ),結(jié)合 KubeVela 來實(shí)現(xiàn)一個(gè)簡單的應(yīng)用持續(xù)交付的流程。

KubeVela 打通了應(yīng)用與基礎(chǔ)設(shè)施之間的交付管控的壁壘,相較于原生的 Kubernetes 對(duì)象,KubeVela 的 Application 更好地簡化抽象了開發(fā)者需要關(guān)心的配置,將復(fù)雜的基礎(chǔ)設(shè)施能力及編排細(xì)節(jié)留給了平臺(tái)工程師。而 KubeVela 的 apiserver 則是進(jìn)一步為開發(fā)者提供了使用 HTTP Request 直接操縱 Application 的途徑,使得開發(fā)者即使沒有 Kubernetes 的使用經(jīng)驗(yàn)與集群訪問權(quán)限也可以輕松部署自己的應(yīng)用。

接下來我們就以 Jenkins 為基礎(chǔ),結(jié)合 KubeVela 來實(shí)現(xiàn)一個(gè)簡單的應(yīng)用持續(xù)交付的流程。

要實(shí)現(xiàn)一個(gè)簡單的應(yīng)用持續(xù)交付,我們需要做如下幾件事情:

  • 需要一個(gè) git 倉庫來存放應(yīng)用程序代碼、測(cè)試代碼,以及描述 KubeVela Application 的 YAML 文件。
  • 需要一個(gè)持續(xù)集成的工具幫你自動(dòng)化完成程序代碼的測(cè)試,并打包成鏡像上傳到倉庫中。
  • 需要在 Kubernetes 集群上安裝 KubeVela 并啟用 apiserver 功能。

我們這里的演示 Demo 采用 Github 作為 git 倉庫,Jenkins 作為 CI 工具,DockerHub 作為鏡像倉庫。應(yīng)用程序以一個(gè)簡單的 Golang HTTP Server 為例,整個(gè)持續(xù)交付的流程如下。

交付流程

從整個(gè)流程可以看出開發(fā)者只需要關(guān)心應(yīng)用的開發(fā)并使用 Git 進(jìn)行代碼版本的維護(hù),即可自動(dòng)走完測(cè)試流程并部署應(yīng)用到 Kubernetes 集群中。

關(guān)于 Jenkins 在 Kubernetes 集群中的安裝配置前面我們已經(jīng)介紹過了,這里我們就不再贅述。

應(yīng)用配置

這里我們采用了 Github 作為代碼倉庫,倉庫地址為 https://github.com/cnych/KubeVela-demo-CICD-app,當(dāng)然也可以根據(jù)各自的需求與喜好,使用其他代碼倉庫,如 Gitlab。為了 Jenkins 能夠獲取到 GitHub 中的更新,并將流水線的運(yùn)行狀態(tài)反饋回 GitHub,需要在 GitHub 中完成以下兩步操作。

配置 Personal Access Token。注意將 repo:status 勾選,以獲得向 GitHub 推送 Commit 狀態(tài)的權(quán)限,將生成的 Token 復(fù)制下來,下面會(huì)用到。

Personal Access Token

然后在 Jenkins 的 Credential 中加入 Secret Text 類型的 Credential 并將上述的 GitHub 的 Personal Access Token 填入。

jenkins-secret-text

接下來到 Jenkins 的 Dashboard > Manage Jenkins > Configure System > GitHub 中點(diǎn)擊 Add GitHub Server 并將剛才創(chuàng)建的 Credential 填入。完成后可以點(diǎn)擊 Test connection 來驗(yàn)證配置是否正確。

Add GitHub Server

由于我們這里的 Jenkins 位于本地環(huán)境,要讓 GitHub 通過 Webhook 來觸發(fā) Jenkins,我們需要提供一個(gè)可訪問的地址,這里我們可以使用 ngrok 來實(shí)現(xiàn),首先前往 https://dashboard.ngrok.com 注冊(cè)一個(gè)賬號(hào),將 Authtoken 和 APIKEY 記錄下來。

export NGROK_AUTHTOKEN=<your-ngrok-authtoken>
export NGROK_API_KEY=<your-ngrok-apikey>

然后我們可以在本地 Kubernetes 集群中安裝 ngrok ingress controller:

helm repo add ngrok https://ngrok.github.io/kubernetes-ingress-controller
# 使用下面命令安裝 ngrok ingress controller
helm install ngrok-ingress-controller ngrok/kubernetes-ingress-controller \
--namespace ngrok-ingress-controller \
--create-namespace \
--set credentials.apiKey=$NGROK_API_KEY \
--set credentials.authtoken=$NGROK_AUTHTOKEN

安裝完成后為 Jenkins 創(chuàng)建一個(gè) ngrok 的 ingress 路由:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: jenkins-ngrok
 namespace: kube-ops
spec:
 ingressClassName: ngrok
 rules:
   - host: prompt-adjusted-sculpin.ngrok-free.app
     http:
       paths:
         - backend:
             service:
               name: jenkins
               port:
                 name: web
           path: /
           pathType: Prefix

上面的 host 域名是 ngrok 為我們分配的,你可以在 ngrok 的控制臺(tái)中手動(dòng)創(chuàng)建,應(yīng)用上面的 ingress 對(duì)象后我們就可以通過 ngrok 為我們分配的域名來訪問 Jenkins 了。

ngrok jenkins

接下來我們就可以在 GitHub 的代碼倉庫的設(shè)定里添加 Webhook,將 Jenkins 的地址對(duì)應(yīng)的 Webhook 地址填入 <ngrok domain>/github-webhook/,這樣該代碼倉庫的所有 Push 事件推送到 Jenkins 中。

github webhook

編寫應(yīng)用

我們這里采用的應(yīng)用是一個(gè)基于 Golang 語言編寫的簡單的 HTTP Server。在代碼中,聲明了一個(gè)名叫 VERSION 的常量,并在訪問該服務(wù)時(shí)打印出來。同時(shí)還附帶一個(gè)簡單的測(cè)試,用來校驗(yàn) VERSION 的格式是否符合標(biāo)準(zhǔn)。

// main.go
package main

import (
    "fmt"
    "net/http"
)

const VERSION = "0.1.0-v1alpha1"

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())
    }
}

測(cè)試代碼如下所示:

// main_test.go

package main

import (
    "regexp"
    "testing"
)

const verRegex string = `^v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` +
    `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
    `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?$`

func TestVersion(t *testing.T) {
    if ok, _ := regexp.MatchString(verRegex, VERSION); !ok {
        t.Fatalf("invalid version: %s", VERSION)
    }
}

在應(yīng)用交付時(shí)需要將 Golang 服務(wù)打包成鏡像并以 KubeVela Application 的形式發(fā)布到 Kubernetes 集群中,因此在代碼倉庫中還包含 Dockerfile 文件,用來描述鏡像的打包方式。

# Dockerfile
FROM golang:1.13-rc-alpine3.10 as builder
WORKDIR /app
COPY main.go .
RUN go build -o kubevela-demo-cicd-app main.go

FROM alpine:3.10
WORKDIR /app
COPY --from=builder /app/kubevela-demo-cicd-app /app/kubevela-demo-cicd-app
ENTRYPOINT ./kubevela-demo-cicd-app
EXPOSE 8088

配置 CI 流水線

在這里我們將包含兩條流水線,一條是用來進(jìn)行測(cè)試的流水線 (對(duì)應(yīng)用代碼運(yùn)行測(cè)試) ,一條是交付流水線 (將應(yīng)用代碼打包上傳鏡像倉庫,同時(shí)更新目標(biāo)環(huán)境中的應(yīng)用,實(shí)現(xiàn)自動(dòng)更新) 。

測(cè)試流水線

在 Jenkins 中創(chuàng)建一條新的名為 KubeVela-demo-CICD-app-test 的流水線:

測(cè)試流水線

然后配置構(gòu)建觸發(fā)器為 GitHub hook trigger for GITScm polling:

構(gòu)建觸發(fā)器

在這條流水線中,首先是采用了 golang 的鏡像作為執(zhí)行環(huán)境,方便后續(xù)運(yùn)行測(cè)試。然后將分支配置為 GitHub 倉庫中的 dev 分支,代表該條流水線被 Push 事件觸發(fā)后會(huì)拉取 dev 分支上的內(nèi)容并執(zhí)行測(cè)試,測(cè)試結(jié)束后將流水線的狀態(tài)回寫至 GitHub 中。這里我們使用的是基于 Kubernetes 的動(dòng)態(tài) Slave Agent,因此在流水線中需要配置 Kubernetes 的相關(guān)信息,包括 Kubernetes 的地址、Service Account 等。

void setBuildStatus(String message, String state) {
  step([
      $class: "GitHubCommitStatusSetter",
      reposSource: [$class: "ManuallyEnteredRepositorySource", url: "https://github.com/cnych/KubeVela-demo-CICD-app"],
      contextSource: [$class: "ManuallyEnteredCommitContextSource", context: "ci/jenkins/test-status"],
      errorHandlers: [[$class: "ChangingBuildStatusErrorHandler", result: "UNSTABLE"]],
      statusResultSource: [ $class: "ConditionalStatusResultSource", results: [[$class: "AnyBuildResult", message: message, state: state]] ]
  ]);
}

pipeline {
  agent {
    kubernetes {
      cloud 'Kubernetes'
      containerTemplate {
        name 'golang'
        image 'golang:1.13-rc-alpine3.10'
        command 'cat'
        ttyEnabled true
      }
      serviceAccount 'jenkins'
    }
  }

  stages {
    stage('Prepare') {
        steps {
            script {
                def checkout = git branch: 'dev', url: 'https://github.com/cnych/KubeVela-demo-CICD-app.git'
                env.GIT_COMMIT = checkout.GIT_COMMIT
                env.GIT_BRANCH = checkout.GIT_BRANCH
                echo "env.GIT_BRANCH=${env.GIT_BRANCH},env.GIT_COMMIT=${env.GIT_COMMIT}"
            }
            setBuildStatus("Test running", "PENDING");
        }
    }
    stage('Test') {
        steps {
          container('golang') {
            sh 'CGO_ENABLED=0 GOCACHE=$(pwd)/.cache go test *.go'
          }
        }
    }
  }

  post {
    success {
        setBuildStatus("Test success", "SUCCESS");
    }
    failure {
        setBuildStatus("Test failed", "FAILURE");
    }
  }
}

我們可以使用上面的代碼來執(zhí)行流水線:

測(cè)試流水線

部署流水線

類似測(cè)試流水線創(chuàng)建一個(gè)名為 KubeVela-demo-CICD-app-deploy 的部署流水線,首先將代碼倉庫中的分支拉取下來,區(qū)別是這里采用 prod 分支。然后使用 Docker 進(jìn)行鏡像構(gòu)建并推送至遠(yuǎn)端鏡像倉庫。構(gòu)建成功后,再將 Application 對(duì)應(yīng)的 YAML 文件轉(zhuǎn)換為 JSON 文件并注入 GIT_COMMIT,最后向 KubeVela apiserver 發(fā)送請(qǐng)求進(jìn)行創(chuàng)建或更新。

首先我們需要通過 VelaUX 來創(chuàng)建一個(gè)應(yīng)用,這里我們創(chuàng)建一個(gè)名為 kubevela-demo-app 的應(yīng)用,包含一個(gè)名為 kubevela-demo-app-web 的組件,組件類型為 webservice,并將組件的鏡像設(shè)置為 cnych/kubevela-demo-cicd-app,如下圖所示:

kubevela app

在應(yīng)用面板上,我們可以找到一個(gè)默認(rèn)的觸發(fā)器,點(diǎn)擊 手動(dòng)觸發(fā),我們可以看到 Webhook URL 和 Curl Command,我們可以在 Jenkins 的流水線中使用任意一個(gè)。

觸發(fā)器

Webhook URL 是這個(gè)觸發(fā)器的觸發(fā)地址,在 Curl Command 里,還提供了手動(dòng) Curl 該觸發(fā)器的請(qǐng)求示例。我們來詳細(xì)解析一下請(qǐng)求體:

{
  // 必填,此次觸發(fā)的更新信息
  "upgrade": {
    // Key 為應(yīng)用的名稱
    "<application-name>": {
      // 需要更新的值,這里的內(nèi)容會(huì)被 Patch 更新到應(yīng)用上
      "image": "<image-name>"
    }
  },
  // 可選,此次觸發(fā)攜帶的代碼信息
  "codeInfo": {
    "commit": "<commit-id>",
    "branch": "<branch>",
    "user": "<user>"
  }
}

upgrade 下是本次觸發(fā)要攜帶的更新信息,在應(yīng)用名下,是需要被 Patch 更新的值。默認(rèn)推薦的是更新鏡像 image,也可以擴(kuò)展這里的字段來更新應(yīng)用的其他屬性。codeInfo 中是代碼信息,可以選擇性地?cái)y帶,比如 commit ID、分支、提交者等,一般這些值可以通過在 CI 系統(tǒng)中使用變量替換來指定。

然后我們可以是部署流水線中使用上面的觸發(fā)器來部署應(yīng)用,的代碼如下所示:

void setBuildStatus(String message, String state) {
  step([
      $class: "GitHubCommitStatusSetter",
      reposSource: [$class: "ManuallyEnteredRepositorySource", url: "https://github.com/cnych/KubeVela-demo-CICD-app"],
      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: jenkins
          containers:
          - name: golang
            image: golang:1.13-rc-alpine3.10
            command:
            - cat
            tty: true
          - name: docker
            image: docker:latest
            command:
            - cat
            tty: true
            env:
            - name: DOCKER_HOST
              value: tcp://docker-dind:2375
'''
      }
    }
    stages {
        stage('Prepare') {
            steps {
                script {
                    def checkout = git branch: 'prod', url: 'https://github.com/cnych/KubeVela-demo-CICD-app.git'
                    env.GIT_COMMIT = checkout.GIT_COMMIT
                    env.GIT_BRANCH = checkout.GIT_BRANCH
                    echo "env.GIT_BRANCH=${env.GIT_BRANCH},env.GIT_COMMIT=${env.GIT_COMMIT}"
                    setBuildStatus("Deploy running", "PENDING");
                }
            }
        }
        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-demo-cicd-app .
                      docker push cnych/kubevela-demo-cicd-app
                      """
                  }
              }
            }
        }
        stage('Deploy') {
            steps {
                sh '''#!/bin/bash
                    set -ex
                    curl -X POST -H 'content-type: application/json' --url http://vela.k8s.local/api/v1/webhook/x0i7t8jdsz2uvime -d '{"action":"execute","upgrade":{"kubevela-demo-app":{"image":"cnych/kubevela-demo-cicd-app"}},"codeInfo":{"commit":"","branch":"","user":""}}'
                '''
            }
        }
    }
    post {
        success {
            setBuildStatus("Deploy success", "SUCCESS");
        }
        failure {
            setBuildStatus("Deploy failed", "FAILURE");
        }
    }
}

測(cè)試效果

在完成上述的配置流程后,持續(xù)交付的流程便已經(jīng)搭建完成。我們可以來檢驗(yàn)一下它的效果。

狀態(tài)

我們首先將 main.go 中的 VERSION 字段修改為 Bad Version Number,即:

const VERSION = "Bad Version Number"

然后提交該修改至 dev 分支,我們可以看到 Jenkins 上的測(cè)試流水線被觸發(fā)運(yùn)行,失敗后將該狀態(tài)回寫給 GitHub。

ci test status

ci test github status

我們重新將 VERSION 修改為 0.1.1,然后再次提交??梢钥吹竭@一次測(cè)試流水線成功完成執(zhí)行,并在 GitHub 對(duì)應(yīng)的 Commit 上看到了成功的標(biāo)志。

ci test status

ci test github status

接下來我們?cè)?GitHub 上提交 Pull Request 嘗試將 dev 分支上的更新合并至 prod 分支上。

PR

可以看到在 Jenkins 的部署流水線成功運(yùn)行結(jié)束后,GitHub 上 prod 分支最新的 Commit 也顯示了成功的標(biāo)志。

ci test status

ci test github status

我們的應(yīng)用已經(jīng)成功部署了,當(dāng)前 Deployment 的副本數(shù)是 3,并且還有一個(gè) Ingress 對(duì)象,這時(shí)我們可以訪問 Ingress 所配置的域名,成功顯示了當(dāng)前的版本號(hào)。

$ vela ls
APP                     COMPONENT               TYPE            TRAITS          PHASE   HEALTHY STATUS          CREATED-TIME
kubevela-demo-app       kubevela-demo-app       webservice      scaler,gateway  running healthy Ready:3/3       2023-10-14 19:11:59 +0800 CST
$ kubectl get pods
NAME                                     READY   STATUS    RESTARTS       AGE
kubevela-demo-app-675896596f-87kxl       1/1     Running   0              9m39s
kubevela-demo-app-675896596f-q5pvz       1/1     Running   0              9m39s
kubevela-demo-app-675896596f-v895m       1/1     Running   0              44m
$ kubectl get ingress
NAME                CLASS   HOSTS                              ADDRESS   PORTS   AGE
kubevela-demo-app   nginx   kubevela-demo-cicd-app.k8s.local             80      10m
$ curl -H "Host: kubevela-demo-cicd-app.k8s.local" http://<ingress controller address>
Version: 0.1.1

如果想實(shí)現(xiàn)金絲雀發(fā)布,則可以使用上節(jié)的 kruise rollout 來實(shí)現(xiàn),至此,我們便已經(jīng)成功實(shí)現(xiàn)了一整套持續(xù)交付流程。在這個(gè)流程中,應(yīng)用的開發(fā)者借助 KubeVela + Jenkins 的能力,可以輕松完成應(yīng)用的迭代更新、集成測(cè)試、自動(dòng)發(fā)布與滾動(dòng)升級(jí),而整個(gè)流程在各個(gè)環(huán)節(jié)也可以按照開發(fā)者的喜好和條件選擇不同的工具,比如使用 Gitlab 替代 GitHub,或是使用 TravisCI 替代 Jenkins。

參考文檔:https://kubevela.io/docs/tutorials/jenkins/。

責(zé)任編輯:姜華 來源: k8s技術(shù)圈
相關(guān)推薦

2025-01-07 00:00:15

Jenkins集成服務(wù)器

2023-10-27 07:36:36

2015-07-22 14:59:30

OpenStac持續(xù)集成持續(xù)交付

2017-08-18 08:27:27

Azure應(yīng)用服務(wù)

2021-07-14 13:46:28

KubeVela阿里云容器

2017-02-27 18:50:42

運(yùn)維持續(xù)交付

2016-02-15 09:37:14

Docker持續(xù)交付應(yīng)用程序

2021-09-03 11:33:38

Jenkins 微服務(wù)集成

2017-02-27 18:28:45

持續(xù)交付部署

2018-10-23 16:35:19

華為云

2023-03-14 16:35:52

2017-12-24 21:29:18

OpenShift持續(xù)交付集群

2020-09-21 08:57:25

持續(xù)交付

2016-01-07 10:29:36

MesosDocker持續(xù)交付

2021-04-23 08:00:00

Kubernetes容器工具

2016-08-05 17:19:37

持續(xù)集成持續(xù)交付系統(tǒng)運(yùn)維

2018-04-24 09:00:00

開發(fā)自動(dòng)化軟件架構(gòu)

2021-01-18 14:51:34

JenkinsNginx前端

2017-02-27 18:35:23

集成交付部署

2020-06-23 10:41:08

云計(jì)算DevOps持續(xù)集成
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)