使用jenkins流水线完成自动部署服务到K8s

Posted 凌霜傲雪归来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用jenkins流水线完成自动部署服务到K8s相关的知识,希望对你有一定的参考价值。

说明

通过本文章,您可以轻松入门cicd过程。本地测试环境为springboot微服务项目。用户提交代码到gitlab,触发jenkins拉取gitllab上的代码,然后完成编译构建成jar包,同步完成sonarsqube代码质量检测。然后在jenkins内部完成生成镜像,并将镜像推送到harbor仓库中,然后通过K8s完成服务的部署。

依赖环境部署

环境准备

使用环境说明

使用的虚拟机环境centos7.9,使用vmware安装

同步主机时区为亚洲,并同步时间

[root@linux-node ~]# echo "ZONE=Asia/Shanghai" >> /etc/sysconfig/clock         
[root@linux-node ~]# rm -f /etc/localtime
#链接到上海时区文件       
[root@linux-node ~]# ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

关闭防火墙和selinux

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# systemctl disable firewalld
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@localhost ~]# setenforce 0
[root@localhost ~]# sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

设置yum源

wget -O /etc/yum.repos.d/CentOS-Base.repo  http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo  http://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum makecache

安装docker

linux安装docker

创建数据目录将数据持久话到该目录下,以便后期好维护

mkdir -p /data

安装maven

linux安装maven

gitlab安装部署

docker安装gitlab

harbor安装部署

docker安装harbor

jenkins安装部署

docker安装jenkins

sonarqube部署

docker安装sonarsqube

k8s部署

部署过程略

创建java工程并测试将代码上传到gitlab仓库

gitlab上创建项目

创建springboot工程,并将代码提交到hello-test工程下

idea创建springboot项目

编写Jenkinsfile的方式

流水线语法

我们在编写jenkins流水线脚本时可以先将框架写好,然后再补齐内容。

pipeline 
    //指定任务在哪个集群节点上执行
    agent any
	//声明环境变量,方便后面使用
	environment 
	    key='value'
	
	
		
    stages 
        stage('拉取git仓库代码') 
            steps 
                echo '拉取git仓库代码-SUCCESS'
            
        
		stage('通过maven构建项目') 
            steps 
                echo '通过maven构建项目-SUCCESS'
            
        
		stage('通过sonarqube做代码质量检测') 
            steps 
                echo '代码质量检测-SUCCESS'
            
        
		stage('通过docker制作自定义镜像') 
            steps 
                echo 'docker制作自定义镜像-SUCCESS'
            
        
		stage('将自定义镜像推送到harbor仓库中') 
            steps 
                echo '推送到harbor仓库-SUCCESS'
            
        
		stage('通过publish  over  ssh通知目标服务器') 
            steps 
                echo '通知目标服务器-SUCCESS'
            
        
    

生成jenkins 流水线脚本

点击下方的流水线语法
例如:我要从git上下载代码

下面填好之后

点击生成流水线脚本

把生成的脚本粘贴到对应的步骤下

这样就完成了流水线代码的生成。
可以在对应的stage处查看对应步骤的日志。

使用git维护Jenkinsfile文件

在gitlab一个项目中创建Jenkinsfile,可以在一个单独的项目中,也可放到对应项目中
在项目目录下创建Jenkinsfile文件,名称必须是这样的。J为大写的。
将内容放到该文件中

点击commit changes
这样工程根目录下就多了个Jenkinsfile文件,我们就可以在gitlab上去维护该文件了。

jenkins上配置使用gitlab上的Jenkinsfile

构建后发现多了该步骤

jenkins全局配置

管理Jenkins中点击

配置maven

手动配置:
主机上安装maven后将maven的安装目录移动到jenkins数据卷中

重命名文件夹

在页面上配置,MAVEN_HOME要使用容器内部目录,不要使用宿主机目录

配置jdk


页面配置jdk

使用 jenkins流水线完成cicd

