• jenkins(pipeline)+k8s 实现CICD(提供源码和测试用例)


    jenkins

    #jenkins安装
    wget https://get.jenkins.io/war-stable/2.332.2/jenkins.war --no-check-certificate
    #创建jenkins用户
    useradd jenkins
    #创建数据目录
    mkdir /export/jenkins/
    mkdir /var/log/jenkins/
    chown jenkins:jenkins /export/jenkins/ -R
    chown jenkins:jenkins /var/log/jenkins/ -R
    #后台启动jenkins
    su - jenkins
    nohup java -Djava.awt.headless=true -DsessionTimeout=1440  -DJENKINS_HOME=/export/jenkins/  -jar /opt/jenkins.war --logfile=/var/log/jenkins/jenkins.log --httpPort=8608 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20  &
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在安装插件的时候有个坑,报错是
    unable to find valid certification path to requested target。。。
    解决办法:
    1.

    #替换国内源
    sed -i 's#https://updates.jenkins.io/download#https://mirrors.tuna.tsinghua.edu.cn/jenkins#g' /export/jenkins/updates/default.json
    sed -i 's#http://www.google.com#https://www.baidu.com#g' /export/jenkins/updates/default.json
    
    • 1
    • 2
    • 3

    插件管理-》advanced 修改站点为:http://mirror.esuni.jp/jenkins/updates/update-center.json
    在这里插入图片描述
    重启jenkins解决

    手动安装插件,包括这几个类:
    maven
    git
    pipeline
    locale
    blueocean
    反正看着装,能多装就多装

    K8s(kubeadm)

    三台机器,实验安装的是1.19版本
    192.168.31.150
    192.168.31.151 master
    192.168.31.152

    三台执行:

    $ systemctl stop firewalld
    $ systemctl disable firewalld
    $ sed -i 's/enforcing/disabled/' /etc/selinux/config
    #关闭swap
    $ swapoff -a
    #设置主机名
    $ hostnamectl set-hostname <hostname>
    #在master添加hosts:
    $ cat >> /etc/hosts << EOF
    192.168.31.150 slave1
    192.168.31.151 master
    192.168.31.152 slave2
    EOF
    
    $ cat > /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF
    $ sysctl --system # 生效
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    master执行:

    #设置国内镜像
    $ cat > /etc/docker/daemon.json << EOF
    { "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"] } 
    EOF
    $ systemctl restart docker
    $ docker info
    
    $ yum install -y kubelet-1.19.0 kubeadm-1.19.0 kubectl-1.19.0
    $ systemctl enable kubelet
    $ kubeadm init \
          --apiserver-advertise-address=192.168.31.151 \
          --image-repository registry.aliyuncs.com/google_containers \
          --kubernetes-version v1.19.0 \
          --service-cidr=10.96.0.0/12 \
          --pod-network-cidr=10.244.0.0/16 \
          --ignore-preflight-errors=all
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    稍微解释一下:
    –apiserver-advertise-address 集群通告地址
    –image-repository 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址
    –kubernetes-version K8s版本,与上面安装的一致
    –service-cidr 集群内部虚拟网络,Pod统一访问入口
    –pod-network-cidr Pod网络,,与下面部署的CNI网络组件yaml中保持一致
    继续执行

    $ mkdir -p $HOME/.kube
    $ cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    $ chown $(id -u):$(id -g) $HOME/.kube/config
    
    • 1
    • 2
    • 3

    kubectl get nodes #查看一下
    在这里插入图片描述

    slave执行

    yum install -y kubelet-1.19.0 kubeadm-1.19.0 kubectl-1.19.0
    #加入集群
    $ kubeadm join 192.168.31.61:6443 --token myyu43.3gmkykvu0h2yesxn \
    --discovery-token-ca-cert-hash sha256:58260e1d46f6249c83828d02c9d09be7ab549f33c1d5777be8f0cca8d8d8fa6b
    
    • 1
    • 2
    • 3
    • 4

    部署网络插件master执行

    $ wget https://docs.projectcalico.org/manifests/calico.yaml
    #下载完后还需要修改里面定义Pod网络(CALICO_IPV4POOL_CIDR),与前面kubeadm init指定的一样
    
    
    $ kubectl apply -f calico.yaml 
    $ kubectl get pods -n kube-system
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    kubectl get node
    在这里插入图片描述

    harbor

    请参考

    https://www.cnblogs.com/blogof-fusu/p/16468938.html

    pipeline配置

    jenkins需要配置两个工具 maven和jdk,
    在这里插入图片描述
    在这里插入图片描述
    可以用你自己的路径

    代码我用的是es的一个代码,在我的gitee里,可以直接拉取,也可以fork到你自己的仓库里,配置拉取代码凭证
    附上gitee地址:https://gitee.com/sedr/cloudtest.git
    在这里插入图片描述

    重点是pipeline,咱们创建一条pipeline,没有装插件则没有这种类型
    在这里插入图片描述

    pipeline {
        agent any
            environment {
                NAME= "cloud-test"
                GIT_URL = "https://gitee.com/sedr/cloudtest.git"
                REPO_DOMAIN= "101.xx.xxx.xx/library" //这里配置你自己的harbor地址
                BUILD_TIME = sh(script: "echo `date +%Y%m%d%H%M`", returnStdout: true).trim()
        }
        options {
          skipDefaultCheckout()
          //timestamps()
          timeout(time: 30, unit: 'MINUTES')
          buildDiscarder(logRotator(daysToKeepStr: '30', numToKeepStr: '7'))
        }
        stages {
            stage('Checkout'){
              steps {
                  deleteDir()
                    checkout([$class: 'GitSCM', branches: [[name: "${branch}"]], extensions: [[$class: 'CleanBeforeCheckout']], userRemoteConfigs: [[credentialsId: '9e26ceab-2a06-4507-837c-658e9f38261b', url: "${GIT_URL}"]]])
                }
            }
            
            stage('Preparation') {
              steps {
                dir("${env.WORKSPACE}") {
                  script{
                      env.GIT_SHA_SHORT = sh(
                      script: "git rev-parse --short=8 HEAD",
                      returnStdout: true
                      ).trim()
                      env.DOCKER_TAG = "${BUILD_TIME}-${GIT_SHA_SHORT}"
                      env.DOCKER_NAME = "${NAME}"
                  }
                }  
              }          
            }
            
            stage('compile') {
                steps {
                 
                    tool name: 'maven3.3', type: 'maven'
                    sh './mvnw clean package'
                }
            }
            
            stage('Build') {
            //   environment {
            //     DOCKER_REGISTER_CRED = credentials('docker-register')
            //   }
              steps {  
                  sh '''
                  echo ${DOCKER_TAG}
                  #docker login -u ${DOCKER_REGISTER_CRED_USR} -p ${DOCKER_REGISTER_CRED_PSW} ${REPO_DOMAIN}
                  docker build -t "${REPO_DOMAIN}/${DOCKER_NAME}:${DOCKER_TAG}" .
                  docker push "${REPO_DOMAIN}/${DOCKER_NAME}:${DOCKER_TAG}"     
                  '''               
              }
            }
            
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    到这里就构建完成了,cd明天补上,睡觉!

    部署

    早呀,昨晚把CI搞完了,今天开始CD,先说一下思路,微服务我们采用deployment的方式部署在kubernetes中,所以需要先准备一个 demo服务的api对象描述文件,deployment.yml,这个demo服务使用了mysql组件,你可以在你本地部署一个mysql,然后修改服务中的连接配置,我给的源码库中包含一个docker-compose.yaml文件,进入compose文件所在目录执行

    docker-compose up -d
    
    • 1

    在这里插入图片描述
    然后我们要准备api对象描述文件,代码库里也有,我这里贴一下

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: weather
      #namespace: logging
    spec:
      selector:
        matchLabels:
          run: weather
      template:
        metadata:
          labels:
            run: weather
        spec:
          containers:
            - name: weather
              image: DOCKER_TAG
              ports:
                - containerPort: 8080
                  name: http
                  protocol: TCP
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: weather
      #namespace: logging
      labels:
        service: weather
    spec:
      type: NodePort
      selector:
        run: weather
      ports:
        - port: 8080
          targetPort: 8080
          nodePort: 30880
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    pipeline中添加一个stage

           stage('deploy') {
            //   environment {
            //     DOCKER_REGISTER_CRED = credentials('docker-register')
            //   }
              steps {  
                  sh '''
                       sed -i "s#DOCKER_TAG#${REPO_DOMAIN}/${DOCKER_NAME}:${DOCKER_TAG}#g" deployment.yml
                       kubectl apply -f deployment.yml
                  '''               
              }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    以上有两个需要注意的地方,sed -i 需要用双引号,否则会替换为源字符串,也就是${REPO_DOMAIN}/${DOCKER_NAME}😒{DOCKER_TAG}
    部署还是比较简单的,如果你的jenkins不在集群中部署,那么要和集群交互,就需要做一些操作,具体请看这里
    https://blog.csdn.net/qq_14999375/article/details/111683598

    到这里就部署完成了,我们来访问一下
    在这里插入图片描述
    出现这个就代表整个CICD完成了!

    有任何问题都可在下方评论,我会经常看的,知无不言言无不尽!

  • 相关阅读:
    【CNN】浅谈经典神经网络Classic Network
    帆软报表-SQL片段报错处理
    聊聊Promise的使用
    如何在 ACK 中使用 MSE Ingress
    With As多表查询
    修改hosts 不生效? 三种方法解决
    Kotlin基本语法
    2022杭电多校七 F-Sumire(数位DP+实用技巧)
    全志A40i android7.1 移植wifi驱动的一般流程
    【学习总结】NoSQL重点归纳
  • 原文地址:https://blog.csdn.net/zb199738/article/details/126202610