国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

使用 Jenkins 與 KubeVela 實現應用的持續交付

開發 前端
KubeVela 的 Apiserver 則是進一步為開發者提供了使用 HTTP Request 直接操縱 Application 的途徑,使得開發者即使沒有 Kubernetes 的使用經驗與集群訪問權限也可以輕松部署自己的應用。接下來我們就以 Jenkins 為基礎,結合 KubeVela 來實現一個簡單的應用持續交付的流程。

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

接下來我們就以 Jenkins 為基礎,結合 KubeVela 來實現一個簡單的應用持續交付的流程。

要實現一個簡單的應用持續交付,我們需要做如下幾件事情:

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

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

交付流程

從整個流程可以看出開發者只需要關心應用的開發并使用 Git 進行代碼版本的維護,即可自動走完測試流程并部署應用到 Kubernetes 集群中。

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

應用配置

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

配置 Personal Access Token。注意將 repo:status 勾選,以獲得向 GitHub 推送 Commit 狀態的權限,將生成的 Token 復制下來,下面會用到。

Personal Access Token

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

jenkins-secret-text

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

Add GitHub Server

由于我們這里的 Jenkins 位于本地環境,要讓 GitHub 通過 Webhook 來觸發 Jenkins,我們需要提供一個可訪問的地址,這里我們可以使用 ngrok 來實現,首先前往 https://dashboard.ngrok.com 注冊一個賬號,將 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 創建一個 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 的控制臺中手動創建,應用上面的 ingress 對象后我們就可以通過 ngrok 為我們分配的域名來訪問 Jenkins 了。

ngrok jenkins

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

github webhook

編寫應用

我們這里采用的應用是一個基于 Golang 語言編寫的簡單的 HTTP Server。在代碼中,聲明了一個名叫 VERSION 的常量,并在訪問該服務時打印出來。同時還附帶一個簡單的測試,用來校驗 VERSION 的格式是否符合標準。

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

測試代碼如下所示:

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

在應用交付時需要將 Golang 服務打包成鏡像并以 KubeVela Application 的形式發布到 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 流水線

在這里我們將包含兩條流水線,一條是用來進行測試的流水線 (對應用代碼運行測試) ,一條是交付流水線 (將應用代碼打包上傳鏡像倉庫,同時更新目標環境中的應用,實現自動更新) 。

測試流水線

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

測試流水線

然后配置構建觸發器為 GitHub hook trigger for GITScm polling:

構建觸發器

在這條流水線中,首先是采用了 golang 的鏡像作為執行環境,方便后續運行測試。然后將分支配置為 GitHub 倉庫中的 dev 分支,代表該條流水線被 Push 事件觸發后會拉取 dev 分支上的內容并執行測試,測試結束后將流水線的狀態回寫至 GitHub 中。這里我們使用的是基于 Kubernetes 的動態 Slave Agent,因此在流水線中需要配置 Kubernetes 的相關信息,包括 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");
    }
  }
}

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

測試流水線

部署流水線

類似測試流水線創建一個名為 KubeVela-demo-CICD-app-deploy 的部署流水線,首先將代碼倉庫中的分支拉取下來,區別是這里采用 prod 分支。然后使用 Docker 進行鏡像構建并推送至遠端鏡像倉庫。構建成功后,再將 Application 對應的 YAML 文件轉換為 JSON 文件并注入 GIT_COMMIT,最后向 KubeVela apiserver 發送請求進行創建或更新。

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

kubevela app

在應用面板上,我們可以找到一個默認的觸發器,點擊 手動觸發,我們可以看到 Webhook URL 和 Curl Command,我們可以在 Jenkins 的流水線中使用任意一個。

觸發器

Webhook URL 是這個觸發器的觸發地址,在 Curl Command 里,還提供了手動 Curl 該觸發器的請求示例。我們來詳細解析一下請求體:

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

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

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

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");
        }
    }
}

測試效果

在完成上述的配置流程后,持續交付的流程便已經搭建完成。我們可以來檢驗一下它的效果。

狀態

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

const VERSION = "Bad Version Number"

然后提交該修改至 dev 分支,我們可以看到 Jenkins 上的測試流水線被觸發運行,失敗后將該狀態回寫給 GitHub。

