随着Kubernetes的普遍应用,基于Kubernetes的jenkins发布模式也需要随之做出一些改变,本博客基于之前搭建的Kubernetes 1.16.0高可用集群搭建一套企业级别Jenkins CI/CD发布流程。

    Jenkins采用Pipline发布,容器化部署,主从结构,Jenkins master负责调度slave,而slave进行拉代码,打包,构建镜像发布等操作,待发布完成后slave自动消亡,不占用服务器资源。代码存储这里为了方便采用的Git仓库,镜像存储采用最新的1.9.0 Harbor。

    服务器资源:

    172.30.0.109 k8smaster1 Harbor

    172.30.0.81   k8smaster2 

    172.30.0.89   k8snode1    Git仓库


    注意:master节点设置为可调度,也可作为node,运行业务容器,K8S部署方案,请参考上一篇博客,在这里不过多描述。

    

    本博客中相关配置文件,后面会上传到百度网盘中


    一、部署Harbor

    1、安装docker-compose

    harbor需要基于docker-compose插件进行安装,管理

    # curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

    # chmod +x /usr/local/bin/docker-compose

    2、安装docker

    Harbor 1.9版本的docker驱动需要至少18.03以上,请自行安装

    3、下载Harbor安装包

    Github上面搜索Harbor

基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第1张图片

    4、修改harbor配置

    修改haribor.yml,

  基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第2张图片

    若使用IP登录,需要修改成IP地址,域名登录,需要修改成域名,这里Harbor使用的是http模式,若要修改成https访问,则要修改密钥配置

    Harbor使用非安全认证,docker需要修改安全配置,设置为新人非安全,否则无法上传镜像包

    docker.service配置如下

   基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第3张图片

    5、Harbor效果,正常上传镜像

