基于Kubernetes Jenkins CICD

2023年 5月 4日 56.5k 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 集群二进制安装

    相关文章

    KubeSphere 部署向量数据库 Milvus 实战指南
    探索 Kubernetes 持久化存储之 Longhorn 初窥门径
    征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
    那些年在 Terraform 上吃到的糖和踩过的坑
    无需 Kubernetes 测试 Kubernetes 网络实现
    Kubernetes v1.31 中的移除和主要变更

    发布评论