GitLab-CI/CD指南

news2024/11/15 11:04:13

由于公司没有运维,写go服务时各个环境编译部署还是略显麻烦,由于代码管理使用的是 gitlab,所以决定使用 gitlab 自带的 CI/CD 来做自动编译和部署,这样每次提交代码以后就可以自动部署到服务器上了。

gitlab 本身只有 CI/CD 的接口,真正执行 CI/CD 任务的是 gilab runner,它负责与 gitlab 通信,接受 CI/CD 任务,并交给 Executor 执行,Executor 有7种类型:

  • Docker
  • Shell
  • Kubernetes
  • SSH
  • VirtualBox
  • Parallels
  • Custom

Executor的类型在注册 Runner 的时候确定,比较常用的是 Docker 和 SSH。GitLab,Runner 和 Executor 之间的关系如下图所示(图片来自GitLab官方文档)。
在这里插入图片描述

安装gitlab-runner

gitlab 的CI/CD 任务是通过 runner 来运行的,runner 也是 go 语言实现的。我们需要单独安装 runner,而且可以在任意位置安装。

runner 有 docker 版和可执行程序版,这里我选择的是可执行程序版,安装方式可以参考官网。

我的服务器是 linux,使用官方提供的脚本安装:

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

可执行程序名叫 gitlab-runner ,被放在 /usr/bin/ 目录下。

注册runner

runner 需要注册到 gitlab,其实就是把 runner 的信息告诉 gitlab,这样 gitlab 才知道把 CI/CD 任务交给谁运行。

注册 runner 的命令是 gitlab-runner register ,回车后会以交互式的方式注册 runner,其中比较重要的几个参数是:

  • executor:运行流水线的环境,也就是前面说的7种 Executor 类型,我使用本地 shell 运行流水线,所以输入 shell

  • url 和 registration-token:runner 和项目是挂钩的,所谓的注册,其实也就是把 runner 和某个项目关联起来。打开项目的 setting→CI/CD,找到 Runners 点击展开,在 Specific runners 栏下面就是我们需要的 url 和 token。如下图所示

    在这里插入图片描述

当然,为每个项目注册一个 runner 也不太合适,我们可以为一个组注册一个 runner,点开某个组,url 和 token 可以在同样的地方找到。这样组内每个项目就都能使用这个 runner 了。此外,也可以给整个 gitlab 注册 runner,但是这需要 root 账号。

另外,同样的 url 和 token 可以注册多个runner,然后通过 tag 来决定项目使用哪个 runner。
注册 runner 和安装 runner 是两个概念,也就是说即便我们只安装了一个 runner,也能注册多个 runner。安装 runner 是下载可执行程序,而注册只是往 gitlab 设置一些配置信息,它和 runner 本身其实没太大关系,注意此时我们的 runner 还没有开始运行。

除了使用交互式注册,还可以使用非交互方式,命令如下:

gitlab-runner register \
  --non-interactive \
  --url "https://gitlab.com/" \
  --registration-token "$PROJECT_REGISTRATION_TOKEN" \
  --executor "shell" \
  --description "share-runner" \
  --maintenance-note "Free-form maintainer notes about this runner" \
  --tag-list "shell,share" \
  --run-untagged="true" \
  --locked="false" \
  --access-level="not_protected"

注意到 --run-untagged 选项,它表示是否运行在没有标签的的分支上运行流水线。如果没有设置这个参数,也可以在 gitlab 页面上设置。就在我们查看 url 和 registration token 的地方,如果 runner 注册成功的话,可以看到下面的信息:

在这里插入图片描述

点击那个铅笔图标,可以设置 runner,在这里我们也可以勾选 run untagged jobs,如下图所示。

在这里插入图片描述

上面我的 runner 前面小圆点是绿色的,那是因为我的 runner 已经运行起来了。

注册完 runner 会生成配置文件 /etc/gitlab-runner/config.toml ,可以打开查看,我们配置的信息都在里面。

启动runner

在启动 runner 之前,我们可以先创建一个专门的用户来运行 runner,比如:

useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash

这里我们添加的用户叫 gitlab-runner ,你也可以使用其他用户,甚至 root ,或者为了方便部署,使用部署的用户。
然后安装并启动 gitlab 服务:

gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
gitlab-runner start

所谓安装就是设置为系统服务,它会在 /etc/systemd/system/ 目录下生成 gitlab-runner.service 文件。
其他命令:

  • gitlab-runner stop 停止 gitlab-runner 服务。
  • gitlab-runner start 启动 gitlab-runner 服务。
  • gitlab-runner restart 重启 gitlab-runner 服务。
  • gitlab-runner status 查看 gitlab-runner 服务状态。
  • gitlab-runner uninstall 卸载 gitlab-runner 服务。
  • gitlab-runner list 列出所有注册的 runner。

