热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

DevOps学习—使用GitLab、GiLabRunner

DevOps学习--使用GitLab、GiLab-Runner下图为我们的自动化部署流程用户推送代码到GitLab,GitLab将配置好的代码更新事件(流水线)发送到GitLab-

DevOps学习 -- 使用 GitLab、GiLab-Runner

下图为我们的自动化部署流程

用户推送代码到 GitLab,GitLab 将配置好的代码更新事件(流水线)发送到 GitLab-Runner或其他CI/DI软件,CI/DI软件完成自动部署。


一、安装配置部署 GitLab


安装 GitLab



  • 1.获取 GitLab,官方地址:https://packages.gitlab.com/gitlab/gitlab-ce,因为我使用的是 Centos8,所以我下载了 wget --content-disposition https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/8/gitlab-ce-15.3.2-ce.0.el8.x86_64.rpm/download.rpm



  • 2.安装 GitLab,使用命令 sudo yum install gitlab-ce-15.3.2-ce.0.el8.x86_64.rpm,如果报缺少包,则缺哪个安哪个。



  • 3.执行gitlab-ctl reconfigure,重新配置 GitLab。



  • 4.查看登陆密码(24小时后失效),使用命令cat /etc/gitlab/initial_root_password



  • 5.在网页上打开GitLab,端口号默认为80,用户名默认为:root



  • 6.修改密码:右上角->Prefrences->Password



  • 7.修改语言:右上角->Prefrences->Prefrences->Localization->Language




新建一个项目,并拉取



  • 1.首页点击新建项目

  • 2.填写相关信息,点击创建

  • 3.克隆项目(需要替换域名为当前gitlab所在主机的IP)

  • 4.使用 git clone http://gitlab.example.com/gitlab-instance-7a3f9f21/xlogin.git 拉取项目


二、安装配置 GitLab-Runner

前面我们讲过,GitLab-Runner 用于接收 GitLab 的更新事件,然后运行我们事先配置好的事件流程(流水线),如 build->test->deploy等。由此可以看出 GitLab-Runner 只是一个执行器,它接收来自 GitLab 特定格式的元数据,然后按照配置好的执行策略(配置文件)来运行;这个配置文件默认为项目根目录下的.gitlab-ci.yml文件。



  • 1.安装 GitLab-Runner,yum install gitlab-runner

  • 2.配置 GitLab-Runner:sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner,指定了gitlab-runner的用户名和工作目录

  • 3.启动 GitLab-Runner:gitlab-runner start

  • 4.将 GitLab-Runner 注册到 GitLab 上:gitlab-runner register。如下图:

Enter an executor:表示通过什么方式运行流水线中配置的 script,如果在本机运行编译部署等任务,则这里填写 shell;其他选项这里暂不做讨论。

注册令牌获取方式:菜单 -> 管理员 -> 管理中心 -> 概览 -> Runner -> 注册一个实例Runner



  • 5.修改配置文件,配置文件地址:/etc/gitlab-runner/config.toml

添加 clone_url 项(不配置通过git拉取的时候会报错)



  • 6.重新启动 gitlab-runner restart

  • 7.补充:如果需要在这台机器上使用 maven、gradle 等进行构建,那么需要安装这些软件。如果在当前机器上进行构建 git 是必须安装的。


三、配置流水线

如前所述,流水线是我们配置自动化部署的关键,用户将代码推送到仓库时,GitLab会自动的调用流水线,GitLab 会将流水线中配置的行为交由 GitLab-Runner 来执行。



  • 1.进入项目详情页,点击 CI/DI -> 编辑器 -> 配置流水线

  • 2.在编辑器中配置流水线,模板网址https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates,我使用的简化后的配置文件如下:

---
variables:
MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN
-Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true
-DdeployAtEnd=true"
image: maven:3.3.9-jdk-8
cache:
paths:
- ".m2/repository"
verify:
stage: test
script:
- 'mvn $MAVEN_CLI_OPTS verify'
except:
variables:
- "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"
deploy:
stage: deploy
script:
- if [ ! -f /etc/gitlab/ci_settings.xml ]; then echo "ci_settings 文件不存在,具体请看介绍:
https://docs.gitlab.com/ee/user/packages/maven_repository/index.html#create-maven-packages-with-gitlab-cicd
"; fi
- 'echo "部署到远程仓库"'
- 'mvn $MAVEN_CLI_OPTS deploy -s /etc/gitlab/ci_settings.xml'
- 'mvn package'
- 'echo "部署到远程机器"'
- 'python3 /root/deploy.py ${CI_PROJECT_DIR}/target/*.jar ${CI_PROJECT_TITLE} /root/config.yml'
- 'echo "部署成功"'
only:
variables:
- "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"

