峰颜疯语风吹沙 發表於 2022-9-14 10:15:00

jenkins流水线部署springboot应用到k8s集群(k3s+jenkins+gitee+maven+docker)(2)

<h3 id="前言上篇已介绍了jenkins在k3s环境部署本篇继续上篇讲述流水线构建部署流程">前言:上篇已介绍了jenkins在k3s环境部署,本篇继续上篇讲述流水线构建部署流程</h3>
<h4 id="1从gitlab上拉取代码步骤">1、从gitlab上拉取代码步骤</h4>
<ul>
<li>
<h5 id="在jenkins中新建一个凭证manage-jenkins---manage-credentials">在jenkins中,新建一个凭证;Manage Jenkins -&gt; Manage Credentials</h5>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220912230000797-1184324876.png"></p>
</li>
<li>
<h5 id="点击jenkins---全局凭据---添加凭据选择用户名和密码类型输入用户名和密码点击创建">点击jenkins -&gt; 全局凭据 -&gt; 添加凭据;选择用户名和密码类型,输入用户名和密码,点击创建</h5>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220912230314948-1864039938.png"></p>
</li>
<li>
<h5 id="编写pipeline-script脚本拉取代码">编写pipeline script脚本,拉取代码</h5>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220912230447638-1071884103.png"></p>
</li>
<li>
<h5 id="选择git代码仓库还有凭证等信息点击生成流水线脚本即帮我们生成了拉取代码的脚本">选择git代码仓库还有凭证等信息,点击“生成流水线脚本”,即帮我们生成了拉取代码的脚本</h5>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220912230726832-472143136.png"></p>
</li>
<li>
<h5 id="复制脚本粘贴到流水线拷贝代码段中">复制脚本,粘贴到流水线拷贝代码段中</h5>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220912231033618-1289060573.png"></p>
</li>
<li>
<h5 id="运行构建项目发现拉取代码成功且已返回代码最后提交的tag">运行构建项目,发现拉取代码成功,且已返回代码最后提交的tag</h5>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220912231647437-1682701282.png"></p>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220912231727968-489489112.png"></p>
<p>代码块:</p>
<pre><code>stage('Clone') {
      echo "1.Clone Stage"
      git url: "https://gitee.com/xujk-27400861/springboot-dubbo.git"
      script {
          build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
      }
      echo "${build_tag}"
    }
</code></pre>
</li>
</ul>
<h4 id="2maven构建springboot代码项目">2、maven构建springboot代码项目</h4>
<ul>
<li>
<h5 id="编写脚本因为我们要编译构建项目的子项目所以需要跳转到子目录去构建">编写脚本,因为我们要编译构建项目的子项目,所以需要跳转到子目录去构建</h5>
<pre><code>stage('执行构建') {
      container('maven')
      {
            sh "mvn --version"
            sh 'pwd'
            sh '''cd provider/
            mvn clean package -DskipTests'''
            //sh 'mvn package'
            echo '构建完成'
      }
   }