基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第4张图片


    二、Git仓库

    生产建议使用Gitlab图形化工具,方便管理

    1、初始化Git服务器

    下载git

    # yum install git -y

    # useradd git

    # groupadd git

    # su - git 切换到git用户,创建仓库

    # mkdir tomcat-java-demo

    # cd tomcat-java-demo

    # git init --bare 初始化git

  基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第5张图片

    # git服务器初始化完成

    2、上传代码到Git仓库

    解压java demo代码

    # unzip tomcat-java-demo.zip

    # cd tomcat-java-demo

    # git init 初始化客户端git,准备上传代码至远程服务端

    # git add . 添加代码至本地git仓库

    # git commit -m 'test'

    # git remote add origin [email protected]:/home/git/tomcat-java-demo 设置git仓库为远程客户端

    # git push origin master 上传代码至远程客户端master分支


    验证代码是否正常上传:

    重新创建一个目录,初始化git,拉取代码

    # mkdir test && cd test

    # git init && git remote add origin [email protected]:/home/git/tomcat-java-demo

    # git pull origin master

    代码拉取成功,上传代码无误


    上传代码至指定分支,如1.0.0

    本地创建1.0.0的分支,切换到1.0.0分支,因为默认是在master分支,然后上传代码到远程1.0.0分支

    # git branch 1.0.0 创建1.0.0分支

    # git checkout 1.0.0 切换到1.0.0分支

    # git push origin 1.0.0 代码上传到远程1.0.0

    会在远程git服务器上看到多了一个1.0.0分支

    image.png

    三、Jenkins部署

    1、部署Jenkins master

        [root@k8s-master1 jenkins]# cat jenkins.yml 

        apiVersion: apps/v1

        kind: StatefulSet

        metadata:

          name: jenkins

          labels:

            name: jenkins

        spec:

          serviceName: jenkins

          replicas: 1

          updateStrategy:

            type: RollingUpdate

          selector:

            matchLabels:

              name: jenkins

          template:

            metadata:

              name: jenkins

              labels:

                name: jenkins

            spec:

              terminationGracePeriodSeconds: 10

              serviceAccountName: jenkins

              #imagePullSecrets:

              #  - name: registry-pull-secret 

              nodeName: k8s-master1

              containers:

                - name: jenkins

                  image: jenkins/jenkins:lts

                  imagePullPolicy: IfNotPresent

                  ports:

                    - containerPort: 8080

                    - containerPort: 50000

                  resources:

                    limits:

                      cpu: 1

                      memory: 1Gi

                    requests:

                      cpu: 0.5

                      memory: 500Mi

                  env:

                    - name: LIMITS_MEMORY

                      valueFrom:

                        resourceFieldRef:

                          resource: limits.memory

                          divisor: 1Mi

                    - name: JAVA_OPTS

                      # value: -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85

                      value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85

                  volumeMounts:

                    - name: data

                      mountPath: /var/jenkins_home

              securityContext:

                fsGroup: 1000

              volumes:

              - name: data

                hostPath:

                  path: /app/jenkins

        

        ---

        apiVersion: v1

        kind: Service

        metadata:

          name: jenkins

        spec:

          type: NodePort

          selector:

            name: jenkins

          ports:

            -

              name: http

              port: 80

              targetPort: 8080

              protocol: TCP

              nodePort: 30009

            -

              name: agent

              port: 50000

              protocol: TCP


    对jenkins容器进行授权

    [root@k8s-master1 jenkins]# cat rbac.yaml 

    # In GKE need to get RBAC permissions first with

    # kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin [--user=|--group=]

    

    ---

    apiVersion: v1

    kind: ServiceAccount

    metadata:

      name: jenkins

    

    ---

    kind: Role

    apiVersion: rbac.authorization.k8s.io/v1beta1

    metadata:

      name: jenkins

    rules:

    - apiGroups: [""]

      resources: ["pods"]

      verbs: ["create","delete","get","list","patch","update","watch"]

    - apiGroups: [""]

      resources: ["pods/exec"]

      verbs: ["create","delete","get","list","patch","update","watch"]

    - apiGroups: [""]

      resources: ["pods/log"]

      verbs: ["get","list","watch"]

    - apiGroups: [""]

      resources: ["secrets"]

      verbs: ["get"]


   ---

    apiVersion: rbac.authorization.k8s.io/v1beta1

    kind: RoleBinding

    metadata:

      name: jenkins

    roleRef:

      apiGroup: rbac.authorization.k8s.io

      kind: Role

      name: jenkins

    subjects:

    - kind: ServiceAccount

      name: jenkins


    # kubectl apply -f rbac.yaml   

    # kubectl apply -f jenkins.yaml


    访问http://172.30.0.109:30009 打开Jenkins web页面,插件安装默认就好,之后再到插件管理页面自行安装需要的插件

  基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第6张图片

    2、Jenkins系统配置

    ①集成Kubernetes到Jenkins中

    在系统管理的系统设置中,修改配置

    基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第7张图片

    修改后可以进行连接测试,在右下角


    ②下载Jenkins与Kubernetes集成的插件

      在系统管理的插件管理中

      Kubernetes

      Kubernetes Continuous Deploy

      Extended Choice Parameter


    ③配置Git仓库访问密钥以及Jenkins容器访问Kubernetes使用的kubeconfig配置

    在凭据中

   基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第8张图片

        访问Git服务器的密钥,只需要做Jenkins服务器到Git无密登录,并复制Jenkins所在服务器的私钥到以上位置,即可实现代码拉取过程的无密登录


        基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第9张图片

    将K8S集群/root/.kube/config文件复制到以上地区,使Jenkins可以访问K8S集群,部署pod


    3、Jenkins slave

     构建Jenkins Slave,再Jenkins上通过Pipline流水线调用JnekinsFile进行发布操作 

      基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第10张图片

     Jenkins Slave Dockerfile:

      基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第11张图片

    构建镜像

    # docker build -t 172.30.0.109/wujqc/jenkins-slave:lts -f dockerfile-jenkins-slave .

    上传到Harbor上

    # docker login 172.30.0.109

    输入harbor管理员账号密码,进行登录

    # docker push 172.30.0.109/wujqc/jenkins-slave:lts

   

    4、创建Pipline发布Java项目到K8S环境

    ①创建流水线项目

     基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第12张图片

    ②设置参数化构建

    基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第13张图片

    可以通过标签,字符参数指定代码分支,Branch等多种方式去拉取Git,Gitlab指定位置的代码,进行编译,这里采用的是字符参数指定代码分支的方式

    ③配置Pipline流水线

    基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第14张图片

    设置git地址,配置能够拉取git的免登录密钥(前面配置的)

    通过字符参数Tag,获取到想要编译的代码分支,如1.0.0,载入变量origin/1.0.0拉取代码,在拉取的代码中读取JenkinsFile进行下一步Jenkins Slave的maven构建,镜像构建,K8S deploy操作

    可以说整个Jenkins项目中,是通过${Tag}版本去拉取指定分支的JenkinsFile以及代码,在此基础上进行的流水线式部署,JenkinsFile中封装的就是整个打包编译,拉取指定服务的dockerfile,deploy.yaml,构建镜像,上传镜像,部署K8S deploy.yaml的流水线操作。

    注意:JenkinsFile需要在git代码路径中,要不然Jenkins识别不到,会报NotFoundFile

    JenkinsFile文件如下:

    基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第15张图片

    注意:这两处ID,需要替换成Jenkins上面的git,kubeconfig密钥ID

    基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第16张图片

    因为Jenkins Slave需要要到Docker进行镜像构建,上传操作,于是将docker以挂载的方式放入Jenkins Slave中,让其能够使用

    Download Deploy File操作,是为了区分各个系统服务,微服务模块,因为不同的服务模块,其deploy.yaml以及Dockerfile可能都不一样,所以需要有一个统一管理的路径去获取到这两个文件,方便管理,只需要将目录挂载到Jenkins Slave中即可,这个路径,可以采用NFS,在这里为了方便使用的hostpath,生产不建议这么使用

    

    5、启动Pipline项目,输入分支号1.0.0

    基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第17张图片

    基于Kubernetes 1.16.0 建立企业Jenkins CI/CD发布平台_第18张图片

    构建成功!