本教程将简要介绍如何在VMware
虚拟机中安装CentOS7
服务器系统,以及Tailscale
、1Panel
、AdGuard Home
、Gitlab
、Gitlab CI/CD
、Jenkins
的应用。
以下是镜像下载地址:
https://repo.huaweicloud.com/centos/7.9.2009/isos/x86_64/
因为要做服务器使用,所以推荐下CentOS-7-x86_64-Minimal-2009.iso
版本。
打开VMware
客户端,点击左上角文件
- 新建虚拟机
,选择典型
,然后点击下一步,
选择下载的CentOS
系统镜像,点击下一步,
选择虚拟机文件保存的位置,继续下一步,
指定磁盘容量,建议设置在50GB
以上,并选择将虚拟磁盘拆分为多个文件
,点击下一步,
进入自定义硬件界面
,
设置内存(建议8GB
以上),处理器(建议双核四线程
以上),移除打印机和声卡驱动,点击应用并确定,回到上一个页面后点击完成,开始安装虚拟机系统。
选中第一个安装选项并回车Install CentOS7
,稍待片刻,进入语言选择界面,选择简体中文
,点击右下角继续
。
点击系统-安装位置
,选择默认磁盘,点击完成。点击网络与主机名
,打开以太网连接,然后点击完成。两者配置完毕,点击开始安装
。
安装过程中可配置root密码
,点击完成即可,右边的创建新用户无须设置。等待系统自行安装完毕。
安装完毕后点击重启
,进入命令行界面。输入用户名root
登录,(密码为上一步设置的root密码
)。
登录完成后,输入ping baidu.com
检查网络是否通畅,如有返回,则说明可以访问外网,无须其他配置。
输入sudo systemctl start sshd
命令,启动ssh远程连接
功能。
输入ip addr | head -n 20
查询虚拟机 ip(ens33
网卡),我的是192.168.36.129
,(下文以192.168.115.237
为例)。
打开宿主机系统的Windows Powershell
,输入ssh root@刚刚查询的IP地址
(如ssh root@192.168.115.237
),将警告此密钥没有任何名称,忽略直接填写 yes。回车输入密码即可在本机终端连接你的虚拟机服务器终端,
此时可以使CentOS
虚拟机后台运行,自主地在Windows Powershell
中进行接下来的操作了。如果你电脑上安装了新版的Windows Terminal添加快速访问终端
,可以直接把它添加到配置文件中。
点击设置
->添加配置文件
->复制
,然后在命令行
一栏中添加如下命令,ssh root@刚刚查询的IP地址
,点击 保存
即可。
有时候我们可能需要把虚拟机中运行的服务提供给宿主机所在的局域网其他主机访问,这时就需要将所需端口到宿主机。
打开VMware
客户端,点击菜单栏编辑
- 虚拟网络编辑器
,并点击右下角的更改设置
按钮。
选择VMnet8
,点击NAT设置
按钮,
在以下窗口中点击添加
按钮,填写主机端口
、虚拟机IP
、虚拟机服务端口
等内容,即可将指定的端口映射到宿主机上,设置完毕后点击确定并应用。
打开Windows安全中心
(Windows denfender
),选择防火墙和网络保护
模块,点击高级设置
,
点击入站规则
,选择右侧的新建规则
,
选择创建端口
规则,点击下一页
,
根据服务需要选择TCP
或UDP
协议类型,一般为TCP
,然后选择所有本地端口
(如果不想暴露所有端口到局域网,可以根据需要指定端口)。点击下一页
。
选择允许连接
,点击下一页
,
全部勾选,点击下一页
,
填写名称和描述,点击完成
,
以上各步骤皆设置完毕后,在浏览器通过宿主机的 IP 加映射的主机端口就可以访问虚拟机中的服务了,同时在设置过防火墙之后,局域网的其他主机也可以访问了。
以上配置只允许在宿主机所在的局域网中访问,有时候我们可能需要远程办公或者在外网操作,这时候就无法访问虚拟机中的网络了。
所以我们需要使用 VPN 组网工具,市面上类似的 VPN 工具有很多,比如蒲公英
这样的,虽然我曾经在该公司工作过,但是我并不推荐个人用户使用它,因为它既不便捷也不便宜,虽然个人在有所限制的情况下可以免费使用。但它提供的免费带宽和设备数远远不够我们的使用需求。
在这里我推荐使用tailscale
或ZeroTier
来进行组网,它们的安装以及配置都十分简单。
访问 https://tailscale.com/download , 下载客户端(支持Android
、Linux
、Macos
、IOS
、Windows
)。
安装完毕之后,点击托盘图标login
登录,
可以直接使用微软
、Github
、谷歌
等账号注册登录,
授权登录,
登录完毕之后,显示自己有一台设备在线。
同样的,在另一台设备重复此操作,登录同一个账号,然后这两台设备就可以相互访问了。
在托盘中可以看到自己的设备IP
和在线的其他设备IP
,
设备管理页面,
在一般情况下,我们无须对Tailscale
做任何配置,但如果你对网络有更高的稳定性要求,默认配置可能就不能够满足了。Tailscale
旨在处于网络上的任何位置的机器进行点对点连接,但在
必须安装VMware Tools
才能开启共享主机文件夹功能,如果你已安装,请跳过此步骤。
首先,打开顶部虚拟机
菜单,点击安装 VMware Tools
按钮,把软件提供的ISO
文件挂载到虚拟磁盘上(点击安装后,可查看虚拟机设置
是否已挂载成功,并勾选已连接
和启动时连接
),重启系统。
重启后进入虚拟机系统中,执行ls /dev
查看是否存在cdrom
目录,不存在的话请检查设置vm-tool
的iso
是否已成功挂载并连接。
如果存在,则继续执行以下命令,安装编译所需的依赖:
yum -y install perl gcc gcc-c++ make cmake kernel kernel-headers kernel-devel net-tools
安装完毕后,依次执行以下命令:
# 在 /mnt目录下创建cdrom文件夹
mkdir -p /mnt/cdrom
# 以只读方式挂载cdrom
mount -t auto /dev/cdrom /mnt/cdrom
# 挂载后,查看/mnt/cdrom下的VMwareTools-xxx.tar.gz文件名
ls /mnt/cdrom
# 拷贝VMwareTools文件到用户根目录 (注意替换文件名)
cp /mnt/cdrom/VMwareTools-10.3.25-20206839.tar.gz ~
# 卸载cdrom
umount /dev/cdrom
# 切换到用户目录
cd ~
# 解压文件 (注意替换文件名)
tar -zxvf VMwareTools-10.3.25-20206839.tar.gz
# 运行可执行文件
./vmware-tools-distrib/vmware-install.pl
提示open-vm-tools packages are available from the OS vendor and VMware recommends using open-vm-tools packages. See http://kb.vmware.com/kb/2073803 for more information. Do you still want to proceed with this installation? [no]
输入yes
后一路回车,然后VMwareTools
的安装就完成了,此时便可移除CD驱动器
或者VMware Tools ISO
镜像的连接了。最后需要执行reboot
,或手动重启虚拟机。
打开虚拟机
-设置
,切换到选项
-共享文件夹
选项卡,勾选总是启用
,然后点击添加
按钮。
选择一个你需要共享的目录,注意,目录名不能包含空格和中文、特殊符号。然后点击下一步
。
勾选启用此共享
,取消勾选只读
,然后点击完成并确定。
进入虚拟机系统,执行vmware-hgfsclient
命令,可查看是否已经开启共享,如果已成功开启,会打印主机目录名。
依次执行以下命令:
# 在mnt目录下创建hgfs文件夹
mkdir -p /mnt/hgfs
# 挂载主机文件夹到指定目录,注意替换 VMShare 为你自己的目录名。
vmhgfs-fuse .host:/VMShare /mnt/hgfs
# 查看目录是否挂载成功
ls /mnt/hgfs/VMShare
挂载成功后,即可在虚拟机系统中读写主机文件夹中的内容了。
在服务器系统中安装 Web 管理面板可以极大提升服务器操作的便捷性,推荐使用基于 Docker 的服务器开源管理面板1Panel
,本文后续的应用安装,也将基于1Panel
进行操作。
只需执行以下命令,即可完成安装
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sh quick_start.sh
点击面板左侧的面板设置
,配置默认的服务器地址
为你的虚拟机系统 IP,比如我的是192.168.36.129
,配置完毕后点击确定。
在面板设置
中的安全
选项卡下,置空默认的安全入口
设置。
有时候我们可能需要通过 SSH 远程登录服务器,所以需要开启 SSH 密钥登录功能,展开面板左侧的主机
菜单,打开SSH管理
页面,root用户
设置为允许SSH登录
,并开启密钥认证
功能。
点击密钥信息
按钮,打开配置弹窗,加密方式
选择RSA
,密码
输入框置空,然后点击生成密钥
即可。
在容器
中的配置
选项卡下,设置镜像加速源,内容如下:
https://hub-mirror.c.163.com
https://docker.m.daocloud.io
https://ghcr.io
https://mirror.baidubce.com
https://docker.nju.edu.cn
我们在虚拟机中安装了服务器系统后,要想访问,总是要通过 IP + 端口
的形式,或者通过修改Hosts
文件的方式进行域名访问,每一个域名都需要单独配置,这样极为不便,推荐安装AdGuard Home
创建一个私人 DNS 解析服务器,这样我们就能够在本地使用自动解析域名的方式访问自己的服务了。
点击1Panel
面板的应用商店
,直接搜索AdGuard
,找到后点击安装
。
弹出自定义参数窗口,一般默认配置无须修改,勾选底部的端口外部访问
,然后点击确定,开始安装。
进入已安装
应用界面查看,安装完毕后,点击服务端口按钮,将自动跳转到 Web 管理页(如果跳转的 IP 地址不对,请按照上面的步骤在面板设置中配置默认的服务器地址
)。
除了使用应用商店
一键安装外,你也可以自行编写Docker compose
模板进行安装,以下是1Panel
提供的模板,你可以直接粘贴到容器
- 创建编排
中进行安装(其中的变量请按需修改)。
networks:
1panel-network:
external: true
services:
adguardhome:
container_name: ${CONTAINER_NAME}
deploy:
resources:
limits:
cpus: ${CPUS}
memory: ${MEMORY_LIMIT}
image: adguard/adguardhome:v0.107.36
labels:
createdBy: Apps
networks:
- 1panel-network
ports:
- ${HOST_IP}:${PANEL_APP_PORT_DNS}:53/tcp
- ${HOST_IP}:${PANEL_APP_PORT_DNS}:53/udp
- ${HOST_IP}:${PANEL_APP_PORT_DHCP_1}:67/udp
- ${HOST_IP}:${PANEL_APP_PORT_DHCP_2}:68/udp
- ${HOST_IP}:${PANEL_APP_PORT_HTTP_1}:80/tcp
- ${HOST_IP}:${PANEL_APP_PORT_DOH}:443/tcp
- ${HOST_IP}:${PANEL_APP_PORT_DOH}:443/udp
- ${HOST_IP}:${PANEL_APP_PORT_HTTP}:3000/tcp
- ${HOST_IP}:${PANEL_APP_PORT_DOT}:853/tcp
- ${HOST_IP}:${PANEL_APP_PORT_QUIC_1}:784/udp
- ${HOST_IP}:${PANEL_APP_PORT_DOT}:853/udp
- ${HOST_IP}:${PANEL_APP_PORT_QUIC_2}:8853/udp
- ${HOST_IP}:${PANEL_APP_PORT_DNS_CRYPT}:5443/tcp
- ${HOST_IP}:${PANEL_APP_PORT_DNS_CRYPT}:5443/udp
restart: always
volumes:
- ./data/work:/opt/adguardhome/work
- ./data/conf:/opt/adguardhome/conf
version: "3"
在初始配置页面,网页管理界面的监听端口选择所有接口
,端口填3000
,DNS 服务器监听接口也选择所有接口
,端口保持默认的53
,然后点击下一步。
设置用户名和密码,点击下一步。
点击后会自动跳转到IP:3000
地址,发现打不开,不要慌张,你应该访问的依然是你面板中自动跳转的端口,就是刚刚设置初始配置的端口(23001
)。
更换为正确地址后,输入用户名和密码,就可以进入控制台页面了。
以下仅列出需要修改的配置,未提及的配置均保持默认。
常规设置
在常规设置
- 日志配置
中,配置查询日志保留时间
为24小时
。
DNS 配置
上游 DNS 服务器
114.114.114.114
114.114.115.115
223.5.5.5
223.6.6.6
119.29.29.29
101.226.4.6
123.125.81.6
101.226.4.6
101.226.4.6
https://dns.google/dns-query
https://dns.quad9.net/dns-query
https://doh.opendns.com/dns-query
https://1.1.1.1/dns-query
tls://dns.rubyfish.cn
tls://8.8.8.8
tls://8.8.4.4
tls://dns.google:853
Bootstrap DNS 服务器
180.76.76.76
119.29.29.29
223.5.5.5
8.8.8.8
8.8.4.4
208.67.222.222
自定义过滤规则
根据自己的需要,可以在这里配置自定义解析规则,比如你想设置的域名是dev.com
以及其所有子域名,解析到虚拟机(已映射到宿主机)的服务上,就可以这样设置(详细配置说明见官方文档):
||dev.com^$dnsrewrite=192.168.2.171,client=192.168.2.0/24
||dev.com^
表示匹配所有根域名为dev.com
的地址$dnsrewrite=192.168.2.171
表示将其重写并解析到 IP 为192.168.2.171
(我的宿主机在局域网中的 IP)的服务器上client=192.168.2.0/24
表示仅当入站 IP 为局域网网段为192.168.2.0 ~ 192.168.2.255
中的主机访问时生效。配置完成后,我们就可以在自己电脑或局域网中的主机上使用自己的私人 DNS 了,
打开VMware虚拟网络编辑器
,将虚拟机中的20053端口
映射到宿主机的53端口
上,并分别映射TCP
和UDP
类型,配置完毕后点击确定并应用该配置。
这时,宿主机的 DNS 解析功能已经配置完毕。打开 Windows 控制面板,配置网络适配器IPV4
,
设置 DNS 解析为自己的宿主机 IP(局域网内的其他主机也可以填写你的宿主机 IP 作为 DNS 解析服务器),
静态网站
在1Panel
中新建一个静态网站
,主域名为www.dev.com
,点击确定。然后在浏览器访问,看看是不是已经被浏览器正确解析啦?
反向代理
我们也可以使用反向代理来使用私人 DNS 解析,在1Panel
中新建一个反向代理
服务,主域名填写panel.dev.com
,代理地址填写127.0.0.1:42629
(端口为你的1Panel
面板访问端口),点击确定。然后在浏览器访问panel.dev.com
时,发现已经解析到1Panel
管理面板了,我们以后访问面板管理服务器,再也不用使用IP + 端口
访问了(需在面板设置中把安全入口
置空)。
如果你已经按照上面安装了Tailscale
,我们还可以把私人 DNS 解析服务器应用到所有加入组网的设备中,而无须在单独为每台设备在网络适配器中设置IPV4 DNS服务器
。
打开Tailscale
控制台,切换到DNS
选项卡,在Nameservers
模块点击Add nameserver
按钮,选择Custom
,
Nameserver IP
输入框填写你虚拟机所在宿主机的Tailscale
分配的IP
(100
开头的),开启Restrict to domain
,Domain
输入框填写你需要使用私人DNS
解析的域名,如dev.com
,配置完毕后,点击Save
保存。
打开AdGuard Home
- 过滤器
- 自定义过滤规则
,在规则中添加||dev.com^$dnsrewrite=100.xxx.xxx.xxx,client=~192.168.0.0/16
条目,IP
为宿主机的Tailscale
所分配的IP
。
以上步骤设置完毕,现在你不必为每台主机都进行DNS
配置了,只要登录了Tailcale
授权账号的组网设备,都可以自动使用该私人DNS服务器
了。
Tailscale
可以进行更多自定义配置,不同账号之间可以共享组网网络,也可以按照不同的组或者标签来进行权限控制,具体操作文档,请访问 https://tailscale.com/kb/ ,这里不再展开说明。
上面的教程中在安装系统时,特意分配了双核四线程
和8G内存
的硬件配置,这同样符合Gitlab仓库
和Citlab CI/CD
的配置需求,我们在日常工作中经常会用到代码托管系统,所以可以在服务器中部署这样一套集代码托管、持续集成、自动部署为一体的流程,供局域网中的任何主机使用。
在我写这篇笔记的时候,1Panel
的应用商店中,还没有收录Gitlab
,所以我们使用自定义的Docker Compose
进行安装。(其实应用商店中的应用也是使用Dcoker Compose
进行安装的,在安装时也可以选择高级设置可以自定义Compose
模板)
选择1Panel
左侧的容器
菜单,切换到编排模板
,点击创建编排模板
,填写名称gitlab-all
(任意),代码框中贴入如下代码 (两个服务可分别部署,如果不需要持续集成功能,可将gitlab-runner
部分删除,以后用到时在单独安装),点击确定保存:
version: "3"
services:
gitlab:
image: gitlab/gitlab-ce:latest
restart: always
hostname: git.dev.com #这里填写映射的域名或者服务器地址
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://git.dev.com'
ports:
- "8888:80"
- "4343:443"
- "2222:22"
volumes:
- "./gitlab/config:/etc/gitlab"
- "./gitlab/logs:/var/log/gitlab"
- "./gitlab/data:/var/opt/gitlab"
gitlab-runner:
image: gitlab/gitlab-runner:latest
restart: always
depends_on:
- gitlab
volumes:
- "./gitlab-runner/config:/etc/gitlab-runner"
- "/var/run/docker.sock:/var/run/docker.sock" #不可修改
切换到编排
选项卡,点击创建编排
,选中编排模板
,填写文件夹名(会把数据和配置文件保存在这里),下拉选择刚才编写的模板
,然后点击确定保存后,docker compose
开始拉取镜像,自动部署成功。
切换到容器
选项卡,发现多了两个正在运行的gitlab-all
为前缀的容器,这就是刚才我们所创建的,当状态为已启动
之后,说明容器运行成功,点击gitlab
容器的 Web 端口,即可自动跳转到所部署的gitlab
首页,
打开网站之后,需要进行登录。默认管理员账号为root
,初始密码须至容器目录中获取。点击容器
选项卡,点击Gitlab
所在容器右侧的终端,连接后输入grep 'Password:' /etc/gitlab/initial_root_password
,即可查看密码,此密码查看方式将在首次登录后自动删除,请务必修改密码。
登录成功后,发现Gitlab
页面为英文页面,我们可以在设置中进行一些个性化配置。
点击左上角的头像,打开Preferences
菜单。
在打开的页面中,往下拉到Localization
模块,可以配置显示语言为Chinese Simolified - 简体中文
。在这个页面中你也可以根据个人喜好进行一些其他配置,包括主题、代码风格、界面布局等。
以上的偏好设置,是针对当前用户的,如果你想对所有用户都预设一个默认配置(比如语言),需要使用root
账号进入管理中心
,进行全局配置。
在管理中心
选项中,展开底部的设置
菜单,打开偏好设置
,
在偏好设置
中下拉,展开本地化
模块,设置默认语言
为Chinese Simolified - 简体中文
。
除了偏好设置
,在设置
菜单中你也可以根据个人需求配置一些其他的项目/用户通用设置,比如仅支持http
方式拉取代码,关闭ssh
方式,比如自动到如其他仓库代码(如Github
、Gitea
)等。
我们在开发中,经常有需要控制用户权限或者为项目分组,比如把前端项目放到一个分组里,把后端项目放到另一个组里,方便管理,Gitlab
就提供了这样的功能。
我们可以点击左上角+
号,新建群组
。
然后点击创建群组
,填写相关信息,可见性级别
选择私有
,然后点击创建
。
群组创建完毕后,自动跳转到群组详情页面,我们可以在其中直接继续创建项目
,然后选创建空白项目
,填写相关信息,并勾选使用自述文件初始化仓库
,然后点击创建
。
这样,一个新的项目就创建成功了,仓库中已自动创建了一个Readme.md
文件,这表示该项目已经被初始化,可以进行推送操作了。
点击右边的克隆,使用GIT
的HTTP
方式把项目代码克隆到本地电脑,然后就可以进行开发了。
新版的Gitlab
还提供了WEB IDE
在线开发的功能,我们也可以进行在线编码,而无须拉取代码到本地。
如果在上面安装Gitlab
没有同时安装Gitlab Runner
服务,需要先进行安装,创建Docker compose
模板,贴入如下代码,运行即可:
gitlab-runner:
image: gitlab/gitlab-runner:latest
restart: always
depends_on:
- gitlab
volumes:
- "./gitlab-runner/config:/etc/gitlab-runner"
- "/var/run/docker.sock:/var/run/docker.sock" #不可修改
已安装Runner
服务后,打开Gitlab
,点击左上角管理中心
设置菜单(不同版本可能入口位置有所区别),展开CI|CD
菜单,点击Runner
,新建实例Runner
(这里只做展示用,所以创建了全局Runner实例
,后续可根据需要可单独在群组、项目中创建实例)。
来到配置页面,设置以下内容:
Linux
,一般无需修改。Docker
(在上一步创建docker comppose
模板时,卷映射地址为/var/run/docker.sock:/var/run/docker.sock
,切勿修改,这将把外部Docker
通讯服务映射到容器内部,当Gitlab Runner
执行构建时,会通知调用外部的Docker
执行操作)。运行未打标签的作业
(当不允许运行未打标签的作业时,标签不能为空),在项目中如果想触发构建流水线,就必须在项目的.gitlab-ci.yml
文件中配置tags
选项指定标签名以在对应Runner
上运行。运行未打标签的作业
,这样所有的项目都可以在此Runner
上运行,触发时机可在对应项目的.gitlab-ci.yml
文件中配置。Runner
的作用描述,以便识别。受保护
选项。配置完毕后,点击创建Runner
,跳转到了注册
页面,显示了如下操作步骤,
切换到1Panel
- 容器
菜单,选择我们刚刚使用Docker compose
创建的gitlab-runner
容器,连接终端
,
依次执行如下操作:
开始注册Runner
,在终端执行gitlab-runner register
命令,
Enter the GitLab instance URL (for example, https://gitlab.com/):
输入Gitlab
的访问地址,填写你的虚拟机 内部 IP 加 Gitlab 服务的端口号(比如http://192.168.36.129:8888
),填写完毕后回车。
Enter the registration token:
把刚才创建Gitlab Runner
时注册页面生成的token
粘贴进来,然后回车。
Verifying runner...
这一步会验证上面输入的instance URL
和token
是否能够访问或连接,如果URL
或token
有误,会结束对话。如果输入了正确的内容,则会提示is valid runner=iPQAvdywz
,并生成一个Runner ID
,自动进入下一步。
Enter a name for the runner. This is stored only in the local config.toml file:
填写一个可供自己辨别的Runner
名称,这个名称用于在生成的config.toml
文件中标明配置块,日后可自行在config.toml
文件中增删Runner
。继续下一步。
Enter an executor: docker-windows, instance, ssh, virtualbox, docker-autoscaler, docker+machine, custom, docker, parallels, shell, kubernetes:
选择Runner
在哪里运行,请填写docker
,然后回车。
Enter the default Docker image (for example, ruby:2.7):
这里可根据个人需要填写该Runner
运行时默认使用的基础镜像,当有项目在此Runner
中运行时,如果.gitlab-ci.yml
中的步骤没有指定镜像,则会自动使用此镜像,.gitlab-ci
配置文件优先。我这里填写node:lts-alpine
。
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded! Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml"
出现该提示,则说明配置完成,Gitlab
和Gitlab Runner
已成功建立连接,并已将配置文件保存在了/etc/gitlab-runner/config.toml
文件中。
配置完成后,回到Gitlab
中,打开Runner
菜单,发现列表中刚刚创建的Runner
已经连接成功,状态应为在线
。大功告成,一个全局的Runner
已经配置完毕。
接下来我们就要在项目中配置.gitlab-ci.yml
文件了,这个文件记录了如何触发CI|CD
流水线和具体的构建步骤。
我这里已经创建了一个Vue-test
项目,接下来我将使用这个项目作为示例。
在编写.gitlab-ci
之前,我们应该先明白自己需要这个使用项目做些什么。比如这个Vue-test
项目,我需要它能够在我提交代码到main
分支后,自动开始进行npm run build
操作,并将产出的dist
目录下的文件,部署到我的服务器搭建的静态网站上。这就需要厘清以下几点:
该流水线需要哪些步骤?
build
: Vue
项目需要先npm install
然后进行npm run build
操作,所以需要一个build
步骤。deploy
: 我需要把它部署到静态网站目录中,所以还需要一个deploy
步骤。构建时需要依赖哪些镜像?
node:lts-alpine
: 在build
步骤中需要使用npm
指令进行操作,所以需要在带有node
环境的镜像中运行,这里我选择的是node:lts-alpine
镜像。lgatica/openssh-client
: 在deploy
步骤中,把文件推送到远程服务器目录,需要远程登录到服务器终端,要用到ssh
功能,所以需要一个带有ssh
功能的镜像中运行,这里我选择lgatica/openssh-client
镜像。需要定义哪些变量?
知道需要哪些东西后,我们开始进行配置CI/CD
,首先在该项目所在的群组左侧,展开设置
,打开CI/CD
菜单,展开Runner
模块,开启为该组启用共享Runner
,这样这个群组下面的所有项目,就都可以使用在全局或群组中创建的Runner
实例了。
然后展开变量
模块,我们需要添加刚才总结出来的几个变量,以供.gitlab-ci.yml
读取(变量可以单独在群组、项目中设置中定义,也可以在gitlab-ci.yml
文件中定义),这里我们把远程服务器IP
、远程服务器SSH登录密钥
等这些通用变量定义到群组中,该群组下面的所有项目都可以继承这些变量。点击添加变量,填写键
和值
,勾选隐藏变量
,,点击确定。
这里我的定义如下:
SSH_PRIVATE_KEY
:在服务器中 SSH 管理模块生成的SSH RSA
密钥对(也可以使用密码,参考下一段笔记使用密码而非密钥
)SSH_SERVER
:192.168.36.129
SSH_USER
: root
STATIC_SITE_PATH
:/opt/1panel/apps/openresty/openresty/www/sites
变量配置完毕,我们切换到Vue-test
项目中,同样展开左下角的设置
,打开CI/CD
菜单,展开Runner
模块,
可以看到,我们现在有一个可以使用的共享Runer
,这就是我们刚才所创建的全局Runner
,并通过群组设置了允许共享
,
然后展开变量
模块,可以看到该项目已经继承了在群组中的通用变量。
变量配置完成,我们现在正式开始编写.gitlab-ci.yaml
文件,可以在本地进行编写,然后把文件推送到仓库。也可以直接点击项目名称下方的配置CI/CD
按钮进行编写,或者点击左侧菜单栏的流水线编辑器
,然后开始配置流水线
。
填写以下内容(仅供参考):
stages:
- build
- deploy
cache:
paths:
- node_modules/
variables:
# 可在这里定义临时变量
# WEB_DIR为要推送到的服务器目录网站路径
WEB_DIR: www.dev.com/index
build:
stage: build
image: node:lts-alpine # 如果与Runner指定的镜像相同,则无须在步骤中指定镜像。
script:
- npm install --registry https://registry.npm.taobao.org
- npm run build
artifacts:
paths:
# 这里定义产物的目录,可供下一个步骤使用
# 产物可以在菜单 构建 - 产物 中找到
- dist
expire_in: 24 hours # 这里定义产物的自定清除时间
only:
- main
deploy:
stage: deploy
image: lgatica/openssh-client
script:
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan $SSH_SERVER >> ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
- scp -r dist/* $SSH_USER@$SSH_SERVER:$STATIC_SITE_PATH/$WEB_DIR/
- ssh $SSH_USER@$SSH_SERVER "service nginx restart"
only:
- main
配置完毕,点击提交更改。可以看到,流水线已开始运行。
点击前面的小月牙图标,可以查看构建详情。
看到这两个勾,说明你已经构建并部署成功。
浏览器打开你的网站,发现内容已经改变,我们已经成功搭建了一套持续集成/部署的代码托管系统。
流水线运行后,回到1Panel
面板,容器
菜单下,会发现多了两个以Runner
为前缀名的容器,这是流水线在构建时启动的临时容器,它会自动拉取registry.gitlab.com/gitlab-org/gitlab-runner/gitlab-runner-helper
和registry.gitlab.com/gitlab-org/cluster-integration/auto-build-image
两个镜像。
流水线中用到的自定义镜像,比如node:lts-alpine
、lgatica/openssh-client
等,都会被自动拉取,并存储在镜像库中。
我们前面在定义通用变量SSH_USER
时使用了root
用户,这是服务器的超级管理员账号,我们在实际的团队工作中,一般不会使用root
用户来构建项目,因为它拥有对所有文件的管理权限,我们必须创建一个具有更小的、局部操作权限的账号,以供流水线构建使用。
比如以上的构建示例中,其实只需要对服务器的这个静态站点目录STATIC_SITE_PATH
(/opt/1panel/apps/openresty/openresty/www/sites
)进行读写操作,而其他的权限一概不需要,我们可以创建一个只对此目录有操作权限的用户,来管理静态站点。
在1Panel
面板左侧菜单栏,展开主机
,连接终端
,依次执行以下命令:
sudo useradd sites_ctrl
创建名为sites_ctrl
的新用户
sudo passwd sites_ctrl
为sites_ctrl
用户设置密码
sudo chown -R sites_ctrl:sites_ctrl /opt/1panel/apps/openresty/openresty/www/sites
赋予sites_ctrl
用户静态站点目录及其子目录的所有权
sudo chmod -R 700 /opt/1panel/apps/openresty/openresty/www/sites
修改静态站点目录及子目录的操作权限,700
表示目录所有者拥有读、写、执行(rwx
)的所有权限
sudo su - sites_ctrl
登录sites_ctrl
用户
ssh-keygen -t rsa
生成SSH密钥
,保存位置默认就好
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
将公钥复制到sites_ctrl
用户的~/.ssh/authorized_keys
文件中,以允许该用户使用SSH密钥
进行登录
cat ~/.ssh/id_rsa
打印rsa
私钥内容,复制下来备用
sudo systemctl restart sshd
重启 SSH 服务以应用更改
以上步骤操作完毕后,需要将前面Gitlab
中配置的SSH_USER
变量值改为sites_ctrl
,SSH_PRIVATE_KEY
值改为上面打印的rsa
私钥。
后续我们触发流水线时,就会自动使用仅有静态站点目录操作权限的sites_ctrl
用户进行推送、部署操作了。
有的时候小项目可能是不那么注重安全,在这样的场景下,我们只追求简便快捷,生成密钥对的过程对于有些人来说是比较繁琐的,我们可以直接使用sshpass
实现自动化交互式密码登录。
首先我们同样把服务器的用户密码配置为变量,变量名可以自定义,我这里命名为SSH_PWD
,然后重新修改.gitlab-ci.yml
的deploy
步骤如下:
deploy:
stage: deploy
image: ringcentral/sshpass #sshpass镜像
script:
# 关闭主机密钥严格检查,清空目标文件夹内容
- sshpass -p $SSH_PWD ssh -o "StrictHostKeyChecking=no" $SSH_USER@$SSH_SERVER "rm -rf $STATIC_SITE_PATH/$WEB_DIR/*"
# 把产物拷贝到目标文件夹
- sshpass -p $SSH_PWD scp -r dist/* $SSH_USER@$SSH_SERVER:$STATIC_SITE_PATH/$WEB_DIR/
only:
- main
除了使用Gitlab
紧密绑定的Runner
服务完成CI/CD
之外,我们其实还有其他选择,Jenkins
就是一个可以实现任意平台(比如Github
、Gitea
、Gitee
、Gitlab
等)持续集成/部署功能的自动构建系统,并将服务独立于其之外。
1Panel
中已经内置了Jenkins
的Docker compose
安装脚本,我们可以在应用商店找到它,进行一键安装。
安装时可填写任意空闲端口,并勾选端口外部访问
。
除了使用应用商店
一键安装外,你也可以自行编写Docker compose
模板进行安装,以下是1Panel
提供的模板,你可以直接粘贴到容器
- 创建编排
中进行安装(其中的变量请按需修改)。
networks:
1panel-network:
external: true
services:
jenkins:
container_name: ${CONTAINER_NAME}
deploy:
resources:
limits:
cpus: ${CPUS}
memory: ${MEMORY_LIMIT}
image: jenkins/jenkins:2.421
labels:
createdBy: Apps
networks:
- 1panel-network
ports:
- ${HOST_IP}:${PANEL_APP_PORT_HTTP}:8080
privileged: true
restart: always
user: root
volumes:
- ./jenkins:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- ${DOCKER_BINARY}:${DOCKER_BINARY}
version: "3"
安装完毕之后,直接在已安装应用
中点击服务端口
,即可自动跳转到Jenkins
的 Web 管理页面
首次登录时,需要先至容器中获取初始密码,以解锁Jenkins
,在Jenkins
所在的容器中连接终端,输入cat /var/jenkins_home/secrets/initialAdminPassword
。
解锁之后,开始进行初始化配置,第一步请选择安装推荐的插件
,
安装完毕之后,创建管理员账号,创建好之后,初始化配置已经完成,可以进入基础配置了。
正如上面的Gitlab CI/CD
笔记一样,在计划配置一个自动构建的流水线之前,我们需要知道自己要做什么。
需求和上面的Gitlab CI/CD
基本一致,我在Gitlab
已经创建了一个vue-jenkins
项目,需要它能够在我提交代码到main
分支后,自动开始进行npm run build
操作,并将产出的dist
目录下的文件,部署到服务器搭建的静态网站上。
基于该需求,我们可知:
该流水线需要哪些步骤?
build
: Vue
项目需要先npm install
然后进行npm run build
操作,所以需要一个build
步骤。deploy
: 我需要把它部署到静态网站目录中,所以还需要一个deploy
步骤。构建时需要依赖哪些插件?
node.js
: 在build
步骤中需要使用npm
指令进行操作,所以需要在带有node
环境的镜像中运行。Publish Over SSH
: 在deploy
步骤中,把文件推送到远程服务器目录,需要远程登录到服务器终端,所以需要用到ssh
功能。Gitlab
: 由于我们的项目源代码托管在Gitlab
仓库中,所以需要把Jenkins
和其连接起来,以使其可以拉取代码并正确反应构建进度到Gitlab
的流水线状态中。需要知道哪些信息?
知道需要哪些东西后,我们接下来就为该项目做一些配置。
选择左侧菜单栏的系统设置
,然后打开插件管理
,切换到Avilable plugins
搜索nodejs
,勾选搜索结果前面的复选框,点击安装。
安装完毕后,回到系统管理
,打开全局工具配置
,滚动到页面底部,点击新增NodeJS
。
填写别名
以及版本等信息,可以在此时安装一些全局的依赖模块,比如yarn
。填完之后点击保存。
同样在插件管理
中,搜索Publish Over SSH
并安装。
安装完毕之后,打开系统设置
,滚动到页面底部,在Publish Over SSH
模块中,点击新增SSH server
,填写任意名称以及远程服务器IP
、远程服务器账号、要推送到的服务器目录根路径。
基础信息配置完毕后,点击下面的高级
,并勾选Use password authentication, or use a different key
,在Passphrase / Password
项输入登录密码(也可以置空密码输入框,把SSH密钥
贴入下面的Key
输入框中)。
所有内容填写完毕后,滚动到底部,点击右下角的Test Configuration
按钮,会自动检测所填的内容是否正确,以及是否能够正常连接,左侧出现Success
,说明可以可以保存了。如果报错,请根据错误提示进行修改。
同样在插件管理
中,搜索Gitlab
并安装。
安装完毕之后,打开系统设置
,找到Gitlab
模块(在页面中间位置),填写任意Connection name
,以及Gitlab
地址GitLab host URL
,然后点击Credentials
下面的添加按钮,新增Jenkins凭据
。
凭据类型选择Gitlab Token
,Domain
和范围
保持默认,ID
和描述
任意填便于自己识别的内容,下面的API token
需要在Gitlab
中获取,见下一段落。
进入Gitlab
,点击对应项目或群组进行设置,打开访问令牌
页面,并添加访问令牌
,填写任意便于自己识别的令牌名称
。到期时间
可不填,默认为一年,最长不超过两年。角色
请使用Maintainer
,范围
选择api
,否则在构建或反射状态时将发生401
权限错误。填写完毕后,点击创建访问令牌
,回到列表页,复制访问令牌,粘贴访问令牌到上一段所述Jenkins 凭据
创建中的API token
输入框中,凭据内容填写完毕后,点击添加
,该操作会在Gitlab
中生成一个bot
用户(默认访问级别为普通
,可使用管理员在用户管理中进行修改)。
添加好之后,Credentials
下拉框选中刚才添加的凭据,然后点击右下角Test Connection
,出现Success
之后,表示连接成功,可以进行保存了。如果报错,请根据错误提示进行修改。
回到Jenkins
的Dashboard
首页,点击Create a job
,填写任务名称,点击创建一个自由风格的软件项目
,然后进入任务配置页。
可以根据自己的需求配置,比如勾选丢弃旧的构建
。
勾选Git
,填写项目地址Repository URL
,填写之后会报凭据错误无法连接仓库,别慌,点击下面的Credentials
添加按钮,类型选择Usmame with password
,输入Gitlab
的密码和用户名,其他不用管,点击保存。然后选择钢才添加的账号密码凭据,错误警告就会消失了(如果仍然报错,请检查账号密码是否正确)。然后再Branches to build
指定一个你要在Jenkins
进行源码管理的分支或标签等名称,比如*/main
或refs/heads/main
、refs/tags/v1.0.0
,点击应用。
勾选 Build when a change is pushed to GitLab
(请复制后面的Gitlab webhook URL
地址,这个在后面需要使用),并勾选可触发该构建任务的事件,比如Push
或者Merge Request
,然后展开高级
。
展开高级
按钮后,往下拉找到Secret token
,点击右下角Genarate
按钮生成一个令牌,点击应用。
打开Gitlab
页面,使用root
账户进入管理中心
,打开设置
- 网络
,展开出站请求
,勾选允许来自 webhooks 和集成对本地网络的请求
(Gitlab 10.6
以上版本,默认不允许向本地网络发送webhook
请求,故须手动勾选此选项)。并取消勾选强制执行 DNS 重新绑定攻击保护
。设置完毕后,点击保存。
Gitlab
进入对应项目(如vue-jenkins
)打开Webhook
设置,点击添加新的 webhook
按钮,进入配置页面。
在Webhook
配置页面,URL
填写刚才我们在Jenkins 构建触发器
第一步中复制的Gitlab webhook URL
地址。Secret 令牌
贴入刚才我们在Jenkins 构建触发器
第二步中生成的Secret token
令牌。然后勾选需要触发构建的事件,一般和Jenkins 构建触发器
第一步中所勾选的触发器一致即可。最后取消勾选底部的SSL验证
,点击添加webhook
按钮保存。
添加webhook
后,可点击列表右侧测试
按钮,指定一个事件,测试是否能够正常触发Jenkins
流水线构建。
测试成功,顶部会有Hook executed successfully: HTTP 200
提示,此时打开Jenkins
,发现构建任务已经在运行了。如果测试时有报错,请根据提示内容检查URL
和Token
是否有误, 点击编辑
按钮滚动到页面底部,可查看测试结果的详细内容。
完成上一步之后,Gitlab
和Jenkins
已经成功建立双向连接。此时,需要继续对Jenkins
剩余的内容进行配置,打开刚才的Job
配置,继续配置构建环境
。
勾选在构建中添加时间戳前缀
,并勾选Provide Node & npm bin/ folder to PATH
为该项目选择前面已配置的Node
版本,点击应用。
点击增加构建步骤
,选择执行Shell
(也可选择Execute NodeJS script
),在命令
中填写以下代码,然后点击应用:
npm install
npm run build
点击增加构建后操作步骤
,选择Send build artifacts over SSH
。
SSH Publishers Name
:
选择刚才我们设置好的ssh server
Transfer Set Source files
:
设置为编译后的产物路径dist/**
Remove prefix
:
同上,设置为dist
,以删除其前缀。
Remote directory
:
要推送到的服务器目录网站路径,此路径相对于前面在Publish Over SSH
设置的要推送到的服务器目录根路径。比如这里我这里填写www.dev.com/index
。
Exec command
:
发布后需要执行的命令,这里我们暂时不填。
Clean remote
:
展开高级,勾选此按钮,用于在推送时先清空此目录内容。
根据以上的步骤操作之后,我们已经完整创建了一个构建任务。现在可以在Gitlab
中推送或合并代码,看看是否能够触发流水线了。
我们修改一下项目代码,然后提交推送到指定触发构建的分支,我这里直接在前面定义的是main
分支,所以就直接推送到main
。
推送成功,进入CI/CD
菜单,可以看到,一个名为jenkins
的流水线,已经开始构建。
点进去,会自动跳转到jenkins
的构建任务详情页面,点击左侧菜单栏的控制台输出
,我们可以看到更详细的构建日志。最后一句会打印Finished: SUCCESS
,Gitlab
的流水线
页面也会显示已通过
。如果构建失败,请在日志中检查错误信息并排查错误。
接下来,我们打开我们部署的目标站点www.dev.com
,可以看到,修改后的代码已成功部署到网站上了。