</code></pre>
</li>
<li>
<h5 id="provider为项目子目录我们要编译的项目-dskiptests参数表示跳过代码测试">provider/为项目子目录,我们要编译的项目;-DskipTests参数,表示跳过代码测试</h5>
<img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220912232712953-225623096.png"></li>
</ul>
<h4 id="3构建docker镜像">3、构建docker镜像</h4>
<ul>
<li>
<h5 id="编写脚本构建docker镜像">编写脚本,构建docker镜像;</h5>
<pre><code>stage('Build') {
      echo "3.Build Stage"
      container('docker') {
          sh "docker -v"
          sh 'pwd'
          sh """cd /home/jenkins/agent/workspace/linetest/provider/
          ls
          docker -H tcp://192.168.231.132:2375 build -t xjk27400861/springbootapp:${build_tag} ."""      
    }
}
</code></pre>
</li>
<li>
<h5 id="我这里通过调用单机节点独立的docker进行镜像打包jenkins内部新构建的docker无法打包因权限问题">我这里通过调用单机节点独立的docker进行镜像打包,jenkins内部新构建的docker无法打包,因权限问题</h5>
</li>
</ul>
<h4 id="4推送docker镜像到docker-hub上以备后续部署应用时使用">4、推送docker镜像到docker hub上,以备后续部署应用时使用</h4>
<ul>
<li>
<h5 id="编写脚本推送docker镜像">编写脚本,推送docker镜像;</h5>
<pre><code>stage('Push') {
echo "4.Push Docker Image Stage"
container('docker') {
      sh "docker -H tcp://192.168.231.132:2375 login --username=xjk*** -p pass@word"
      sh "docker -H tcp://192.168.231.132:2375 push xjk27400861/springbootapp:${build_tag}"
   }
}
</code></pre>
</li>
<li>
<h5 id="docker-login登录到docker-hub上然后使用docker-push命令推送--h-使用其他节点的docker">docker login登录到docker hub上,然后使用docker push命令推送;- H 使用其他节点的docker</h5>
</li>
<li>
<h5 id="ubuntu开启docker远程访问">Ubuntu开启Docker远程访问</h5>
<p>输入命令:</p>
<pre><code>   sudo gedit /lib/systemd/system/docker.service
</code></pre>
<p>找到ExecStart段,修改为</p>
<pre><code>ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock -H fd:// --containerd=/run/containerd/containerd.sock
</code></pre>
<p>保存并退出编辑后,重载守护进程以及重启Docker</p>
<pre><code>sudo systemctl daemon-reload
sudo service docker restart
</code></pre>
<p>可通过执行命令查看是否开放了远程访问端口</p>
<pre><code>sudo systemctl status docker.service
</code></pre>
</li>
</ul>
<h4 id="5拉取docker镜像部署到k8s环境中">5、拉取docker镜像,部署到k8s环境中</h4>
<ul>
<li>
<h5 id="编写脚本部署应用">编写脚本,部署应用</h5>
<pre><code>stage('Deploy') {
echo "5. Deploy Stage"
container('kubectl') {
    sh "kubectl version"
    def namespace="jenkinsdemo"//springboot2node
sh """cd /home/jenkins/agent/workspace/linetest/provider/
      ls
      sed -i 's/&lt;BUILD_TAG&gt;/${build_tag}/' k8s.yaml
      sed -i 's/&lt;BUILD_NAMESPACE&gt;/${namespace}/' k8s.yaml
      kubectl delete -f .
      kubectl apply -f k8s.yaml --record
      """
}
}
</code></pre>
</li>
<li>
<h5 id="部署成功后通过k8s主机节点端口访问应用">部署成功后,通过k8s主机节点+端口,访问应用</h5>
<img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220912234645064-2005587389.png"></li>
</ul>
<h4 id="6完整pipeline脚本">6、完整pipeline脚本</h4>
<pre><code>def label = "jnlp"
podTemplate (label: label,cloud: 'kubernetes',containers: [
//image: 'datorresf/jenkins-agent-mvn',
//image: 'maven:latest',
containerTemplate(
    name: 'maven',
    image: 'maven:3.8.1-ibmjava-8',
    alwaysPullImage: false,
    ttyEnabled: true,
    command:'cat'
    ),//docker:19.03.8
    containerTemplate(
      name: 'docker',
      image: "docker:stable",
      ttyEnabled: true,
      command: 'cat',
    ),
    containerTemplate(name: 'kubectl', image: 'bibinwilson/docker-kubectl:latest', command: 'cat', ttyEnabled: true)
],serviceAccount: 'jenkinsbuild',//jenkinsbuild
volumes: [
    hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
    hostPathVolume(mountPath: '/root/.m2', hostPath: '/root/.m2'),
    hostPathVolume(mountPath: '/home/jenkins/.kube', hostPath: '/root/.kube'),
    hostPathVolume(mountPath: '/etc/kubernetes/pki', hostPath: '/etc/kubernetes/pki'),
])
{   
node('jnlp') {
stage('Clone') {
    echo "1.Clone Stage"
    git credentialsId: '56cc9ad2-aafa-41f3-bc6b-2d7d66c52f32', url: "https://gitee.com/xujk-27400861/springboot-dubbo.git"
    script {
      build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
    }
   echo "${build_tag}"
}
stage('Test') {
    echo "2.Test Stage"
}
stage('执行构建') {
container('maven')
{
      sh "mvn --version"
      sh 'pwd'
      sh '''cd provider/
            mvn clean package -DskipTests'''
      //sh 'mvn package'
      echo '构建完成'
}
}
stage('Build') {
echo "3.Build Stage"
container('docker') {
      sh "docker -v"
      sh 'pwd'
      sh """cd /home/jenkins/agent/workspace/linetest/provider/
      ls
      docker -H tcp://192.168.231.132:2375 build -t xjk27400861/springbootapp:${build_tag} ."""
    }
}
stage('Push') {
echo "4.Push Docker Image Stage"
container('docker') {
      sh "docker -H tcp://192.168.231.132:2375 login --username=xjk*** -p ***"
      sh "docker -H tcp://192.168.231.132:2375 push xjk27400861/springbootapp:${build_tag}"
   }
}
stage('Deploy') {
    echo "5. Deploy Stage"
    container('kubectl') {
      sh "kubectl version"
      def namespace="jenkinsdemo"//springboot2node
      sh """cd /home/jenkins/agent/workspace/linetest/provider/
      ls
      sed -i 's/&lt;BUILD_TAG&gt;/${build_tag}/' k8s.yaml
      sed -i 's/&lt;BUILD_NAMESPACE&gt;/${namespace}/' k8s.yaml
      kubectl delete -f .
      kubectl apply -f k8s.yaml --record
      """
      }
   }
}
}
</code></pre>
<h4 id="7完整pipeline脚本说明">7、完整pipeline脚本说明</h4>
<ul>
<li>
<h5 id="创建一个pod里面包含构建有三个docker容器mavendocker与kubectl分别进行代码maven构建docker打包镜像kubectl部署应用到k8s环境">创建一个pod,里面包含构建有三个docker容器,maven,docker与kubectl,分别进行代码maven构建,docker打包镜像,kubectl部署应用到k8s环境</h5>
</li>
<li>
<h5 id="代码段serviceaccount-jenkinsbuild指定操作k8s环境的账户这个是rancher263部署jenkins的时候自动创建的账户service-account">代码段:serviceAccount: 'jenkinsbuild';指定操作k8s环境的账户;这个是rancher2.6.3部署jenkins的时候,自动创建的账户(service account)</h5>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913174101685-134275317.png"></p>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913174130055-1526133616.png"></p>
</li>
<li>
<h5 id="代码段docker--h-tcp1921682311322375操控单节点docker进行镜像打包及推送操作">代码段:docker -H tcp://192.168.231.132:2375;操控单节点docker进行镜像打包及推送操作</h5>
</li>
<li>
<h5 id="部署应用的时候可能会提示用户jenkinsbuild没有构建pod或者services的权限可以通过rancher的rbac编辑用户权限rolesrolebindings">部署应用的时候,可能会提示用户jenkinsbuild没有构建pod或者services的权限,可以通过rancher的rbac编辑用户权限(Roles&amp;RoleBindings)</h5>
<p><strong>Roles设置</strong><br>
<img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913174616163-246112406.png"><br>
<strong>编辑配置</strong><br>
<img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913174750529-1308821370.png"><br>
<strong>RoleBindings无需修改,后面如果有需要其他用户操作k8s的话,可以通过创建Role与RoleBindings,赋予其他账户对应的权限来操作k8s环境</strong></p>
</li>
<li>
<h5 id="jenkins的k8s连通环境配置">jenkins的k8s连通环境配置</h5>
<p><strong>Manage Jenkins -&gt; Manage nodes and clouds 依次点击,进入配置页面</strong><br>
<img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913175323487-806426174.png"></p>
<p><strong>点击:Configure Clouds;名称默认:kubernetes,我们的脚本里用cloud属性指定的k8s集群</strong><br>
<img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913175612123-1599062120.png"></p>
<p><strong>由于我使用的是rancher通过应用市场安装的,此处的kubernetes设置的都是默认值,无需修改</strong><br>
<img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913175849554-2089398969.png"></p>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913175925658-1129944271.png"></p>
</li>
<li>
<h5 id="配置连接集群外的k8s集群方法">配置连接集群外的k8s集群方法</h5>
<p><strong>修改k8s集群的地址(https://192.168.231.133:6443)</strong><br>
<img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913182757024-1015504044.png"></p>
<p><strong>连接k8s集群的认证方式,我这里配置了3种,用户名密码&amp;秘钥文本&amp;kube.config文件</strong><br>
<img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913182910104-498784510.png"></p>
<p><strong>用户名密码方式,就直接输入我们k8s集群的访问用户名和密码,在jenkins创建全局凭证,配置时选中即可</strong><br>
<img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913183112645-455481549.png"></p>
<p><strong>秘钥文本方式,我们通过rancher,下载k8s的配置文件</strong><br>
<img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913183205130-432858624.png"></p>
<p><strong>打开配置文件,把下图圈起来的数据,在jenkins创建凭据,secret text类型</strong><br>
<img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913183310164-1668356418.png"></p>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913183452274-1341099060.png"></p>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913183612911-1935139118.png"></p>
<p><strong>使用k8s的配置文件,创建secret file类型的凭证,上传我们的配置文件,测试;由于文件里配置的是k8s集群的访问域名,所以提示失败,如果域名可通的话,也是可以的</strong><br>
<img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913183917781-1286722776.png"></p>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913183743718-1891687171.png"></p>
</li>
<li>
<h5 id="流水线脚本配置maven镜像文件的时候要注意与你springboot项目中使用的版本保持一致否则会出现编译构建错误">流水线脚本配置maven镜像文件的时候,要注意与你springboot项目中使用的版本保持一致,否则会出现编译构建错误</h5>
<p><img src="https://img2022.cnblogs.com/blog/248637/202209/248637-20220913184130796-115170793.png"></p>
</li>
<li>
<h5 id="关于serviceaccount-jenkinsbuild这段需要设置访问k8s集群的用户名同时需要设置role与rolebindings赋予用户应有的权限否则会提示权限错误">关于serviceAccount: 'jenkinsbuild',这段,需要设置访问k8s集群的用户名,同时需要设置role与rolebindings赋予用户应有的权限,否则会提示权限错误</h5>
</li>
<li>
<h5 id="本文使用的代码见仓库含有k8s部署文件httpsgiteecomxujk-27400861springboot-dubbotreemasterprovider">本文使用的代码见仓库,含有k8s部署文件,https://gitee.com/xujk-27400861/springboot-dubbo/tree/master/provider</h5>
</li>
<li>
<h5 id="同时也可以通过jenkinsfile构建在项目中相应目录创建jenkinsfile里面参考流水线脚本也是可以实现构建发布的此处不详述">同时,也可以通过jenkinsfile构建,在项目中相应目录创建jenkinsfile,里面参考流水线脚本,也是可以实现构建发布的,此处不详述</h5>
</li>
</ul>
<p><strong>好的,本篇到此为止</strong></p><br><br>
来源:https://www.cnblogs.com/kunwn/p/16687516.html
頁: [1]
查看完整版本: jenkins流水线部署springboot应用到k8s集群(k3s+jenkins+gitee+maven+docker)(2)