gitlab-ci和jenkins

273 阅读4分钟

常见概念

持续集成/持续交付/持续部署

  • 持续集成:从编码到构建再到测试(单测)的反复持续过程
  • 持续交付:在持续集成产物的基础上,通过外部使用人员的反馈优化,以最快的速度产出一个可交付给用户的产品,持续交付持续集成的延续。
  • 持续部署:将可交付的产品,快速且安全的交付给用户的一套方法和系统,它是持续交付的最后一程 由此可见,持续交付贯穿了整个流程,它包含持续集成持续部署,但又不是单纯的等于二者相加,因为持续交付不是特指从开发到将产品交付给最终的客户的过程,而是在这一整个过程中的每个阶段都可以快速持续的交付,无论是提测,测试还是修复,持续的产出并持续的验证都可以称之为持续交付

gitlab-ci

安装Runner

如果服务器已经安装过runner,则直接注册就行

参照docs.gitlab.com/runner/inst…

查了一下服务器系统为CentOS,所以直接执行CentOS的命令

image.png

curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash

image.png

sudo yum install gitlab-runner

image.png

注册Runner

注册的时候如果gitlab没有CI/CD。。。。就自己开启下流水线

image.png

image.png

然后参照docs.gitlab.com/runner/regi…

image.png

在gitlab可以找到对应的信息

image.png

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对应的错误信息

image.png

尝试升级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

image.png

参考文章:

修改配置后,需要重载才能生效。 但有些修改必须重启才能生效,所以如果不是业务繁忙,建议重启。

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

发现执行下面的命令时出错

image.png 然后到对应的gitlab-runner服务器执行以下命令,报了以下错误

image.png

参考github.com/curl/curl/i… 以为是证书的问题,所以替换了服务器的证书, 但是替换完没有效果

尝试用curl去请求

curl -i www.baidu.com -v

发现开了代理。。。在群里问了下,有人在服务器上装了clash来装依赖。。。。 image.png 所以最后关闭代理。gitlab-ci可以正常运行了。。。。真是惊险的一天

// 查看代理情况
env | grep -i proxy
// 关闭代理
unset 对应的代理变量

jenkins

凭据

  1. 找一台机器的公私钥(使用的时候要取对应的凭据)
  2. 将私钥添加到凭据中,选择ssh username with secret key或者username with password(推代码的时候可用)
  3. 操作gitlab的话,将公钥放到设置/仓库/部署密钥中
  4. 部署将目标机器的公钥,添加到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的分支去进行构建,分支过多的情况下,可以点击高级,配置里面的快速过滤,在构建页面就可以进行搜索过滤 image.png

image.png

也可以点击添加参数,然后添加一些需要配置的

例如部署的环境,执行的操作是部署还是回滚等等

  • 名称:在流水线代码中可以获取到的变量
  • 选项:可以选择的一些参数值
  • 描述:对参数的描述,构建的时候在选项旁会有备注

image.png

效果图如下

image.png

如果配置完之后报如下问题,只需要手动build with parameters拉取一下代码,就可以获取到

wecom-temp-0f6c68e10884b46703659150ef4fad7e.png

自动构建

提交代码的时候自动构建

image.png

定时和轮询

定时构建:顾名思义,每隔一定时间构建一次

轮询SCM:每隔一定时间轮询版本控制工具中的代码版本,如果版本号与上次轮询有变化,则构建。

在 Schedule 中填写 0 * * * *。
 
第一个参数代表的是分钟 minute,取值 0~59;
 
第二个参数代表的是小时 hour,取值 0~23;
 
第三个参数代表的是天 day,取值 1~31;
 
第四个参数代表的是月 month,取值 1~12;
 
最后一个参数代表的是星期 week,取值 0~707 都是表示星期天

常见示例

# 每1分钟
*/1 * * * *
# 每5分钟
H/5 * * * *
# 每2小时
H */2 * * *
# 每天早上8点
0 8 * * *
# 每天中午11点30
30 11 * * *
# 每天下午16到17点,每5分钟
*/5 16-17 * * *

因为该流水线的操作涉及到内外网,互访受限,所以不能通过hooks触发, 而是通过轮询的方式。

jenkins需要配置gitlab插件

image.png

image.png

scm使用的是Jenkinsfile文件,所以将下面的流水线代码在Jenkinsfile文件中写入,放到gitlab上即可

image.png

流水线代码

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来做这一操作。