ci test status

ci test github status

我們重新將 VERSION 修改為 0.1.1,然后再次提交。可以看到這一次測試流水線成功完成執行,并在 GitHub 對應的 Commit 上看到了成功的標志。

ci test status

ci test github status

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

PR

可以看到在 Jenkins 的部署流水線成功運行結束后,GitHub 上 prod 分支最新的 Commit 也顯示了成功的標志。

ci test status

ci test github status

我們的應用已經成功部署了,當前 Deployment 的副本數是 3,并且還有一個 Ingress 對象,這時我們可以訪問 Ingress 所配置的域名,成功顯示了當前的版本號。

$ 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

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

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

責任編輯:姜華 來源: k8s技術圈
相關推薦

2025-01-07 00:00:15

Jenkins集成服務器

2023-10-27 07:36:36

2015-07-22 14:59:30

OpenStac持續集成持續交付

2017-08-18 08:27:27

Azure應用服務

2021-07-14 13:46:28

KubeVela阿里云容器

2017-02-27 18:50:42

運維持續交付

2016-02-15 09:37:14

Docker持續交付應用程序

2021-09-03 11:33:38

Jenkins 微服務集成

2017-02-27 18:28:45

持續交付部署

2018-10-23 16:35:19

華為云

2016-01-07 10:29:36

MesosDocker持續交付

2017-12-24 21:29:18

OpenShift持續交付集群

2020-09-21 08:57:25

持續交付

2023-03-14 16:35:52

2021-04-23 08:00:00

Kubernetes容器工具

2016-08-05 17:19:37

持續集成持續交付系統運維

2018-04-24 09:00:00

開發自動化軟件架構

2017-02-27 18:35:23

集成交付部署

2021-01-18 14:51:34

JenkinsNginx前端

2017-10-19 09:47:55

容器化微服務集成
點贊
收藏

51CTO技術棧公眾號