编写流水线

我们通过在项目根目录下创建一个叫 .gitlab-ci.yml 的文件来定义流水线,也就是 CI/CD 如何执行。

流水线分为阶段和作业,阶段通过 stages 关键字定义,阶段是作业的容器,每个阶段内可以定义多个作业。阶段之间是串行执行的,阶段内的多个作业是并行执行的。

关于流水线的编写,可以参看官方文档,或者《GitLab CI/CD 从入门到实战》这本书。当然 gitlab 官方也提供了很多示例,各种语言都有,如果不知到如何开始,可以参考官方示例。

基本结构如下:

stages: # 定义阶段
 - test    # 阶段名
 - build   # 阶段名
 - deploy  # 阶段名
 
 unit_test:    # 作业名
	 stage: test # 作业属于 test 阶段
	 script:     # 作业执行的命令
		 - echo "unit test"
		 
compile:        # 作业名
	stage: build  # 作业属于 build 阶段
	script:       # 作业执行的命令
		- echo "build"
		
deploy_test:     # 作业名
	stage: deploy  # 作业属于 deploy 阶段
	secipt:        # 作业执行的命令
		- echo "deploy test"

我用的是 go 语言,使用 shell 运行和部署,只有测试环境和正式环境。

default:
  interruptible: true # 允许打断流水线

variables:
  GOBIN: "/usr/local/go/bin/go"
  GOINSECURE: git.i****d.com
  GOPRIVATE: git.i****d.com
  GOPROXY: https://goproxy.cn,direct

image: golang:latest

stages:
  - test
  - build
  - deploy

format:
  stage: test
  script:
    - echo "单元测试"
    - pwd
    - echo ~
    - echo $CI_COMMIT_BRANCH
    - echo $CI_DEFAULT_BRANCE
    - export GOINSECURE=$GOINSECURE
    - export GOPRIVATE=$GOPRIVATE
    - export GOPROXY=$GOPROXY
    - $GOBIN version
    - $GOBIN mod tidy
    - $GOBIN test -v 2>&1 | go-junit-report -set-exit-code > report.xml
  artifacts:
    when: always
    reports:
      junit: report.xml

compile:
  stage: build
  script:
    - echo "编译"
    - pwd
    - echo ~
    - export GOINSECURE=$GOINSECURE
    - export GOPRIVATE=$GOPRIVATE
    - export GOPROXY=$GOPROXY
    - $GOBIN version
    - $GOBIN mod tidy
    - mkdir -p _build
    - $GOBIN build -o _build/$CI_PROJECT_NAME main.go
  artifacts:
    expire_in: 1 hour
    paths:
      - _build

# 部署生产环境(仅release分支)
deploy_prod:
  stage: deploy
  variables:
    SERVER_IP: "1**.**.**.*"
  script: 
    - echo "部署生产环境"
    - ssh z**j@$SERVER_IP mkdir -p /data/z**j/$CI_PROJECT_NAME # 创建项目文件夹
    - ssh z**j@$SERVER_IP mkdir -p /data/z**j/$CI_PROJECT_NAME/config # 创建配置文件夹
    - ssh z**j@$SERVER_IP "cd /data/z**j/$CI_PROJECT_NAME/ && [ -f run.sh ] && ./run.sh stop || :" # 停止服务
    - scp _build/$CI_PROJECT_NAME z**j@$SERVER_IP:/data/z**j/$CI_PROJECT_NAME/ # 拷贝可执行文件
    - scp run.sh z**j@$SERVER_IP:/data/z**j/$CI_PROJECT_NAME/ # 拷贝run.sh
    - scp config/application.prod.toml z**j@$SERVER_IP:/data/z**j/$CI_PROJECT_NAME/config/application.toml # 拷贝配置文件
    - ssh z**j@$SERVER_IP "cd /data/z**j/$CI_PROJECT_NAME/ && chmod +x run.sh"
    - ssh z**j@$SERVER_IP "cd /data/z**j/$CI_PROJECT_NAME/ && ./run.sh start" # 重启服务
  only:
    - release # 仅release分支部署到生产环境
  environment: production

