CICD之 gitlab和gtilab runner

gitlab官网地址
官网文档地址 https://docs.gitlab.com/runner/install/docker.html

一。gitlab

1。gitlab安装

方式一:rpm包安装(centos)
   1,下载rpm包
	  清华源软件镜像站https://mirrors.tuna.tsinghua.edu.cn/
	  linux命令wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ee/yum/el7/gitlab-ee-12.9.0-ee.0.el7.x86_64.rpm --no-check-certificate
	   或者windows电脑访问软件直接下载rpm包然后上传linux
	   
	2.运行rmp包
	    rpm -ivh gitlab-ce-12.9.0-ce.0.e17.x86_64.rpm
	
	3.修改项目仓库存储地址
		vim /etc/gitlab/gitlab.rb,搜索git_data_dirs,修改项目存储路径
		gitlab-ctl reconfigure,使生效
	

	4。启动
		gitlab-ctl start    //启动
		gitlab-ctl status   //查看状态
		gitlab-ctl stop    //停止

方式二:docker安装
	1.gitlab文件夹下创建三个文件夹作为映射文件夹(容器卷) :config   logs   data
	2,拉取镜像:docker pull gitlab/gitlab-ce
	3.运行镜像
		docker run 
			-d 
			--hostname 192.168.61.146     //有hostname,不然后面创建项目的克隆地址是随机的
			-p 443:443 -p 80:80 -p 222:22 
			--name gitlab-ce
			--restart always 
			-v /home/piaoransheng/gitlab/config:/etc/gitlab
			-v /home/piaoransheng/gitlab/logs:/var/log/gitlab
			-v /home/piaoransheng/gitlab/data:/var/opt/gitlab
		gitlab/gitlab-ce
		
	4.修改项目仓库存储地址
		vim /etc/gitlab/gitlab.rb,搜索git_data_dirs,修改项目存储路径
		gitlab-ctl reconfigure,使生效
	

	5.启动
		docker start gitlab-ce    //启动
		docker stop  gitlab-ce    //停止下·
		docker rm    gitlab-ce     //删除

	6.测试访问:http://192.168.61.146/users/sign_in


方式三:docker-compose安装
version: '3'
services: 
  gitlab:
    image: 10.10.4.129:5000/gitlab/gitlab-ce:latest
    container_name: gitlab
    hostname: 10.10.4.129   //如果有修改more端口80为2880,这边要加上端口2880
    restart: always
    privileged: true   #避免挂载目录提示没有权限
    volumes:
      - ./volumes/config:/etc/gitlab
      - ./volumes/logs:/var/log/gitlab
      - ./volumes/data:/var/opt/gitlab
    ports: 
      - 80:80
      - 443:443
      - 222:22


测试:http://10.10.4.129/

2。gitlab登录与创建项目

