热门标签 | 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)的基本概念、目的及其在现代软件开发中的应用。通过实例分析,帮助读者理解如何有效实施持续集成,提高软件开发效率。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • 扫描线三巨头 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. ... [详细]
  • 本文详细介绍了Java中org.w3c.dom.Text类的splitText()方法,通过多个代码示例展示了其实际应用。该方法用于将文本节点在指定位置拆分为两个节点,并保持在文档树中。 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 在现代网络环境中,两台计算机之间的文件传输需求日益增长。传统的FTP和SSH方式虽然有效,但其配置复杂、步骤繁琐,难以满足快速且安全的传输需求。本文将介绍一种基于Go语言开发的新一代文件传输工具——Croc,它不仅简化了操作流程,还提供了强大的加密和跨平台支持。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 解决微信电脑版无法刷朋友圈问题:使用安卓远程投屏方案
    在工作期间想要浏览微信和朋友圈却不太方便?虽然微信电脑版目前不支持直接刷朋友圈,但通过远程投屏技术,可以轻松实现在电脑上操作安卓设备的功能。 ... [详细]
  • 网络运维工程师负责确保企业IT基础设施的稳定运行,保障业务连续性和数据安全。他们需要具备多种技能,包括搭建和维护网络环境、监控系统性能、处理突发事件等。本文将探讨网络运维工程师的职业前景及其平均薪酬水平。 ... [详细]
  • 从零开始构建完整手机站:Vue CLI 3 实战指南(第一部分)
    本系列教程将引导您使用 Vue CLI 3 构建一个功能齐全的移动应用。我们将深入探讨项目中涉及的每一个知识点,并确保这些内容与实际工作中的需求紧密结合。 ... [详细]
  • 本报告涵盖了个人博客账号和码云账号的注册过程,以及对网络工程专业学习的反思与展望。通过回顾初入大学时的专业选择,分析当前的专业知识和技能水平,并对未来的职业规划进行了详细讨论。 ... [详细]
  • 本文详细介绍了 com.facebook.drawee.view.SimpleDraweeView 中的 setScaleType 方法,提供了多个实际代码示例,并解释了其在不同场景下的应用。 ... [详细]
  • 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社区 版权所有