91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

jenkins 如何在 k8s 集群中實現動態 agent

發布時間:2020-07-24 20:09:11 來源:網絡 閱讀:2476 作者:wzlinux 欄目:系統運維

一、背景介紹

目前很多企業應用都已經容器化,版本發布比較多,構建的次數也比較多,相對于之前單臺 jenkins 有了很大的挑戰
,傳統的 Jenkins Slave 一主多從方式會存在一些痛點:

  • 主 Master 發生單點故障時,整個流程都不可用了;
  • 每個 Slave 的配置環境不一樣,來完成不同語言的編譯打包等操作,但是這些差異化的配置導致管理起來非常不方便,維護起來也是比較費勁;
  • 資源分配不均衡,有的 Slave 要運行的 job 出現排隊等待,而有的 Slave 處于空閑狀態;
  • 最后資源有浪費,每臺 Slave 可能是實體機或者 VM,當 Slave 處于空閑狀態時,也不會完全釋放掉資源了。
    kubernetes 集群之中,我們正是利用這一容器平臺來實現 jenkins 的自動擴容。

jenkins集群架構圖

jenkins 如何在 k8s 集群中實現動態 agent

從圖上可以看到 Jenkins Master 和 Jenkins Slave 以 Docker Container 形式運行在 Kubernetes 集群的 Node 上,Master 運行在其中一個節點,并且將其配置數據存儲到一個 Volume 上去,Slave 運行在各個節點上,并且它不是一直處于運行狀態,它會按照需求動態的創建并自動刪除。

這種方式的工作流程大致為:當 Jenkins Master 接受到 Build 請求時,會根據配置的 Label 動態創建一個運行在 Docker Container 中的 Jenkins Slave 并注冊到 Master 上,當運行完 Job 后,這個 Slave 會被注銷并且 Docker Container 也會自動刪除,恢復到最初狀態。

這種方式帶來的好處有很多:

  • 服務高可用,當 Jenkins Master 出現故障時,Kubernetes 會自動創建一個新的 Jenkins Master 容器,并且將 Volume 分配給新創建的容器,保證數據不丟失,從而達到集群服務高可用。
  • 動態伸縮,合理使用資源,每次運行 Job 時,會自動創建一個 Jenkins Slave,Job 完成后,Slave 自動注銷并刪除容器,資源自動釋放,而且 Kubernetes 會根據每個資源的使用情況,動態分配 Slave 到空閑的節點上創建,降低出現因某節點資源利用率高,還排隊等待在該節點的情況。
  • 擴展性好,當 Kubernetes 集群的資源嚴重不足而導致 Job 排隊等待時,可以很容易的添加一個 Kubernetes Node 到集群中,從而實現擴展。

二、部署 jenkins

我們把 master 節點部署到 k8s 集群中,大家可以參照 官方 github 文檔進行配置,我這里進行了一點簡化,我這里使用的是 nfs 來存儲 jenkins 的數據,用于進行持久存儲。

kubectl apply -f https://raw.githubusercontent.com/wangzan18/jenkins-agent-k8s-cicd/master/master/jenkins.yaml

說明一下:這里 Service 我們暴漏了端口 8080 和 50000,8080 為訪問 Jenkins Server 頁面端口,50000 為創建的 Jenkins Slave 與 Master 建立連接進行通信的默認端口,如果不暴露的話,Slave 無法跟 Master 建立連接。這里使用 NodePort 方式暴漏端口,并未指定其端口號,由 Kubernetes 系統默認分配,當然也可以指定不重復的端口號(范圍在 30000~32767)。

2.1、配置 kubernetes plugin

Jenkins 的配置過程我這里不再掩飾,我們直接配置 kubernetes plugin。
管理員賬戶登錄 Jenkins Master 頁面,點擊 “系統管理” —> “管理插件” —> “可選插件” —> “Kubernetes plugin” 勾選安裝即可。

jenkins 如何在 k8s 集群中實現動態 agent

安裝完畢后,點擊 “系統管理” —> “系統設置” —> “新增一個云” —> 選擇 “Kubernetes”,然后填寫 Kubernetes 和 Jenkins 配置信息。

jenkins 如何在 k8s 集群中實現動態 agent

