一、GitLab版本管理
Git是一个开源的分布式版本控制系统,用于代码的存储和版本控制。
GitLab 是一个用于仓库管理系统的开源项目。使用Git作为代码管理工具,并在此基础上搭建起来的web服务。
因为GitLab是为基于Linux的操作系统开发的,不能在Windows系统上运行,官方也没有计划支持Windows,所以只能安装到Linux系统。
如果windows机器,可以选择使用Linux虚拟机或docker来安装。
参考链接:https://docs.gitlab.com/ee/install/requirements.html
注意:本文仅用作演示,所以将在windows下安装docker,再在docker中运行gitlab,来进行环境搭建。该方式可能会有gitlab数据备份失败的问题。
1.docker安装
Docker 并非是一个通用的容器工具,它依赖于已存在并运行的 Linux 内核环境。
因此,Docker 也必须部署在 Linux 内核的系统上。如果其他系统想部署 Docker 就必须安装一个虚拟 Linux 环境。
win10系统的话可以很方便的安装docker,也是我本次采用的方式。
Hyper-V 是微软开发的虚拟机,类似于 VMWare 或 VirtualBox,仅适用于 Windows 10。这是 Docker Desktop for Windows 所使用的虚拟机。
参考链接:https://www.runoob.com/docker/windows-docker-install.html
1-1 查看电脑是否支持虚拟化
如果不支持的话,需要进BIOS修改,不同电脑biso选项不同,比如:
1-2 启用Hyper-V
控制面板-》程序和功能-》启动或关闭Window功能
1-3 下载安装包并安装
win10 系统可以直接下载官方提供的Docker Desktop Installer.exe进行安装。
下载链接:https://hub.docker.com/editions/community/docker-ce-desktop-windows
其他windows环境可以参考链接:https://www.runoob.com/docker/windows-docker-install.html
1-4 安装完毕后,桌面会有docker图标,双击即可启动docker
第一次打开docker会有一个示例,依照示例可以创建已经镜像,并启动一个容器,之后就可以在仪表盘可视化管理容器和镜像。
如果感觉难以理解镜像、容器、程序之间的关系,我可以根据个人理解提供一个比喻:
运行程序就像是打游戏,docker则是一间网吧。因为网吧的电脑配置资源有限,一次安装不下多款游戏,所以老板自己做了几个电脑系统,
其中一个系统只装了游戏A(就叫系统A),一台机器只装了游戏B(就叫系统B)...,这个过程就是创建镜像。
客人来了想玩游戏A,老板就给他找了台电脑安装了系统A,并运行里面的游戏A,这就是运行起来一个容器。
docker常用的命令有:
docker pull: 从镜像仓库中拉取或者更新指定镜像。
实例:从Docker Hub下载java最新版镜像。【 docker pull java 】
docker build: 创建本地镜像。
实例:从Docker Hub下载java最新版镜像。【 docker build -t runoob/ubuntu:v1 . 】
解析:-t runoob/ubuntu:v1,为构建的镜像标记名称,镜像名为:runoob/ubuntu,tag为v1;.,单独的点,意思为根据当前目录下的Dockerfile文件生成镜像。
docker run: 运行镜像。
实例:从Docker Hub下载java最新版镜像。【 docker run -p 8080:80 -v /home/data:/data -d runoob/ubuntu:v1 】
解析:使用镜像runoob/ubuntu:v1,(-d)以后台模式启动一个容器,(-p)将容器的80端口映射到主机的8080端口,(-v)将主机的目录/home/data 映射到容器的目录/data。
更多可以参考链接:https://www.runoob.com/docker/docker-command-manual.html
2. 在Docker中安装gitlab
2.1 拉取gitlab的镜像,gitlab-ce为稳定版本,后面不填写版本则默认pull最新latest版本
执行命令: $ docker pull gitlab/gitlab-ce
2.2 运行gitlab, 注意22 对应的ssh;80对应的是http;443 对应的是https。
a. 通过命令运行
执行命令: $ docker run -d -p 443:443 -p 80:80 -p 222:22 --name gitlab --restart always -v /home/gitlab/config:/etc/gitlab -v /home/gitlab/logs:/var/log/gitlab -v /home/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce
# -d:后台运行
# -p:将容器内部端口向外映射
# --name:命名容器名称
# -v:将容器内数据文件夹或者日志、配置等文件夹挂载到宿主机指定目录
b. 通过docker客户端运行
先点击要运行的gitlab镜像右边的【run】按钮
添加容器配置和容器名称,点击【run】按钮
到容器列表界面可以看到,容器已经运行起来了。
2.3 额外配置
按上面的方式,gitlab容器运行没问题,但在gitlab上创建项目的时候,生成项目的http地址是按容器的hostname来生成的,也就是容器的id。
作为gitlab服务器,我们需要一个固定的URL访问地址,因此我们要改一下gitlab.rb的配置。
通过docker窗口可以方便的看到配置文件的路径
windows系统下对应资源管理器路径:\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes
external_url 'http://10.100.17.37:80'
改完重启gitlab即可。
注意external_url配置的端口是内部http的端口,我之前配的是【external_url 'http://10.100.17.37:32770'】,这样会把内部端口由80改为了32770,这样再把内部80端口映射到宿主机的32770时,就映射不到啦。
当时的解决方法是创建容器时,直接将内部端口由32770映射到外部的32770。即使用命令【docker run -d -p 32773:443 -p 32770:32770 -p 32771:22 --name gitlab --restart always gitlab/gitlab-ce】,
然后再修改external_url为http://10.100.17.37:32770就不会报错。
2.4 创建gitlab账号权限及组
经过不懈努力,我们已经可以访问gitlab网站了。不过地址端口要注意使用80映射的那个端口(使用docker客户端默认打开地址的是ssh映射的端口)
a. 管理员第一次登录gitlab,需要重置管理员账户(root)密码:
cmd输入命令【 docker ps 】,查询出gitlab容器的id。
cmd输入命令【 docker exec -it 容器id /bin/bash 】,进入到容器内部。
继续输入命令【 gitlab-rails console 】
弹出 Loading production environment 后,在下面逐步输入:
1、【user=User.where(id:1).first】 查出指定修改的用户,1 为root
2、【user.password='hzq123456'】 需要设置的密码
3、【user.password_confirmation='hzq123456'】 确认上面输入的密码
4、【user.save!】 保存
注意,图中因为密码太短所以改失败了,换个长点的密码即可。
有了账户密码我们现在可以登录进去啦!
b.有了管理员账户,我们还需要创建常规用户。
这步也有两种方式,一种是让用户在登录界面注册,然后通过root账户审批通过即可;
另一种方式是通过root账户创建:
注意,如果刚接触gitlab,实在找不到对应页面的入口,直接输入图中的地址哦。
管理员创建用户必须填写用户邮箱地址,以便发送重置密码的链接,用户第一次登录前必须重置密码。所以还需要配置邮件服务器,这部分可以在网上搜索配置。
c. 创建组,及为组分配用户
点击保存后会自动跳转到用户分配页面:
创建项目后,也可以在项目界面分配用户或组:
OK! Gitlab准备完毕后,就可以继续CI/CD自动化部署的流程了。
二、Gitlab CI/CD
持续集成 CI(Continuous Integration):在源代码变更后,触发自动检测、构建和测试的过程。在代码提交后,会自动进行构建和测试,并反馈结果。当结果符合预期时,再将代码集成到主干。持续集成的目标是快速确保当前变更是可用的。
持续交付 CD(Continuous Delivery):是基于持续集成基础上,将集成后的代码自动化部署到各个环境测试,确定可以发布生产版本。
持续部署 CD(Continuous Deployment):是基于持续交付的基础上,将在各个环境经过测试的应用自动化部署到生产环境。其实各个环境的发布过程都是一样的。应用发布到生产环境后,我们需要对应用进行健康检查、添加应用的监控项、 应用日志管理。
1. 安装并运行gitlab-runner
参考链接:https://docs.gitlab.com/runner/install
GiTLab Runner是一个脚本运行器,类似于Jenkins,可以为我们执行一些CI持续集成、构建的脚本任务(即.gitlab-ci.yml),运行器具有执行脚本、调度、协调的工作能力。
在windows环境下,可以直接在服务器安装runner,也可以安装在docker中。
因为runner执行ci脚本时需要使用各种命令,如果本机已经安装了执行脚本要用的各类软件,比如maven、docker、nodejs等,最好直接在服务器上安装gitlab-runner。这样runner可以直接使用本机的环境来运行,这种情况下注册时注意选择【shell】作为执行器。
不过由于我这里用工作的电脑来演示,为了保持原系统的干净,采用麻烦一些的方式,依然使用docker安装,注册时执行器也选择【docker】,方便拉取不同的镜像来执行脚本。
1-1 拉取 gitlab-runner 镜像
cmd输入命令:
【 docker pull gitlab/gitlab-runner:latest 】
1-2 启动 gitlab-runner
cmd输入命令:
【 docker run -d --name gitlab-runner --restart always -v /srv/gitlab-runner/config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest 】
注意:那个【-v /var/run/docker.sock:/var/run/docker.sock】 一定要加上。
因为docker daemon进程默认监听的是/var/run/docker.sock这个文件,所以docker客户端只要把请求命令发往这里,daemon就能收到并且做出响应。
这个命令将外部docker客户端的/var/run/docker.sock映射给了内部docker客户端,使内部docker客户端也可以访问外部的docker daemon服务。
否则后面注册如果选择了docker作为执行器时,因为是docker-in-docker模式,内部的docker将无法启动。例如出现下面的错误:
启动后如果看日志可能会发现提示缺少【/etc/gitlab-runner/config.toml】文件,这是因为还需要注册。无需关闭容器,直接进行下一步操作即可。
2. 将gitlab项目或组注册到gitlab-runner
2-1 先使用管理员账户,进入【项目】或【组】的页面,然后打开Settings -> CI/CD。
注意红框中的地址和token,注册时要用到。
2-2 开始注册
先说明一下,executer有多种选择,常见如下:
shell-需要在安装runner的机器上手动安装需要的依赖,比如要编译maven项目,需要安装maven,编译vuejs需要安装node等;
docker-一个很好的选择是使用Docker,因为它允许一个干净的构建环境,以及简单的依赖管理(所有用于构建项目的依赖都可以放在Docker映像中)。Docker执行器允许你轻松地创建一个带有依赖服务的构建环境,比如MySQL;
Kubernetes-执行程序允许您为构建使用一个现有的Kubernetes集群。执行程序将调用Kubernetes集群API,并为每个GitLab CI作业创建一个新的Pod(带有一个构建容器和服务容器)。
方式A: 逐步注册,然后根据需要修改配置文件
首先在cmd输入命令:【 docker exec -it gitlab-runner gitlab-runner register 】
执行器选【docker】的话,注册共需要再进行6次输入:
1-输入gitlab的地址;(地址为上图Gitlab的ci/cd配置页面红框选中内容,不能用localhost,可以用ip)
2-输入token;(token为上图Gitlab的ci/cd配置页面红框选中内容)
3-可以输入空;
4-可以输入空;
5-输入docker;(表示使用docker镜像来执行gitlab-ci.yml文件内部script命令,具体参加注意事项)
6-执行gitlab-ci.ym文件内script命令的默认镜像,因为gitlab-ci.yml中可以为每一阶段单独指定执行命令的镜像,这里理论上随便输入一个hub.docker.com上存在的镜像即可,建议根据实际要用到的脚本来选择。
因为我后面自动部署是要将程序做成镜像发布,要使用docker的命令,所以这里最终也填了【docker】。
注意,因为注册的环境里再次使用了docker镜像,相当于docker-in-docker-in-docker的模式。
为了让runner下载的docker镜像也能连上docker daemon,需要修改runner的配置【/etc/gitlab-runner/config.toml】
当然如果你不需要把程序打包成docker镜像来运行,可以不管这个配置。
步骤如下:
进入到容器内部,先使用【cat etc/gitlab-runner/config.toml】打开配置文件,将里面的配置复制到文本编辑器。
修改volumes 配置为【volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]】
再次使用【cat > etc/gitlab-runner/config.toml】命令开始重写配置文件,将改好的配置粘贴进去,再按CTRL+ c 退出即可自动保存。
方式B: 使用组合命令,注册时同时修改配置
docker exec gitlab-runner gitlab-runner register -n \
--url http://xx.xxx.xx.xx:32770/ \
--registration-token aGzYCxxxxxnrMxY7u_k \
--tag-list department-A \
--executor docker \
--docker-image "docker" \
--docker-volumes /root/.m2:/root/.m2 \
--docker-volumes /root/.npm:/root/.npm \
--docker-volumes /var/run/docker.sock:/var/run/docker.sock \
--description "the runner of department-A" \
1. executor,使用docker。
2. 通过docker-image指定一个docker镜像。这里使用的是docker:latest。
3. 通过docker-volumns挂载本地目录:
挂载docker.sock是为了docker:latest镜像操控runner服务器的docker服务;
挂载.m2文件夹,是为了避免maven每次编译项目时都重新下载jar包。(后面.gitlab-ci.yml文件中使用了maven镜像)
第一句的-n是什么作用我也不清楚,去掉貌似也没影响。
另外有个镜像拉取策略的配置【pull_policy】可以关注一下,可以选择优先使用本地缓存的镜像还是拉取最新的镜像,官方有比较详细的解释。默认为always,在断网或者想要加快ci执行的速度时貌似可以设置if-not-present。
参考链接:https://docs.gitlab.com/runner/executors/docker.html#using-multiple-pull-policies
以上步骤做完之后,咱们再回到gitlab页面刷新看看效果,这时项目下面已经存在一个可用的runner了。
3.在项目根目录下创建runner执行文件【.gitlab-ci.yml】
.gitlab-ci.yml位于git项目根目录下,用于定义 CI/CD 流程分为几个阶段,每个阶段需要执行哪些任务等。
3-1 创建项目
我这里直接使用以前写的一个demo项目。在项目根目录建一个.gitlab-ci.yml文件,然后因为我准备把程序做成镜像在docker上运行,还在要发布的模块根目录下新建一个Dockerfile文件。
3-2 .gitlab-ci.yml 文件
before_script: - export DOCKER_IMAGE_TAG=$(date +%Y%m%d%H%M) stages: - compile - build #编译配置 auto-compile: stage: compile tags: [ "department-A" ] image: name: maven only: # 打包分支 - develop script: - mvn clean install -Dmaven.test.skip=true -f ./Maven_Demo/demo/pom.xml artifacts: paths: - Maven_Demo/demo/demo-springboot/target/*.jar #构建配置 auto-build: stage: build tags: [ "department-A" ] # image: docker only: # 打包分支 - develop dependencies: - auto-compile script: - docker build -t hzq/demo-springboot:$DOCKER_IMAGE_TAG ./Maven_Demo/demo/demo-springboot - docker stop mydemo || true - docker rm mydemo || true - docker run --name mydemo -p 13005:13005 -d hzq/demo-springboot:$DOCKER_IMAGE_TAG
export 用来设置一个变量,我这里设置一个时间字符串,用作镜像名称的标签。
stages 表示分成几个job来执行,因为每一步需要用到的image不同。
auto-compile和auto-build 只是作为当前job的名称,貌似可以顺便写。不过里面的stage要和stages里面写的步骤一致。
tags 用来选择该标签对应的注册runner的实例。
image 该步骤要用来执行script的镜像。
only 用来指定哪些分支发生提交时,才需要执行当前job。
expect 与only相反
script 该步骤需要执行的shell脚本,里面具体的命令大家可以去网上查。
dependencies 要依赖哪个步骤完成再执行。
variables 定义变量。
allow_failure 指定当前job是否容错,正常job失败会跳过后续job流程
before_script 在当前job执行前执行的shell脚本
after_script 在当前job执行后执行的shell脚本
when 依赖的上一个job执行什么状态后执行当前job, on_success on_failure always manual 默认on_success
3-3 Dockerfile文件
Dockerfile是给.gitlab-ci.yml里面的docker build命令构建程序镜像用的。
里面主要包含指定程序运行的环境,导入执行文件,设置执行命令等操作。
### 基础镜像 FROM openjdk:11 #声明一个挂载点,容器内此路径会对应宿主机的某个文件夹 VOLUME /tmp #声明工作目录 WORKDIR /home #应用构建成功后的jar文件被复制到镜像的工作目录内,名字也改成了app.jar COPY target/*.jar /home/app.jar #添加运行权限 RUN chmod +x app.jar #设置时区,容器时间与主机时间保持一致 RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone #暴露端口 EXPOSE 13005 #启动容器时的进程 ENTRYPOINT java -jar /home/app.jar --spring.profiles.active=dev
3-4 提交代码,验证结果
这时候提交代码就可以在gitlab中看到执行.gitlab-ci.yml的过程,注意分支要和only属性配置的一致。
我们再打开docker,可以看到程序镜像已经创建好,并自动运行起来了。
每次修改代码并重新提交后,将会自动创建新的镜像和容器并运行。这样简单的CI/CD就搭建完毕啦。
其他关于Kubernetes,Rancher,Jenkins工具的使用,等有空再一起探索吧。
--------------------------------------------------------------------------------------------------------------------
以下是参考的链接:
GITLab:
https://www.cnblogs.com/zxtceq/p/11082525.html
https://blog.csdn.net/weixin_30549657/article/details/100093425
https://blog.csdn.net/MonoBehaviour/article/details/84852984
http://www.360doc.com/content/17/0215/11/17572791_629136631.shtml
CI/CD:
(gitlab-runner,shell注册,netcore)https://www.cnblogs.com/yuyoho/p/13273794.html
(gitlab-runner,docker注册,sh脚本,node)https://blog.csdn.net/qq_36737839/article/details/113694367
(gitlab-runner,docker注册,maven,docker push)https://blog.csdn.net/qq_34596292/article/details/111349745
(gitlab-runner,docker注册,vue,maven,CI示例)https://blog.csdn.net/qq_34596292/article/details/111349745
(docker.sock详解)https://blog.csdn.net/boling_cavalry/article/details/92846483
--------------------------------------------------------------------------------------------------------------------