# 部署测试环境(非main和release分支)
deplog_test:
  stage: deploy
  variables:
    SERVER_IP: "1**.**.**.*"
  script:
    - echo "部署测试环境"
    - ssh z**j@$SERVER_IP mkdir -p /data/z**j/$CI_PROJECT_NAME # 创建项目文件夹
    - ssh z**j@$SERVER_IP mkdir -p /data/z**j/$CI_PROJECT_NAME/config # 创建配置文件夹
    - ssh z**j@$SERVER_IP "cd /data/z**j/$CI_PROJECT_NAME/ && [ -f run.sh ] && ./run.sh stop || :" # 停止服务
    - scp _build/$CI_PROJECT_NAME z**j@$SERVER_IP:/data/z**j/$CI_PROJECT_NAME/ # 拷贝可执行文件
    - scp run.sh z**j@$SERVER_IP:/data/z**j/$CI_PROJECT_NAME/ # 拷贝run.sh
    - scp config/application.test.toml z**j@$SERVER_IP:/data/z**j/$CI_PROJECT_NAME/config/application.toml # 拷贝配置文件
    - ssh z**j@$SERVER_IP "cd /data/z**j/$CI_PROJECT_NAME/ && chmod +x run.sh"
    - ssh z**j@$SERVER_IP "cd /data/z**j/$CI_PROJECT_NAME/ && ./run.sh start" # 重启服务
  except:
    - $CI_DEFAULT_BRANCH
    - release
  environment: test

多环境部署通过不同的分支来实现, .gitlab-ci.yml 中的 environment 关键字只是对部署任务做一个记录和分类,方便管理和查询部署任务,并无实际区分部署环境的功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2041589.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

金蝶云星辰V1与旺店通·企业版对接集成采购入库单查询(列表+详情)连通创建其他入库单(其他)

金蝶云星辰V1与旺店通企业版对接集成采购入库单查询(列表详情)连通创建其他入库单(其他) 接入系统:金蝶云星辰V1 金蝶云星辰基于金蝶云苍穹云原生PaaS平台构建,聚焦小型企业在线经营和数字化管理,提供财务云、税务云、…

操作系统中的进程:深入解析与理解

文章目录 一、什么是进程?🤔二、进程的特性 🌟三、进程的组成 🧩四、进程的状态与转换 🔄🔀五、进程的调度与管理 🔧🔀六、代码示例(C)创建进程进程等待&…

scanf中%c前加不加空格的区别

%c前加空格可以让scanf跳过空白字符&#xff08;如空格、制表符、换行符等&#xff09;&#xff0c;直接读取非空白字符。如果不加空格就会读取空白字符。 可以用两段测试客官有无慧根的程序来说明这个问题&#xff0c;测试代码如下&#xff1a; #include <stdio.h> in…

Ubuntu22.04安卓编译环境搭建及so库编译

1.配置Android-ARM64开发环境工具链: vim ~/.profile 或者 ~/.bashrc 或者 /etc/profile 编辑环境变量文件 输入下面内容 export CROSS_TRIPLE=aarch64-linux-android export CROSS_ROOT=/usr/${CROSS_TRIPLE} export ANDROID_NDK=${CROSS_ROOT} export AS=${CROSS_ROOT}…

【人工智能】数据集合集!

本文将为您介绍10个经典、热门的数据集&#xff0c;希望对您在选择适合的数据集时有所帮助。 点击蓝字 关注我们 1 Habitat Platform 发布方&#xff1a; Facebook AI Research西蒙菲莎大学佐治亚理工学院Facebook Reality LabsIntel LabsUniversity of California, Berkeley…

1- 关键字static

文章目录 1 前言2 static修饰局部变量2.1 局部变量无static修饰2.2 局部变量有static修饰 3 static修饰全局变量 1 前言 在C语言中&#xff0c;static是用来修饰变量和函数的&#xff1a; 修饰局部变量 - 称为静态局部变量修饰全局变量 - 称为静态全局变量修饰函数 - 称为静态…

django空巢老人志愿服务系统-计算机毕业设计源码58726

摘 要 随着社会老龄化问题日益突出&#xff0c;空巢老人群体的关注和关怀日益重要。本研究设计并实现了基于Python的空巢老人志愿服务系统&#xff0c;旨在利用技术手段提供更多关爱和支持给空巢老人群体。 该系统结合Python编程语言的灵活性和易用性&#xff0c;实现了慈善捐赠…

HCIE杭州考试分享

考试过程&#xff1a; 首先提醒大家关注一下天气&#xff0c;我去杭州没看天气&#xff0c;去了一直下雨&#xff0c;鞋子也湿了&#xff1b;27号早上七点多到的杭州&#xff0c;雨一直下&#xff0c;去了直奔网吧上机&#xff0c;最后的机时&#xff0c;早饭和晚饭都在网吧吃…

Linux多线程间通信机制(互斥锁、条件变量、信号量,读写锁)同步与异步(二)

原文链接&#xff1a;https://blog.csdn.net/weixin_55796564/article/details/119699146 一、概述 本章介绍了线程同步的几种不同的方法&#xff0c;包括互斥锁、条件变量、自旋锁以及读写锁&#xff0c;当然&#xff0c;除此之外&#xff0c;线程同步的方法其实还有很多&…

