纯手工搭建 GitaLab与 Gitlab-CI/CD—干货
作者:javastarboy
背景:前几年(2018 年前后)的 jenkins+docker+k8s 的CI/CD 在工作之中受益不少。提升了不少工作效率。而随着这几年的使用发现,目前 gitlab-CI/CD 在持续集成部署中更加方便、高效。 尤其是在测试环节中,研发无需编写复杂的 jenkins 脚本,只要提交代码,即可自动构建部署。 环境的处理也与 git 思想一致,在敏捷迭代中,效果显著。 最近,小编的其中一个客户也有此方面诉求,便着手搭建了一下这套流程,奈何网上资料过于零散,虽然仅用一天时间便搭建起来,但是我认为,前面已经这么多人(项目组)用过了,在开源的浪潮下,就不应该让后人这么繁琐的搭建这套流程。 所以此篇文章旨在读此一篇,便可拿到所有资料链接、便可成功搭建 Gitlab-CI/CD。
1、准备工作
1.1 服务器准备
- 服务器两台:实际使用中,gitlab 与 gitlab-runner 会分开使用(后文介绍)
- Gitlab 服务器:4C8G 5M宽带【如果 2C4G 基本上会经常卡死】
- Gitlab-Runner 服务器:2C4G(runner 比较吃内存,实际使用中建议根据需要搭配,这里学习使用,仅用 4G)。 当然,项目中 runner 也可使用 docker + k8s 更加便利。
- 服务器版本
我最后用的是 CentoOS7.6 (因为在 CentoOS8 中,在安装 gitlab 过程中会有命令兼容问题,我 gitlab 用的是腾讯云,gitlab-runner 用的阿里云,这两个云自研的 OpenCloud8 都有问题。所以建议使用原生的 CentoOS7.6,可以规避很多问题
) - 服务器的购买
无论买哪个,一定要珍惜自己的新人机会,就一次,能省下很多钱
- 阿里云:各方面都挺好,但仅新用户合适,老用户真的太贵了。 建议珍惜新人优惠,赶在双 11 一次性买个三年的, 小编买的是 2C8G5M 宽带 3年 g5 服务器,当时才 700 多,现在已经 8000 多了。
- 腾讯云:性价比较高,小编买的是新人优惠 188 元 1 5 个月 2C4G6M 宽带轻量级
- 华为云:主要是企业用的多,个人学习不建议
- 京东云:用的太少了,不建议买
1.2 软件准备
此文章写于 2023 年 3 月 5 日,相关软件版本用的当下最新版
- Gitlab CE(社区版) 15.9.2
- gitlab-runner 15.9.1
- JDK 11 (这个无所谓,根据项目选择)
- Git 2.31.1
- maven 3.6.3 (用于 maven 构建项目)
- gradle (用于 gradle 构建项目)
2、Gitlab 的安装
安装参考链接
官网 gitlab ce 安装包
2.1 安装 gitlab 相关命令
- 先创建一个 gitlab 用户(后面用于发布 jar 服务方便管理,与安装无关)
也可看小编另一篇文章Liunx创建用户与授权大招以及Linux修改SSH端口linux 创建用户并授权案例,一劳永逸
# 创建tomcat用户于tomcat目录上
useradd gitlab
# 修改密码
passwd gitlab 回车
然后键入密码
# 授权tomcat目录
chown -R 777 /home/gitlab
# 修改sudo 权限:
1)键入 vi /etc/sudoers 进入编辑模式,然后键入 i 追加如下权限
gitlab ALL=(ALL) ALL
2)若需跨服务执行 sudo 权限,追加如下权限
gitlab ALL=(ALL) NOPASSWD:ALL)
3)最后按 esc 键,输入 `:wq` 保存
# 后续安装 maven、gitlab 等用户都需要同步授权目录使用
chown -R gitlab:tomcat /usr/share/apache-maven
-
安装依赖包
yum install -y curl policycoreutils-python openssh-server
-
设置 SSH 开机自启动并启动 SSH 服务
systemctl enable sshd systemctl start sshd
-
安装 Postfix
yum install -y postfix
-
Postfix 设置
# 设置 Postfix 服务开机自启动 systemctl enable postfix # 打开 Postfix 的配置文件 main.cf vim /etc/postfix/main.cf
按 i 进入编辑模式,删除 inet_interfaces = all 前的 #,在 inet_interfaces = localhost 前加上 #。修改完成后如下图所示。 然后按 Esc 并输入 :wq 保存修改并退出文件
-
启动 Postfix
systemctl start postfix
-
执行以下命令,添加 GitLab 软件包仓库(CentoOS 8.2以上会有问题)
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
-
安装 GitLab
sudo EXTERNAL_URL="服务器的公网IP地址" yum install -y gitlab-ce
-
在本地浏览器中访问已获取的公网 IP,返回页面如下所示,则表示已成功安装 GitLab
2.2 设置管理员帐户密码
- 获取管理员帐户默认密码
bash cat /etc/gitlab/initial_root_password
- 登录 GitLab
在本地浏览器中访问云服务器的公网 IP,进入 GitLab 登录界面。使用 root 帐户及已获取的登录密码进行登录 - 修改管理员帐户密码
由于保存默认密码的文件将在首次配置运行24小时后自动删除,请尽快修改 root 帐户登录密码。选择页面右上角的用户头像,在弹出菜单中选择 Perferences。在 “User Settings” 页面中,选择左侧导航栏的 Password。在页面中输入目前使用密码,新密码及确认新密码后,单击 Save Password 即可。如下图所示:
- 创建项目与Add SSH Key 属于工具的使用,这里不赘述了,大家可以自行验证。
也可转此文章:SSH Key的操作
3、Gitlab-Runner 安装
3.1 先安装必要软件
- 安装 Git
# 安装 git yum -y install git # 查看是否安装成功 git --version # 如果版本是 1.8*,那就再更新一下 git 版本,否则后面 gitlab-runner 第二次 stage 阶段会报错 yum update git
- 安装 jdk11
# 查找openjdk yum search java|grep jdk # 或者带颜色查找,看着方便点 yum search java | grep -i --color jdk # 选择需要的文件进行安装(以 1.8 为例) yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel # 或者如下命令,安装 open jdk1.8 的所有文件(省事) yum install -y java-1.8.0-openjdk* # ======================================== # 其他命令 # 查找已安装的jdk yum list installed | grep [java][jdk] # 卸载所有openjdk相关文件 yum -y remove java-1.8.0-openjdk* # 安装OpenJDK 8 JRE yum install java-1.8.0-openjdk # 安装OpenJDK 8 JDK yum install java-1.8.0-openjdk-devel # 查找已安装的jdk yum list installed | grep [java][jdk] # 卸载所有openjdk相关文件 yum -y remove java-1.8.0-openjdk*
- 安装 maven 3.6.3
-
maven 官方下载地址
- 将下载好的maven安装包放在磁盘的 /usr/local/ 目录下,如下图:
- 解压apache-maven-3.6.3-bin.tar.gz文件。如下图:
- 将解压后的文件夹改成一个短一点的名字:maven3.6
mv /usr/local/apache-maven-3.8.6/ /usr/local/bin/maven3.6
- 修改 maven settings.xml 仓库镜像地址为阿里云镜像(否则下载依赖会很慢)
<mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror>
- 配置maven环境变量,编辑:vi /etc/profile 文件
# 输入如下命令打开配置文件 vi /etc/profile # 输入 i 进入编辑模式 export MAVEN_HOME=/usr/local/bin/maven3.6 export PATH=$PATH:$MAVEN_HOME/bin # 按 esc 键,然后疏忽 :wq 回车保存 # 输入如下命令,生效配置 source /etc/profile # 输入命令,验证安装是否成功,打印出 maven 版本即成功,如图: mvn -v
-
maven 官方下载地址
- 安装 gradle 3.6.3
安装原理同 maven
- 安装包下载地址
- 上传包至 /usr/local/bin 下
- unzip gradle-5.5.1-all.zip
- vim /etc/profile
- shift+G 进入最后一行,数
i
进入编辑模式 - 追加如下配置
# gradle
GRADLE_HOME=/usr/local/bin/gradle-5.5.1
export PATH=$PATH:GRADLE_HOME/bin
- exit退出编辑,
:wq!
保存并推出 - source /etc/profile
- gradle -v
3.2 安装 Gitlab-Runner
注意:此时已经切换到另外一台服务器了,后面CI/CD 主要在这里执行
3.2.1 安装 gitlab-runner
# Download the binary for your system
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
# Give it permission to execute
sudo chmod +x /usr/local/bin/gitlab-runner
# Create a GitLab Runner user
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
# Install and run as a service
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start
3.2.2 注册runner
1、命令注册
# 注册命令(注意 gitlab 服务器地址以及获取 token 方式见后图)
sudo gitlab-runner register --url `http://你 gitlab 服务器的公网IP`/ --registration-token `我是项目的token值(获取方式见后图)`
# 接下来就是输入一些列命令,按照提示操作即可,示例如下($为服务器的步骤提示):
# 1. 填写gitlab的地址,确保容器内能够顺利访问到该地址
$ Enter the GitLab instance URL (for example, https://gitlab.com/):
输入:http://gitlab服务器公网ip/
# 填写需要注册的runner token,此处选择shared runner token【获取方式见后面截图】
$ Enter the registration token:
输入:BHRagrsztQAxdMPPhxGm
# 描述信息随意填写,也可不填
$ Enter a description for the runner:
输入:gitlab-runner-01
# tag随意填写
$ Enter tags for the runner (comma-separated):
输入:lmx-runner-4
# 随意填写,可不填
$ Enter optional maintenance note for the runner:
Registering runner... succeeded
# 选择执行器的种类,建议选择docker【小编为演示方便,选择了 shell】
$ Enter an executor: docker, shell, ssh, kubernetes, custom, docker-ssh, parallels, virtualbox, docker+machine, docker-ssh+machine:
输入:shell
token 获取位置如图:
Setting -> CI/CD -> Genneral pioelines settings -> Expand
2、回到 gitlab 查看 runne
gitlab 页面如下,部分信息可以再次修改
3.2.3 gitlab-runner 的命令
# 启动 重起 停止
gitlab-runner start
gitlab-runner restart
gitlab-runner stop
# 查看gitlab-runner运行状态
gitlab-runner status
4、实践-自动化部署 java SpringBoot 项目
4.1 配置一个 gitlab-runner
见 3.2.2 注册runner 章节的注册一个 runner 说明
4.2 编辑 .gitlab-ci.yml
先初始化 .gilab-ci.yml 文件,然后编辑脚本
gitlab-ci templates
后文分别举例了三种部署方式
- 基于 gitlab-runner 本机部署
- 向指定的虚机服务器部署
- 通过 sshpass 方式执行目标虚机服务器命令(需要安装 sshpass 软件,处理各种命令执行权限问题,细节调试比较繁琐,不过不用担心,小编这里已经把调试好的脚本给到大家,调整变量参数即可)
- 通过 rsa ssh 私钥部署(最简单,前提要配置私钥,可以免去各种权限问题)
- 通过 docker 部署—待补充…
- 通过分支、manual 等加入审批环节并区分生产环境,分支命名严格规范—待补充…
4.2.1 方案一:基于 gitlab-runner 本机部署项目示例–基础版
大家调试的时候,可以先调试 test 环节,保证你的 gitlab-runner 流程是正常的,然后再一步一步深入调试
当前示例的 jar 应用最终会部署在 gitlab-runner 本机上。 实际应用中不会这样部署,否则 gitlab-runner服务器资源会很紧张,咱们由浅入深,先调试名奶原理,再看后面章节。
流程图示意(区别于下章的虚机部署方式)
4.2.1.1 .gitlab-ci.yml 脚本示例
# 定义一些变量, 下面各阶段会使用
variables:
# 运行的 jar 名称
JAR_NAME: test-0.0.1-SNAPSHOT.jar
# jar 包存放位置,不能是 git 目录,否则下一个 stage 阶段会清除文件, 这里默认放到上一级了
JAR_PATH: ../
# 本次构建的阶段: test、package、deploy
stages:
- test
- package
- deploy
# 测试流水线
test:
stage: test
tags:
- lmx-runnser-4
only:
- main
script:
- echo "流水线成功运行!"
# 打包
package:
stage: package
tags:
- lmx-runnser-4
only:
- main
script:
- echo "=============== 开始install任务 ==============="
- pwd
- mvn clean
- mvn package
- rm -rf $JAR_PATH/$JAR_NAME
- mv ./target/$JAR_NAME $JAR_PATH/$JAR_NAME
- cd $JAR_PATH
- ls
# 启动jar包
deploy:
stage: deploy
tags:
- lmx-runnser-4
only:
- main
script:
- echo "=============== 开始部署任务 ==============="
- cd $JAR_PATH
- pwd
- ls
- ./test.sh
- echo "发布完成!"
- test.sh 脚本如下
#!/bin/bash
set -ex
pkill -9 java
# 注意:一定要写上 2>&1 & 进行重定向,否则任务会卡在 running 不动
nohup java -Dfile.encoding=utf-8 -jar test-0.0.1-SNAPSHOT.jar > test.log 2>&1 &
exit 0
4.2.1.2 本章注意事项与问题
- jar 包存放位置
package阶段,将 jar 包存放到了打包目录的上级目录,是因为打包好的 jar 文件在 git 目录中,runner 的下一个 stage 阶段会清除这里的文件
。把 jar 包目录移走就不会影响下一步的 deploy - 执行启动命令后任务卡在 running 环节不动
这是因为 runner 中执行启动命令后没有做重定向导致,需要在启动参数后面追加> test.log 2>&1 &
命令重定向
4.2.2 方案二:向指定虚机服务器部署项目脚本示例
公司内部项目部署,可能每个项目都有分派自己的虚机服务器,所以我们需要把 runner 中打好的 jar 包上传到对应虚机服务并进行停起服务操作。 这里面会涉及到几个知识点
sshpass 软件进行远程服务器 ssh 访问; 或通过 rsa 秘钥的方式创建服务链接
,前者会遇到一些权限、带密码登录虚机、脚本调试等问题。 为了大家方便,小编已经给大家做成变量的方式,大家仅需调整自己的变量参数即可。
示意流程图
4.2.2.1 sshpass 方式的 .gitlab-ci.yml 脚本示例
- 准备工作:
- 需要目标虚机 user、passwd、jar 存放路径
- 目标需求需要安装 sshpass 软件
安装命令yum install sshpass
- 目标虚机上需要给 user 授权sudo免密登录
root 用户输入命令vi /ect/sudoers
然后输入i
回车进入编辑模式,追加如下参数gitlab ALL=(ALL) NOPASSWD:ALL)
然后按 ESC 键,输入:wq
回车保存 - gitlab-runner 执行 sshpass 命令如果报错
Bad owner or permissions on /etc/ssh/ssh_config.d/05-redhat.conf
则需要执行
4.1.chmod 600 /etc/ssh/ssh_config.d/05-redhat.conf
(或chmod 600 ~/.ssh/config,以操作系统配置为准)
4.2. 如果 4.1 命令执行后无效,则可能是用户的用户组不正确,假设执行命令的用户是 root,则更改用户组的命令为:chown root:root /etc/ssh/ssh_config.d/05-redhat.conf
,然后重新执行 4.1 命令即可解决
#! /bin/bash
# 定义一些变量, 下面各阶段会使用
variables:
# 运行的 jar 名称
JAR_NAME: "test-0.0.1-SNAPSHOT.jar"
# jar 包存放位置,不能是 git 目录,否则下一个 stage 阶段会清除文件, 这里默认放到上一级了
JAR_PATH: ../
# 目标虚机服务器用户名
targetUsr: "gitlab"
# 目标虚机服务器登录密码
targetPwd: "gitlab-passwpord"
# 目标虚机服务器ip
targetHost: "172.222.206.141"
# 目标虚机服务器端口【默认22端口时可以不指定,小编服务器当时中病毒了,所以后来改了端口号,这里把指定端口号这种方式也提供给大家】
# 调整端口也可看小编另一篇文章[Liunx创建用户与授权大招以及Linux修改SSH端口](https://blog.csdn.net/u012723183/article/details/129811221)
targetPort: 22
# 目标虚机服务器jar 包存放位置
targetUploadPath: "/home/gitlab/"
# 如下两项为启动参数,按需调整,非必须
APPLICATION_CONFIG: "-Dfile.encoding=utf-8"
JAVA_OPTIONS: "-Dspring.profiles.active=dev -server -Xms256m -Xmx1024m"
LOG: test.log
# 本次构建的阶段: package、upload、deploy
stages:
- package
- upload
- deploy
# 打包
package:
stage: package
tags:
- lmx-runnser-4
# 除了 main 分支都构建,这里也可以改成 only 只有 xxx 分支构建,按需调整
except:
- main
script:
# 调试过程中如果遇到问题,可以放开 set -ex 这样就能打印出来命令了
#- set -ex
- echo "=============== 开始打包 ==============="
- pwd
# 执行 maven 的清理、打包命令(如果是 gradle 调整对应命令即可)
- mvn clean
- mvn package
# 删除临时存放目录的文件
- rm -rf $JAR_PATH/$JAR_NAME
# 将最新打包好的文件移动到临时目录(原因看上一个章节注意事项)
- mv ./target/$JAR_NAME $JAR_PATH/$JAR_NAME
# 进入到临时目录查看一下文件
- cd $JAR_PATH
- ls
# 开始上传 jar 包到目标服务器
upload:
stage: upload
tags:
- lmx-runnser-4
except:
- main
before_script:
# 进入到 jar 包存放目录
- cd $JAR_PATH
- ls
script:
# - set -ex
- echo "=============== 开始上传 jar 包到目标服务器 ==============="
# 通过sshpass命令拷贝 runner 上的 jar 包到目标虚机服务器【命令示例:sshpass -p passwd scp -P 2203 test-0.0.1-SNAPSHOT.jar gitlab@101.55.206.139:/home/gitlab/】
- sshpass -p $targetPwd scp -P $targetPort $JAR_NAME $targetUsr@$targetHost:$targetUploadPath
# 通过 sshpass 停起虚机上的应用
deploy:
stage: deploy
tags:
- lmx-runnser-4
except:
- main
before_script:
# 进入到 jar 包存放目录
- cd $JAR_PATH
- ls
script:
# 查证问题的时候可以打印一下 -ex 命令,方便查证问题
# - set -ex
- echo "=============== 开始停起虚机上的应用 ==============="
# 通过sshpass命令杀掉目标服务器上即将启动的 jar 应用进程
- pid=$(sshpass -p $targetPwd ssh -P $targetPort ssh -o StrictHostKeyChecking=no $targetUsr@$targetHost 'ps -ef|grep '$JAR_NAME' | grep -v "grep" | awk "{print \$2}"')
- echo 当前运行的 pid 为 ${pid}
- |
if [ ${pid} ]; then
echo "开始杀进程停服务"
sshpass -p $targetPwd ssh -o StrictHostKeyChecking=no $targetUsr@$targetHost 'ps -ef|grep '$JAR_NAME' | grep -v "grep" | awk "{print \$2}" | xargs sudo kill -9'
else
echo "当前无程序运行"
fi
# 通过sshpass命令启动 java 应用
- echo "开始启动服务"
- sshpass -p $targetPwd ssh -o StrictHostKeyChecking=no $targetUsr@$targetHost 'java -jar '$targetUploadPath$JAR_NAME' > '$LOG' 2>&1 & '
- pid=$(sshpass -p $targetPwd ssh -o StrictHostKeyChecking=no $targetUsr@$targetHost 'ps -ef|grep '$JAR_NAME' | grep -v "grep" | awk "{print \$2}"')
- echo "发布完成!当前运行的PID 为:" ${pid}
4.2.2.2 gitlab-ci/cd 模版制作【.gitlab-ci-template.yml】
实际工作中,项目会有很多,分部门分项目组,分 group 等等情况。 既然咱们实现了自动化,旨在降低业务功能研发同学的工作成本,不应该每个项目都写这样一个复杂的脚本。 所以写一个公共的gitlab-ci模版就成为必要,把核心实现都在模版中动态引入,研发人员只需要调整自己项目的动态参数 variables 即可实现自动化部署
4.2.2.2.1 原理
其实就是类似 java 开发的面向对象原理, 将一个大的复杂的方法,抽象出来公共实现,动态传入数据即可。
-
第一步:先创建一个新工程,用于存放模版(此工程无需构建,其实就是一个物理存放文件的路径,后面会从这里引用模版)
-
第 二步:先将4.2.2.1 章节中 stages 阶段提取到公共模版.gitlab-ci-template.yml 中【注意: 脚本一定是动态绑定参数】
4.2.2.2.2 模版脚本【.gitlab-ci-template.yml】
- .gitlab-ci-maven-template.yml
待补充.....
- .gitlab-ci-template.yml
#include:
- local: '.gitlab-ci-maven-template.yml'
- local: '.gitlab-ci-gradle-template.yml'
# 本次构建的阶段: package、upload、deploy
stages:
- package
- upload
- deploy
# 打包
package:
stage: package
tags:
- lmx-runnser-4
# 除了 main 分支都构建,这里也可以改成 only 只有 xxx 分支构建,按需调整
except:
- main
script:
# 调试过程中如果遇到问题,可以放开 set -ex 这样就能打印出来命令了
#- set -ex
- echo "=============== 开始打包 ==============="
- pwd
# 执行 maven 的清理、打包命令(如果是 gradle 调整对应命令即可)
- mvn clean
- mvn package
# 删除临时存放目录的文件
- rm -rf $JAR_PATH/$JAR_NAME
# 将最新打包好的文件移动到临时目录(原因看上一个章节注意事项)
- mv ./target/$JAR_NAME $JAR_PATH/$JAR_NAME
- cd $JAR_PATH
- ls
# 远程虚机服务器上部署 jar 方案,准备如下:
# 1、需要目标虚机 user、passwd、jar 存放路径
# 2、目标需求需要安装 sshpass 软件【yum install sshpass】
# 3、目标虚机上需要给 user 授权sudo免密登录【【vi /ect/sudoers】==》gitlab ALL=(ALL) NOPASSWD:ALL)】,否则后面停服命令将无法执行
# 4、gitlab-runner 本机如果报错 Bad owner or permissions on /etc/ssh/ssh_config.d/05-redhat.conf
# 4.1 则需要执行 chmod 600 /etc/ssh/ssh_config.d/05-redhat.conf (或chmod 600 ~/.ssh/config,以操作系统配置为准)
# 4.2 如果 4.1 命令执行后无效,则可能是用户的用户组不正确,假设执行命令的用户是 root,则更改用户组的命令为:chown root:root /etc/ssh/ssh_config.d/05-redhat.conf,然后重新执行 4.1
# 开始上传 jar 包到目标服务器
upload:
stage: upload
tags:
- lmx-runnser-4
except:
- main
before_script:
# 进入到 jar 包存放目录
- cd $JAR_PATH
- ls
script:
# - set -ex
- echo "=============== 开始上传 jar 包到目标服务器 ==============="
# 通过sshpass命令拷贝 runner 上的 jar 包到目标虚机服务器【命令示例:sshpass -p passwd scp -P 2203 test-0.0.1-SNAPSHOT.jar gitlab@101.55.206.139:/home/gitlab/】
- sshpass -p $targetPwd scp -P $targetPort $JAR_NAME $targetUsr@$targetHost:$targetUploadPath
# 通过 sshpass 停起虚机上的应用
deploy:
stage: deploy
tags:
- lmx-runnser-4
except:
- main
before_script:
# 进入到 jar 包存放目录
- cd $JAR_PATH
- ls
script:
# 查证问题的时候可以打印一下 -ex 命令,方便查证问题
# - set -ex
- echo "=============== 开始停起虚机上的应用 ==============="
# 通过sshpass命令杀掉目标服务器上即将启动的 jar 应用进程
- pid=$(sshpass -p $targetPwd ssh -p $targetPort -o StrictHostKeyChecking=no $targetUsr@$targetHost 'ps -ef|grep '$JAR_NAME' | grep -v "grep" | awk "{print \$2}"')
- echo 当前运行的 pid 为 ${pid}
- |
if [ ${pid} ]; then
echo "开始杀进程停服务"
sshpass -p $targetPwd ssh -p $targetPort -o StrictHostKeyChecking=no $targetUsr@$targetHost 'ps -ef|grep '$JAR_NAME' | grep -v "grep" | awk "{print \$2}" | xargs sudo kill -9'
else
echo "当前无程序运行"
fi
# 通过sshpass命令启动 java 应用
- echo "开始启动服务"
- sshpass -p $targetPwd ssh -p $targetPort -o StrictHostKeyChecking=no $targetUsr@$targetHost 'java -jar '$targetUploadPath$JAR_NAME' > '$LOG' 2>&1 & '
- pid=$(sshpass -p $targetPwd ssh -p $targetPort -o StrictHostKeyChecking=no $targetUsr@$targetHost 'ps -ef|grep '$JAR_NAME' | grep -v "grep" | awk "{print \$2}"')
- echo "发布完成!当前运行的PID 为:" ${pid}
4.2.2.2.3 项目动态脚本variables【.gitlab-ci.yml】
首先需要先引入上面做好的模版脚本,类似研发中的引包
#! /bin/bash
# 引入模版
include:
# 模版所在 project ,gitlab-instance-ecd28528为分组,ht-gitlab-ci为项目名称
- project: 'gitlab-instance-ecd28528/ht-gitlab-ci'
# 模版文件
file: '.gitlab-ci-template.yml'
# 模版项目所在分支
ref: main
# 定义一些变量, 下面各阶段会使用
variables:
# 运行的 jar 名称
JAR_NAME: "test-0.0.1-SNAPSHOT.jar"
# jar 包存放位置,不能是 git 目录,否则下一个 stage 阶段会清除文件, 这里默认放到上一级了
JAR_PATH: ../
# 目标虚机服务器用户名
targetUsr: "gitlab"
# 目标虚机服务器登录密码
targetPwd: "gitlab-passwpord"
# 目标虚机服务器ip
targetHost: "172.222.206.141"
# 目标虚机服务器端口
targetPort: 22
# 目标虚机服务器jar 包存放位置
targetUploadPath: "/home/gitlab/"
# 如下两项为启动参数,按需调整,非必须
APPLICATION_CONFIG: "-Dfile.encoding=utf-8"
JAVA_OPTIONS: "-Dspring.profiles.active=dev -server -Xms256m -Xmx1024m"
LOG: test.log
4.2.2.3 rsa密钥SSH免密登录方式的 .gitlab-ci.yml 脚本示例(更简单)
4.2.2.3.1 SSH 免密登录
上面介绍的命令中,都是通过sshpass 软件实现主控服务器(gitlab-runner)向目标虚机服务器远程scp文件并执行命令。 显然操作起来,其命令过于复杂且不安全。 所以咱们通过配置 SSH 免密登录之后来编辑脚本就更加简单且安全了。
1. 开始之前,先介绍一下,如何给一台服务器设置 rsa 密钥登录
此过程与咱们本次要实现的 gitlab-runner免密登录无关(在这里提前介绍是怕大家稍后配置 gitlab-runner免密时遇到一个多公钥文件情况不知如何处理),属于额外给大家介绍一下单纯设置服务器 rsa 秘钥登录技巧。 点击下面链接有详细命令讲解
菜鸟教程-设置 SSH 通过密钥登录
核心命令如下:
cat /root/.ssh/id_rsa.pub >> authorized_keys
chmod 600 authorized_keys
chmod 700 ~/.ssh
vi /etc/ssh/sshd_config -----按如下图2方式调整
systemctl restart sshd ------重启 sshd
sshd_config配置文件调整
下载id_rsa,然后打开本地 xshell/finalshell/winscp等 ssh连接工具,引入id_rsa文件即可,下图为 finalshell 示例:
2. 下面讲解 gitlab-runner 主控机操控远程受控机的SSH 免密登录配置方式
原理:如下图,是咱们 gitlab-ci的操作流程示意,我们上文中通过 sshpass 实现 gitlab-runner 远程操控虚机命令
我们只需要将此过程实现免密登录即可简化命令操作并且安全.
处理流程如下:
1) 在 gitlab-runner 服务器的 gitlab-runner 用户下生成密钥对
# 切换用户
su gitlab-runner
# 生成密钥对
ssh-keygen -t rsa
# 连续三次回车效果如图
2) 如上图,将生成好的公钥文件/home/gitlab-runner/.ssh/id_rsa.pub
下载后上传至目标虚机服务器的/root/.ssh
目录下,然后将id_rsa.pub内容进行追加到authorized_keys
当中实现免密登录。注意:如果你的目标虚机做过 rsa 密钥配置(4.2.2.3.1章第一点的介绍),则/root/.ssh下也会存在一个id_rsa.pub文件,这时大家只需要把 gitlab-runner的id_rsa.pub文件随便放一个位置即可,因为主要的目的是通过 id_rsa.pub 将公钥信息载入authorized_keys,所以如果有多个公钥文件也无所谓的。
# 将公钥写入 authorized_keys【 cat 后面可以指定你的公钥路径,如果你有多个公钥,自行放置,我的是放在了/home/gitlab/.ssh下】
cat /home/gitlab/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
3)在 gitlab-runner服务器上测试一下远程免密登录虚机
# -p 2203是指定 ssh 登录端口号(默认是 22 端口,大家想学习如何更改 ssh 端口号的也可看小编另一篇文章[Liunx创建用户与授权大招以及Linux修改SSH端口](https://blog.csdn.net/u012723183/article/details/129811221))
ssh -p 2203 root@101.55.206.139
# 如果是默认的 22 端口,命令可以简化如下
ssh root@101.55.206.139
4.2.2.3.2 SSH免密登录的 gitlab-ci.yml脚本调整
1. 项目.gitlab-ci.yml 脚本调整
主要调整了用户为 root 用户,去掉了密码,因为免密登录了
#! /bin/bash
# 引入模版
include:
- project: 'gitlab-instance-ecd28528/ht-gitlab-ci'
file: '.gitlab-ci-template.yml'
ref: main
# 定义一些变量, 下面各阶段会使用
variables:
# 运行的 jar 名称
JAR_NAME: "test-0.0.1-SNAPSHOT.jar"
# jar 包存放位置,不能是 git 目录,否则下一个 stage 阶段会清除文件, 这里默认放到上一级了
JAR_PATH: ../
# 目标虚机服务器用户名
targetUsr: "root"
# 目标虚机服务器ip
targetHost: "101.55.206.139"
# 目标虚机服务器端口
targetPort: 2203
# 目标虚机服务器jar 包存放位置
targetUploadPath: "/home/gitlab/"
# 如下两项为启动参数,按需调整,非必须
APPLICATION_CONFIG: "-Dfile.encoding=utf-8"
JAVA_OPTIONS: "-Dspring.profiles.active=dev -server -Xms256m -Xmx1024m"
LOG: test.log
2. 模版脚本调整.gitlab-ci-template.yml
调整了 sshpass 命令为 ssh 命令,并且 scp 命令得到了简化
# 本次构建的阶段: package、upload、deploy
stages:
- package
- upload
- deploy
# 打包
package:
stage: package
tags:
- lmx-runnser-4
# 除了 main 分支都构建,这里也可以改成 only 只有 xxx 分支构建,按需调整
except:
- main
script:
# 调试过程中如果遇到问题,可以放开 set -ex 这样就能打印出来命令了
#- set -ex
- echo "=============== 开始打包 ==============="
- pwd
# 执行 maven 的清理、打包命令(如果是 gradle 调整对应命令即可)
- mvn clean
- mvn package
# 删除临时存放目录的文件
- rm -rf $JAR_PATH/$JAR_NAME
# 将最新打包好的文件移动到临时目录(原因看上一个章节注意事项)
- mv ./target/$JAR_NAME $JAR_PATH/$JAR_NAME
- cd $JAR_PATH
- ls
# 远程虚机服务器上部署 jar 方案,准备如下:
# 1、需要目标虚机 user、passwd、jar 存放路径
# 2、目标需求需要安装 sshpass 软件【yum install sshpass】
# 3、目标虚机上需要给 user 授权sudo免密登录【【vi /ect/sudoers】==》gitlab ALL=(ALL) NOPASSWD:ALL)】,否则后面停服命令将无法执行
# 4、gitlab-runner 本机如果报错 Bad owner or permissions on /etc/ssh/ssh_config.d/05-redhat.conf
# 4.1 则需要执行 chmod 600 /etc/ssh/ssh_config.d/05-redhat.conf (或chmod 600 ~/.ssh/config,以操作系统配置为准)
# 4.2 如果 4.1 命令执行后无效,则可能是用户的用户组不正确,假设执行命令的用户是 root,则更改用户组的命令为:chown root:root /etc/ssh/ssh_config.d/05-redhat.conf,然后重新执行 4.1
# 开始上传 jar 包到目标服务器
upload:
stage: upload
tags:
- lmx-runnser-4
except:
- main
before_script:
# 进入到 jar 包存放目录
- cd $JAR_PATH
- ls
script:
# - set -ex
- echo "=============== 开始上传 jar 包到目标服务器 ==============="
# 【设置免密登录后】拷贝 runner 上的 jar 包到目标虚机服务器【命令示例:scp -P 2203 test-0.0.1-SNAPSHOT.jar root@101.55.206.139:/home/gitlab/】
- scp -P $targetPort $JAR_NAME $targetUsr@$targetHost:$targetUploadPath
# 通过 sshpass 停起虚机上的应用
deploy:
stage: deploy
tags:
- lmx-runnser-4
except:
- main
before_script:
# 进入到 jar 包存放目录
- cd $JAR_PATH
- ls
script:
# 查证问题的时候可以打印一下 -ex 命令,方便查证问题
# - set -ex
- echo "=============== 开始停起虚机上的应用 ==============="
# 通过sshpass命令杀掉目标服务器上即将启动的 jar 应用进程【命令示例:ssh -p 2203 -o StrictHostKeyChecking=no root@101.23.206.23 'ps -ef|grep 'test-0.0.1-SNAPSHOT.jar ' | grep -v "grep" | awk "{print \$2}"'】
- pid=$(ssh -p $targetPort -o StrictHostKeyChecking=no $targetUsr@$targetHost 'ps -ef|grep '$JAR_NAME' | grep -v "grep" | awk "{print \$2}"')
- echo 当前运行的 pid 为 ${pid}
- |
if [ ${pid} ]; then
echo "开始杀进程停服务"
ssh -p $targetPort -o StrictHostKeyChecking=no $targetUsr@$targetHost 'ps -ef|grep '$JAR_NAME' | grep -v "grep" | awk "{print \$2}" | xargs sudo kill -9'
else
echo "当前无程序运行"
fi
# 通过sshpass命令启动 java 应用
- echo "开始启动服务"
- ssh -p $targetPort -o StrictHostKeyChecking=no $targetUsr@$targetHost 'java -jar '$targetUploadPath$JAR_NAME' > '$LOG' 2>&1 & '
- pid=$(ssh -p $targetPort -o StrictHostKeyChecking=no $targetUsr@$targetHost 'ps -ef|grep '$JAR_NAME' | grep -v "grep" | awk "{print \$2}"')
- echo "发布完成!当前运行的PID 为:" ${pid}
4.2.2.4 本章注意事项与问题
- gitlab-runner
执行 sshpass
命令如果报错Bad owner or permissions on /etc/ssh/ssh_config.d/05-redhat.conf
- 需要root 执行授权命令:
chmod 600 /etc/ssh/ssh_config.d/05-redhat.conf
- 有的 linux 操作系统没有05-redhat.conf 文件,可能是~/.ssh/config,那么调整命令为
chmod 600 ~/.ssh/config
即可(小编当时在这里折腾半天,具体原因是下面第二个问题 group )。
- 需要root 执行授权命令:
- 如果上面 chmod 600 命令执行后无效,则可能是用户的用户组不正确,假设执行命令的用户是 root,则更改用户组的命令为:
chown root:root /etc/ssh/ssh_config.d/05-redhat.conf
,然后重新执行 chmod 600 命令即可解决 - 执行 sudo kill -9 停服命令报错问题(会有俩错误记不清了,按照我这个搞就能好使)
目标虚机上需要给 user 授权sudo免密登录
root 用户输入命令vi /ect/sudoers
然后输入i
回车进入编辑模式,追加如下参数gitlab ALL=(ALL) NOPASSWD:ALL)
然后按 ESC 键,输入:wq
回车保存,搞定! - 执行过程中 sshpass 停服杀进程命令以及启动服务命令中,会遇到几个脚本错误问题,主要是咱们在 gitlab-ci 中编写 shell 脚本的一些细节问题,这也是相比于 rsa 秘钥方式复杂的地方,主要注意问题如下
- {print $2} $ 前面追加转义符 {print \$2}
- sshpass 后面的 shell 命令用引号
'shell 命令'
包装 ,所以命令本身如果有引号就要做特殊处理比如下面示例中的"test-0.0.1-SNAPSHOT.jar"
sshpass -p lmx@2023 ssh -o StrictHostKeyChecking=no gitlab@101.55.206.139 'ps -ef|grep "test-0.0.1-SNAPSHOT.jar" | grep -v "grep" | awk "{print \$2}"'
- 如果引用的内容是变量形式,则还需要使用单引号处理,比如下面脚本的
'$JAR_NAME'
。小编当时在这里耽误了大半天时间,各种调试,所以一定要注意。
pid=$(sshpass -p $targetPwd ssh -o StrictHostKeyChecking=no $targetUsr@$targetHost 'ps -ef|grep '$JAR_NAME' | grep -v "grep" | awk "{print \$2}"')
- 比如上面这个获取 pid 变量的参数,要注意两点
- pid=$(命令) 中,
pid=$
等号中间不能有空格
(真的太坑了,小编这里也耽误很久) - 等号后面的命令一定要用
$(命令)
语法包装 - 引用 pid 变量的时候语法是
${pid}
如案例中的if [ ${pid} ]; then
- pid=$(命令) 中,
4.2.2.5 docker 方式的 .gitlab-ci.yml 脚本示例(更简单)
待更新
4.2.3 通过分支、manual 等加入审批环节并区分生产环境部署
待更新,预计 3 月中旬更新
4.4 提交代码验证项目的构建与部署
1、查看构建状态
2、浏览器输入自己的 test 接口,验证一下项目运行情况
5、其他遇到的问题
5.1 gitlab 内存不够【gitlab.rb】
服务器要求:至少 2C8G, 建议 4C8G 或更高
报错:fatal: The remote end hung up unexpectedly
解决:git config --global http.postBuffer 524288000
查看:git config --global --list
继续报错:fatal: Out of memory, malloc failed (tried to allocate 262144000 bytes)
解决(内存不足,干脆删掉):git config --global --unset http.postbuffer
写的比较详细的链接可参考,主要是调整 gitlab.rb 配置参数(我目前试了没搞定)
5.2 sudo 命令执行问题
报错:sudo: /usr/libexec/sudo/sudoers.so 必须属于用户 ID 0(的用户)
sudo: 在加载插件“sudoers_policy”时在 /etc/sudo.conf 第 14 行出错
问题原因:有人将/usr/bin/sudo的权限改为777或将目录/usr的权限授权给非root用户了
解决办法:
chmod 4755 /usr/bin/sudo
chown -R root:root /usr
5.3 deploy执行服务器 sh 脚本卡在 running 不动
# 注意:一定要写上 2>&1 & 进行重定向,否则任务会卡在 running 不动
最终:nohup java -Dfile.encoding=utf-8 -jar test-0.0.1-SNAPSHOT.jar > test.log 2>&1 &
5.4 -p 端口号与 -P 端口号
注意 p 的大小写不同
sshpass -p 端口号
ssh -p 端口号
scp -P端口号
5.5 gitlab自动构建(二次构建)报错–fatal: git fetch-pack: expected shallow list
解决方案
- 查看 git版本:
git --version
- 更新安装源
yum install http://opensource.wandisco.com/centos/7/git/x86_64/wandisco-git-release-7-2.noarch.rpm
- 安装或更新 git
#安装git
yum install git
#更新git
yum update git
- 如果还是没有更新,可用如下方案
升级 git 版本
5.6 Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
如果成功配置了 rsa 依然报错 Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
原因是:gitlab-runner register 的用户与 rsa 用户不是一个导致文章来源:https://www.toymoban.com/news/detail-402001.html
附:
Gitlab CI/CD 简单介绍
Gitlab CI/CD 介绍
Gitlab-Runner 相关命令
Liunx创建用户与授权大招以及Linux修改SSH端口文章来源地址https://www.toymoban.com/news/detail-402001.html
到了这里,关于纯手工搭建 GitaLab与Gitlab-CI/CD--附 gitlab-ci.yml示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!