kubernetes安装jenkins,及配置pipinline

半兽人 发表于: 2022-09-28   最后更新时间: 2022-10-13 20:17:00  
{{totalSubscript}} 订阅, 2,845 游览

摘要

1、kubernetes与Jenkis架构

kubernetes部署Jenkis架构

Jenkins Master 和 Jenkins Slave 以 Pod 形式运行在 Kubernetes 集群的 Node 上,Master是常驻服务,所有的配置数据都存储在一个 Volume 中,Slave 不是一直处于运行状态,它会按照需求动态的创建并自动删除。

2、工作原理

当 Jenkins Master 接受到 Build 请求时,会根据配置的 Label 动态创建一个运行在 Pod 中的 Jenkins Slave 并注册到 Master 上,当运行完 Job 后,这个 Slave 会被注销并且这个 Pod 也会自动删除,恢复到最初状态。

3、优势

相对于部署在虚拟机环境下的Jenkins一主多从架构,将Jenkins部署到K8S会带来以下好处:

  • 服务高可用: 当 Jenkins Master 出现故障时,Kubernetes 会自动创建一个新的 Jenkins Master 容器,并且将 Volume 分配给新创建的容器,保证数据不丢失,从而达到集群服务高可用。

  • 动态伸缩: 合理使用资源,每次运行 Job 时,会自动创建一个 Jenkins Slave,Job 完成后,Slave 自动注销并删除容器,资源自动释放,而且 Kubernetes 会根据每个资源的使用情况,动态分配 Slave 到空闲的节点上创建,降低出现因某节点资源利用率高,还排队等待在该节点的情况。

  • 扩展性:当 Kubernetes 集群的资源严重不足而导致 Job 排队等待时,可以很容易的添加一个 Kubernetes Node 到集群中,从而实现扩展。

开始

Step 1:部署Jenkins

1、创建一个名为 jenkins 的 namespace:

kubectl create namespace jenkins

2、声明一个PVC对象,用做存储

kubectl apply -f https://www.kubebiz.com/raw/KubeBiz/jenkins/latest/PersistentVolumeClaim.yaml

3、以Deployment方式部署Jenkins master

kubectl apply -f https://www.kubebiz.com/raw/KubeBiz/jenkins/latest/Deployment.yaml

4、暴露服务

创建一个 NodePort 类型的服务:

kubectl apply -f https://www.kubebiz.com/raw/KubeBiz/jenkins/latest/NodePort.yaml

查看:

kubectl get svc -n jenkins
NAME             TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
jenkins-export   NodePort   10.100.145.138   <none>        8080:32080/TCP   24s

服务启动成功后,就可以通过 NodePort 访问 jenkins 服务了。

5、创建一个名为 jenkins2 的 ServiceAccount ,并且为其赋予特定的权限,之后在配置Jenkins-Slave时会用到。

kubectl apply -f https://www.kubebiz.com/raw/orchome/jenkins/latest/rbac.yaml

Step 2:安装Kubernetes插件

1、前面我们已经获取到Jenkins的外网IP地址,我们直接在浏览器输入NodeIP:32080,提示需要输入初始化密码,需要先获取jenkins pod名称:

# kubectl get pods -n jenkins
NAME                                  READY   STATUS    RESTARTS   AGE
jenkins-deployment-55f9896fbd-cv5kd   1/1     Running   0          2m19s

2、然后通过 kubectl exec 获取 jenkins 获取初始化密码

kubectl exec jenkins-deployment-55f9896fbd-cv5kd -n jenkins -- cat /var/jenkins_home/secrets/initialAdminPassword

返回密码:

035d0b616c9942fd9b1eeb8fcc8469b4

3、选择推荐安装,添加完管理员帐号admin,即可进入到 jenkins 主界面。

4、接下来安装jenkins依赖插件。

位置 Manage Jenkins -> Manage Plugins -> Available -> Kubernetes勾选安装即可。

kubernets plugin

kubernets插件,它能够动态的生成 Slave 的 Pod。