[登录网址](http://192.168.61.146/)
初始账号:root
密码在:config/initial_root_password里

创建组/项目/用户 menu-admin——
查看项目        menu——project-your project

设置中文:右上下三角号——>preferences——>Localization——>Language

设置root账号的密码:菜单——管理员——用户——点击管理员账号——编辑——更改密码root123456

项目代码存储在每个runner的/builds/root/mygitlab-project-1文件夹里面,注意不是gitlab,也不是gitlab-runner,而是gitlab-runner里面的runner
所以在注册runner时可以做个映射,具体见下面runner 注册
   gitlab-runner register 
    --docker-volumes /home/piaoransheng/gitlab-runner/projects:/builds/root //把runner运行的路径映射到本地,/builds/root是通过

二。gitlab runner

1.gitlab runner安装

1,简介: gitlab-runner是用来运行流水线,流水线是由一个一个的job(作业)拼接而成(项目根目录下的.gitlab-ci.yml)
	    gitlab runner是一个开源项目,用于运行作业并将结果发送回Gitlab
        gitlab runner类似于Jenkins的agent,执行CI持续继承、构建的脚本任务
		

2.gitlab runner类型与状态
   类型:
		shared 共享类型,运行整个平台项目的作业
		group  项目组类型,运行特定group下项目的作业
		specific 项目类型,运行指定项目的作业
	
	状态:
		locked 锁定状态
		paused 暂停状态
  
3.gtilab runner安装	
    (两个必备映射:本机docker、gitlab-runner配置文件)
	docker run 
		-d 
		--name gitlab-runner 
		--restart always    
		-v /var/run/docker.sock:/var/run/docker.sock   //要有这个,不然执行器类型为docker的runner无法运行 报错误 后台是否启动Docker Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running
		-v /home/piaoransheng/gitlab-runner/config:/etc/gitlab-runner  //配置文件的映射,用来修改runner拉取镜像策略,不然每次都要拉取作业所需镜像,比如maven,浪费时间并且docker images也会有多个maven的镜像
	gitlab/gitlab-runner:latest
	
	测试:docker ps 看到gitlab-runner服务已经启动
	
	或者docker-compose方式安装
		version: '3'
		services: 
		  gitlab-runner:
		    image: 10.10.4.129:5000/gitlab/gitlab-runner:latest
		    container_name: gitlab-runner
		    hostname: 10.10.4.129
		    restart: always
		    privileged: true   #避免挂载目录提示没有权限
		    volumes:
		      - /var/run/docker.sock:/var/run/docker.sock
		      - ./volumes/config:/etc/gitlab-runner

2.注册runner

1.runner注册
	1.获取注册token   	
		shared类型token:menu——admin——overview——runners
		group类型token: men——groups——your groups——点击gruop——setting——CI/CD——runners
		project类型token: menu——Projects——your projects——点击项目——setting——CI/CD——runners
	
	2.注册, (注册后就会在容器里/etc/gitlab-runner/config或者本机映射)的config.toml出现记录
		 a.交互方式注册执行器类型为shell的runner
			a.敲命令:gitlab-runner register,回车
			b.根据提示粘贴注册地址,回车 (见上面获取注册token)
			c.根据提示输入注册token,回车(见上面获取注册token)
			d.根据提示输入runner描述:build,回车
			e.根据提示输入runner包名:build,回车
			f.根据提示输入runner执行器:shell(shell/docker/kubernetes),回车
			g.测试 在menu——admin——overview——runners页面最下面出现刚才注册的那一条runner
		
		b.docker方式注册执行器类型为shell的runner
			1.进入gitlab-runner容器里面: docker exec -it  c82ccb670c86 /bin/bash
			2.敲命令
					gitlab-runner register 
						--non-interactive      //非交互模式
						--executor "shell"    //执行器类型,有shell docker k8s
						--url "http://192.168.61.146"  //从gitlab页面获取 见上面获取注册token
						--registration-token "UNywwHz-3eofcXjtyfvS"  //见上面获取注册token
						--description "deploy"
						--tag-list "build,deploy"  //runner 包名,后面脚本文件的tags要和这边对应,才会使用到这个runner
						--run-untagged="true"      //是否运行没有指定runner的作业
						--locked="false"           //是否所帝国
						--access-level="not_protected"'
					
			3.测试 
			       在menu——admin——overview——runners页面最下面出现刚才注册的那一条runner
			       或者/etc/gitlab-runner/config config.toml
					
		c.docker方式注册执行器类型为docker的runner(四个必备映射:本机docker、项目路径、maven配置文件、maven仓库)
		     
			  gitlab-runner register 
					--non-interactive      //非交互模式
					--executor "docker"    //执行器类型,有shell docker k8s
					--docker-image alpine:latest //docker运行默认镜像,执行器类型为docker的才需要
					--url "http://192.168.61.146"  //从gitlab页面获取 见上面获取注册token
					--registration-token "UNywwHz-3eofcXjtyfvS" //见上面获取注册token
					--description "deploy"
					--tag-list "build,deploy"  //runner 包名
					--run-untagged="true"      //是否运行没有指定runner的作业
					--locked="false"           //是否锁定
					--access-level="not_protected"
					--docker-volumes /var/run/docker.sock:/var/run/docker.sock  //也和本地docker映射
					--docker-volumes /home/project/docker/conventional-station:/builds/yongfu/conventional-station:Z  //项目路径 这个需要注册完然后跑一个作业 echo "当前目录:$(pwd)看项目具体在容器哪里,然后再进去gitlab-runner的config.toml文件进行修改
					 --docker-volumes /home/piaoransheng/maven/apache-maven-3.8.1/conf/settings.xml:/usr/local/maven/config/setting.xml   //maven配置文件
					 --docker-volumes /home/piaoransheng/maven/apache-maven-3.8.1/cangku:/home/piaoransheng/maven/apache-maven-3.8.1/cangku    //maven仓库
					 			
			  注意:执行器为docker类型的runner注册完去gitlab-runner容器/etc/gitlab-runner/config.toml
			  对应的映射是/home/piaoransheng/gitlab-runner/config/config.toml
			  在[[runners.docker] image下面加上pull_policy = "if-not-present" //拉取策略,就不用每次执行都要拉取镜像,执行器类型为docker的才需要		
	
	测试:在menu——admin——overview——runners页面最下面出现刚才注册的那一条runner
			       或者/etc/gitlab-runner/config config.toml


2.gitlab-runner一些命令(需要进入gitlab-runner容器里面才能运行)
  卸载                     gitlab-runner uninstall
  启动                     gitlab-runner start
  重启                     gitlab-runner restart
  停止                     gitlab-runner stop
  状态                     gitlab-runner status
  注册执行器:                                      gitlab-runner register 
  已注册的执行器列表                                 gitlab-runner list
  检查执行器是否可以连接,但不验证gitlab是否正在使用它     gitlab-runner verify
  删除                                        gitlab-runner delete
  注销                                        gitlab-runner unregister	  
  使用令牌注销执行器          gitlab-runner unregister --url http://192.168.61.146 --token UNywwHz-3eofcXjtyfvS
  使用名称注销执行器          gitlab-runner unregister --name gitlab-runner-name
  注销所有执行器              gitlab-runner unregister --all-runners
			
	
3.运行流水线任务(流水线任务定义在项目根目录下的.gitlab-ci.yml)
	1,项目创建gitlab-ci.yml文件  在gitlab页面,menu——project——your project——点击项目——set up ci/cd
	   项目跟目录就出现了文件.gitlab-ci.yml
    2.编辑.gitlab-ci.yml定义流水线任务
    3。提交代码,流水线任务就执行了

3.流水线任务脚本编写

a 创建脚本文件
menu——project——your project——点击项目——点击set up for CI/CD——选择分支点击create new CI/CD pileline

在这里插入图片描述
在这里插入图片描述

b 验证脚本 .gitlab-ci.yml
校验:menu——projects——your projects——点击项目——CICD——有个CI LINT(在run pipeline的左边)
   把文件内容复制进去,然后validata
c 脚本语法 .gitlab-ci.yml

1.简览

stages             全部阶段
cache:             缓存,有全局缓存和作业缓存
environment         
inherit
services           执行器类型为docker的runner用到
images             执行器类型为docker的runner用到,有全局镜像和作业镜像
						默认images: 注册runner时声明:alpine:latest 
						全局images : 流水线yml文件声明
						每个作业作业images, 流水线yml文件声明
						作业有用作业的image,作业没有用全局的image,全局没有用默认的image						
job                 
	 scripts               作业任务
	 before_script:        作业有用作业的,作业没有用全局的,全局没有就不执行
	 after_script:		   作业有用作业的,作业没有用全局的,全局没有就不执行
	 tags                  指定哪个执行器
	 allow_failure         是否允许失败(默认false),如果为true,前面的Job失败,不会影响流水线后面的job的继续运行
	 retry                 作业失败时重试,直到达到retry指定的次数
	 timeout               超时(作业的超时时间可以超过项目级别超时时间,但是不能超过runner特定的超时时间)
	 parallel
	 only                  定义哪些分支被执行
	 except                定义哪些分支不会被执行    
	 rules
	 workflow
	 artifacts             生成制品
	 depency               获取制品	
	 when                  控制作业运行(on_success  on_failure  always  manual  delayed  never)
	                         前面阶段作业  成功        失败        总是     收到    延迟     从不				

2.语法具体示例

only:
	-dev(dev分支)    - branches(所有分支)
except:
	-dev


cache:      缓存,有全局缓存和作业缓存
  paths: 
	- target/ *.jar


artifacts:  #生成制品
   name: mygitlab-1.0-SHAPSHOT.jar  #制品名称
   when: on_success   #job运行成功时做制品库
   paths:             #源文件路径
     - target/xx.jar
 
 dependencies:    #使用制品
    - build #job名称
  1. 三阶段试验成功示例
variables:
  IMAGE_NAME: "conventional-station"
  IMAGE_TAG: "v1.0.0-snapshot.1.0"
  CONTAINER_NAME: "conventional-station"
  DOCKER_FILE_PATH: "./Dockerfile"

stages:          #定义这个流水线的所有阶段
  - Build
  - Image
  - Deploy

build:               #自定义的作业名称
  stage: Build       #处于流水线哪个阶段
  tags:              #用哪个注册过的runner,页面menu——admin——overview——runners 最下面显示所有runner
    - dev-executor
  only:
    - dev
  image: maven:3-openjdk-11       #在哪个镜像环境里面运行
  script:
    - echo "当前目录:$(pwd)"   # builds/root/mygitlab-project-1(在这个maven容器,如果shell启动是在gitlab-runner容器)
    - ls
    - echo "编译打包"
    - mvn clean package -Dmaven.test.skip=true -s /usr/local/maven/config/setting.xml  #-s指定配置文件
    - ls
    - ls target
  artifacts:
    name: $IMAGE_NAME-1.0-SHAPSHOT.jar  #制品名称
    when: on_success   #job运行成功时做制品库
    expire_in: 30 days #保留时间
    paths:             #源文件路径
      - target/*.jar


creatImage:
  stage: Image
  tags:
    - dev-executor
  image: bradj/docker:latest
  dependencies:    #使用制品
    - build #job名称
  script:
    - echo "当前目录:$(pwd)"   # docker镜像路径:builds/root/mygitlab-project-1
    - ls
    - echo "构建镜像"

    #停止并关闭容器
    - >
      if docker ps | grep ${CONTAINER_NAME} ;then
        echo "进入停止容器"
        docker stop `docker ps -a | grep ${CONTAINER_NAME} | awk '{print $1}' `
      fi
    - >
      if docker ps -a | grep ${CONTAINER_NAME} ;then
        echo "进入删除容器"
        docker rm   `docker ps -a | grep ${CONTAINER_NAME} | awk '{print $1}' `
      fi

    #删除镜像
    - >
      if docker images | grep ${IMAGE_NAME} | awk '{print $3}' ;then
        echo "进入删除镜像"
        docker rmi $(docker images | grep ${IMAGE_NAME} | awk '{print $3}')
      fi

    #构建镜像
    - docker build -t ${IMAGE_NAME}:${IMAGE_TAG} .

deploy:
  stage: Deploy
  tags:
    - dev-executor
  image: bradj/docker:latest
  script:
    - echo "容器名称:${CONTAINER_NAME},  镜像:${IMAGE_NAME}:${IMAGE_TAG}"
    - docker run -d  -p 9091:9091 --name ${CONTAINER_NAME} ${IMAGE_NAME}:${IMAGE_TAG}



踩坑记录:
 1.提交代码部署报错提示环境内没有Dock:Docker Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running
     安装gitlab-runner的时候映射本机docker,这样gitlab-runner才能运行执行器类型为docker的runner

2.runner每次执行脚本都重新再拉取所需镜像(gitlab-runner要再拉取镜像,比如maven,docker,配置gitlab-runner)
      去runner容器里面的/etc/gitlab-runner/config config.toml ,找到这个runner进行如下配置
       在[[runners.docker]下面加上pull_policy = "if-not-present" //拉取策略,就不用每次都拉取镜像

3.runner每次执行脚本都去下载依赖包导(gitlab-runner里面的容器要再下载依赖,配置gitlab-runner里面的容器,比如maven)
   a.注册runner的时候映射maven配置文件、maven仓库(也可以注册完去gitlab-runner/config/congit.toml文件修改)
   b.runner作业脚本指定maven配置文件 mvn clean package -Dmaven.test.skip=true -s /usr/local/maven/config/setting.xml

4.运行jar包提示找不到主类
   pom加入插件
  <build>
	    <plugins>
	        <plugin>
	            <groupId>org.springframework.boot</groupId>
	            <artifactId>spring-boot-maven-plugin</artifactId>
	        </plugin>
	    </plugins>
	</build>



  	<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.test.MainApplication</mainClass>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

5.Depoy阶段运行成功,容器日志显示项目启动,端口8081,但是无法访问
	运行镜像要做端口映射  docker run -d  -p 8081:8081 --name $CONTAINER_NAME $IMAGE_NAME:$IMAGE_TAG