一直想模仿公司的代码部署环境,使用GitLab的CI/CD功能自动的部署代码,还有k8s的线上容器环境,最近空余时间比较多,有空折腾了,之前自己采购了几台树莓派4B。组建了一个基本的k8s环境,但是对于k8s的网络和命名空间理解太模糊,搁浅了,直到前几天,心血来潮,使用了树莓派搭建了一个GitLab,几天折腾已经可以部署一些简单的项目了,今天总结一下。
一台树莓派4B 8G
一台有固定公网IP的主机
树莓派64位系统:
github.com/openfans-co…
安装Gitlab
首先使用SSH连接到树莓派
然后更新软件包的最新列表:
sudo apt-get update
安装相关依赖:
sudo apt-get install -y postfix libatomic1
postfix主要是发邮件的依赖
安装包地址:packages.gitlab.com/gitlab/gitl…
GitLab有两个版本:社区版(CE)和企业版(EE),CE 比 EE 要少一些功能,EE 可能需要购买额外功能,个人来说CE够用了。曾经使用阿里云的1H2G的轻量云安装过Gitlab,还特意调了半天的安装参数,扩大了swap内存交换空间,还是卡得很就放弃了。
下载最新的安装包:
wget --content-disposition https://packages.gitlab.com/gitlab/gitlab-ce/packages/debian/buster/gitlab-ce_14.0.1-ce.0_arm64.deb/download.deb
基本的安装完成了,接下来设置配置文件
sudo vim /etc/gitlab/gitlab.rb
更改域名和gitlab的nginx的监听端口
external_url 'http://gitlab.*****.com'
nginx['enable'] = true
nginx['listen_port'] = 8880
配置完成,应用这个配置(时间有点长,好几分钟):
sudo gitlab-ctl reconfigure
讲一下穿透原理,自己有一个域名,用一个二级域名解析到一个有固定外网IP的机器,在这个固定外网机器的上面部署Nginx和frp服务端,在树莓派上除了gitlab和gitlab自带的nginx还需要安装一个frp的客户端:
graph TD
用户 ==gitlab.****.com==> 11[DNS解析];
11==***.***.***.***:**==>1[外网机器nginx监听端口]
1==反向代理到frpc端口 127.0.0.1:***==>2[外网机器frps服务端];
2==端口映射 tcp通信==>3[内网机器frpc客户端];
3==端口映射==>4[Gitlab内置Nginx端口监听];
4==进程通信Unix socket==>5[gitlab服务];
frpc 安装
从Github下载arm最新的安装包:
github链接:github.com/fatedier/fr…
wget https://github.com/fatedier/frp/releases/download/v0.37.0/frp_0.37.0_linux_arm64.tar.gz
解压tar包:
tar -zxvf frp_0.34.0_linux_arm.tar.gz
复制文件到相关的路径,遵循规范吧,有利于后面编写跟随系统启动的服务:
sudo cp frpc /usr/local/bin/frpc
cd frp_0.34.0_linux_arm/
sudo mkdir /etc/frc
sudo cp frpc.ini /etc/frpc/frpc.ini
设置配置文件,把gitlab自带的nginx监听的端口8880映射到外网机器7026端口,顺便映射一下ssh端口,让外网机器ssh也能链接到这个内网机器:
vim /etc/frpc/frpc.ini
[common]
server_addr = ***.***.***.***
server_port = 7000
token = ********
[gitlab-pi4_master]
type = tcp
local_ip = 127.0.0.1
local_port = 8880
remote_port = 7026
[ssh-pi4_master]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 7222
此时frp的客户端frpc的软件路径是:/usr/local/bin/frpc
,配置文件路径:/etc/frpc/frpc.ini
现在来写一个跟随系统启动的frpc系统级服务:
sudo nano /usr/lib/systemd/system/frpc.service
[Unit]
Description=frpc
After=multi-user.target
[Service]
TimeoutStartSec=30
ExecStart=/usr/local/bin/frpc -c /etc/frpc/frpc.ini
ExecStop=/bin/kill $MAINPID
[Install]
WantedBy=multi-user.target
启动frpc服务,开机自启
sudo systemctl start frpc
sudo systemctl enable frpc
设置外网机器
解析一个A记录的二级域名到外网机器的固定IP,这里是腾讯云。
外网机器自己安装了一个宝塔,一键安装了nginx,frps需要手动安装,基本的安装方式跟客户端差不多
在gitlab下载安装与客户端版本一样的并x86架构的frp,需要注意服务端的启动软件是frps,客户端的启动文件是frpc。
可以借鉴一下我的配置文件:
[common]
bind_addr = 0.0.0.0
bind_port = 7000
bind_udp_port = 7001
kcp_bind_port = 7000
dashboard_addr = 0.0.0.0
dashboard_port = 7200
dashboard_user = admin
dashboard_pwd = *******
log_file = ./frps.log
log_level = info
log_max_days = 3
disable_log_color = false
token = ******
allow_ports = 2000-3000,3001,3003,4000-50000
max_pool_count = 5
max_ports_per_client = 0
tcp_mux = true
现在访问外网ip加服务端设置的端口dashboard_port :7200可以访问了,用户名为:dashboard_user字段的值,密码是dashboard_pwd字段的值 :
域名解析和外网机器的nginx 配置
在宝塔的网站
添加一个静态网站:
如何安装宝塔,请参考宝塔:www.bt.cn/
为什么添加一个静态网站,是为了后面用宝塔来设置nginx配置文件
点开网站设置,再点反向代理:
打开缓存,提高加载速度,把内网的机器的缓存的静态文件缓存到外网机器的nginx,填写代理名为GitLab(这里可以随便填),目标URL为127.0.0.1,端口填写自己在Frp客户端设置的映射GitLab的remote_port:7026。
也可以申请SSL证书,把密钥pem和key填写在网站设置里面的SSL那里,保存就生效了,这里就不赘述了
到现在我的GitLab的网站就可以访问了:
看看系统负载,几乎无压力:
GitLab的CI/CD
GitLiab的初始密钥需要自己实现进入GitLab的console控制台查看
首先进入安装目录:
cd /opt/gitlab/bin
然后输入命令进入Rails 控制台
sudo gitlab-rails console
进入控制台后先查询为1的用户。更改这个用户密码为123456
u=User.where(id:1).first
u.password='12345678'
现在就用账号root进入GitHub
现在就需要安装runner了,什么是runner,就是搭配GitLab的执行自动化代码部署的一个软件,可以安装到其他机器或者自己机器上。点击menu->admin->runner就可以看到我自己的runner的配置和展示设置了
下面截图我自己就安装了两个runner,第一个是远程服务器的runner,第二个就是树莓派本身安装的runner。
可以看到右上角的注册url和注册token,下面安装runner需要使用到
安装runner
安装的教程可以参考官方文档:
docs.gitlab.com/runner/inst…
简要的说一下在这个安装GitLab的树莓派上安装的流程:
首先下载安装包,注意是arm64版本:
需要添加gitlab官方库:
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
通过命令安装:
sudo apt-get install gitlab-ci-multi-runner
gitlab-runner register
会有几个命令行询问,会要求输入gitlab的服务URL,和注册的token,就是输入上面截图右上角的url和token。
还有询问设置runner的tag和describe(描述),这两个可以填一样的,runner的tag很有用处,在GitLab的CI文件指定的runner就是用的这个Tag。最后询问这个runner的类型,我们输入shell就行,一般shell就是最通用的。完成了在GitLab刷新就可以看到了,之前装过了就没有截图给大家了。
实践的项目还是之前的贴子用Docker部署前端静态文件和Python后端框架,使用nginx容器部署一个静态页面,现在还可以玩,链接:xg.tuwei.space ,代码开源在GitLab:github.com/koala9527/s… 。
CI/CD最主要是.gitlab-ci.yml文件的编写,代码已经在GitLab中,现在拿出来讲一下吧。只有项目中有这个文件,推送代码到GitLab就会识别进入自动打包或部署的流程,前提是.gitlab-ci.yml文件指定了正确的runner和触发的分支。
stages:
- build
- deploy
variables:
PROJECT_NAME: koala9527/fruit-synthesis
REGISTRY_URL: ***.***.***.***:7029
build_develop:
stage: build
script:
- cp -rf ./ /home/gitlab-runner/fruit-synthesis
only:
- develop
tags:
- b4master
build_master:
stage: build
script:
- cp -rf ./ /home/gitlab-runner/fruit-synthesis
- docker build . -t $PROJECT_NAME
- docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:latest
- docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:backups-$CI_JOB_ID
- podman push --format=docker $REGISTRY_URL/$PROJECT_NAME:latest
- podman push --format=docker $REGISTRY_URL/$PROJECT_NAME:backups-$CI_JOB_ID
only:
- master
tags:
- baiduyun
deploy_develop:
stage: deploy
script:
- docker restart fruit-synthesis
only:
- develop
tags:
- b4master
deploy_master:
stage: deploy
script:
- podman pull $REGISTRY_URL/$PROJECT_NAME:latest
- docker stop fruit-synthesis
- docker rm fruit-synthesis
- docker run --name fruit-synthesis -p 8090:80 -d $REGISTRY_URL/$PROJECT_NAME:latest
only:
- master
tags:
- baiduyun
我们来详细讲解一下这个文件的内容
stages
指定了两个构建阶段,这里名字自定义,我的是打包和部署两个阶段,名字可以在GitLab的项目流水线上看到
variables
制定了整个构建任务的环境变量,整个文件都可以使用这些变量,我定义一个项目名称和远程镜像仓库的名字。
先说一下develop分支触发的打包流程,这里其实并不需要打包,只是复制代码就可以了,到develop的build任务中重启一下容器代码就直接生效了。
build
build_develop
build_develop
任务名字,任务至少要包含script关键字用于执行某个任务。
stage
指定这个任务是在哪个阶段执行,或者说是哪个阶段要执行哪个任务。
script
下面一行行的shell命令就是在runner上执行的命令。在测试服我执行了一个复制文件的命令,在runner执行命令时会实现从GitLab拉取代码。为什么我要复制项目的代码,是因为我实现在runner的服务器上启动可一个Nginx容器映射了宿主机的文件,执行复制命令就是更新一下这个映射的代码。在测试服部署阶段重启容器就更新了代码。
only
指定了触发这个任务的代码分支,复制代码的命令只在develop分支执行。
tags
指定任务的runner,名字指的是runner的tag,在安装runner的时候会提醒填写runner的tag。
build_master
build_master
这个任务是指定触发的代码分支是master分支,在develop合并到master分支时触发任务,所以only指定的是master分支,指定的runner是我部署在另外的远程服务器的runner,tag为:baiduyun。
script
中的命令意思就是复制代码,把代码打包成镜像推送到自己的私有镜像仓库
,私有镜像仓库可以是阿里云镜像仓库,Harber,Nexus 镜像仓库等等。私有仓库的私有镜像记得需要docker login 命令登录仓库哦。
deploy
deploy_develop
deploy_develop
任务就和build_develop
差不多,只是stage
构建阶段和script
执行的shell命令不同。script
仅仅是重启了容器,在.gitlab-ci.yml文件最下面的#注释的部分说明了首先要在机器上运行容器,如果不运行的话,重启命令是会失败。
deploy_master
deploy_master
与build_master
的stage
构建阶段和script
不一样,script是拉取镜像停止旧的容器,删除旧的容器,从新的镜像运行新的容器,其实这个步骤完全可以做成测试服务一样,映射文件重启容器就行,之所以这样做是因为为后面再加一个分支做准备,现在的master的构建步骤作为pre_release(预发布)分支。再做一个master的构建任务,master就直接拉镜像了,或者直接使用curl应用触发器触发K8S重新部署应用。
.gitlab-ci.yml文件的讲解完了。可以在CI/CD里任务里面看到任务执行的详情,提交代码合并代码可以触发相应的流程,有问题会在作业这个界面提示,根据提示调整就行了。
记得刚开始工作的时候没有使用Git,直接使用FTP提交代码到线上,代码实时生效,出BUG了不知道那里出错了,排查很困难。直到现在使用GitLab提交代码就可以直接部署,太方便了。配合Dokcer太香了,减少了很多运维工作。
初探GitLab,大多数都是一些零基础的安装教程方法,这些东西都是需要做一次基本就不用再做了,主要是后面CI文件的编写需要了解那些关键字的意思。
如有错误,望批评指教,不胜感激 !觉得有收获,希望帮忙点赞~