安装插件相对较慢,请耐心等待,并且由于是在线安装,集群需要开通外网。

Step 3:配置Jenkins

接下来将进入最重要的一个步骤,在Kubernetes插件安装完毕后,我们需要配置Jenkins和Kubernetes参数,使Jenkins连接到K8S集群,并能调用Kubernetes API 动态创建Jenkins Slave,执行构建任务。

点击进入 Manage Jenkins —> Manage nodes and clouds,

Manage nodes and clouds

然后点击 Configure Clouds -> 选择 Kubernetes。

Configure Clouds

输入Kubernetes Apiserver地址,以及服务证书key

Apiserver的位置在:

cat /etc/kubernetes/admin.conf

服务证书key是集群凭证中的certificate-authority-data字段内容

cat /etc/kubernetes/admin.conf | grep certificate-authority-data

进行base64解码

echo "LS0tLS1C....省略....CBDRVJUSUZJQ0FURS0tLS0tCg==" | base64 -d

配置集群

填写集群Namespace、上传凭据、Jenkins地址

Namespace此处填写之前创建Namespace即可,此处为jenkins。凭证处,点击”Add“,凭证类型选择"Secret file",将Kubernetes集群详情页全部内容复制下来,保存为kubeconfig上传。

Secret file

点击”连接测试“,如果出现 Connected to Kubernetes v1.2x.x 的提示信息证明 Jenkins 已经可以和 Kubernetes 系统正常通信了。

screenshot

接下来,我们点击”添加Pod模板“,这个Pod模板即Jenkins-slave pod的模板。

  • namespace,我们这里填 ”jenkins“
  • 标签列表,这里我们填jnlp-slave,这个标签我们在后面创建Jobs会用到,非常重要。
  • 用法,选择 ”尽可能使用这个节点“
  • 镜像,填写”jenkins/jnlp-slave:latest-jdk11“,这个容器镜像是我们CI/CD的运行环境。

screenshot

screenshot

选择添加卷,主机路径和挂载路径都填写为”/var/run/docker.sock“,使得jenkins-slave可以使用宿主机的Docker,让我们可以在容器中进行镜像Build等操作。

docker.sock

点击最下方的Advanced,Service Account 输入jenkins2,这是我们之前创建的SA。

Service Account

其他几个参数由于只是演示,我们都使用默认值,在实际使用的时候,请自行选择合理的参数。到这里我们的 Kubernetes Plugin 插件就算配置完成了。

Step 4:运行一个简单任务

Kubernetes 插件的配置工作完成了,接下来我们就来添加一个 Job 任务,看是否能够在 Slave Pod 中执行,任务执行完成后看 Pod 是否会被销毁。

1、在 Jenkins 首页点击create new jobs,创建一个测试的任务,输入任务名称,然后我们选择 Freestyle project 类型的任务,点击OK。

k8s-jnlp-slave-test

2、在任务配置页,最下面的 Label Expression 这里要填入jnlp-slave,就是前面我们配置的 Slave Pod 中的 Label,这两个地方必须保持一致

Label Expression

3、在任务配置页的 Build 区域,选择Execute shell,输入一个简单的测试命令,并点击保存。

Execute shell

4、构建,可以在这里看到已经new了一个job

job

5、完成后,点击查看Console output,查看任务运行情况。

Console output

到这里我们就完成了使用 Kubernetes 动态生成 Jenkins Slave 了。

Step 6、运行一个pipeline任务

pipeline介绍

Pipeline,简单来说,就是一套运行在 Jenkins 上的工作流(流水线)框架,将原来独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排和可视化的工作。Jenkins Pipeline 有几个核心概念:

  • Node:节点,一个 Node 就是一个 Jenkins 节点,是执行 Step 的具体运行环境,比如我们之前动态运行的 Jenkins Slave 就是一个 Node 节点。

  • Stage:阶段,一个 Pipeline 可以划分为若干个 Stage,每个 Stage 代表一组操作,比如:Build、Test、Deploy,Stage 是一个逻辑分组的概念,可以跨多个 Node。

  • Step:步骤,Step 是最基本的操作单元,可以是打印一句话,也可以是构建一个 Docker 镜像,由各类 Jenkins 插件提供,比如命令:sh ‘make’,就相当于我们平时 shell 终端中执行 make 命令一样。