說明一下:

  • Name 處默認為 kubernetes,也可以修改為其他名稱,如果這里修改了,下邊在執行 Job 時指定 podTemplate() 參數 cloud 為其對應名稱,否則會找不到,cloud 默認值取:kubernetes。
  • Kubernetes URL 處我填寫了 https://kubernetes 這里我填寫了 Kubernetes Service 對應的 DNS 記錄,通過該 DNS 記錄可以解析成該 Service 的 Cluster IP,注意:也可以填寫 https://kubernetes.default.svc.cluster.local 完整 DNS 記錄,因為它要符合 <svc_name>.<namespace_name>.svc.cluster.local 的命名方式,或者直接填寫外部 Kubernetes 的地址 https://<ClusterIP>:<Ports>
  • Jenkins URL 處我填寫了 http://jenkins.default:8080 ,跟上邊類似,也是使用 Jenkins Service 對應的 DNS 記錄,不過要指定為 8080 端口,因為我們設置暴漏 8080 端口。同時也可以用 http://<ClusterIP>:<Node_Port> 方式。

配置完畢,可以點擊 “Test Connection” 按鈕測試是否能夠連接的到 Kubernetes,如果顯示 Connection test successful 則表示連接成功,配置沒有問題。

因為我們的 jenkins 是集群內部的 pod,所以它是可以直接和 kubernetes api 進行通信,并且我們也賦予了相應的權限,如果說 master 是創建在集群外部的,我們需要提前為 jenkins agent 創建一個 service account,然后把相應的 token 賦予到憑據的 sercet text。

三、pipeline job 驗證測試

3.1、pipeline 支持

創建一個 Pipeline 類型 Job 并命名為 jenkins-pipeline,然后在 Pipeline 腳本處填寫一個簡單的測試腳本如下:

podTemplate {
    node(POD_LABEL) {
        stage('Run shell') {
            sh 'echo hello world'
        sh 'sleep 60'
        }
    }
}

創建還 job 之后,點擊構建,我們會在構建隊列中發現一個待執行的 job,因為我們在 pipeline 中要求 jenkins agent 節點的名稱為 POD_LABEL,沒有發現這個 agent,所以會去請求 kubernetes 去創建 agent 節點。
jenkins 如何在 k8s 集群中實現動態 agent

jenkins agent 節點創建好了之后,會去 jenkins master 注冊,并去執行隊列中的 job,完成之后取消注冊,并自行銷毀。
jenkins 如何在 k8s 集群中實現動態 agent

我們還可以去 console 查看構建日志。

jenkins 如何在 k8s 集群中實現動態 agent

也可以在 k8s 上面看到啟動的 agent 容器。

wangzan:~/k8s $ kubectl get pod --show-labels
NAME                                   READY   STATUS    RESTARTS   AGE   LABELS
jenkins-5df4dff655-f4gk8               1/1     Running   0          25m   app=jenkins,pod-template-hash=5df4dff655
jenkins-pipeline-5-lbs5j-b2jl6-0mk2g   1/1     Running   0          7s    jenkins/label=jenkins-pipeline_5-lbs5j,jenkins=slave
myapp1                                 1/1     Running   0          21h   app=myapp1

podTemplate

The podTemplate is a template of a pod that will be used to create agents. It can be either configured via the user interface, or via pipeline.
Either way it provides access to the following fields:

  • cloud The name of the cloud as defined in Jenkins settings. Defaults to kubernetes
  • name The name of the pod.
  • namespace The namespace of the pod.
  • label The label of the pod. Can be set to a unique value to avoid conflicts across builds, or omitted and POD_LABEL will be defined inside the step.
  • yaml yaml representation of the Pod, to allow setting any values not supported as fields
  • yamlMergeStrategy merge() or override(). Controls whether the yaml definition overrides or is merged with the yaml definition inherited from pod templates declared with inheritFrom. Defaults to override().
  • containers The container templates that are use to create the containers of the pod (see below).
  • serviceAccount The service account of the pod.
  • nodeSelector The node selector of the pod.
  • nodeUsageMode Either 'NORMAL' or 'EXCLUSIVE', this controls whether Jenkins only schedules jobs with label expressions matching or use the node as much as possible.
  • volumes Volumes that are defined for the pod and are mounted by ALL containers.
  • envVars Environment variables that are applied to ALL containers.
    • envVar An environment variable whose value is defined inline.
    • secretEnvVar An environment variable whose value is derived from a Kubernetes secret.
  • imagePullSecrets List of pull secret names, to pull images from a private Docker registry.
  • annotations Annotations to apply to the pod.
  • inheritFrom List of one or more pod templates to inherit from (more details below).
  • slaveConnectTimeout Timeout in seconds for an agent to be online (more details below).
  • podRetention Controls the behavior of keeping slave pods. Can be 'never()', 'onFailure()', 'always()', or 'default()' - if empty will default to deleting the pod after activeDeadlineSeconds has passed.
  • activeDeadlineSeconds If podRetention is set to 'never()' or 'onFailure()', pod is deleted after this deadline is passed.
  • idleMinutes Allows the Pod to remain active for reuse until the configured number of minutes has passed since the last step was executed on it.
  • showRawYaml Enable or disable the output of the raw Yaml file. Defaults to true
  • runAsUser The user ID to run all containers in the pod as.
  • runAsGroup The group ID to run all containers in the pod as.
  • hostNetwork Use the hosts network.