新建任务,选择流水线

git下载代码到本地


下面填好之后

点击生成流水线脚本

把生成的脚本粘贴到对应的步骤下

通过maven构建项目

使用sh:shell script步骤

将生成的脚本粘贴到gitlab Jenkinsfile对应的步骤下

通过sonarqube做代码质量检测

通过docker制作自定义镜像

配置使得jenkins内部具有构建镜像能力 docker in docker配置

修改/var/run/docker.sock权限,使其属于root组,并且其他用户有读和写的权限

修改jenkins数据数据卷,jenkins内部要有执行docker命令的能力,需要将下面文件挂载到容器内部。

Jenkins docker-compose.yml文件

version: '3.1'
services:
  jenkins:
    image: jenkins/jenkins:2.319.1-lts
    container_name: jenkins
    ports:
      - 8090:8080
      - 8091:50000
    volumes:
      - /data/jenkins_home/:/var/jenkins_home/
      - /var/run/docker.sock:/var/run/docker.sock
      - /usr/bin/docker:/usr/bin/docker
      - /etc/docker/daemon.json:/etc/docker/daemon.json

由于之前使用docker run方式启动的jenkins,此时需要删除掉容器,不要删除之前创建的数据卷就可以,然后使用docker-compose方式启动,此时不会删除数据,以后推荐改成docker-compose方式,这样运维人员也知道你的启动时加了哪些参数了,易于维护。

docker  stop jenkins
docker  rm  jenkins
docker-compose  up -d 


进入到容器内部,测试,发现成功。

生成构建镜像的jenkinsfile内容

将自定义镜像推送到harbor仓库中

使用K8s编排容器完成部署

准备部署的yaml文件

放到项目的根目录下,放到项目的根路径下

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pipline-deployment
  namespace: dev
spec:
  replicas: 2
  selector:
    matchLabels:
      app: pipline-pod
  template:
    metadata:
      labels:
        app: pipline-pod
    spec:
      containers:
        - name: pipline
          image: 192.168.59.129:8888/hello/pipline-test:latest
          ports:
            - containerPort: 8080
---

apiVersion: v1
kind: Service
metadata:
  name: pipline-service
  namespace: dev
spec:
  selector:
    app: pipline-pod
  type: NodePort
  ports:
    - port: 30002
      targetPort: 8080

配置jenkins可以ssh连接到K8s master节点

系统配置里配置K8S主节点

将pipline.yaml文件传送到K8s-master节点上


生成代码放到Jenkinsfile文件中

查看K8s-master节点对应的目录里是否有pipline.yaml文件

在k8s-master节点上执行kubectl apply -f pipline.yaml 命令将服务部署起来

解决jenkins上执行ssh命令时需要输入密码问题

ssh无密码登录设置
docker exec -it jenkins bash
cd ~
mkdir .ssh
$ cd ~/.ssh
ssh-keygen -t rsa -C “email@example.com”
系统提示输入文件保存位置等信息,连续按三次回车即可,生成的SSH key文件的保存路径会在终端中给出:id_rsa id_rsa.pub
cat id_rsa.pub 将内容追加到k8s-master节点/root/.ssh/authorized_keys文件后面
验证
在jenkins容器内部验证,发现不用再输入密码了

配置远程执行命令


gitlab jenkinsfile增加以下步骤

测试验证,注意每次提交需要打tag,不修改pipline文件时并不会重新部署服务。

集成钉钉通知将部署结果发送到钉钉里

安装DingTalk插件

创建钉钉群,获取到webhook

创建过程略

系统配置钉钉

系统管理–系统配置

自动化ci操作

配置提交代码后jenkins自动拉取代码 (webhook配置)

需要安装gitlab插件

勾选下面当代码推送后触发构建

在gitlab上


点击下面的Add webhook后提示
不能填写本地主机的url允许本地地址构建webhook

需要在admin settings network 处勾选

重新添加
会在项目下看到webhook的地址