创建pipeline任务

Pipeline 有两种创建方法,一是直接在 Jenkins 的 Web UI 界面中输入脚本,二是通过创建一个 Jenkinsfile 脚本文件放入项目源码库中,这里为了方便演示,我们使用在 Web UI 界面中输入脚本的方式来运行Pipeline。

1、 点击”new item“,输入Job名称,选择Pipeline,点击"OK"。

jenkins pipeline

2、 在最下方的pipeline 脚本部分,输入以下脚本内容,并点击保存

node('jnlp-slave') {
    stage('Clone') {
      echo "1.Clone Stage"
    }
    stage('Test') {
      echo "2.Test Stage"
    }
    stage('Build') {
      echo "3.Build Stage"
    }
    stage('Deploy') {
      echo "4. Deploy Stage"
    }
}

上面的脚本内容中,我们给 node 添加了一个 jnlp-slave 标签,指定这个pipeline的4个stage,都运行在jenkins的slave节点中。

3、任务创建好之后,点击”立即构建“,我们可以通过kubectl命令发现UK8S集群中正启动一个新的pod用于构建任务。

bash-4.4# kubectl get po -n jenkins
NAME                                  READY   STATUS              RESTARTS   AGE
jnlp-0qn7x                            0/1     ContainerCreating   0          1s

4、 回到 Jenkins 的 Web UI 界面中查看 本次构建历史的 Console Output,也可以类似如下的信息,表明构建成功

Started by user admin
[Pipeline] Start of Pipeline
[Pipeline] node
Agent jnlp-vjcdm is provisioned from template jnlp
---
apiVersion: "v1"
kind: "Pod"
metadata:
  labels:
    jenkins: "slave"
    jenkins/label-digest: "bb74484d3d8cfdd5465f289d1fe175836bf9e531"
    jenkins/label: "jnlp-slave"
  name: "jnlp-vjcdm"
  namespace: "jenkins"
spec:
  containers:
  - env:
    - name: "JENKINS_SECRET"
      value: "********"
    - name: "JENKINS_AGENT_NAME"
      value: "jnlp-vjcdm"
    - name: "JENKINS_NAME"
      value: "jnlp-vjcdm"
    - name: "JENKINS_AGENT_WORKDIR"
      value: "/home/jenkins/agent"
    - name: "JENKINS_URL"
      value: "http://192.168.40.147:8080/"
    image: "jenkins/jnlp-slave:latest-jdk11"
    imagePullPolicy: "IfNotPresent"
    name: "jnlp"
    resources:
      limits: {}
      requests: {}
    tty: false
    volumeMounts:
    - mountPath: "/home/jenkins/agent"
      name: "workspace-volume"
      readOnly: false
    workingDir: "/home/jenkins/agent"
  hostNetwork: false
  nodeSelector:
    kubernetes.io/os: "linux"
  restartPolicy: "Never"
  serviceAccountName: "jenkins2"
  volumes:
  - emptyDir:
      medium: ""
    name: "workspace-volume"

Running on jnlp-vjcdm in /home/jenkins/agent/workspace/pipeline
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Clone)
[Pipeline] echo
1.Clone Stage
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] echo
2.Test Stage
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Build)
[Pipeline] echo
3.Build Stage
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Deploy)
[Pipeline] echo
4. Deploy Stage
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
更新于 2022-10-13

step1第2步部署pvc的时候不用部署pv吗,第3步的部署deploy会报错:pod has unbound immediate PersistentVolumeClaims

你的kubernetes没有配置自动生成pv,你就自己创建吧。

查看kubernetes更多相关的文章或提一个关于kubernetes的问题,也可以与我们一起分享文章