侧边栏壁纸
博主头像
往事随风博主等级

当你感到悲哀痛苦时,最好是去学些什么东西。学习会使你永远立于不败之地!

  • 累计撰写 12 篇文章
  • 累计创建 6 个标签
  • 累计收到 1 条评论
标签搜索

目 录CONTENT

文章目录

阿里云k8s部署jenkins环境并完成应用构建到部署的流水线作业

往事随风
2022-08-26 / 0 评论 / 0 点赞 / 125 阅读 / 3,104 字 / 正在检测是否收录...

1、速部署ack-jenkins

容器服务-Kubernetes -> 市场 -> 应用目录 -> ack-jenkins:
image
点击 参数 菜单修改 AdminPassword 字段, 选择Kubernetes集群、填写命名空间发布名称并点击 创建
image-1661500323975
访问jenkins服务并登陆:
image-1661500341636
image-1661500353023
ps:如未设置登陆密码,则可在部署完毕后使用如下命名查看:

$ printf $(kubectl get secret --namespace ci jenkins-ci-jenkins -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo

2、配置 Kubernetes Cloud

2.1、配置 Kubernetes Cloud

Jenkins使用Kubernetes Plugin连接Kubernetes集群并动态生成和释放slave pod,关于slave pod的模板配置需要在 系统管理 -> 系统配置 -> 云 中进行配置

  • 名称:kubernetes;
  • Kubernetes 地址:https://kubernetes.default.svc.cluster.local:443;jenkins 系统安装在当前集群中,可以使用内部服务端点访问集群的 API Server
  • Kubernetes 命名空间:jenkins;动态 slave pod 会在命名空间 jenkins 下生成和销毁
    点击测试按钮验证连接无误:
    image-1661500492135
  • Jenkins 地址:http://ack-jenkins-default:8080;slave pod连接jenkins master使用的服务端点
  • Jenkins 通道:ack-jenkins-default-agent:50000;slave pod使用jnlp连接jenkins master
    image-1661500519085
  • Pod Templates -> 名称: slave-pipeline; slave pod名称
  • Pod Templates -> 命名空间:jenkins
  • Pod Templates -> 标签列表:slave-pipeline;jenkins 构建任务通过此标签选择使用哪个模板生成slave pod
    image-1661500556010
  • Pod Templates -> 容器列表 -> jnlp;用于jnlp连接jenkins master
    image-1661500579759
  • Pod Templates -> 容器列表 -> kaniko;用于构建和推送容器镜像
    image-1661500612630
  • Pod Templates -> 容器列表 -> maven:用于maven构建和打包应用
    image-1661500640022
  • Pod Templates -> 容器列表 -> kubectl:用于kubectl命令行部署应用
    image-1661500658800
  • Pod Templates -> 环境变量;为kaniko设置DOCKER_CONFIG指定docker.json文件路径
    创建jenkins-docker-cfg secret用于镜像仓库权限设置
    本示例中使用了阿里云镜像服务提供的杭州区域镜像仓库:
$ docker login -u xxx -p xxx registry-vpc.cn-beijing.aliyuncs.com
Login Succeeded
$ kubectl create secret generic jenkins-docker-cfg -n ci --from-file=/root/.docker/config.json

配置slave pod启动时挂载 secret jenkins-docker-cfg:
image-1661500711011
如果需要设置maven缓存目录,可以挂载hostPath volume 或者共享存储卷到/root/.m2/repository:
image-1661500724811
如果需要更改 settings.xml,先创建 ConfigMap:

kubectl create configmap maven-config --from-file=settings.xml -n jenkins

再配置挂载到slave pod:
image-1661500750266
如果需要部署应用到本集群,可以在slave pod中使用ServiceAccount通过kubectl部署,配置ServiceAccount:
image-1661500765009

2.2 创建构建任务

创建构建任务cicd-pipeline,拉取源码项目https://github.com/haoshuwei/jenkins-demo.git,分支master;maven打包构建,kaniko构建和推送容器镜像;kubectl部署到本集群。
在本示例中,需要打包容器镜像为:registry-vpc.cn-beijing.aliyuncs.com/haoshuwei24/application-demo:20200915
则配置构建参数如下:
image-1661500796060
构建任务配置如下:
image-1661500820899
执行构建:
image-1661500835739

可以在 https://github.com/haoshuwei/jenkins-demo.git 中查看Jenkinsfile内容。

3、连接外部集群

连接外部集群需要创建和使用证书
示例:创建k8sCertAuth证书
在此步骤中,我们需要先创建和配置一个名称为k8sCertAuth的集群证书, 点击 凭证 添加证书:
image-1661500873207
image-1661500881924
image-1661500892325

4、详解构建任务示例demo-pipeline

demo-pipeline 构建任务完成的持续集成/持续交付任务为:拉取源码、构建应用war包、打包和推送容器镜像以及部署应用到k8s集群。示例源码项目地址为https://github.com/AliyunContainerService/jenkins-demo.git , 整个构建流程会按照示例项目中Jenkinsfile声明的内容执行构建。

4.1、demo-pipeline的任务配置

demo-pipeline设置了4个构建参数,分别为origin_repo repo image_tagbranchbranch 用于指定本次构建拉取应用源码仓库的哪个分支, 另外3个变量用于构建和推送应用容器镜像的地址,例如示例应用的容器镜像要推送到 registry.cn-hangzhou.aliyuncs.com/ack-cicd/ack-jenkins-demo:latest, 则origin_reporegistry.cn-hangzhou.aliyuncs.com/ack-cicd, repoack-cicd,image_taglatest
image-1661500975168
构建任务中配置从Git仓库拉取源码并指定Jenkinsfile路径:
image-1661500991684

4.2、 Jenkinsfile解析

我们在示例源码项目的Jenkinsfilejenkins-demo/Jenkinsfile中定义了以下内容:

pipeline{
      // 定义groovy脚本中使用的环境变量
      environment{
        // 将构建任务中的构建参数转换为环境变量
        IMAGE_TAG =  sh(returnStdout: true,script: 'echo $image_tag').trim()
        ORIGIN_REPO =  sh(returnStdout: true,script: 'echo $origin_repo').trim()
        REPO =  sh(returnStdout: true,script: 'echo $repo').trim()
        BRANCH =  sh(returnStdout: true,script: 'echo $branch').trim()
      }

      // 定义本次构建使用哪个标签的构建环境,本示例中为 “slave-pipeline”
      agent{
        node{
          label 'slave-pipeline'
        }
      }

      // "stages"定义项目构建的多个模块,可以添加多个 “stage”, 可以多个 “stage” 串行或者并行执行
      stages{
        // 定义第一个stage, 完成克隆源码的任务
        stage('Git'){
          steps{
            git branch: '${BRANCH}', credentialsId: '', url: 'https://github.com/AliyunContainerService/jenkins-demo.git'
          }
        }

        // 添加第二个stage, 运行源码打包命令
        stage('Package'){
          steps{
              container("maven") {
                  sh "mvn package -B -DskipTests"
              }
          }
        }


        // 添加第三个stage, 运行容器镜像构建和推送命令, 用到了environment中定义的groovy环境变量
        stage('Image Build And Publish'){
          steps{
              container("kaniko") {
                  sh "kaniko -f `pwd`/Dockerfile -c `pwd` --destination=${ORIGIN_REPO}/${REPO}:${IMAGE_TAG} --skip-tls-verify"
              }
          }
        }

        // 添加第四个stage, 部署应用到指定k8s集群
        stage('Deploy to Kubernetes') {
            parallel {
                    steps {
                        container('kubectl') {
                            step([$class: 'KubernetesDeploy', authMethod: 'certs', apiServerUrl: 'https://kubernetes.default.svc.cluster.local:443', credentialsId:'k8sCertAuth', config: 'deployment.yaml',variableState: 'ORIGIN_REPO,REPO,IMAGE_TAG'])
                        }
                    }
            }
        }
      }
}

4.2.1 environment{} 代码块

用于获取构建参数并转换为Jenkinsfile中使用的环境变量。

4.2.2 agent{} 代码块

用于指定本次构建使用的构建节点标签为slave-pipeline。 进入 系统管理 -> 系统设置 -> 云 可以看到Kubernetes云的配置, 此配置用于定义如何动态创建构建节点:
image-1661501084341
image-1661501101529
image-1661501138486
image-1661501156366

我们可以从上图的Kubernetes云配置中看到, 当我们执行构建任务时,jenkins会动态连接本集群的api server url:https://kubernetes.default.svc.cluster.local:443jenkins 命名空间下创建 slave pod slave-pipeline-xxx, 此slave pod包含4个containers, 分别为用于slave连接master的jnlp、用于maven编译打包java源码的maven、用于容器镜像构建和部署的kaniko以及用于部署k8s应用的kubectl

当使用kaniko容器进行容器镜像构建和推送时, 我们需要获取镜像推送到仓库的权限, 这个权限是以k8s secret的方式挂载到slave-pipeline-xxx的pod里的,环境变量DOCKER_CONFIG则定义了kaniko获取镜像仓库推送权限文件的默认路径。 在此我们需要创建名为jenkins-docker-cfg的secret:

在一台linux机器上执行以下命令:

$ docker login -u xxx -p xxx registry.cn-hangzhou.aliyuncs.com
$ kubectl create secret generic jenkins-docker-cfg -n ci --from-file=/root/.docker/config.json

4.2.3 stages{}代码块

stages{}代码块定义了多个stage,分别完成持续集成/持续部署过程中的不同步骤。

4.2.3.1 源码拉取

源码仓库中一般包含Jenkinsfile Dockerfile deployment.yaml等文件

stage('Git'){
  steps{
    git branch: '${BRANCH}', credentialsId: '', url: 'https://github.com/AliyunContainerService/jenkins-demo.git'
  }
}
4.2.3.2 maven编译和打包源码

maven编译的时候,用户通常会想使用缓存功能, maven缓存需要使用NAS共享存储,创建nas volume并挂载到Kubernetes云的slave-pipeline模板上, 类似jenkins-docker-cfg的挂载。

stage('Package'){
  steps{
    container("maven") {
      sh "mvn package -B -DskipTests"
    }
  }
}
4.2.3.3 kaniko构建和推送镜像

kaniko工具构建容器镜像可以不依赖docker daemon进程,在用户态空间完成镜像构建和推送, 更安全可靠。

stage('Image Build And Publish'){
  steps{
    container("kaniko") {
      sh "kaniko -f `pwd`/Dockerfile -c `pwd` --destination=${ORIGIN_REPO}/${REPO}:${IMAGE_TAG} --skip-tls-verify"
    }
  }
}
4.2.3.4 kubectl部署k8s应用
stage('Deploy to Kubernetes') {
  steps {
    container('kubectl') {
      step([$class: 'KubernetesDeploy', authMethod: 'certs', apiServerUrl: 'https://kubernetes.default.svc.cluster.local:443', credentialsId:'k8sCertAuth', config: 'deployment.yaml',variableState: 'ORIGIN_REPO,REPO,IMAGE_TAG'])
    }
  }
}

在此步骤中,我们需要先创建和配置一个名称为k8sCertAuth的集群证书, 点击 凭证 添加证书:
image-1661501291765
image-1661501307472
image-1661501318110
variableState: 'ORIGIN_REPO,REPO,IMAGE_TAG' 字段声明需要替换deployment.yaml文件中的哪些环境变量。

5、系统配置详解

5.1 构建环境配置说明

(1)kubernetes集群动态分配构建pod的配置;
image-1661501385734
(2)slave-pipeline 使用了4个container分别完成流水线中各个stage的构建,Kubernetes Pod Templates配置
container jnlp:
image-1661501411694
container kaniko:
image-1661501425244
container kubectl:
image-1661501444991
container maven:
image-1661501460318
(3) 使用到的构建镜像:

  • jnlp 用于构建节点jnlp连接master:

    jenkinsci/jnlp-slave:3.35-5
    
  • maven 用于mvn打包构建:

     maven:3.6.2-jdk-14
    
  • kaniko 用于镜像构建和推送:

    registry.cn-hangzhou.aliyuncs.com/acs/kaniko:v0.14.0
    
  • kubectl 用于kubectl部署应用:

    registry.cn-hangzhou.aliyuncs.com/acs/kubectl:1.14.8
    

    (4) kaniko配置镜像仓库权限:

image-1661501489058

5.2 示例项目说明

(1)示例项目中使用的源码仓库

https://github.com/AliyunContainerService/jenkins-demo.git

(2)kaniko 构建和推送docker镜像说明

kaniko可以不依赖docker daemon并在用户空间执行完成Dockerfile中的每一行命令,最终完成docker镜像的构建和推送。

kaniko -f `pwd`/Dockerfile -c `pwd` --destination=${origin_repo}/${repo}:${image_tag}

(3)部署应用到Kubernetes集群插件说明
插件配置如下:

image-1661501517503

对应的Pipeline语法为:

step([$class: 'KubernetesDeploy', authMethod: 'certs', apiServerUrl: 'https://kubernetes.default.svc.cluster.local:443', credentialsId:'k8sCertAuth', config: 'deployment.yaml',variableState: 'ORIGIN_REPO,REPO,IMAGE_TAG'])

声明的变量ORIGIN_REPO,REPO,IMAGE_TAG可在构建执行时把deployment.yaml文件中对应的变量值替换为实际值:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: jenkins-java-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: jenkins-java-demo
  template:
    metadata:
      labels:
        app: jenkins-java-demo
    spec:
      containers:
      - name: jenkins-java-demo
        image: ${ORIGIN_REPO}/${REPO}:${IMAGE_TAG}
        imagePullPolicy: Always
        ports:
        - containerPort: 8080

---
apiVersion: v1
kind: Service
metadata:
  name: jenkins-java-demo
spec:
  ports:
  - port: 80
    targetPort: 8080
    name: jenkins-java-demo
  selector:
    app: jenkins-java-demo
  type: LoadBalancer

(4)Jenkinsfile说明

pipeline{
      // 定义groovy脚本中使用的环境变量
      environment{
        // 本示例中使用DEPLOY_TO_K8S变量来决定把应用部署到哪套容器集群环境中,如“Production Environment”, “Staging001 Environment”等
        IMAGE_TAG =  sh(returnStdout: true,script: 'echo $image_tag').trim()
        ORIGIN_REPO =  sh(returnStdout: true,script: 'echo $origin_repo').trim()
        REPO =  sh(returnStdout: true,script: 'echo $repo').trim()
        BRANCH =  sh(returnStdout: true,script: 'echo $branch').trim()
      }

      // 定义本次构建使用哪个标签的构建环境,本示例中为 “slave-pipeline”
      agent{
        node{
          label 'slave-pipeline'
        }
      }

      // "stages"定义项目构建的多个模块,可以添加多个 “stage”, 可以多个 “stage” 串行或者并行执行
      stages{
        // 定义第一个stage, 完成克隆源码的任务
        stage('Git'){
          steps{
            git branch: '${BRANCH}', credentialsId: '', url: 'https://github.com/AliyunContainerService/jenkins-demo.git'
          }
        }

        // 添加第二个stage, 运行源码打包命令
        stage('Package'){
          steps{
              container("maven") {
                  sh "mvn package -B -DskipTests"
              }
          }
        }


        // 添加第四个stage, 运行容器镜像构建和推送命令, 用到了environment中定义的groovy环境变量
        stage('Image Build And Publish'){
          steps{
              container("kaniko") {
                  sh "kaniko -f `pwd`/Dockerfile -c `pwd` --destination=${ORIGIN_REPO}/${REPO}:${IMAGE_TAG}"
              }
          }
        }


        stage('Deploy to Kubernetes') {
            parallel {
                stage('Deploy to Production Environment') {
                    when {
                        expression {
                            "$BRANCH" == "master"
                        }
                    }
                    steps {
                        container('kubectl') {
                            step([$class: 'KubernetesDeploy', authMethod: 'certs', apiServerUrl: 'https://kubernetes.default.svc.cluster.local:443', credentialsId:'k8sCertAuth', config: 'deployment.yaml',variableState: 'ORIGIN_REPO,REPO,IMAGE_TAG'])
                        }
                    }
                }
                stage('Deploy to Staging001 Environment') {
                    when {
                        expression {
                            "$BRANCH" == "latest"
                        }
                    }
                    steps {
                        container('kubectl') {
                            step([$class: 'KubernetesDeploy', authMethod: 'certs', apiServerUrl: 'https://kubernetes.default.svc.cluster.local:443', credentialsId:'k8sCertAuth', config: 'deployment.yaml',variableState: 'ORIGIN_REPO,REPO,IMAGE_TAG'])
                        }
                    }
                }
            }
        }
      }
    }

了解更多阿里云容器服务内容,请访问 https://www.aliyun.com/product/containerservice

0

评论区