3.2、Container Group

前面的 pipeline 中的 agent 是使用的默認的鏡像 jenkins/jnlp-slave:3.35-5-alpine,我們也可以添加其他的一些鏡像到 pod 里面。
創建一個 Pipeline 類型 Job 并命名為 jenkins-pipeline-container,然后在 Pipeline 腳本處填寫一個簡單的測試腳本如下:

podTemplate(containers: [
    containerTemplate(name: 'maven', image: 'maven:3.3.9-jdk-8-alpine', ttyEnabled: true, command: 'cat'),
    containerTemplate(name: 'golang', image: 'golang:1.8.0', ttyEnabled: true, command: 'cat')
  ]) {

    node(POD_LABEL) {
        stage('Get a Maven project') {
            git 'https://github.com/jenkinsci/kubernetes-plugin.git'
            container('maven') {
                stage('Build a Maven project') {
                    sh 'mvn -B clean install'
                }
            }
        }

        stage('Get a Golang project') {
            git url: 'https://github.com/hashicorp/terraform.git'
            container('golang') {
                stage('Build a Go project') {
                    sh """
                    mkdir -p /go/src/github.com/hashicorp
                    ln -s `pwd` /go/src/github.com/hashicorp/terraform
                    cd /go/src/github.com/hashicorp/terraform && make core-dev
                    """
                }
            }
        }

    }
}

jenkins 如何在 k8s 集群中實現動態 agent

從 k8s 中也可以看到 pod 中存在三個容器。

wangzan:~/k8s $ kubectl get pod --show-labels
NAME                                             READY   STATUS    RESTARTS   AGE   LABELS
jenkins-5df4dff655-f4gk8                         1/1     Running   0          42m   app=jenkins,pod-template-hash=5df4dff655
jenkins-pipeline-container-1-6zf73-chltq-b0rjt   3/3     Running   0          70s   jenkins/label=jenkins-pipeline-container_1-6zf73,jenkins=slave
myapp1           

containerTemplate

The containerTemplate is a template of container that will be added to the pod. Again, its configurable via the user interface or via pipeline and allows you to set the following fields:

  • name The name of the container.
  • image The image of the container.
  • envVars Environment variables that are applied to the container (supplementing and overriding env vars that are set on pod level).
    • envVar An environment variable whose value is defined inline.
    • secretEnvVar An environment variable whose value is derived from a Kubernetes secret.
  • command The command the container will execute.
  • args The arguments passed to the command.
  • ttyEnabled Flag to mark that tty should be enabled.
  • livenessProbe Parameters to be added to a exec liveness probe in the container (does not support httpGet liveness probes)
  • ports Expose ports on the container.
  • alwaysPullImage The container will pull the image upon starting.
  • runAsUser The user ID to run the container as.
  • runAsGroup The group ID to run the container as.

3.3、使用 SCM

使用 SCM 可以有很多好處:

  • 每次修改 pipeline 我們不用到 console 中去修改;
  • 開發人員可以方便的自定義 pipeline,選擇自己需要的 container;
  • 當 jenkins 數據丟失,也不會丟掉 pipeline。

使用 SCM ,就需要我們把上面所寫的 pipeline 代碼放到 Jenkinsfile,一般是這個名字,當然也可以自定義名稱,我們把上面第一個案例使用 SCM 運行一下,首先就是修改我們的 job。
我的 jenkinsfile 地址為 https://github.com/wangzan18/jenkins-agent-k8s-cicd/blob/master/jenkinsfile/jenkins-pipeline-podtemplate.jenkinsfile 。

jenkins 如何在 k8s 集群中實現動態 agent

然后在控制臺查看運行日志。

jenkins 如何在 k8s 集群中實現動態 agent

其他參數大家可以根據自己的情況進行設定。

四、普通 job 驗證

Jenkins 中除了使用 Pipeline 方式運行 Job 外,通常我們也會使用普通類型 Job,如果也要想使用 kubernetes plugin 來構建任務
那么就需要點擊 “系統管理” —> “系統設置” —> “云” —> “Kubernetes” —> “Add Pod Template” 進行配置 “Kubernetes Pod Template” 信息。

jenkins 如何在 k8s 集群中實現動態 agent

