常见概念
持续集成/持续交付/持续部署
- 持续集成:从编码到构建再到测试(单测)的反复持续过程
- 持续交付:在持续
集成产物的基础上,通过外部使用人员的反馈优化,以最快的速度产出一个可交付给用户的产品,持续交付是持续集成的延续。 - 持续部署:将可交付的产品,快速且安全的交付给用户的一套方法和系统,它是
持续交付的最后一程 由此可见,持续交付贯穿了整个流程,它包含持续集成和持续部署,但又不是单纯的等于二者相加,因为持续交付不是特指从开发到将产品交付给最终的客户的过程,而是在这一整个过程中的每个阶段都可以快速持续的交付,无论是提测,测试还是修复,持续的产出并持续的验证都可以称之为持续交付
gitlab-ci
安装Runner
如果服务器已经安装过runner,则直接注册就行
参照docs.gitlab.com/runner/inst…
查了一下服务器系统为CentOS,所以直接执行CentOS的命令
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash
sudo yum install gitlab-runner
注册Runner
注册的时候如果gitlab没有CI/CD。。。。就自己开启下流水线
然后参照docs.gitlab.com/runner/regi…
在gitlab可以找到对应的信息
tags是对Runner进行分类,以便不同项目的不同业务选择。
比如,对一个Runner设置了linux标签后,对应的Job必须要设置这个标签,才能在这个Runner上执行。例如
stages:
- test
- deploy
build:
stage: test
tags:
- linux
script:
- make
- make test
编写.gitlab-cli.yml配置文件
可以参考docs.gitlab.com/ee/ci/yaml/…
构建失败排查
运行了好久的流水线突然挂掉了。。。。
谷歌了几种方式,以为是gitlab版本问题,就问了一下运维,发现刚升级了gitlab,然而最后发现最好使的还是去debug对应的错误信息
尝试升级git
参考文章:www.seozen.top/centos-upda…
尝试升级gitlab-runner
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
sudo yum update
sudo yum install gitlab-runner
参考文章:blog.csdn.net/Tri_C/artic…
尝试clone_url
cd /etc/gitlab-runner/ 进入目录修改config.toml,
- 直接使用当前域名,修改后没反应
- 尝试ping一下gitlab的域名,拿到ip地址,修改后报错,例如ping www.baidu.com
参考文章:
修改配置后,需要重载才能生效。 但有些修改必须重启才能生效,所以如果不是业务繁忙,建议重启。
sudo systemctl reload gitlab-runner
# or
sudo systemctl restart gitlab-runner
尝试打出debug日志
参考文章:gitlab.com/gitlab-org/… 在对应的job开启debugger
stages:
- pull
- install
- push
pull:
variables:
CI_DEBUG_TRACE: "true"
stage: pull
发现执行下面的命令时出错
然后到对应的gitlab-runner服务器执行以下命令,报了以下错误
参考github.com/curl/curl/i… 以为是证书的问题,所以替换了服务器的证书, 但是替换完没有效果
尝试用curl去请求
curl -i www.baidu.com -v
发现开了代理。。。在群里问了下,有人在服务器上装了clash来装依赖。。。。
所以最后关闭代理。gitlab-ci可以正常运行了。。。。真是惊险的一天
// 查看代理情况
env | grep -i proxy
// 关闭代理
unset 对应的代理变量
jenkins
凭据
- gitlab拉代码用的凭据
- 部署用的凭据 具体参考:www.cnblogs.com/hellxz/p/pi…
- 找一台机器的公私钥(使用的时候要取对应的凭据)
- 将私钥添加到凭据中,选择ssh username with secret key或者username with password(推代码的时候可用)
- 操作gitlab的话,将公钥放到设置/仓库/部署密钥中
- 部署将目标机器的公钥,添加到authorized_keys中(!!重要,光使用凭据是不行的),确保可以通过私钥进行登陆目标机
在代码中就可以使用凭据来进行操作
// 根据发布的不同环境选择凭据
switch(deploy_host) {
case 'xxx':
// 自定义变量,再下面使用
userId='xxx'
break
case 'yyy':
userId='yyy'
break
}
// 通过ssh的方式使用凭据,通过下面的变量keyfile指定密钥文件
withCredentials([sshUserPrivateKey(credentialsId: "${userId}", keyFileVariable: 'keyfile')]){
sh "scp -o StrictHostKeyChecking=no -i ${keyfile} -r ./docs/* root@${deploy_host}:/etc/fe/nginx/docs"
}
// 通过username和password的方式使用
withCredentials([usernamePassword(credentialsId:"offline-password",
usernameVariable: "GIT_USERNAME",
passwordVariable: "GIT_PASSWORD")]) {
// 配置 Git 工具中仓库认证的用户名、密码
sh 'git config --local credential.helper "!p() { echo username=\\$GIT_USERNAME; echo password=\\$GIT_PASSWORD; }; p"'
sh "git add ."
sh "git commit -m 'update package'"
sh 'git push origin test'
}
// 最直接的方式直接把jenkins的公钥放到gitlab中,就直接使用命令推代码就行了
sh "git add ."
sh "git commit -m 'update package'"
sh 'git push origin test'
参数化构建
新建一个流水线项目
构建的时候可能需要配置不同的参数
例如,选择gitlab的分支去进行构建,分支过多的情况下,可以点击高级,配置里面的快速过滤,在构建页面就可以进行搜索过滤
也可以点击添加参数,然后添加一些需要配置的
例如部署的环境,执行的操作是部署还是回滚等等
- 名称:在流水线代码中可以获取到的变量
- 选项:可以选择的一些参数值
- 描述:对参数的描述,构建的时候在选项旁会有备注
效果图如下
如果配置完之后报如下问题,只需要手动build with parameters拉取一下代码,就可以获取到
自动构建
提交代码的时候自动构建
定时和轮询
定时构建:顾名思义,每隔一定时间构建一次
轮询SCM:每隔一定时间轮询版本控制工具中的代码版本,如果版本号与上次轮询有变化,则构建。
在 Schedule 中填写 0 * * * *。
第一个参数代表的是分钟 minute,取值 0~59;
第二个参数代表的是小时 hour,取值 0~23;
第三个参数代表的是天 day,取值 1~31;
第四个参数代表的是月 month,取值 1~12;
最后一个参数代表的是星期 week,取值 0~7,0 和 7 都是表示星期天
常见示例
# 每1分钟
*/1 * * * *
# 每5分钟
H/5 * * * *
# 每2小时
H */2 * * *
# 每天早上8点
0 8 * * *
# 每天中午11点30
30 11 * * *
# 每天下午16到17点,每5分钟
*/5 16-17 * * *
因为该流水线的操作涉及到内外网,互访受限,所以不能通过hooks触发, 而是通过轮询的方式。
jenkins需要配置gitlab插件
scm使用的是Jenkinsfile文件,所以将下面的流水线代码在Jenkinsfile文件中写入,放到gitlab上即可
流水线代码
pipeline {
agent {
node {
label 'fe.compile_build01' // 构建节点
}
}
environment {
git_url = "" // 拉取代码的git地址
git_branch="${env.git_branch}"
deploy_host = '' // 要部署的ip,可以放到构建的参数中
}
stages {
stage('checkout') {
steps {
echo "开始拉取最新代码"
checkout([$class: 'GitSCM', branches: [[name: '${git_branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [],
userRemoteConfigs: [[credentialsId: 'fe-for-depoly', //凭据起的id
url: "${git_url}"]]])
// 下面这种模式 看着更简洁 但是无法直接使用传递过来的git参数 参数里多了origin前缀
// git credentialsId: 'ops.test-target', branch: "${git_branch}", url: "${git_url}"
echo "代码检出成功"
}
}
stage('install') {
steps {
echo '安装依赖'
sh 'yarn install'
echo '依赖安装完成'
}
}
stage('build') {
steps {
echo '开始打包'
sh 'npm run styleguide:build'
echo '打包完成'
}
}
stage('deploy') {
steps {
echo "开始部署stage"
echo "部署环境为:${deploy_host}"
withCredentials([sshUserPrivateKey(credentialsId: "fe-for-depoly", keyFileVariable: 'keyfile')]){
// ssh -o StrictHostKeyChecking=no 当第一次连接服务器时,自动接受新的公钥
sh "scp -o StrictHostKeyChecking=no -i ${keyfile} -r ./docs/* root@${deploy_host}:/etc/fe/nginx/docs"
}
echo '部署完成'
}
}
}
}
感受
用完之后的感受就是,gitlab-ci是内置的,用起来比较轻量,jenkis需要安装一些插件,配置一些东西才可以实现想要的功能。但是gitlab-ci在使用的时候,因为依赖的是gitlab-runner,经常性的因为gitlab升级啊,服务器的一些权限问题,导致构建失败,而且想跨内外网部署比较困难,所以后期才使用jenkins来做这一操作。