点击此处测试自动化构建


解决测试webhook返回403问题

解决:
在系统配置里将此处勾选去掉
系统管理 -> 系统设置 -> Enable authentication for ‘/project’ end-point

重新测试会发现jenkins已经开始自动构建了。

ps://img-blog.csdnimg.cn/09cfd85cec5944fb84c039cce83a5314.png)
解决构建过程中提交代码后然后发现没有改动的问题:

解决办法:
需要使用kubectl rollout命令重新滚动一次

 kubectl rollout restart deployment pipline-deployment -n dev

修改Jenkinsfile

自动化ci Jenkinsfile文件

pipeline 
    //指定任务在哪个集群节点上执行
    agent any
	//声明环境变量,方便后面使用
	environment 
	    harbor_user='admin'
        harbor_password='Harbor12345'
        harbor_addr='192.168.59.129:8888'
        harbor_repo='hello'
	
	
		
    stages 
        stage('拉取git仓库代码') 
            steps 
               checkout([$class: 'GitSCM', branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: 'hello-demo', url: 'http://192.168.59.129:8099/root/hello-demo.git']]])
            
        
    
		stage('通过maven构建项目') 
            steps 
                sh '/var/jenkins_home/maven/bin/mvn  clean package -DskipTests'
            
        
		stage('通过sonarqube做代码质量检测') 
		steps 
            sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner   -Dsonar.sources=./   -Dsonar.projectname=$JOB_NAME   -Dsonar.projectKey=$JOB_NAME -Dsonar.java.binaries=./target/  -Dsonar.login=23adbf175860533b91bd72d5795ad4f74ab81989'
     
            
        
		stage('通过docker制作自定义镜像') 
            steps 
               sh '''mv ./target/*.jar  ./docker/
                docker build -t  $JOB_NAME:latest  ./docker/'''
            
        
		stage('将自定义镜像推送到harbor仓库中') 
            steps 
                sh '''docker login -u $harbor_user -p $harbor_password $harbor_addr
                docker tag $JOB_NAME:latest  $harbor_addr/$harbor_repo/$JOB_NAME:latest
                docker push $harbor_addr/$harbor_repo/$JOB_NAME:latest'''
            
        
		stage('将pipline.yaml传送到K8s-master节点') 
            steps 
            sshPublisher(publishers: [sshPublisherDesc(configName: 'k8s', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'pipline.yaml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            
        

        	stage('在k8s-master上执行部署命令') 
            steps 

               sh '''ssh   root@192.168.59.128   kubectl apply  -f  /root/deploy/pipline.yaml
               ssh   root@192.168.59.128    kubectl rollout restart deployment pipline-deployment -n dev'''
            
        

    
	post 
	    success 
		dingtalk(
		    robot: 'jenkins-dingding',
			type: 'MARKDOWN',
			title: "success: $JOB_NAME",
			text: ["- 成功构建: $JOB_NAME! \\n - 版本:latest \\n - 持续时间:$currentBuild.durationString"]
		)
				
		
		failure 
		dingtalk(
			robot: 'jenkins-dingding',
			type: 'MARKDOWN',
			title: "success: $JOB_NAME",
			text: ["- 失败构建: $JOB_NAME! \\n - 版本:latest \\n - 持续时间:$currentBuild.durationString"]
		
		)
		
		
	
	
	

以上是关于使用jenkins流水线完成自动部署服务到K8s的主要内容,如果未能解决你的问题,请参考以下文章

Jenkins教程——从安装到部署Docker服务声明式流水线HelloWorld

再见 Jenkins!几行脚本搞定自动化部署,这款神器有点厉害

如何使用 Jenkins 的脚本化流水线(Pipeline)

企业级Docker+Jenkins+Gitlab自动化流水线构建

Jenkins构建完成后自动部署到指定服务器

devops持续集成开发——jenkins流水线发布一个node环境下的前端vue项目