分为验证和部署两个阶段,阶段一验证代码,阶段二分别部署代码到远程 maven 仓库和远程机器



  • 3.现在当用户对目标仓库进行 push 的时候,GitLab 会自动运行流水线,首先将事件发送给 GitLab-Runner,然后 GitLab-Runner 拉取最新仓库并运行配置的流水线任务。

  • 4.配置文件中可以使用一些预定义的 CI 环境变量,可查阅:https://docs.gitlab.com/ee/ci/variables/predefined_variables.html


部署到远程 maven 仓库

这一步主要体现在 mvn $MAVEN_CLI_OPTS deploy -s /etc/gitlab/ci_settings.xml,这里使用了 maven 插件,相应的 pom.xml 文件为:


4.0.0


repo
http://123.123.132.123:8081/repository/maven-releases/


repo
http://123.123.132.123:8081/repository/maven-snapshots/



上面的 project.distributionManagement.repository.id 和 ci_settings.xml 文件中的 servers.server.id 一一对应。ci_setttings.xml 文件和 .m2/settings.xml 文件类似,属于 maven 的配置文件。在 ci_settings.xml 文件中,我们配置了远程 maven 仓库的账号密码,由此 maven 可以将打包后的结果 push 到远程 maven 仓库。

ci_settings.xml文件内容为:

xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">


repo
admin

123456




部署到远程机(并运行)

前面用到的部署脚本deploy.py运行环境为:至少python3.8、PyYAML包,代码如下:

import yaml
import os
import sys
class Executor:
def __init__(self, argv: list):
self.file = argv[3]
self.argv = argv
def _read_yml(self, file, mode='r', encoding='utf8') -> dict:
"""
读取 yml 文件
:param file: 文件名
:param mode: 打开文件模式,默认为 'r'
:param encoding: 编码格式
:return: dict
"""
with open(file, mode, encoding=encoding) as f:
res = yaml.full_load(f)
return res
def _validate(self, data: dict) -> bool:
"""
验证数据
:param data: 数据
:return: bool
"""
params = self.argv
if len(params) <3:
return False
self.jar_path = params[1]
self.project_name = params[2]
return True
def _run_command(self,command: str) -> list:
"""
运行本地命令
:param command: 命令
:return: 结果
"""
with os.popen(command) as f:
strs = f.readlines()
return strs
def _run_remote_command(self, data: dict) -> None:
"""
运行远程命令
:param data: 包含url、identity_file、command、username
:return: None
"""
ip = str(data.get("url"))
identity_file = str(data.get("identity_file"))
username = str(data.get("username"))
command = str(data.get("command"))
if len(ip) == 0 | len(identity_file) == 0 | len(command) == 0 | len(username) == 0:
print("远程命令参数出错,【ip】:【%s】【identity_file】:【%s】【command】:【%s】" % (ip, identity_file, command))
return
remote_command = f"ssh -i {identity_file} {username}@{ip} '{command}'"
print("开始执行远程命令:%s" % remote_command)
strs = self._run_command(remote_command)
print("远程命令执行结果:【%s】" % strs)
print("远程命令【%s】执行结束." % remote_command)
def _ssh(self, data: dict) -> None:
"""
mode = ssh
:param data: 数据
:return: None
"""
print("模式:【ssh】")
has_command = str(data.get("has_command"))
run_command = str(data.get("command"))
if (has_command == "True") & len(run_command) > 0:
self._run_remote_command(data)
else:
print("命令未执行,请检查参数.")
def _scp(self, data: dict) -> None:
"""
mode = scp
:param data: 数据
:return: None
"""
print("模式:【scp】")
identity_file = data.get("identity_file")
jar_path = self.jar_path
username = data.get("username")
spliter = os.sep
project_name = self.project_name
ip = data.get("url")
base_dir = data.get("base_dir")
has_command = str(data.get("has_command"))
run_command = str(data.get("command"))
success = False
command = f"scp -i {identity_file} {jar_path} {username}@{ip}:{base_dir}{spliter}{project_name}{spliter} "
print("开始执行命令: %s" % command)
strs = self._run_command(command)
if len(strs) == 0:
success = True
print("命令执行成功")
else:
print("命令【%s】执行失败" % command)
print("错误信息: %s" % strs)
if success & (has_command == "True") & len(run_command) > 0:
self._run_remote_command(data)
def _sftp(self, data: dict) -> None:
"""
mode = sftp
:param data: 数据
:return: None
"""
print("模式:【sftp】")
print(data)
def execute(self) -> None:
"""
开始执行
:return: None
"""
data = self._read_yml(self.file)
if not self._validate(data):
print("配置文件:%s 格式错误" % self.file)
deploy = data.get('deploy')
# 找到当前项目需要部署机器
needs = dict()
for one_instance in deploy:
ins = deploy.get(one_instance)
if self.project_name == ins.get("project_name"):
needs[one_instance] = ins
print("%s 将被部署到 %s 台机器" % (self.project_name, str(len(needs))))
for one_instance in needs:
ins = needs.get(one_instance)
print("%s 部署到 %s" % (self.project_name, one_instance))
mode = ins.get('mode')
# 通过反射方式调用函数
mode = "_" + mode
# 检查是否有 mode 函数 或者 属性
if hasattr(self, mode):
getattr(self, mode)(ins)
else:
print("未知模式:%s: %s" % (one_instance, mode))
if __name__ == "__main__":
argv = sys.argv
executor = Executor(argv)
executor.execute()