如何获取设备消息?

一、什么是消息&#xff1f; 消息是设备向萤石云平台传输的带有特定内容的信息&#xff0c;大部分消息由设备端主动产生&#xff0c;并且上报到平台。举个例子&#xff0c;设备开启画面变化检测&#xff0c;当设备画面产生变化&#xff0c;设备就会产生报警&#xff08;画面…

Adobe Premiere Pro 2023-23.6.7.1 解锁版下载与安装教程 (一款专业的视频编辑软件)

前言 Adobe Premiere Pro&#xff08;简称PR&#xff09;是一款知名的专业视频编辑软件&#xff0c;数字视频剪辑软件。主要用来编辑视频和音频&#xff0c;可以在RGB和YUV色彩空间中以高达32位色彩的视频分辨率对4K和更高质量的视频文件进行编辑&#xff0c;支持VST音频插件和…

windows 10/11禁用更新

一、操作 获取“禁用更新”文件。将“禁用更新”文件从百度网盘中下载到电脑桌面。 百度网盘:链接:https://pan.baidu.com/s/1eGEtJYgN3MR4qGoUpnP7xw?pwd=ccrc提取码:ccrc 双击运行“禁用更新”。 弹出如下对话框,点击“是”。 弹出如下对话框,点击“是”。 确…

中仕公考:大四还没毕业能考公吗?

应届大学生是否可以报考公务员? 对于尚未获得毕业证书的应届大学生&#xff0c;有资格报名参与公务员考试。具体到学历和学位的要求&#xff0c;截止日期定于2024年7月底。在报名过程中&#xff0c;考生必须填写《报名登记表》和《报名推荐表》&#xff0c;确保提供的信息真实…

【手眼标定】使用kalibr对imu和双目摄像头进行联合标定

使用kalibr对imu和双目摄像头进行联合标定 前言 方式一&#xff1a;ros2消息格式通过ros1_bridge转为ros1消息格式&#xff0c;在ros1环境下录制bag进行标定。一、IMU标定二、双目摄像头标定三、手眼标定&#xff08;imu和双目摄像头的联合标定&#xff09; 方式二&#xff1a;…

Python轻量级 NoSQL 数据库之tinydb使用详解

概要 在现代应用开发中,使用数据库来存储和管理数据是非常常见的需求。对于简单的数据存储需求,关系型数据库可能显得过于复杂。TinyDB 是一个纯 Python 实现的轻量级 NoSQL 数据库,专为嵌入式场景设计,适用于小型项目、原型开发和教学等场景。本文将详细介绍 TinyDB 库,…

SPAW7000高精度功率分析记录仪,测试方案

测试目标 评估双电机四驱系统中前后电机的性能。 分析前后电机之间的实时联动情况。 测量并分析电机控制器的输入与输出功率。 计算功率转换效率和损耗。 验证电机系统的谐波特性。 测试设备 SPAW7000高精度功率分析记录仪&#xff1a;用于测量功率、电压、电流等参数&am…

这个tiktok短视频才发布了一天,就能卖货1.6w美金

这个tiktok短视频才发布了一天&#xff0c;就能卖货1.6w美金&#xff01; 今天的讨论课上&#xff0c; 我的学员们问我 TikTok上的一条带货短视频的结构是怎样的&#xff1f; 我们一起看了这个案例。 一、案例分析 这是TikTok上的一位达人“moreco1in" 他拥有862K粉丝…

LeetCode.3152.特殊数组II

题目描述&#xff1a; 如果数组的每一对相邻元素都是两个奇偶性不同的数字&#xff0c;则该数组被认为是一个 特殊数组 。 你有一个整数数组 nums 和一个二维整数矩阵 queries&#xff0c;对于 queries[i] [fromi, toi]&#xff0c;请你帮助你检查 子数组 nums[fromi..toi…

【Linux】多线程7——线程池

1.线程池的概念 1.1.池化技术 池化技术指的是提前准备一些资源&#xff0c;在需要时可以重复使用这些预先准备的资源。 在系统开发过程中&#xff0c;我们经常会用到池化技术。通俗的讲&#xff0c;池化技术就是&#xff1a;把一些资源预先分配好&#xff0c;组织到对象池中…

idea Spring-boot 项目debug启动过慢 :已验证

问题描述 Springboot项目在Idea中开发&#xff0c;server模型启动正常&#xff0c;但debug模式启动非常缓慢。 解决方案&#xff1a; 检查了项目配置&#xff0c;均没有问题&#xff0c;等20分钟以上能正常启动&#xff0c;但这样无法调试。查很多资料都没有找到问题解决方案…