操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    enkins分布式構(gòu)建與并行構(gòu)建

    jenkins的架構(gòu)

    Jenkins采用的是“master+agent(slave)”架構(gòu)。Jenkins master負(fù)責(zé)提供界面、處理HTTP請(qǐng)求及管理構(gòu)建環(huán)境;構(gòu)建的執(zhí)行則由Jenkins agent負(fù)責(zé)

    Jenkins agent的橫向擴(kuò)容:只需要增加agent就可以輕松支持更多的項(xiàng)目同時(shí)執(zhí)行

    ? node:節(jié)點(diǎn),指包含Jenkins環(huán)境及有能力執(zhí)行項(xiàng)目的機(jī)器。master和agent都被認(rèn)為是節(jié)點(diǎn)。

    ? executor:執(zhí)行器,是真正執(zhí)行項(xiàng)目的單元。一個(gè)執(zhí)行器可以被理解為一個(gè)單獨(dú)的進(jìn)程(事實(shí)上是線程)。在一個(gè)節(jié)點(diǎn)上可以運(yùn)行多個(gè)執(zhí)行器。

    ? agent:代理,在概念上指的是相對(duì)于Jenkins master的一種角色,實(shí)際上是指運(yùn)行在機(jī)器或容器中的一個(gè)程序,它會(huì)連接上Jenkins master,并執(zhí)行Jenkins master分配給它的任務(wù)。

    增加agent支持并行構(gòu)建

    Jenkins agent作為一個(gè)負(fù)責(zé)執(zhí)行任務(wù)的程序,它需要與Jenkins master建立雙向連接。連接方式有多種,這也代表有多種增加agent的方式。

    標(biāo)簽是什么

    當(dāng)agent數(shù)量變多時(shí),如何知道哪些agent支持JDK 8、哪些agent支持Node.js環(huán)境呢?我們可以通過給agent打標(biāo)簽(有時(shí)也稱為tag)來確定。

    同一個(gè)agent可以擁有多個(gè)標(biāo)簽。在標(biāo)簽名中不能包含空格,也不能包含!、&、|、<、>、(、)這些特殊字符中的任何一個(gè)。因?yàn)榘厥庾址臉?biāo)簽名與標(biāo)簽表達(dá)式(用于過濾agent)沖突。

    通過JNLP協(xié)議增加agent

    Java網(wǎng)絡(luò)啟動(dòng)協(xié)議(JNLP)是一種允許客戶端啟動(dòng)托管在遠(yuǎn)程Web服務(wù)器上的應(yīng)用程序的協(xié)議。Jenkins master與agent通過JNLP協(xié)議進(jìn)行通信。而Java Web Start(JWS)可以被理解為JNLP協(xié)議的一個(gè)客戶端。

    (1)進(jìn)入Manage Jenkins→Global Security→TCP port for JNLP配置頁面,如圖所示。我們可以選擇開放固定端口或者隨機(jī)開放Jenkins master的一個(gè)端口來提供JNLP服務(wù)。

    隨機(jī)開放端口不利于自動(dòng)化,所以選擇開放固定端口。此端口用于master與agent之間的TCP通信,與訪問Jenkins界面時(shí)的端口有別。

    (2)進(jìn)入Manage Jenkins→Manage Nodes→New Node頁面,如圖所示。選項(xiàng)“Permanent Agent”指的是常駐代理客戶端。

    單擊“OK”按鈕后,進(jìn)入node配置頁面

    ? Name:agent名稱。

    ? Remote root directory:agent機(jī)器上的工作目錄(Jenkins master不關(guān)心),使用絕對(duì)路徑。

    ? Labels:agent的標(biāo)簽。

    ? Usage:agent的使用策略。有兩種:

    ? ? Use this node as much as possible,盡可能使用此agent。

    ? ? Only build jobs with label expressions matching this node,只有當(dāng)構(gòu)建任務(wù)符合本agent的標(biāo)簽時(shí),才使用此agent。

    ? Launch method:agent的運(yùn)行方式。JNLP協(xié)議的agent選擇“Launch agent via Java WebStart”。配置完成后進(jìn)入節(jié)點(diǎn)列表頁面,此時(shí)master節(jié)點(diǎn)的狀態(tài)顯示是在線的,即可用的

    當(dāng)節(jié)點(diǎn)不可用時(shí),如node1節(jié)點(diǎn),Jenkins master不再分配任務(wù)給它

    (3)單擊節(jié)點(diǎn)列表中的node1,跳轉(zhuǎn)到“Agent node1”頁面,顯示詳情如圖所示。

    JNLP協(xié)議agent連接Jenkins master還有3種方式。一是在agent機(jī)器的瀏覽器中打開此頁面,單擊“Launch”按鈕。二是通過javaws命令從master節(jié)點(diǎn)下載Java Web Start程序。三是無界面方式連接。第3種方式不需要界面操作,我們毫不猶豫地選擇它,因?yàn)橹挥羞@樣才方便自動(dòng)化。

    (4)SSH登錄到Jenkins agent機(jī)器,下載agent.jar文件(JNLP協(xié)議的客戶端),下載路徑為:<Jenkins master地址>/jenkins/jnlpJars/agent.jar。假設(shè)這臺(tái)機(jī)器已經(jīng)安裝好JDK,則執(zhí)行命令:java-jar agent.jar-jnlpUrl http://192.168.23.11:8667/jenkins/computer/node1/slave-agent.jnlp-workDir "/app"。其中-workDir參數(shù)用于指定agent的工作目錄。當(dāng)命令提示連接成功后,我們打開Jenkins master頁面,查看node1的詳情頁,如圖所示,表示已經(jīng)連接成功。

    agent與master之間的連接過程沒有任何權(quán)限控制。這是因?yàn)槲覀儧]有設(shè)置Jenkins的安全控制(默認(rèn)Jenkins向匿名用戶開放所有權(quán)限)。當(dāng)設(shè)置了安全控制后,新建node,我們將在node的詳情頁看到連接master的命令就變成了:

    其中-secret**就是agent與master之間的連接憑證。每一個(gè)JNLP客戶端的憑證都不一樣。

    提示:升級(jí)Jenkins后,也需要重新下載agent.jar。agent.jar需要與Jenkins master同步升級(jí)。

    最后,我們看到通過JNLP協(xié)議增加agent的方式是需要在Jenkins界面上進(jìn)行手動(dòng)操作的(增加節(jié)點(diǎn)的操作)。這部分是無法自動(dòng)化的,因此,我們只在以下場(chǎng)景中使用這種方式。

    ? 在安全性要求相對(duì)較高的情況下,只能手動(dòng)增加agent。

    ? 增加Windows agent。

    通過Swarm插件增加agent

    Swarm插件只需要啟動(dòng)Swarm客戶端(指定Jenkins master地址),master與agent就會(huì)自動(dòng)建立連接。

    (1)安裝Swarm插件。

    (2)確保Jenkins agent機(jī)器上安裝有JDK。

    (3)在Jenkins agent機(jī)器上下載Swarm客戶端

    (4)在Jenkins agent上啟動(dòng)swarm-client連接服務(wù)器端。

    當(dāng)日志顯示連接成功后,在節(jié)點(diǎn)列表頁面可以看到Swarm客戶端連接成功

    swarm-client部分參數(shù)的介紹。

    ?-deleteExistingClients:如果Jenkins master上已經(jīng)存在同名的node,則先刪除。(慎用)

    ?-description:描述。

    ?-disableClientsUniqueId:默認(rèn)Swarm會(huì)在node名稱后加上一個(gè)唯一ID。加上此參數(shù)后,代表取消加上唯一ID。

    ?-disableSslVerification:取消SSL校驗(yàn)。

    ?-executors N:設(shè)置executor的個(gè)數(shù)。

    ?-labels VAL:分配給agent的標(biāo)簽,如果有多個(gè),則使用空格分隔。注意,這是給agent打標(biāo)簽。

    ?-master VAL:指定Jenkins master的URL。

    ?-mode MODE:Jenkins master分配項(xiàng)目給agent時(shí)使用的格式,即有兩種格式,即normal(盡可能分配job)和exclusive(當(dāng)與指定label匹配時(shí)才分配項(xiàng)目)。

    ?-username VAL:連接時(shí)使用的用戶名。

    ?-password VAL:連接時(shí)使用的密碼。不推薦使用。

    ?-passwordEnvVariable VAL:從環(huán)境變量中讀取密碼。推薦使用。

    ?-passwordFile VAL:從文本文件中讀取密碼。推薦使用。

    ?-retry N:最大重連次數(shù),默認(rèn)無次數(shù)限制。

    ?-retryInterval N:每次重連間隔時(shí)長,單位為秒。默認(rèn)值為10秒。

    agent部分詳解

    如何在pipeline中使用標(biāo)簽?zāi)?/p>

    agent部分描述的是整個(gè)pipeline或在特定階段執(zhí)行任務(wù)時(shí)所在的agent。換句話說,Jenkinsmaster根據(jù)此agent部分決定將任務(wù)分配到哪個(gè)agent上執(zhí)行。agent部分必須在pipeline塊內(nèi)的頂層定義,而stage塊內(nèi)的定義是可選的。

    agent any告訴Jenkins master任何可用的agent都可以執(zhí)行。

    agent部分的定義可以放在階段中,用于指定該stage執(zhí)行時(shí)的agent。

    注意:pipeline塊內(nèi)的agent部分是必需的,不能省略。

    通過標(biāo)簽指定agent:

    當(dāng)pipeline需要在JDK 8環(huán)境下進(jìn)行構(gòu)建時(shí),就需要通過標(biāo)簽來指定agent。代碼如下:

    有些構(gòu)建任務(wù)是需要在JDK 8及Windows環(huán)境下執(zhí)行的。也就是說,我們需要過濾同時(shí)具有windows和jdk8標(biāo)簽的agent。

    上文中,在增加agent時(shí),已經(jīng)配置好了該agent上的默認(rèn)工作目錄路徑,但是agent部分允許我們對(duì)工作目錄進(jìn)行自定義。node除了label選項(xiàng),還提供了另一個(gè)選項(xiàng)——customWorkspace,自定義工作目錄,寫法如下:

    customWorkspace選項(xiàng)除了寫絕對(duì)路徑,還可以寫相對(duì)于默認(rèn)工作目錄路徑的相對(duì)路徑。

    不分配節(jié)點(diǎn) : agent none

    when指令的beforeAgent選項(xiàng) :

    在默認(rèn)情況下,階段內(nèi)所有的代碼都將在指定的Jenkins agent上執(zhí)行。when指令提供了一個(gè)beforeAgent選項(xiàng),當(dāng)它的值為true時(shí),只有符合when條件時(shí)才會(huì)進(jìn)入該Jenkins agent。這樣就可以避免沒有必要的工作空間的分配,也就不需要等待可用的Jenkins agent了。在某些場(chǎng)景下,beforeAgent選項(xiàng)通常用于加速pipeline的執(zhí)行。示例如下:

    只有分支為production時(shí),才會(huì)進(jìn)入“Example Deploy”階段。這樣就可以避免在some-label的agent中拉取代碼,從而達(dá)到加速pipeline執(zhí)行的目的。

    KubeVela 作為一個(gè)聲明式的應(yīng)用交付控制平面,天然就可以以 GitOps 的方式進(jìn)行使用,并且這樣做會(huì)在 GitOps 的基礎(chǔ)上為用戶提供更多的益處和端到端的體驗(yàn),包括:

    • 應(yīng)用交付工作流(CD 流水線):KubeVela 支持在 GitOps 模式中描述過程式的應(yīng)用交付,而不只是簡(jiǎn)單的聲明終態(tài);
    • 處理部署過程中的各種依賴關(guān)系和拓?fù)浣Y(jié)構(gòu);
    • 在現(xiàn)有各種 GitOps 工具的語義之上提供統(tǒng)一的上層抽象,簡(jiǎn)化應(yīng)用交付與管理過程;
    • 統(tǒng)一進(jìn)行云服務(wù)的聲明、部署和服務(wù)綁定;
    • 提供開箱即用的交付策略(金絲雀、藍(lán)綠發(fā)布等);
    • 提供開箱即用的混合云/多云部署策略(放置規(guī)則、集群過濾規(guī)則等);
    • 在多環(huán)境交付中提供 Kustomize 風(fēng)格的 Patch 來描述部署差異,而無需學(xué)習(xí)任何 Kustomize 本身的細(xì)節(jié)

    GitOps 模式需要依賴 FluxCD 插件,所以在使用 GitOps 模式下交付應(yīng)用之前需要先啟用 FluxCD 插件。

    vela addon enable fluxcd

    GitOps 工作流分為 CI 和 `CD 兩個(gè)部分:

    • CI:持續(xù)集成對(duì)業(yè)務(wù)代碼進(jìn)行代碼構(gòu)建、構(gòu)建鏡像并推送至鏡像倉庫。目前有許多成熟的 CI 工具:如開源項(xiàng)目常用的 GitHub Action、Travis 等,以及企業(yè)中常用的 Jenkins、Tekton 等,KubeVela 圍繞 GitOps 可以對(duì)接任意工具下的 CI 流程。
    • CD:持續(xù)部署會(huì)自動(dòng)更新集群中的配置,如將鏡像倉庫中的最新鏡像更新到集群中。目前主要有兩種方案的 CD:
      • Push-Based:Push 模式的 CD 主要是通過配置 CI 流水線來完成的,這種方式需要將集群的訪問秘鑰共享給 CI,從而使得 CI 流水線能夠通過命令將更改推送到集群中。前面我們講解的 Jenkins 方式就屬于該方案。
      • Pull-Based:Pull 模式的 CD 會(huì)在集群中監(jiān)聽倉庫(代碼倉庫或者配置倉庫)的變化,并且將這些變化同步到集群中。這種方式與 Push 模式相比,由集群主動(dòng)拉取更新,從而避免了秘鑰暴露的問題。前面課程中我們講解的 Argo CD 與 Flux CD 就屬于這種模式。

    而交付面向的人員有以下兩種:

    • 面向平臺(tái)管理員/運(yùn)維人員的基礎(chǔ)設(shè)施交付,用戶可以通過直接更新倉庫中的配置文件,從而更新集群中的基礎(chǔ)設(shè)施配置,如系統(tǒng)的依賴軟件、安全策略、存儲(chǔ)、網(wǎng)絡(luò)等基礎(chǔ)設(shè)施配置。
    • 面向終端開發(fā)者的交付,用戶的代碼一旦合并到應(yīng)用代碼倉庫,就自動(dòng)化觸發(fā)集群中應(yīng)用的更新,可以更高效的完成應(yīng)用的迭代,與 KubeVela 的灰度發(fā)布、流量調(diào)撥、多集群部署等功能結(jié)合可以形成更為強(qiáng)大的自動(dòng)化發(fā)布能力。

    面向平臺(tái)管理員/運(yùn)維人員的交付

    如下圖所示,對(duì)于平臺(tái)管理員/運(yùn)維人員而言,他們并不需要關(guān)心應(yīng)用的代碼,所以只需要準(zhǔn)備一個(gè) Git 配置倉庫并部署 KubeVela 配置文件,后續(xù)對(duì)于應(yīng)用及基礎(chǔ)設(shè)施的配置變動(dòng),便可通過直接更新 Git 配置倉庫來完成,使得每一次配置變更可追蹤。

    這里我們將部署一個(gè) MySQL 數(shù)據(jù)庫作為項(xiàng)目的基礎(chǔ)設(shè)施,同時(shí)部署一個(gè)業(yè)務(wù)應(yīng)用,使用這個(gè)數(shù)據(jù)庫。配置倉庫的目錄結(jié)構(gòu)如下:

    • clusters/ 中包含集群中的 KubeVela GitOps 配置,用戶需要將 clusters/ 中的文件手動(dòng)部署到集群中。這個(gè)是一次性的管控操作,執(zhí)行完成后,KubeVela 便能自動(dòng)監(jiān)聽配置倉庫中的文件變動(dòng)且自動(dòng)更新集群中的配置。其中,clusters/apps.yaml 將監(jiān)聽 apps/ 下所有應(yīng)用的變化,clusters/infra.yaml 將監(jiān)聽 infrastructure/ 下所有基礎(chǔ)設(shè)施的變化。
    • apps/ 目錄中包含業(yè)務(wù)應(yīng)用的所有配置,在本例中為一個(gè)使用數(shù)據(jù)庫的業(yè)務(wù)應(yīng)用。
    • infrastructure/ 中包含一些基礎(chǔ)設(shè)施相關(guān)的配置和策略,在本例中為 MySQL 數(shù)據(jù)庫。
    ├── apps
    │ └── my-app.yaml
    ├── clusters
    │ ├── apps.yaml
    │ └── infra.yaml
    └── infrastructure
    └── mysql.yaml

    KubeVela 建議使用如上的目錄結(jié)構(gòu)管理你的 GitOps 倉庫。clusters/ 中存放相關(guān)的 KubeVela GitOps 配置并需要被手動(dòng)部署到集群中,apps/infrastructure/ 中分別存放你的應(yīng)用和基礎(chǔ)設(shè)施配置。通過把應(yīng)用和基礎(chǔ)配置分開,能夠更為合理的管理你的部署環(huán)境,隔離應(yīng)用的變動(dòng)影響。

    clusters/ 目錄

    首先,我們來看下 clusters 目錄,這也是 KubeVela 對(duì)接 GitOps 的初始化操作配置目錄。

    clusters/infra.yaml 為例:

    apiVersion: core.oam.dev/v1beta1
    kind: Application
    metadata:
    name: infra
    spec:
    components:
    - name: database-config
    type: kustomize
    properties:
    repoType: git
    # 將此處替換成你需要監(jiān)聽的 git 配置倉庫地址
    url: https://github.com/cnych/KubeVela-GitOps-Infra-Demo
    # 如果是私有倉庫,還需要關(guān)聯(lián) git secret
    # secretRef: git-secret
    # 自動(dòng)拉取配置的時(shí)間間隔,由于基礎(chǔ)設(shè)施的變動(dòng)性較小,此處設(shè)置為十分鐘
    pullInterval: 10m
    git:
    # 監(jiān)聽變動(dòng)的分支
    branch: main
    # 監(jiān)聽變動(dòng)的路徑,指向倉庫中 infrastructure 目錄下的文件
    path: ./infrastructure

    apps.yamlinfra.yaml 幾乎保持一致,只不過監(jiān)聽的文件目錄有所區(qū)別。在 apps.yaml 中,properties.path 的值將改為 ./apps,表明監(jiān)聽 apps/ 目錄下的文件變動(dòng)。

    cluster 文件夾中的 GitOps 管控配置文件需要在初始化的時(shí)候一次性手動(dòng)部署到集群中,在此之后 KubeVela 將自動(dòng)監(jiān)聽 apps/ 以及 infrastructure/ 目錄下的配置文件并定期更新同步。

    apps/ 目錄

    apps/ 目錄中存放著應(yīng)用配置文件,這是一個(gè)配置了數(shù)據(jù)庫信息以及 Ingress 的簡(jiǎn)單應(yīng)用。該應(yīng)用將連接到一個(gè) MySQL 數(shù)據(jù)庫,并簡(jiǎn)單地啟動(dòng)服務(wù)。在默認(rèn)的服務(wù)路徑下,會(huì)顯示當(dāng)前版本號(hào)。在 /db 路徑下,會(huì)列出當(dāng)前數(shù)據(jù)庫中的信息。

    apiVersion: core.oam.dev/v1beta1
    kind: Application
    metadata:
    name: my-app
    namespace: default
    spec:
    components:
    - name: my-server
    type: webservice
    properties:
    image: cnych/kubevela-gitops-demo:main-76a34322-1697703461
    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: scaler
    properties:
    replicas: 1
    - type: gateway
    properties:
    class: nginx
    classInSpec: true
    domain: vela-gitops-demo.k8s.local
    http:
    /: 8088
    pathType: ImplementationSpecific

    這是一個(gè)使用了 KubeVela 內(nèi)置組件類型 webservice 的應(yīng)用,該應(yīng)用綁定了 gateway 運(yùn)維特征。通過在應(yīng)用中聲明運(yùn)維能力的方式,只需一個(gè)文件,便能將底層的 Deployment、Service、Ingress 集合起來,從而更為便捷地管理應(yīng)用。

    infrastructure/ 目錄

    infrastructure/ 目錄下存放一些基礎(chǔ)設(shè)施的配置。此處我們使用 mysql controller 來部署了一個(gè) MySQL 集群。

    apiVersion: core.oam.dev/v1beta1
    kind: Application
    metadata:
    name: mysql
    namespace: default
    spec:
    components:
    - name: mysql-secret
    type: k8s-objects # 需要添加一個(gè)包含 ROOT_PASSWORD 的 secret
    properties:
    objects:
    - apiVersion: v1
    kind: Secret
    metadata:
    name: mysql-secret
    type: Opaque
    stringData:
    ROOT_PASSWORD: root321
    - name: mysql-operator
    type: helm
    properties:
    repoType: helm
    url: https://helm-charts.bitpoke.io
    chart: mysql-operator
    version: 0.6.3
    - name: mysql-cluster
    type: raw
    dependsOn:
    - mysql-operator
    - mysql-secret
    properties:
    apiVersion: mysql.presslabs.org/v1alpha1
    kind: MysqlCluster
    metadata:
    name: mysql-cluster
    spec:
    replicas: 1
    secretName: mysql-secret

    在這個(gè) MySQL 應(yīng)用中,我們添加了 3 個(gè) KubeVela 的組件,第一個(gè)是一個(gè) k8s-objects 類型的組件,也就是直接應(yīng)用 Kubernetes 資源對(duì)象,我們這里需要部署一個(gè) Secret 對(duì)象;然后添加一個(gè) helm 類型的組件,用來部署 MySQL 的 Operator。當(dāng) Operator 部署成功且正確運(yùn)行后,最后我們將開始部署 MySQL 集群。

    部署 clusters/ 目錄下的文件

    配置完以上文件并存放到 Git 配置倉庫后,我們需要在集群中手動(dòng)部署 clusters/ 目錄下的 KubeVela GitOps 配置文件。

    首先,在集群中部署 clusters/infra.yaml。可以看到它自動(dòng)在集群中拉起了 infrastructure/ 目錄下的 MySQL 部署文件:

    $ kubectl apply -f clusters/infra.yaml
    $ vela ls
    APP COMPONENT TYPE TRAITS PHASE HEALTHY STATUS CREATED-TIME
    infra database-config kustomize running healthy 2023-10-19 15:27:28 +0800 CST
    mysql mysql-operator helm running healthy Fetch repository successfully, Create helm release 2023-10-19 15:27:31 +0800 CST
    successfully
    └─ mysql-cluster raw running healthy 2023-10-19 15:27:31 +0800 CST

    至此,我們通過部署 KubeVela GitOps 配置文件,自動(dòng)在集群中拉起了數(shù)據(jù)庫基礎(chǔ)設(shè)施。

    $ kubectl get pods
    NAME READY STATUS RESTARTS AGE
    mysql-cluster-mysql-0 4/4 Running 0 35m
    mysql-operator-0 2/2 Running 0 35m

    通過這種方式,我們可以方便地通過更新 Git 配置倉庫中的文件,從而自動(dòng)化更新集群中的配置。

    面向終端開發(fā)者的交付

    對(duì)于終端開發(fā)者而言,在 KubeVela Git 配置倉庫以外,還需要準(zhǔn)備一個(gè)應(yīng)用代碼倉庫。在用戶更新了應(yīng)用代碼倉庫中的代碼后,需要配置一個(gè) CI 來自動(dòng)構(gòu)建鏡像并推送至鏡像倉庫中。KubeVela 會(huì)監(jiān)聽鏡像倉庫中的最新鏡像,并自動(dòng)更新配置倉庫中的鏡像配置,最后再更新集群中的應(yīng)用配置。使用戶可以達(dá)成在更新代碼后,集群中的配置也自動(dòng)更新的效果,代碼倉庫位于 https://github.com/cnych/KubeVela-GitOps-App-Demo

    準(zhǔn)備代碼倉庫

    準(zhǔn)備一個(gè)代碼倉庫,里面包含一些源代碼以及對(duì)應(yīng)的 Dockerfile。這些代碼將連接到一個(gè) MySQL 數(shù)據(jù)庫,并簡(jiǎn)單地啟動(dòng)服務(wù)。在默認(rèn)的服務(wù)路徑下,會(huì)顯示當(dāng)前版本號(hào)。在 /db 路徑下,會(huì)列出當(dāng)前數(shù)據(jù)庫中的信息,基本代碼如下所示:

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

    我們希望用戶改動(dòng)代碼進(jìn)行提交后,自動(dòng)構(gòu)建出最新的鏡像并推送到鏡像倉庫。這一步 CI 可以通過前面我們講解的 Jenkins 來實(shí)現(xiàn),基本一致。

    首先為代碼倉庫創(chuàng)建一個(gè) Webhook,指向 Jenkins 的觸發(fā)器地址:

    然后在 Jenkins 中創(chuàng)建一個(gè)名為 KubeVela-GitOps-App-Demo 的流水線:

    并勾選 GitHub hook trigger for GITScm polling 觸發(fā)器。

    觸發(fā)器

    然后添加如下所示的流水線腳本:

    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: jenkins
    containers:
    - name: golang
    image: golang:1.16-alpine3.15
    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: 'main', url: 'https://github.com/cnych/KubeVela-GitOps-App-Demo.git'
    env.GIT_COMMIT = checkout.GIT_COMMIT
    env.GIT_BRANCH = checkout.GIT_BRANCH

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

    構(gòu)建后我們就可以將應(yīng)用的鏡像打包后推送到 Docker Hub 去。

    配置秘鑰信息

    在新的鏡像推送到鏡像倉庫后,KubeVela 會(huì)識(shí)別到新的鏡像,并更新倉庫及集群中的 Application 配置文件。因此,我們需要一個(gè)含有 Git 信息的 Secret,使 KubeVela 向 Git 倉庫進(jìn)行提交。部署如下文件,將其中的用戶名和密碼替換成你的 Git 用戶名及密碼(或 Token):

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

    準(zhǔn)備配置倉庫

    配置倉庫與之前面向運(yùn)維人員的配置大同小異,只需要加上與鏡像倉庫相關(guān)的配置即可。

    修改 clusters/ 中的 apps.yaml,該 GitOps 配置會(huì)監(jiān)聽倉庫中 apps/ 下的應(yīng)用文件變動(dòng)以及鏡像倉庫中的鏡像更新:

    # ...... 省略其他的
    imageRepository:
    # 鏡像地址
    image: <your image>
    # 如果這是一個(gè)私有的鏡像倉庫,可以通過 `kubectl create secret docker-registry` 創(chuàng)建對(duì)應(yīng)的鏡像秘鑰并相關(guān)聯(lián)
    secretRef: dockerhub-secret
    filterTags:
    # 可對(duì)鏡像 tag 進(jìn)行過濾
    pattern: "^main-[a-f0-9]+-(?P<ts>[0-9]+)"
    extract: "$ts"
    # 通過 policy 篩選出最新的鏡像 Tag 并用于更新
    policy:
    numerical:
    order: asc
    # 追加提交信息
    commitMessage: "Image: {{range .Updated.Images}}{{println .}}{{end}}"

    修改 apps/my-app.yaml 中的 image 字段,在后面加上 # {"$imagepolicy": "default:apps"} 的注釋,KubeVela 會(huì)通過該注釋去更新對(duì)應(yīng)的鏡像字段,default:apps 是上面 GitOps 配置對(duì)應(yīng)的命名空間和名稱。

    spec:
    components:
    - name: my-server
    type: webservice
    properties:
    image: cnych/kubevela-gitops-demo:main-9e8d2465-1697703645 # {"$imagepolicy": "default:apps"}

    clusters/ 中包含鏡像倉庫配置的文件更新到集群中后,我們便可以通過修改代碼來完成應(yīng)用的更新。

    部署 clusters/apps.yaml

    $ kubectl apply -f clusters/apps.yaml
    $ vela ls
    APP COMPONENT TYPE TRAITS PHASE HEALTHY STATUS CREATED-TIME
    apps apps kustomize running healthy 2023-10-19 16:31:49 +0800 CST
    my-app my-server webservice scaler,gateway runningWorkflow unhealthy Ready:0/1 2023-10-19 16:32:11 +0800 CST
    $ kubectl get pods
    NAME READY STATUS RESTARTS AGE
    my-server-6947fd65f9-84zhv 1/1 Running 0 2m

    這樣我們就可以通過部署 KubeVela GitOps 配置文件,自動(dòng)在集群中拉起應(yīng)用了。我們可以通過 curl 應(yīng)用的 Ingress 來驗(yàn)證結(jié)果是否正確,可以看到目前的版本是 0.1.5,并且成功地連接到了數(shù)據(jù)庫:

    $ kubectl get ingress
    NAME CLASS HOSTS ADDRESS PORTS AGE
    my-server nginx vela-gitops-demo.k8s.local 80 115s
    $ curl -H "Host:vela-gitops-demo.k8s.local" http://192.168.0.100
    Version: 0.1.8
    $ curl -H "Host:vela-gitops-demo.k8s.local" http://192.168.0.100/db
    User: KubeVela
    Description: It's a test user

    修改代碼

    將代碼文件中的 Version 改為 0.2.0,并修改數(shù)據(jù)庫中的數(shù)據(jù):

    const VERSION = "0.2.0"

    ...

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

    提交該改動(dòng)至代碼倉庫,正常我們配置的 CI 流水線就會(huì)自動(dòng)開始構(gòu)建鏡像并推送至鏡像倉庫。

    而 KubeVela 會(huì)通過監(jiān)聽鏡像倉庫,根據(jù)最新的鏡像 Tag 來更新配置倉庫中 apps/ 下的應(yīng)用 my-app

    此時(shí),可以看到配置倉庫中有一條來自 kubevelabot 的提交,提交信息均帶有 Update image automatically. 前綴。你也可以通過 {{range .Updated.Images}}{{println .}}{{end}}commitMessage 字段中追加你所需要的信息。

    經(jīng)過一段時(shí)間后,應(yīng)用 my-app 就自動(dòng)更新了。KubeVela 會(huì)通過你配置的 interval 時(shí)間間隔,來每隔一段時(shí)間分別從配置倉庫及鏡像倉庫中獲取最新信息:

    • 當(dāng) Git 倉庫中的配置文件被更新時(shí),KubeVela 將根據(jù)最新的配置更新集群中的應(yīng)用。
    • 當(dāng)鏡像倉庫中多了新的 Tag 時(shí),KubeVela 將根據(jù)你配置的 policy 規(guī)則,篩選出最新的鏡像 Tag,并更新到 Git 倉庫中。而當(dāng)代碼倉庫中的文件被更新后,KubeVela 將重復(fù)第一步,更新集群中的文件,從而達(dá)到了自動(dòng)部署的效果。

    通用我們可以通過 curl 對(duì)應(yīng)的 Ingress 查看當(dāng)前版本和數(shù)據(jù)庫信息:

    $ kubectl get ingress
    NAME CLASS HOSTS ADDRESS PORTS AGE
    my-server nginx vela-gitops-demo.k8s.local 80 12m

    $ curl -H "Host:vela-gitops-demo.k8s.local" http://<ingress-ip>
    Version: 0.2.0

    $ curl -H "Host:vela-gitops-demo.k8s.local" http://<ingress-ip>/db
    User: KubeVela
    Description: It's a test user

    User: KubeVela2
    Description: It'
    s another test user

    版本已被成功更新!至此,我們完成了從變更代碼,到自動(dòng)部署至集群的全部操作。

    總結(jié)

    在運(yùn)維側(cè),如若需要更新基礎(chǔ)設(shè)施(如數(shù)據(jù)庫)的配置,或是應(yīng)用的配置項(xiàng),只需要修改配置倉庫中的文件,KubeVela 將自動(dòng)把配置同步到集群中,簡(jiǎn)化了部署流程。

    在研發(fā)側(cè),用戶修改代碼倉庫中的代碼后,KubeVela 將自動(dòng)更新配置倉庫中的鏡像,從而進(jìn)行應(yīng)用的版本更新。通過與 GitOps 的結(jié)合,KubeVela 加速了應(yīng)用從開發(fā)到部署的整個(gè)流程。可能你會(huì)覺得這和 Flux CD 不是差不多嗎?的確是這樣的,KubeVela 的 GitOps 功能本身就是依賴 Flux CD 的,但是 KubeVela 的功能可遠(yuǎn)遠(yuǎn)不止于此,比如說上面我們的應(yīng)用使用的 MySQL 數(shù)據(jù)我們是通過 MySQL Operator 來部署的,那如果我現(xiàn)在還換成云資源 RDS 呢?按照以前的方式方法,那么我們需要去云平臺(tái)手動(dòng)開通 RDS 或者使用 Terraform 來進(jìn)行管理,但在 KubeVela 中我們完全可以幫助開發(fā)者集成、編排不同類型的云資源,涵蓋混合多云環(huán)境,讓你用統(tǒng)一地方式去使用不同廠商的云資源。同樣的我們只需要在 GitOps 倉庫中的配置文件 Application 對(duì)象中去添加云資源的管理配置即可,這樣做到了一個(gè)對(duì)象管理多種資源的能力,這也是 KubeVela 的核心能力之一。

    最后如果你覺得應(yīng)用太多管理不太方便,那么我們還可以使用 vela top 命令獲取平臺(tái)的概覽信息以及對(duì)應(yīng)用程序的資源狀態(tài)進(jìn)行診斷。

    參考文檔:https://kubevela.io/zh/docs/end-user/gitops/fluxcd/

網(wǎng)站首頁   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號(hào):冀ICP備2024067069號(hào)-3 北京科技有限公司版權(quán)所有