部署脚本的配置文件config.yml如下:

deploy:
ins1:
## 项目名称,脚本里用项目名称来匹配远程机,一个项目可配置多个远程机,从而部署到多个环境
project_name: test
url: 123.123.123.123
username: root
## 私钥文件地址
identity_file: /root/xxxx.pem
## 模式 -- 只实现了 ssh 和 scp 模式,ssh 仅运行命令,scp 将jar包部署到远程机
mode: scp
## jar文件最终路径为 {base.dir}/{project_name}/
base_dir: /box/
## 是否运行命令
has_command: True
## 运行命令
command: sh /box/test/start.sh

至此,配置完毕。


四、常见问题


GitLab、Git-Runner 运行卡顿?高 IO?


添加 swap 分区



  • 创建连续空间:dd if=/dev/zero of=/data/swap bs=512 count=8388616

  • 创建 swap 分区:mkswap /data/swap

  • 启动 swap 分区:swapon /data/swap

  • 在 /etc/fstab 文件中记录文件的名字,使系统重启后,swap 仍然有效 echo “/data/swap swap swap defaults 0 0” >> /etc/fstab

  • 查看 swap 分区:cat /proc/swaps

之后可以选择重新加载 gitlab:sudo gitlab-ctl reconfigure


GitLab-Runner 运行权限问题

通过 gitlab-runner 运行脚本使用的是前面配置的 gitlab-runner 用户角色,因为 gitlab-runner 在部署的时候使用了私钥文件,所以 gitlab-runner 用户角色必须有私钥文件的读权限。



推荐阅读
  • 持续集成概述与实践指南
    本文探讨了持续集成(CI)的基本概念、目的及其在现代软件开发中的应用。通过实例分析,帮助读者理解如何有效实施持续集成,提高软件开发效率。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 本文介绍如何使用 Sortable.js 库实现元素的拖拽和位置交换功能。Sortable.js 是一个轻量级、无依赖的 JavaScript 库,支持拖拽排序、动画效果和多种插件扩展。通过简单的配置和事件处理,可以轻松实现复杂的功能。 ... [详细]
  • 探讨一个显示数字的故障计算器,它支持两种操作:将当前数字乘以2或减去1。本文将详细介绍如何用最少的操作次数将初始值X转换为目标值Y。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本文详细介绍了如何在 Spring Boot 应用中通过 @PropertySource 注解读取非默认配置文件,包括配置文件的创建、映射类的设计以及确保 Spring 容器能够正确加载这些配置的方法。 ... [详细]
  • This document outlines the recommended naming conventions for HTML attributes in Fast Components, focusing on readability and consistency with existing standards. ... [详细]
  • Robot Framework在汽车电子测试中的应用探索
    随着汽车电子软件的重要性日益增加,为了适应市场的快速变化,汽车电子行业的开发和测试流程也在不断进化。敏捷开发、持续集成与部署(CI/CD)、DevOps等概念成为行业内的热门话题,这些方法不仅促进了OEM和零部件供应商的高效协作,还提高了软件的质量和可靠性。本文将探讨如何利用Robot Framework这一强大的自动化测试框架,来提升汽车电子测试的效率和效果。 ... [详细]
author-avatar
你看我的泪
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有