Labels 名:在配置非 pipeline 類型 Job 時,用來指定任務運行的節點。
Containers Name: 這里要注意的是,如果 Name 配置為 jnlp,那么 Kubernetes 會用下邊指定的 Docker Image 代替默認的 jenkinsci/jnlp-slave 鏡像,否則,Kubernetes plugin 還是會用默認的 jenkinsci/jnlp-slave 鏡像與 Jenkins Server 建立連接,即使我們指定其他 Docker Image。這里我配置為 jenkins-slave,意思就是使用 plugin 默認的鏡像與 jenkins server 建立連接,當我選擇 jnlp 的時候,發現鏡像無法與 jenkins server 建立連接,具體情況我也不太清楚,也有可能是鏡像的問題。

新建一個自由風格的 Job 名稱為 jenkins-simple,配置 “Restrict where this project can be run” 勾選,在 “Label Expression” 后邊輸出我們上邊創建模板是指定的 Labels 名稱 jnlp-agent,意思是指定該 Job 匹配 jenkins-slave 標簽的 Slave 上運行。

jenkins 如何在 k8s 集群中實現動態 agent

效果如我們預期所示:
jenkins 如何在 k8s 集群中實現動態 agent

五、自定義 jenkins-slave 鏡像

前面我隨便在 https://hub.docker.com/r/jenkins/jnlp-slave 中選擇了一個鏡像,發現無法與 jenkins server 建立連接,那我們就自己制作一個鏡像。

通過 kubernetest plugin 默認提供的鏡像 jenkinsci/jnlp-slave 可以完成一些基本的操作,它是基于 openjdk:8-jdk 鏡像來擴展的,但是對于我們來說這個鏡像功能過于簡單,比如我們想執行 Maven 編譯或者其他命令時,就有問題了,那么可以通過制作自己的鏡像來預安裝一些軟件,既能實現 jenkins-slave 功能,又可以完成自己個性化需求,那就比較不錯了。如果我們從頭開始制作鏡像的話,會稍微麻煩些,不過可以參考 jenkinsci/jnlp-slave 和 jenkinsci/docker-slave 這兩個官方鏡像來做,注意:jenkinsci/jnlp-slave 鏡像是基于 jenkinsci/docker-slave 來做的。這里我簡單演示下,基于 jenkinsci/jnlp-slave:latest 鏡像,在其基礎上做擴展,安裝 Maven 到鏡像內,然后運行驗證是否可行吧,大家可以查看我的鏡像:https://hub.docker.com/r/wangzan18/jenkins-slave-maven 。

podTemplate(containers: [
    containerTemplate(
        name: 'jnlp', 
        image: 'wangzan18/jenkins-agent:maven-3.6.3', 
        alwaysPullImage: false, 
        args: '${computer.jnlpmac} ${computer.name}'),
  ]) {

    node(POD_LABEL) {
        stage('git pull') {
           echo "hello git"
        }
        stage('build') {
           sh 'mvn -version'
        }
        stage('test') {
            echo "hello test"
        }
        stage('deploy') {
            echo "hello deploy"
            sleep 10
        }
    }
}

這里 containerTemplate 的 name 屬性必須叫 jnlp,Kubernetes 才能用自定義 images 指定的鏡像替換默認的 jenkinsci/jnlp-slave 鏡像。此外,args 參數傳遞兩個 jenkins-slave 運行需要的參數。還有一點就是這里并不需要指定 container('jnlp'){...} 了,因為它被 Kubernetes 指定了要被執行的容器,所以直接執行 Stage 就可以了。

jenkins 如何在 k8s 集群中實現動態 agent

可以看到已經達到我們想要的效果,確實也是使用我們自定義的 jenkins-slave 鏡像。

問題:非pipeline job

我測試的過程中,使用自由風格的 job,不管使用什么鏡像,鏡像就是無法自主連接 jenkins server,目前我也不清楚是哪里的原因,如果有知道的小伙伴可以留言回復。

jenkins 如何在 k8s 集群中實現動態 agent

參考文檔:https://github.com/jenkinsci/kubernetes-plugin

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

太康县| 高碑店市| 正镶白旗| 镇宁| 新泰市| 云霄县| 商水县| 兖州市| 聊城市| 凤翔县| 竹山县| 广元市| 五常市| 绥宁县| 公主岭市| 西昌市| 大宁县| 郓城县| 维西| 福安市| 淅川县| 罗定市| 永仁县| 汶川县| 韶山市| 宁化县| 中牟县| 抚顺县| 阿尔山市| 元朗区| 宜君县| 荣昌县| 青岛市| 鄂伦春自治旗| 榆树市| 泽库县| 咸宁市| 务川| 胶南市| 股票| 江山市|