亚洲精品一二三| 久久精品中文字幕| 在线天堂av| 黄动漫在线看| 欧美va亚洲va国产综合| 色综合咪咪久久网| 激情六月婷婷| 在线亚洲午夜片av大片| 久久精品国产亚洲高清剧情介绍| 九色丨porny丨| 9.1国产丝袜在线观看| 成人午夜私人影院| 成人小视频免费在线观看| 免费一级片91| 95av在线视频| 国产精品毛片a∨一区二区三区| 高潮在线视频| 九九爱精品视频| 久久99精品视频一区97| 亚洲高清电影| 激情小说 在线视频| 国产一区二区三区丝袜| 国产三级欧美三级| 日韩不卡免费高清视频| 91精品久久久久久久久久久久久久 | 国产成人综合精品| 欧美日韩亚洲不卡| 香蕉久久夜色精品| 成人私拍视频| 黑人糟蹋人妻hd中文字幕| 亚洲色图狂野欧美| 97se狠狠狠综合亚洲狠狠| 禁断一区二区三区在线| 三级国产在线观看| 日本一区二区精品| 欧美老少配视频| 色噜噜狠狠一区二区三区果冻| 亚洲在线观看| 99热这里有精品| 亚欧黄色av| 在线视频不卡一区二区三区| 午夜剧场成人观在线视频免费观看| 国产精品福利在线播放| 久久91视频| 国产美女极品在线| 131美女爱做视频| 久久久久久欧美精品色一二三四| 亚洲欧美在线免费观看| 色视频欧美一区二区三区| 久久久久9999亚洲精品| 春暖花开成人亚洲区| 日韩色在线观看| 国内精品久久久久久久影视简单 | 久久6精品影院| 一区二区三区在线影院| 国产传媒日韩欧美成人| 天天精品视频| 在线观看二区| 日韩欧美亚洲一区| 精品久久久久久中文字幕2017| 欧美 日韩 国产在线| 51ⅴ精品国产91久久久久久| 精品免费日韩av| 69av一区二区三区| 日本精品一区二区三区四区的功能| 在线电影一区二区| 日韩久久视频| 欧美限制电影| 午夜成年人在线免费视频| 国模吧无码一区二区三区| 国产xxxx振车| 99在线免费视频观看| 日韩精品久久一区| 日本一区二区三区视频在线播放| 国产精品久久一区| 欧美中文在线视频| 日本一区二区三区在线播放| 992tv成人免费视频| 69久久夜色精品国产69乱青草| 国产一区二区三区18| 久久国内精品一国内精品| 在线激情影院一区| 久久久成人精品视频| 久久久av亚洲男天堂| 久久高清视频免费| 国产成人一区二区三区| 9.1国产丝袜在线观看| 人人做人人澡人人爽欧美| 欧美久久精品午夜青青大伊人| 欧美乱妇15p| 亚洲成人精品久久久| 亚洲欧美在线免费观看| 欧美大荫蒂xxx| 亚洲free性xxxx护士白浆| 国内精品视频在线| 91精品国产综合久久久久久久久| 国产精自产拍久久久久久| 精品久久久久久综合日本| av不卡在线免费观看| 人妻少妇被粗大爽9797pw| 日韩亚洲欧美精品| 精品国产免费一区二区三区 | 日韩视频免费观看高清完整版在线观看| 欧美亚州韩日在线看免费版国语版| 精品国产99国产精品| 日韩视频―中文字幕| 国产三级精品网站| 椎名由奈jux491在线播放| 国产美女在线免费观看| 国产偷倩在线播放| 国产在线观看高清视频| 91九色国产在线播放| va中文字幕| 欧美极品少妇xxxxⅹ喷水| 日本高清不卡aⅴ免费网站| 亚洲美女喷白浆| 国产一区二区色| 欧美成人dvd在线视频| 日产精品高清视频免费| 1024亚洲| 欧洲视频在线免费观看| 免费理论片在线观看播放老| 欧美电影免费看| 国产成人一区二区三区影院| 久久国产欧美| 亚洲电影在线免费观看| 亚洲欧美国产精品| 国产蜜臀av在线一区二区三区| 嫩草国产精品入口| 日韩网站在线| 亚洲一区视频在线观看视频| 天天综合色天天| 日韩在线视频观看| 91精品国产高清自在线看超| 成人小视频在线观看免费| 91久久精品一区| 国产色综合天天综合网| 亚洲色图色老头| 欧美大肚乱孕交hd孕妇| 国产精品热久久久久夜色精品三区| 日韩精品电影在线| 国内一区二区在线| 91麻豆精品91久久久久久清纯| 国产成人97精品免费看片| 成人三级视频在线观看一区二区| 亚洲国产午夜伦理片大全在线观看网站| 亚洲天堂2017| 日本三级久久| 日韩电影免费观| 日本五码在线| 天堂视频福利| 天堂成人在线| a视频在线观看| 加勒比色综合久久久久久久久| 久久麻豆精品| 自拍av一区二区三区| 久久久亚洲福利精品午夜| 奇米影视四色在线| 精品国产欧美日韩| 久久精品欧美一区二区三区不卡| 亚洲人吸女人奶水| 国产精品影片在线观看| 国产精品一区二区三区网站| 夜夜嗨av色综合久久久综合网| 欧美xxxx黑人又粗又长密月| 小视频免费在线观看| 成人性生交大片免费看中文网站| 欧美日韩一二三区| 亚洲精品免费在线视频| 最新国产在线拍揄自揄视频| 全国精品久久少妇| 亚洲高清色综合| 亚洲精品欧洲精品| 欧美天堂在线| 欧美日韩亚洲系列| 成人三级视频在线观看一区二区| 亚洲精品少妇久久久久久| 亚洲欧洲一级| 久久久久久亚洲| 最近最好的中文字幕2019免费| 毛片一区二区| 亚洲最新中文字幕| 日韩中文字幕二区| 日韩av自拍| 欧美色视频日本版| 男人添女人下部高潮视频在观看| 日本乱理伦在线| 国产91精品一区二区麻豆网站| 国产精品h在线观看| www在线看| 亚洲三级免费观看| 精品无人乱码一区二区三区的优势| 久久经典视频| 亚洲婷婷综合久久一本伊一区 | 国产欧美一区二区三区在线老狼| 96国产粉嫩美女| 亚州一区二区三区| 亚洲视频网在线直播| 99亚洲精品视频| 午夜在线视频一区二区区别|