基于Kubernetes Jenkins CICD

2023年 5月 4日 28.3k 0

传统构建jenkins会有许多的问题,我们需要采用一种更高效可靠的方式来完成这个CI/CD流程,而Docker虚拟化容器技能很好的解决这个痛点,又特别是在Kubernetes集群环境下面能够更好来解决上面的问题

一、在Kubernetes 安装 Jenkins优点

目前很多公司采用Jenkins集群搭建复合需求的CI/CD流程,但是会存在一些问题

  • 主Master发生单点故障时,整个流程都不可用
  • 每个Slave的环境配置不一样,来完成不同语言的编译打包,但是这些差异化的配置导致管理起来不方便,维护麻烦
  • 资源分配不均衡,有的slave要运行的job出现排队等待,而有的salve处于空闲状态
  • 资源有浪费,每台slave可能是物理机或者虚拟机,当slave处于空闲状态时,也不能完全释放掉资源
  • 正因为上面的问题,我们需要采用一种更高效可靠的方式来完成这个CI/CD流程,而Docker虚拟化容器技能很好的解决这个痛点,又特别是在Kubernetes集群环境下面能够更好来解决上面的问题
    image_1djmeig52of315pukfvpcspsm1t.png-63.4kB
    如上图我们可以看到Jenkins master和Jenkins slave以Pod形式运行在Kubernetes集群的Node上,Master运行在其中一个节点,并且将其配置数据存储到一个volume上去,slave运行在各个节点上,但是它的状态并不是一直处于运行状态,它会按照需求动态的创建并自动删除
    这种方式流程大致为: 当Jenkins Master接受到Build请求后,会根据配置的Label动态创建一个运行在Pod中的Jenkins Slave并注册到Master上,当运行完Job后,这个Slave会被注销并且这个Pod也会自动删除,恢复到最初的状态(这个策略可以设置)

  • 服务高可用,当Jenkins Master出现故障时,Kubernetes会自动创建一个新的Jenkins Master容器,并且将Volume分配给新创建的容器,保证数据不丢失,从而达到集群服务高可用的作用
  • 动态伸缩,合理使用资源,每次运行Job时,会自动创建一个Jenkins Slave,Job完成后,Slave自动注销并删除容器,资源自动释放,并且Kubernetes会根据每个资源的使用情况,动态分配slave到空闲的节点上创建,降低出现因某节点资源利用率高,降低出现因某节点利用率高出现排队的情况
  • 扩展性好,当Kubernetes集群的资源严重不足导致Job排队等待时,可以很容器的添加一个Kubernetes Node到集群,从而实现扩展
  • 二、Kubernetes 安装Jenkins

    这里我们使用k8s的pv进行存储数据,当然也可以使用storage class对象来自动创建
    创建pv需要使用nfs,我这里直接创建一台nfs服务器

    我们在k8s集群的任意一个节点配置一台nfs集群,其他节点主要是挂载
    for i in k8s-01 k8s-02 k8s-03 k8s-04;do ssh root@$i "yum install nfs-utils rpcbind -y";done
    
    #我这里使用单独的NFS服务器,IP为192.168.0.100
    #NFS服务节点操作如下
    mkdir -p /data1/k8s-vloume
    echo "/data1/k8s-vloume  *(rw,no_root_squash,sync)" >/etc/exports
    systemctl start rpcbind
    systemctl enable rpcbind
    systemctl enable nfs
    systemctl restart nfs
    #IP改成网段
    
    其他k8s节点直接启动rpcbind并且挂载目录就可以
    
    #挂载
    systemctl start rpcbind
    systemctl enable rpcbind
    mkdir /data1/k8s-vloume -p
    mount -t nfs 192.168.0.100:/data1/k8s-vloume /data1/k8s-vloume
    
    
    #创建完成你们自己测一下就可以了
    

    这里需要创建一个命名空间

    kubectl create namespace abcdocker
    
    #在创建一下jenkins存储yaml的目录
    mkdir -p /opt/jenkins 
    

    接下来我们开始创建Jenkins Deployment

    vim /opt/jenkins/jenkins_deployment.yaml
    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
      name: jenkins         #deployment名称
      namespace: abcdocker      #命名空间
    spec:
      template:
        metadata:
          labels:
            app: jenkins
        spec:
          terminationGracePeriodSeconds: 10     #优雅停止pod
          serviceAccount: jenkins               #后面还需要创建服务账户
          containers:
          - name: jenkins
            image: jenkins/jenkins:lts               #镜像版本
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 8080                #外部访问端口
              name: web
              protocol: TCP
            - containerPort: 50000              #jenkins save发现端口
              name: agent
              protocol: TCP
            resources:
              limits:
                cpu: 1000m
                memory: 1Gi
              requests:
                cpu: 500m
                memory: 512Mi
            livenessProbe:
              httpGet:
                path: /login
                port: 8080
              initialDelaySeconds: 60          #容器初始化完成后,等待60秒进行探针检查
              timeoutSeconds: 5
              failureThreshold: 12          #当Pod成功启动且检查失败时,Kubernetes将在放弃之前尝试failureThreshold次。放弃生存检查意味着重新启动Pod。而放弃就绪检查,Pod将被标记为未就绪。默认为3.最小值为1
            readinessProbe:
              httpGet:
                path: /login
                port: 8080
              initialDelaySeconds: 60
              timeoutSeconds: 5
              failureThreshold: 12
            volumeMounts:                       #需要将jenkins_home目录挂载出来
            - name: jenkinshome
              subPath: jenkins
              mountPath: /var/jenkins_home
            env:
            - name: LIMITS_MEMORY
              valueFrom:
                resourceFieldRef:
                  resource: limits.memory
                  divisor: 1Mi
            - name: JAVA_OPTS
              value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Duser.timezone=Asia/Shanghai
          securityContext:
            fsGroup: 1000
          volumes:
          - name: jenkinshome
            persistentVolumeClaim:
              claimName: opspvc             #这里将上面创建的pv关联到pvc上
    
    #这里不进行创建
    

    因为要保证Jenkins持久化缓存数据,我们创建了一个PV

    cat >/opt/jenkins/jenkins_pv.yaml <<EOF
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: opspv
    spec:
      capacity:
        storage: 20Gi
      accessModes:
      - ReadWriteMany
      persistentVolumeReclaimPolicy: Delete
      nfs:
        server: 192.168.0.100
        path: /data1/k8s-vloume
    
    ---
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: opspvc
      namespace: abcdocker
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 20Gi
    EOF
    
    #注意修改NFS挂载目录以及NFS Server
    #nfs后面的目录是nfs挂载的目录,因为pod会执行mount -t ip:/data1/所以后面是nfs挂载目录,而并非是宿主机的目录
    

    另外还需要一个拥有相关权限的serviceAccount的Jenkins用户,这里我们手动赋予Jenkins一些必要的权限,当然直接给cluster-admin的集群角色权限也是可以的

    cat >/opt/jenkins/jenkins_rbac.yaml <<EOF
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: jenkins
      namespace: abcdocker
    
    ---
    
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: jenkins
    rules:
      - apiGroups: ["extensions", "apps"]
        resources: ["deployments"]
        verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
      - apiGroups: [""]
        resources: ["services"]
        verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
      - 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: ClusterRoleBinding
    metadata:
      name: jenkins
      namespace: abcdocker
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: jenkins
    subjects:
      - kind: ServiceAccount
        name: jenkins
        namespace: abcdocker
    EOF
    

    现在还缺少一个svc,因为我们虽然现在jenkins已经在内部可以访问,但是我们在外面是无法访问的。接下来我们创建一个svc

    cat >/opt/jenkins/jenkins_svc.yaml <<EOF
    apiVersion: v1
    kind: Service
    metadata:
      name: jenkins
      namespace: abcdocker
      labels:
        app: jenkins
    spec:
      selector:
        app: jenkins
      type: NodePort
      ports:
      - name: web
        port: 8080
        targetPort: web
        nodePort: 30002
      - name: agent
        port: 50000
        targetPort: agent
    EOF
    

    接下来我们进行创建

    [root@abcdocker-k8s01 jenkins]# ll
    total 16
    -rw-r--r-- 1 root root 2453 Aug 29 17:42 jenkins_deployment.yaml
    -rw-r--r-- 1 root root  407 Aug 29 17:43 jenkins_pv.yaml
    -rw-r--r-- 1 root root 1120 Aug 29 17:43 jenkins_rbac.yaml
    -rw-r--r-- 1 root root  289 Aug 29 17:43 jenkins_svc.yaml
    

    这里可以直接使用kubectl apple -f .,我为了排查错误,进行一个顺序执行

    #这里我先执行pv然后在执行rbac,依次deployment和svc
    [root@abcdocker-k8s01 jenkins]# kubectl apply -f jenkins_pv.yaml 
    persistentvolume/opspv created
    persistentvolumeclaim/opspvc created
    [root@abcdocker-k8s01 jenkins]# kubectl apply -f jenkins_rbac.yaml 
    serviceaccount/jenkins created
    clusterrole.rbac.authorization.k8s.io/jenkins created
    clusterrolebinding.rbac.authorization.k8s.io/jenkins created
    [root@abcdocker-k8s01 jenkins]# kubectl apply -f jenkins_deployment.yaml 
    deployment.extensions/jenkins created
    [root@abcdocker-k8s01 jenkins]# kubectl apply -f jenkins_rbac.yaml 
    serviceaccount/jenkins unchanged
    clusterrole.rbac.authorization.k8s.io/jenkins unchanged
    clusterrolebinding.rbac.authorization.k8s.io/jenkins unchanged
    [root@abcdocker-k8s01 jenkins]# kubectl apply -f jenkins_svc.yaml 
    service/jenkins created
    

    创建完毕后,我们进行检查

    #首先查看pvc状态
    kubectl get pv,pvc -n abcdocker 
    NAME                     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM              STORAGECLASS   REASON   AGE
    persistentvolume/opspv   20Gi       RWX            Delete           Bound    abcdocker/opspvc                           65s
    
    NAME                           STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    persistentvolumeclaim/opspvc   Bound    opspv    20Gi       RWX                           65s
    
    
    #接下来查看rbac
    kubectl get serviceaccounts -n abcdocker |grep jenkins
    jenkins   1         104s
    
    #最后检查pod和svc
    kubectl get pod,svc -n abcdocker
    NAME                          READY   STATUS    RESTARTS   AGE
    pod/jenkins-6b874b8d7-dhv57   1/1     Running   0          8m26s
    
    NAME              TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                          AGE
    service/jenkins   NodePort   10.254.154.161           8080:30002/TCP,50000:21866/TCP   62s
    
    #需要说明一下8080端口为我们jenkins访问端口
    #50000端口为jenkins save发现端口
    

    Pod正常运行了,我们就可以通过浏览器访问集群任意IP的svc端口
    image_1djg8bsio1n3j19dmuq71lk6efc9.png-94.8kB
    管理员密码文件路径,也可以在pod 日志里面看到

    cat /data1/k8s-vloume/jenkins/secrets/initialAdminPassword
    6d3c67495bcb43c2a74d97309702dab7
    
    #因为我们持久化在/data/k8s下,所以jenkins的所有配置都在这下面
    

    直接选择推荐安装就可以
    image_1djg8djcioh724rbsr1m7n5t8m.png-134kB
    等待安装完毕
    image_1djg8tlku1ko01d1c1sr114dcaab13.png-162kB
    安装完成后我们进入jenkins主页面
    image_1djmdslf9su1tbm1101ia7bgi1g.png-100.2kB
    接下来就是配置Jenkins
    我们需要安装k8s插件,让Jenkins构建Job可以动态生成Slave的Pod
    点击Jenkins-->插件-->安装插件Kubernetes
    image_1djoevce7schvri3hp6vs1shh2a.png-138.1kB
    安装完毕后会重启Jenkins,然后我们就可以配置插件
    Manage Jenkins >>Configure System 找到插件
    image_1djohlpeapn715ud1amigjd11ul37.png-92.3kB
    在配置上拉到最下面,ADD一个Kubernetes
    image_1djoib1i31bli1vkkn74f018f3k.png-40.3kB

    Name   配置的名称
    Kubernetes URL  这里的URL是K8s内部的URL,实际上就是svcname 这里不需要修改直接复制就行
    Kubernetes Namespace k8s的命名空间 (实际上就是Jenkins所在的命名空间)
    

    https://kubernetes.default.svc.cluster.local
    svcname+default+后面参数复制就可以
    image_1djoj2sjn12d7if21c7q1ghc1rg54h.png-52.1kB

    Jenkins URL   这里的URL是jenkins的svc名称加上命名空间,实际上就是在k8s集群内部访问jenkins的一个方法,这里也不需要修改
    http://jenkins.abcdocker.svc.cluster.local:8080
    
    #其他默认即可
    

    image_1djojk9kl181f39hf8v1r11gjv4u.png-89kB
    添加一个 Jenkins Slave Pod模板
    image_1djojonu41n391rd7imi6gc13du5r.png-24.6kB

    Name   = Pod 名称
    Namespave   = Pod命名空间
    Labels   =  Pod标签
    

    image_1djr71qi9k4e1kr918q61j5a1o35p.png-65.5kB
    接下来是容器的模板配置

    Name  容器的名称
    Docker image  镜像,这里直接使用我的镜像
    #jenkins 2.176.x版本以上使用:registry.cn-beijing.aliyuncs.com/abcdocker/jenkins:v1.2
    #jenkins 2.176.x版本以下使用:registry.cn-beijing.aliyuncs.com/abcdocker/jenkins:v1.1
    #jenkins 2.176以上版本有maven命令使用:registry.cn-beijing.aliyuncs.com/abcdocker/jenkins:v1.4
    
    #镜像里面主要是运行了kubectl命令和Docker的配置,下面我们还需要将kubeconfig挂载进来
    
    
    ########
    如果需要自定义maven仓库可以使用下面的dockerfile
    [root@k8s-01 jenkins]# cat Dockerfile
    FROM registry.cn-beijing.aliyuncs.com/abcdocker/jenkins:v1.2
    MAINTAINER abcdocker "i4t.com"
    COPY maven /usr/local/maven
    RUN cd /usr/local/maven
    

    红色代表不可以修改,否则jenkins slave启动会提示错误,反复重启
    image_1djt412951cc54k21c5i1p01roaal.png-141.4kB
    如果jenkins提示权限错误,请在配置中添加jenkins rbac创建的serviceaccounts
    image_1djt43r32185thvu13qs6u41bd8b2.png-45.9kB
    上面说了,镜像主要是用于kubectl,kubectl是需要kubeconfig文件,所以我们还需要创建一个volume的配置
    image_1djr7j2n7s3e16hgvse1jbe1gm81j.png-73.4kB
    如果我们想在容器里面执行docker命令,需要将docker.sock挂载进去
    还需要将kubeconfig挂在进容器
    1.png-97.7kB
    image_1djr8a7g71urojok1du7tq31gqo45.png-60.5kB
    然后我们点击保存即可
    接下来添加一个job,来测试一下jenkins是否可以在slave节点上执行
    image_1djr8kk151mg5lflaa115sj197g4i.png-172kB
    接下来进行配置Jenkins
    这里的label标签就是我们在配置中配置的标签
    image_1djr8o25j1fp61mlovt5ubvm0u5c.png-75kB
    配置标签的地方
    image_1djr8mhrdm94f8n18j7ibud6i4v.png-34.9kB
    添加一个shell命令,测试docker和kubectl
    2.png-125.8kB
    现在我们先看一下Pod是否可以动态获取

    $ kubectl get pod -n abcdocker
    NAME                      READY   STATUS    RESTARTS   AGE
    jenkins-6b874b8d7-xxwwr   1/1     Running   0          31h
    
    #目前只有一个jenkins在运行,接下来我们进行构建项目
    

    容器正在创建,目前属于等待状态
    image_1djr99gd91i661pen2gc1m33ldr6u.png-86.9kB
    这里可以看到已经新启动了一个pod节点

    $ kubectl get pod -n abcdocker
    NAME                      READY   STATUS              RESTARTS   AGE
    jenkins-6b874b8d7-xxwwr   1/1     Running             0          2d
    jenkins-slave-423xz       0/1     ContainerCreating   0          5s
    

    等待容器创建成功,Jenkins就会绑定到这个Pod节点上,进行执行任务
    image_1djt3sn0i14ki57d1t189auivua2.png-172.8kB
    如果遇到pod一直重启的情况,请使用kubectl get pod -n xxx -o wide查看pod运行节点,使用docker ps过滤出pod,通过docker logs -f查看错误日志
    当Jenkins slave节点执行完毕任务后,默认情况下执行完job就会被删除

    $ kubectl get pod -n abcdocker
    NAME                      READY   STATUS    RESTARTS   AGE
    jenkins-6b874b8d7-xxwwr   1/1     Running   0          2d
    

    如果想让job等待30分钟释放,可以在下图添加
    11111.png-139.9kB
    小结 Jenkins Master收到Build请求时,会根据配置的Label动态创建一个运行在Pod中的Jenkins Slave并注册到Master上,当Job运行完,这个Slave会被注销并且这个Pod也会自动删除,恢复到最初状态

    三、项目演示 使用Jenkins Pipline部署

    Jenkins Pipline介绍
    Gitlab配置
    接下来我们在代码仓库创建一个分支
    image_1dk07h04h18vop2g9rs1un0ncad4.png-229.1kB
    配置root用户免密
    首先先查看服务器公钥
    DE94CCEF-4B5E-4A8E-AF23-8888478C086C.png-246.1kB
    上git配置key
    4444.png-256.1kB
    接下来在服务器上提交git代码就可以
    image_1dk088jcosei15oughj1kvaopgg7.png-178kB
    上传代码

    #这里需要有git命令
    yum install -y git 
    git config --global user.name "root"
    git config --global user.email "admin@example.com"
    
    #克隆
    git clone git@10.4.82.15:root/abcdocker-test.git
    cd abcdocker-test
    wget http://down.i4t.com/hello-world-war-master.zip
    unzip hello-world-war-master.zip
    mv hello-world-war-master/* .
    rm -rf hello-world-war-master*
    
    #提交代码
    
    
    #接下来看图就行了
    

    gitlab配置完毕
    image_1dk08c1ip1sbu1bju1c4j11spiiigk.png-119.7kB

    四、配置Dockerfile

    首先我们需要自定义一个tomcat基础镜像,也可以使用dockerhub提供的

    cat >>Dockerfile <<EOF
    FROM centos
    MAINTAINER www.i4t.com "cyh@i4t.com"
    WORKDIR /tmp
    ## Please see https://i4t.com/3552.html   install JDK
    COPY jdk1.8.0_66.tar.gz /tmp
        RUN tar zxf /tmp/jdk1.8.0_66.tar.gz -C /usr/local/ && rm -rf /tmp/jdk1.8.0_66.tar.gz && 
            ln -s /usr/local/jdk1.8.0_66 /usr/local/jdk
    #/etc/profile
        ENV JAVA_HOME /usr/local/jdk
        ENV CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
        ENV PATH $PATH:$JAVA_HOME/bin
    # add apache
    # Please see i4t.com && baidu.com
        COPY apache-tomcat-8.5.39.tar.gz /tmp
        RUN tar zxf apache-tomcat-8.5.39.tar.gz -C /usr/local  && rm -rf /tmp/apache-tomcat-8.5.39.tar.gz && 
            mv /usr/local/apache-tomcat-8.5.39 /usr/local/tomcat && 
            rm -rf /usr/local/tomcat/webapps/docs examples host-manager manager
    EXPOSE 8080
    ENTRYPOINT /usr/local/tomcat/bin/startup.sh && tail -f /usr/local/tomcat/logs/catalina.out
    EOF
    
    ###接下来需要下载相对应的安装包  (Dockerfile和JDK和tomcat需要放在一个目录下)
    wget http://down.i4t.com/jdk1.8.0_66.tar.gz
    wget http://down.i4t.com/apache-tomcat-8.5.39.tar.gz
    

    接下来可以进行打包

    docker build -t registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:v2 .
    
    #如果不想自己做tomcat镜像,也可以使用dockerhub上的镜像。也可以使用我这里打包好的镜像
    

    现在我们已经完成tomcat镜像的创建,接下来配置Jenkins,每次打包上线自动替换ROOT目录

    五、编写jenkins Pipline

    Jenkins pipline 语法介绍
    配置gitlab账号密码
    由于Jenkins需要使用gitlab账号密码,这里我们做一下免密
    image_1dk86d5me1asa1kqketn1r651sc09.png-84.9kB
    image_1dk86e298etledshpl9l817u7m.png-92.2kB
    image_1dk86enal1ovc1msc8q918hj1bcu13.png-90.6kB
    配置如下
    image_1dk86gi361nkt1tjf1gat3hgrei1g.png-88.1kB
    创建Jenkins pipline项目
    image_1dk86j6fgo14ps41b9ahnkp3r1t.png-179.7kB
    我这里添加参数化构建
    image_1dk86ljv31bjaoq016v95eqakh2a.png-91.6kB
    接下来编写jenkins pipline脚本

    node('abcdocker-slave') {
        stage('Git Clone') {
             checkout([$class: 'GitSCM', branches: [[name: '${git}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab_password', url: 'http://192.168.0.100/root/abcdocker-test.git']]])    
    
        }
        stage('Maven Build') {
               sh '''
            /usr/local/maven/bin/mvn clean package -Dmaven.test.skip=true -f $WORKSPACE
    
            echo FROM registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:test2 >$WORKSPACE/target/Dockerfile
            echo RUN  rm -rf /usr/local/tomcat/webapps/* >>$WORKSPACE/target/Dockerfile
            echo COPY hello-world-war-1.0.0 /usr/local/tomcat/webapps/ROOT >>$WORKSPACE/target/Dockerfile
               '''
    
          echo "3.Docker Build Stage"
               sh '''
            docker build -t registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git} ${WORKSPACE}/target/
            docker login --username=用户名 registry.cn-beijing.aliyuncs.com --password 镜像密码
            docker push registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git}
                  '''
        }
        stage('Deploy') {
          echo "4. Deploy Stage"
          sh'kubectl set image deployment/tomcat -n abcdocker-test my-tomcat=registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git}'
        }
    }
    

    Pipline脚本讲解

    node('abcdocker-slave') {
    
    #这里代表node节点运行在标签为abcdocker-slave上,前面已经定义了,这里就不在定义
    

    gitlab拉取代码配置

        stage('Git Clone') {
             checkout([$class: 'GitSCM', branches: [[name: '${git}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab_password', url: 'http://192.168.0.100/root/abcdocker-test.git']]])    
        }
    
    #这里就是一个选择git地址,然后分支。不会生成可以参考pipline语法
    

    在下图生成的配置直接拷贝到pipline里面ji
    image_1dk86t1co11gdsf91j7u1rn7k0l2n.png-100.5kB
    Java maven打包步骤
    我这里使用阿里云的镜像仓库,演示一下如何上传。
    这里需要注意的是,我们的jenkins slave节点的Pod镜像需要使用下面我提供的版本,否则没有maven命令
    registry.cn-beijing.aliyuncs.com/abcdocker/jenkins:v1.4

        stage('Maven Build') {
            sh '''
            /usr/local/maven/bin/mvn clean package -Dmaven.test.skip=true -f $WORKSPACE
            echo FROM registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:test2 >$WORKSPACE/target/Dockerfile
            echo RUN  rm -rf /usr/local/tomcat/webapps/* >>$WORKSPACE/target/Dockerfile
            echo COPY hello-world-war-1.0.0 /usr/local/tomcat/webapps/ROOT >>$WORKSPACE/target/Dockerfile
            '''
          echo "3.Docker Build Stage"
               sh '''
              docker build -t registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git} ${WORKSPACE}/target/
              docker login --username=cyh60441314 registry.cn-beijing.aliyuncs.com --password XXXX密码
              docker push registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git}
                  '''
        }
    

    接下来是使用kubectl set替换镜像

        stage('Deploy') {
          echo "4. Deploy Stage"
          sh'kubectl set image deployment/tomcat -n abcdocker-test my-tomcat=registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git}'
        }
    

    命令参数解释

    kubectl set image deployment/SVC_NAME -n namespace_name container_name=images:v1
    
    #注意后面是容器名称,并不是svc名称
    

    完整Jenkins Pipline脚本如下

    node('abcdocker-slave') {
        stage('Git Clone') {
             checkout([$class: 'GitSCM', branches: [[name: '${git}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab_password', url: 'http://192.168.0.100/root/abcdocker-test.git']]])    
    
        }
        stage('Maven Build') {
            sh '''
            /usr/local/maven/bin/mvn clean package -Dmaven.test.skip=true -f $WORKSPACE
    
            echo FROM registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:test2 >$WORKSPACE/target/Dockerfile
            echo RUN  rm -rf /usr/local/tomcat/webapps/* >>$WORKSPACE/target/Dockerfile
            echo COPY hello-world-war-1.0.0 /usr/local/tomcat/webapps/ROOT >>$WORKSPACE/target/Dockerfile
            '''
    
          echo "3.Docker Build Stage"
               sh '''
              docker build -t registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git} ${WORKSPACE}/target/
              docker login --username=用户名 registry.cn-beijing.aliyuncs.com --password harbor密码
              docker push registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git}
                  '''
        }
        stage('Deploy') {
          echo "4. Deploy Stage"
          sh'kubectl set image deployment/tomcat -n abcdocker-test my-tomcat=registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git}'
        }
    }
    

    然后jenkins我们点击保存
    创建tomcat svc环境

    #创建命名空间
    kubectl create namespace abcdocker-test
    

    创建tomcat deploy文件

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      labels:
        name: tomcat
      name: tomcat
      namespace: abcdocker-test
    spec:
      replicas: 1
      selector:
        matchLabels:
          name: tomcat
      strategy:
        rollingUpdate:
          maxSurge: 1
          maxUnavailable: 0
        type: RollingUpdate
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: tomcat
            name: tomcat
        spec:
          containers:
          - env:
            - name: JAVA_OPTS
              value: -server -d64 -XX:MetaspaceSize=256m
            - name: MAX_HEAP
              value: 512m
            - name: MIN_HEAP
              value: 512m
            image: registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:v2
            imagePullPolicy: IfNotPresent
            name: my-tomcat
            ports:
            - containerPort: 8080
              protocol: TCP
            resources:
              limits:
                memory: 1536Mi
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
    

    创建svc

    apiVersion: v1
    kind: Service
    metadata:
      name: my-tomcat-svc
      namespace: abcdocker-test
      labels:
        app: tomcat
    spec:
      selector:
        app: tomcat
      type: NodePort
      ports:
      - name: web
        port: 8080
        #targetPort: 8080
        nodePort: 30005
    

    创建之后我们查看状态

    [root@k8s-01 ~]# kubectl get pod,svc -n abcdocker-test
    NAME                          READY   STATUS    RESTARTS   AGE
    pod/tomcat-855dccd5bc-wkn5z   1/1     Running   0          27m
    
    NAME                    TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
    service/my-tomcat-svc   NodePort   10.254.62.11           8080:30005/TCP   26h
    

    访问页面,查看是否正常 (集群任意IP+30005)
    image_1dk87u5co1q8c1rih4qp1pueei434.png-416.9kB
    项目部署
    接下来我们演示一下环境部署
    image_1dk880p6a1d011ige7fn18dp6ts3h.png-153.9kB
    点击Build
    image_1dk881m36lq61vl3mjq10jp11af3u.png-110.5kB
    我这里没有区分环境,这里也是可以区分环境的
    image_1dk882n411kro1vd516s0n9m1uvr4b.png-111.4kB
    日志分析
    image_1dk884gmquvg1srv1goo19qc9m14o.png-125.1kB
    image_1dk885c5g1qs81m4t125g5portb55.png-178.5kB
    image_1dk8866ipvdv1f8t16bs3qfm1c5i.png-184.5kB
    image_1dk887rj51kh184i1r4912rn1vl25v.png-185.9kB
    替换镜像
    image_1dk888a6keq31t4h4o91pp6fu6c.png-43.9kB
    效果图
    image_1dk8895tu7ou17ddnai1toagj66p.png-59.9kB
    Jenkins上也可以看到每个步骤的构建时间
    image_1dk88a6cb1i91pq21ck332ni3u76.png-109.3kB

    相关文章:

    1. Kubernetes 1.14 二进制集群安装
    2. CentOS 7 ETCD集群配置大全
    3. Kubenetes 1.13.5 集群二进制安装
    4. Kuerbernetes 1.11 集群二进制安装

    相关文章

    了解 Llama 3:迄今最强大的免费开源大模型从概念到使用
    KubeSphere 在互联网电商行业的应用实践
    在 KubeSphere 上快速安装和使用 KDP 云原生数据平台
    使用 KubeSphere 实现微服务的灰度发布
    在 Kubernetes 中实现微服务应用监控
    基于 KubeKey 扩容 Kubernetes v1.24 Worker 节点实战

    发布评论