gitlab:从CentOS 7.9迁移至Ubuntu 24.04.2(版本17.2.2-ee)
摘要: GitLab 18 版本已不再支持 CentOS 7.9,因此本次将其迁移至 Ubuntu 24.04.2 系统。这相当于对 GitLab 相关环境进行了全新部署,涉及 Ubuntu 系统安装、GitLab 指定版本安装、数据迁移、备份设置、内网穿透配置、杀毒软件(ClamAV)安装以及 GitLab 升级等一系列操作。
过程中耗时最长的是 GitLab 数据迁移中的 PostgreSQL 问题,以及备份过程中 rsync 脚本的编写。升级操作虽然也耗时,但步骤相对简单。
注:迁移过程中务必提前规划好 Ubuntu 系统的用户权限方案 —— 是使用 root 用户还是其他账号。本次迁移在权限配置上耗费了大量时间,实属不必要的麻烦。
相关文章
- CentOS7上安装gitlab
- gitlab使用163邮箱向用户发送邮件
- gitlab备份库局域网中远程备份至另一台windows电脑
- gitlab迁移及版本升级
- gitlab:不能中文搜索
- gitlab:从CentOS 7.9迁移至Ubuntu 24.04.2(版本17.2.2-ee)
一、 Ubuntu 系统安装
可参考此文 Linux:Ubuntu server 24.02 上搭建 ollama + dify“安装Ubuntu”一章。尽管本次使用的是ESXi 7版本的虚拟机,但安装过程与之基本一致,均采用默认设置,一路“下一步”即可完成。这里对一些常见配置进行记录。
1.1 系统更新及root密码配置
驱动更新
# 1. 更新软件包列表:
sudo apt update# 2. 升级已安装的软件包:
sudo apt upgrade -y# 3. 更新驱动程序:
sudo apt install ubuntu-drivers-common
sudo ubuntu-drivers autoinstall
通过创建的普通用户界面下输入命令,然后按提示两次输入密码即可。
sudo passwd root
1.2 SSH配置
自己系统安装时默认已开启 SSH,重新配置不会受到影响。
查看是否安装了SSH服务
cikkod@gitlab:/var/opt/gitlab/backups$ ps -ef |grep ssh
root 18951 1 0 Sep03 ? 00:00:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
root 634339 18951 0 Sep04 ? 00:00:00 sshd: cikkod [priv]
cikkod 634439 634339 0 Sep04 ? 00:04:01 sshd: cikkod@pts/2
cikkod 732075 634440 0 Sep04 pts/2 00:00:17 ssh cikkod@gitlab
root 732076 18951 0 Sep04 ? 00:00:00 sshd: cikkod [priv]
cikkod 732633 732076 0 Sep04 ? 00:00:14 sshd: cikkod@pts/0
cikkod 2146490 1305862 0 19:52 pts/0 00:00:00 grep --color=auto ssh
没有安装的话,执行下面语句
sudo apt-get update #先更新下资源列表
sudo apt-get install openssh-server #安装openssh-server
sudo ps -ef | grep ssh #查看是否安装成功
sudo systemctl restart sshd #重新启动SSH服务
进入ssh配置文件
cikkod@gitlab:/var/opt/gitlab/backups$ sudo vim /etc/ssh/sshd_config
[sudo] password for cikkod:
PermitRootLogin 是一个用于配置 SSH 服务器的选项。这个选项决定了是否允许 root 用户通过 SSH 直接登录到服务器。通常情况下,为了提高安全性,最好禁止 root 用户通过 SSH 直接登录,而是使用一个普通用户登录后再通过 su 或者 sudo 切换到 root 用户来执行需要特权的操作。这样可以降低系统受到攻击的风险。
常见的 PermitRootLogin 选项取值包括:
- yes:允许 root 用户通过 SSH 直接登录。
- no:禁止 root 用户通过 SSH 直接登录。
- without-password:允许 root 用户通过 SSH 密钥登录,但不允许使用密码登录。
按i进入编辑模式,找到#PermitRootLogin prohibit-password,默认是注释掉的。
把 PermitRootLogin prohibit-password 改为 PermitRootLogin yes,注意PermitRootLogin prohibit-password被注释掉了,要去掉注释。如果没有找到PermitRootLogin without-password,直接文件末尾添加PermitRootLogin yes即可。然后按esc,输入:wq保存并退出。
重启sshd服务
sudo systemctl restart ssh
1.3 网络IP配置
查看当前网络接口信息
ip addr show
对于Ubuntu 17.10及更高版本(包括20.04/22.04/24.04等主流LTS版本),网络配置的默认工具是Netplan,配置文件统一存放在/etc/netplan/目录下,文件名以.yaml结尾(如00-installer-config.yaml、50-cloud-init.yaml等)。
cikkod@gitlab:/var/opt/gitlab/backups$ ls -l /etc/netplan/
total 8
-rw------- 1 root root 231 Sep 4 10:22 50-cloud-init.yaml
-rw-r--r-- 1 root root 231 Sep 4 10:18 50-cloud-init.yaml.bak
cikkod@gitlab:/var/opt/gitlab/backups$
修改前务必备份,以便出错时可快速恢复。
sudo cp /etc/netplan/50-cloud-init.yaml /etc/netplan/50-cloud-init.yaml.bak
使用文本编辑器打开网络配置文件,使用nano保存退出通过ctrl+o ,再按enter确认文件名,再按ctrl+x退出。vim保存退出通过在英文输入发法下,退出编辑模式后 :wq
sudo nano /etc/netplan/50-cloud-init.yaml
或
sudo vim /etc/netplan/50-cloud-init.yaml
以下为我自己的配置
network:version: 2ethernets:ens160:addresses:- "172.16.1.166/24"nameservers:addresses:- 61.139.2.69search: []routes:- to: "default"via: "172.16.1.1"
配置层级 | 字段/键 | 值/示例 | 含义/作用 |
---|---|---|---|
network | version | 2 | 声明 Netplan 配置版本(当前主流版本必须为 2 ,支持多接口、桥接等高级功能)。 |
ethernets | ens160 | 定义以太网接口的配置块(ens160 是实际网卡名称,需与 ip link 查看的名称一致)。 | |
ethernets: ens160 | addresses | ["172.16.1.166/24"] | 为接口配置静态 IP 地址(CIDR 格式)。 - IP:172.16.1.166 - 子网掩码:255.255.255.0 (/24 表示前 24 位为网络位)。 |
nameservers | addresses: [61.139.2.69] search: [] | 配置 DNS 服务器(用于域名解析)。 - addresses :DNS 服务器 IP 列表(示例为中国电信公共 DNS)。 - search :搜索域列表(空表示不使用额外域名后缀)。 | |
routes | - to: "default" via: "172.16.1.1" | 配置静态路由规则。 - to: "default" :目标网络为 0.0.0.0/0 (所有非本地子网的流量)。 - via: "172.16.1.1" :流量通过网关 172.16.1.1 转发(通常为本地路由器)。 |
检查语法是否正确
sudo netplan generate
如果没有报错,应用配置:
sudo netplan apply
重新启动网络服务以使更改生效:
sudo systemctl restart networking
重启后,建议检查网络服务是否成功启动,避免因配置错误导致服务无法运行:
# 查看 networking 服务的状态(是否 active)
sudo systemctl status networking# 查看网络接口是否正常(如 ens160)
ip addr show ens160# 查看路由表是否生效
ip route show
1.4 时间配置
# 设置时区为上海(北京时间)
sudo timedatectl set-timezone Asia/Shanghai# 启用自动时间同步
sudo timedatectl set-ntp true# 检查时间同步状态
timedatectl# 启用自动时间同步
sudo timedatectl set-ntp true# 检查时间同步状态
timedatectl
cikkod@gitlab:/var/opt/gitlab/backups$ date
Fri Sep 5 03:43:09 AM UTC 2025
cikkod@gitlab:/var/opt/gitlab/backups$ sudo timedatectl set-timezone Asia/Shanghai
cikkod@gitlab:/var/opt/gitlab/backups$ sudo timedatectl set-ntp true
cikkod@gitlab:/var/opt/gitlab/backups$ timedatectlLocal time: Fri 2025-09-05 11:43:28 CSTUniversal time: Fri 2025-09-05 03:43:28 UTCRTC time: Fri 2025-09-05 03:43:28Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yesNTP service: activeRTC in local TZ: no
cikkod@gitlab:/var/opt/gitlab/backups$ date
Fri Sep 5 11:43:50 AM CST 2025
cikkod@gitlab:/var/opt/gitlab/backups$ timedatectl statusLocal time: Fri 2025-09-05 11:44:05 CSTUniversal time: Fri 2025-09-05 03:44:05 UTCRTC time: Fri 2025-09-05 03:44:05Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yesNTP service: activeRTC in local TZ: no
cikkod@gitlab:/
配置自定义NTP服务器(可选)
# 编辑时间同步配置文件
sudo nano /etc/systemd/timesyncd.conf# 添加以下内容(使用中国NTP服务器)
[Time]
NTP=ntp.aliyun.com ntp.ntsc.ac.cn
FallbackNTP=ntp.ubuntu.com# 保存后重启服务
sudo systemctl restart systemd-timesyncd# 测试NTP服务器连接
ping ntp.aliyun.com# 测试NTP端口
nc -zv ntp.aliyun.com 123# 允许NTP流量(UDP端口123)
sudo ufw allow 123/udp
详细时间设置操作可以参考此链接"Ubuntu 时间不对,我如何设置为北京…"点击查看元宝的回答
1.5 休眠配置
查看休眠模式的情况,如果sleep状态是loaded,也就是处于自动休眠开启状态
systemctl status sleep.target
关闭系统的自动休眠开关
sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
如果你想要恢复自动休眠功能,可以使用以下命令
sudo systemctl unmask sleep.target suspend.target hibernate.target hybrid-sleep.target
cikkod@gitlab:/var/opt/gitlab/backups$ systemctl status sleep.target
○ sleep.target - SleepLoaded: loaded (/usr/lib/systemd/system/sleep.target; static)Active: inactive (dead)Docs: man:systemd.special(7)
cikkod@gitlab:/var/opt/gitlab/backups$ systemctl status sleep.target
○ sleep.target - SleepLoaded: loaded (/usr/lib/systemd/system/sleep.target; static)Active: inactive (dead)Docs: man:systemd.special(7)
cikkod@gitlab:/var/opt/gitlab/backups$ sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
[sudo] password for cikkod:
Created symlink /etc/systemd/system/sleep.target → /dev/null.
Created symlink /etc/systemd/system/suspend.target → /dev/null.
Created symlink /etc/systemd/system/hibernate.target → /dev/null.
Created symlink /etc/systemd/system/hybrid-sleep.target → /dev/null.
cikkod@gitlab:/var/opt/gitlab/backups$ systemctl status sleep.target
○ sleep.targetLoaded: masked (Reason: Unit sleep.target is masked.)Active: inactive (dead)
cikkod@gitlab:/var/opt/gitlab/backups$
详细禁止休眠操作可以参考此链接 "ubuntu如何禁止休眠"点击查看元宝的回答
1.6 磁盘分配
查看磁盘使用情况
root@gitlab:~# df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 1.6G 1.3M 1.6G 1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv 98G 7.0G 86G 8% /
tmpfs 7.9G 0 7.9G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda2 2.0G 100M 1.7G 6% /boot
tmpfs 1.6G 12K 1.6G 1% /run/user/1000
root@gitlab:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 1.2T 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 2G 0 part /boot
└─sda3 8:3 0 1.2T 0 part└─ubuntu--vg-ubuntu--lv 252:0 0 100G 0 lvm /
sr0 11:0 1 1024M 0 rom
root@gitlab:~#
扩展 LVM 逻辑卷
root@gitlab:~# sudo vgdisplay ubuntu-vg--- Volume group ---VG Name ubuntu-vgSystem IDFormat lvm2Metadata Areas 1Metadata Sequence No 2VG Access read/writeVG Status resizableMAX LV 0Cur LV 1Open LV 1Max PV 0Cur PV 1Act PV 1VG Size <1.20 TiBPE Size 4.00 MiBTotal PE 314059Alloc PE / Size 25600 / 100.00 GiBFree PE / Size 288459 / 1.10 TiBVG UUID hLZ7KV-t2QH-ZIOs-bQ2s-OGHt-eelL-ZkcGtWroot@gitlab:~# sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lvSize of logical volume ubuntu-vg/ubuntu-lv changed from 100.00 GiB (25600 extents) to <1.20 TiB (314059 extents).Logical volume ubuntu-vg/ubuntu-lv successfully resized.
root@gitlab:~# sudo resize2fs /dev/ubuntu-vg/ubuntu-lv
resize2fs 1.47.0 (5-Feb-2023)
Filesystem at /dev/ubuntu-vg/ubuntu-lv is mounted on /; on-line resizing required
old_desc_blocks = 13, new_desc_blocks = 154
The filesystem on /dev/ubuntu-vg/ubuntu-lv is now 321596416 (4k) blocks long.root@gitlab:~# sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv
resize2fs 1.47.0 (5-Feb-2023)
The filesystem is already 321596416 (4k) blocks long. Nothing to do!root@gitlab:~# df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 1.6G 1.3M 1.6G 1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv 1.2T 7.0G 1.2T 1% /
tmpfs 7.9G 0 7.9G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda2 2.0G 100M 1.7G 6% /boot
tmpfs 1.6G 12K 1.6G 1% /run/user/1000
root@gitlab:~#
详细磁盘分配操作可以参考此链接"为啥我分配1.2T的磁盘,显示如图了r…"点击查看元宝的回答
二、GitLab 指定版本安装
更新软件包和安装常用的系统工具和依赖包
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl openssh-server ca-certificates tzdata perl
通过命令行查看版本,或者通过此链接下载安装包 Gitlab Packages,个人采用命令行的方式
apt list -a gitlab-ee
如果没有数据的话,可以自行添加 GitLab 企业版(GitLab EE)官方 APT 软件源。详细添加gitlab官方源操作可以参考此链接在 Debian/Ubuntu 系统上自动添加 GitLab 企业版(GitLab EE)官方 APT 软件源
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash
安装指定版本的gitlab-ee,这里需要注意一个关于“EXTERNAL_URL”设置的问题,这个指的是在Gitlab安装完成后,通过在浏览器输入的访问地址。在Ubuntu 24.04.2上如何安装指定版本gitlab-ee…"点击查看元宝的回答
注意:为了避免不必要的麻烦,此值一定不要写成以前服务器访问地址,比如可以设置为最新IP地址,后面在调整。
可通过以下命令,查看“EXTERNAL_URL”配置
[root@localhost ~]# sudo cat /etc/gitlab/gitlab.rb | grep -E "^external_url"external_url 'http://172.16.1.166'
[root@localhost ~]#
sudo EXTERNAL_URL="http://172.16.1.168" apt install gitlab-ee=17.2.2-ee.0
完成安装后,在浏览中输入地址,默认为root账号,其密码在以下位置。注意:它只在首次安装后存在,并且有一个有效期(默认 24 小时)。在数据恢复成功后,也会重置为之前的密码。
cat /etc/gitlab/initial_root_password
GitLab 服务默认在安装后通常会设置为开机自启动。
# 检查服务状态
sudo systemctl status gitlab-runsvdir.service# 启用开机自启动
sudo systemctl enable gitlab-runsvdir.service# 禁用开机自启动
sudo systemctl disable gitlab-runsvdir.service
cikkod@gitlab:~$ sudo systemctl status gitlab-runsvdir.service
[sudo] password for cikkod:
● gitlab-runsvdir.service - GitLab Runit supervision processLoaded: loaded (/usr/lib/systemd/system/gitlab-runsvdir.service; enabled; preset: enabled)Active: active (running) since Mon 2025-09-15 17:19:24 CST; 15h agoMain PID: 1584 (runsvdir)Tasks: 528 (limit: 4915)Memory: 13.8G (peak: 13.8G swap: 1.0G swap peak: 3.2G)CPU: 8h 17min 39.301sCGroup: /gitlab.slice/gitlab-runsvdir.service├─ 1584 runsvdir -P /opt/gitlab/service "log: ...........................................................................................................................................>├─ 1595 runsv redis-exporter├─ 1596 runsv puma├─ 1597 runsv redis├─ 1598 runsv gitlab-kas├─ 1599 runsv gitlab-workhorse├─ 1600 runsv alertmanager├─ 1601 runsv node-exporter├─ 1602 runsv prometheus├─ 1603 runsv postgres-exporter├─ 1604 runsv gitlab-exporter├─ 1605 runsv nginx├─ 1606 runsv postgresql├─ 1607 runsv logrotate├─ 1608 runsv gitaly├─ 1609 runsv sidekiq├─ 1610 svlogd -tt /var/log/gitlab/logrotate
lines 1-25
三、数据迁移
对原始服务器gitlab数据进行备份,备份的文件主要有2份:1.项目文件备份 xxxx_17.2.2-ee_gitlab_backup.tar,2.配置文件gitlab-secrets.json
和gitlab.rb
,其中,gitlab-secrets.json
为密钥文件不能直接替换,对于gitlab.rb
也不要直接替换,选择按需重新配置。
关闭gitlab
gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq
gitlab-ctl stop nginx
对项目文件备份,配置文件只能手动备份
gitlab-rake gitlab:backup:create
复制 GitLab 备份文件到当前服务器
root@gitlab:/etc/gitlab# sudo scp root@172.16.1.166:/var/opt/gitlab/backups/1756897995_2025_09_03_17.2.2-ee_gitlab_backup.tar /var/opt/gitlab/backups/
The authenticity of host '172.16.1.166 (172.16.1.166)' can't be established.
ED25519 key fingerprint is SHA256:DLAeM+sviXVObI2P9NP2yoKY3cC/YgIbkJMqH7OtumM.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? y
Please type 'yes', 'no' or the fingerprint: tes
Warning: Permanently added '172.16.1.166' (ED25519) to the list of known hosts.
root@172.16.1.166's password:
1756897995_2025_09_03_17.2.2-ee_gitlab_backup.tar 100% 18GB 66.2MB/s 04:40
root@gitlab:/etc/gitlab# cd ../var/opt/gitlab
bash: cd: ../var/opt/gitlab: No such file or directory
root@gitlab:/etc/gitlab# cd ..
root@gitlab:/etc# cd ..
root@gitlab:/# cd /var/opt/gitlab
root@gitlab:/var/opt/gitlab# ls
alertmanager gitaly gitlab-exporter gitlab-shell nginx postgresql redis
backups git-data gitlab-kas gitlab-workhorse node-exporter prometheus trusted-certs-directory-hash
bootstrapped gitlab-ci gitlab-rails logrotate postgres-exporter public_attributes.json
root@gitlab:/var/opt/gitlab# cd backups
root@gitlab:/var/opt/gitlab/backups# ls
1756897995_2025_09_03_17.2.2-ee_gitlab_backup.tar
恢复备份的问题非常多主要集中以下几种:
种类 | 问题 |
---|---|
控件启动 | 在新的服务器恢复备份过程,并不是需要把gitlab全部关闭,而是要打开 PostgreSQL,Gitaly ,Redis |
权限 | 个人采用非root账号,在这个过程中权限问题问题非常多,核心权限就是把登录账号加入到git组中;还有就是不要人物权限给到的越大越好,gitlab会自动判断,比如需要750给到777后,gitlab会认为不安全,从而直接拒绝执行 |
将 cikkod 用户加入 git 组
# 将 cikkod 用户加入 git 组
sudo usermod -aG git cikkod# 修改备份目录权限,允许 git 组读取
sudo chmod 750 /var/opt/gitlab/backups
sudo chgrp git /var/opt/gitlab/backups# 确保现有备份文件的组也是 git
sudo chgrp -R git /var/opt/gitlab/backups/
验证用户所属组及权限
cikkod@gitlab:~$ whoami
cikkod
cikkod@gitlab:~$ sudo -v && echo "有 sudo 权限" || echo "无 sudo 权限"
有 sudo 权限
cikkod@gitlab:~$ groups
cikkod adm cdrom sudo dip plugdev lxd git
cikkod@gitlab:~$ ls -ld /var/opt/gitlab/backups/
drwxr-x--- 2 git git 4096 Sep 15 23:31 /var/opt/gitlab/backups/
cikkod@gitlab:~$
恢复备份
root@gitlab:/var/opt/gitlab/backups# sudo gitlab-backup restore BACKUP=1756897995_2025_09_03_17.2.2-ee
2025-09-03 12:18:25 UTC -- Unpacking backup ...
2025-09-03 12:21:01 UTC -- Unpacking backup ... done
2025-09-03 12:21:01 UTC -- Restoring database ...
2025-09-03 12:21:01 UTC -- Be sure to stop Puma, Sidekiq, and any other process that
connects to the database before proceeding. For Omnibus
installs, see the following link for more information:
http://172.16.1.168/help/raketasks/backup_restore.html#restore-for-omnibus-gitlab-installationsBefore restoring the database, we will remove all existing
tables to avoid future upgrade problems. Be aware that if you have
custom tables in the GitLab database these tables and all data will be
removed.Do you want to continue (yes/no)?
恢复完成后,重启服务并验证
sudo gitlab-ctl restart
sudo gitlab-ctl status
如果可以正常启动就可以开始修改配置,主要有以下几步:
1.将原有的gitlab重新配置一个临时IP地址,及访问地址,这样在后去需要的时候还可以访问旧服务器
2.修改新服务的IP地址
3.配置新服务的gitlab文件,主要为gitlab.rb
文件
# 重新加载配置(关键步骤!)
sudo gitlab-ctl reconfigure# 启动所有服务
sudo gitlab-ctl start# 检查状态
sudo gitlab-ctl status
中途遇到耗时最长的PostgreSQL问题
root@gitlab:/var/opt/gitlab/backups# sudo gitlab-psql -d template1 <<EOF
ALTER ROLE gitlab SUPERUSER;
ALTER EXTENSION pg_trgm OWNER TO gitlab;
ALTER EXTENSION btree_gist OWNER TO gitlab;
ALTER ROLE gitlab NOSUPERUSER;
COMMIT;
EOF
ALTER ROLE
ERROR: syntax error at or near "OWNER"
LINE 1: ALTER EXTENSION pg_trgm OWNER TO gitlab;^
ERROR: syntax error at or near "OWNER"
LINE 1: ALTER EXTENSION btree_gist OWNER TO gitlab;^
ALTER ROLE
WARNING: there is no transaction in progress
COMMIT
root@gitlab:/var/opt/gitlab/backups# sudo gitlab-psql -d template1 <<EOF
UPDATE pg_extension SET extowner = (SELECT oid FROM pg_roles WHERE rolname = 'gitlab')
WHERE extname IN ('pg_trgm', 'btree_gist');
EOF
UPDATE 0
root@gitlab:/var/opt/gitlab/backups# sudo gitlab-psql -d gitlabhq_production <<EOF
UPDATE pg_extension SET extowner = (SELECT oid FROM pg_roles WHERE rolname = 'gitlab')
WHERE extname IN ('pg_trgm', 'btree_gist');
EOF
UPDATE 2
root@gitlab:/var/opt/gitlab/backups# sudo gitlab-psql -d gitlabhq_production -c "SELECT e.extname, r.rolname AS owner FROM pg_extension e JOIN pg_roles r ON e.extowner = r.oid"extname | owner
------------+-------------plpgsql | gitlab-psqlbtree_gist | gitlabpg_trgm | gitlab
(3 rows)root@gitlab:/var/opt/gitlab/backups#
四、备份设置
备份总共分为2步,第一步为定时对gitlab文件进行备份,第二步为将备份文件远程传输到另一台设备,具体操作参见 gitlab备份库局域网中远程备份至另一台windows电脑,此处仅做脚本问题完善
4.1 GitLab 本地备份
虽然 gitlab-rake gitlab:backup:create 可以直接运行,但为了可维护性、日志记录、错误检测,建议封装成脚本。
脚本名称:/home/synch_backup_home/run_gitlab_backup.sh
#!/bin/bash# =============================================
# GitLab 本地全量备份脚本
# 功能:创建备份,inotify 会自动同步
# 作者:cikkod
# 时间:2025-09-04
# =============================================# --- 配置 ---
BACKUP_LOG="/home/synch_backup_home/gitlab_backup.log"
GIT_USER="git" # GitLab 服务运行用户# --- 函数 ---
log() {echo "[$(date '+%Y%m%d-%H%M%S')] $1" | tee -a "$BACKUP_LOG"
}error_exit() {log "ERROR: $1"exit 1
}# --- 主流程 ---
log "GitLab backup started."# 检查是否已有备份在运行(GitLab 本身有锁机制,但可加一层)
if pgrep -f "gitlab-rake gitlab:backup" > /dev/null; thenlog "Another backup is already running. Skipping."exit 0
fi# 执行备份(必须以 git 用户运行)
#sudo -u $GIT_USER /usr/bin/gitlab-rake gitlab:backup:create RAILS_ENV=production
sudo -u git /usr/bin/gitlab-rake gitlab:backup:create RAILS_ENV=productionif [ $? -eq 0 ]; thenlog "GitLab backup completed successfully."
elseerror_exit "Gitlab backup failed!"
fi
设置权限
chmod +x /home/synch_backup_home/run_gitlab_backup.sh
当前用户 cikkod 不是 git 用户,所以需要 sudo 提权,配置 sudo 免密执行特定命令,编辑 sudoers 文件(必须用 visudo)
sudo visudo
在文件末尾添加一行
cikkod ALL=(git) NOPASSWD: /usr/bin/gitlab-rake
cikkod ALL=(git) NOPASSWD: /usr/bin/gitlab-rake, /bin/cat, /bin/cp
验证 sudo 是否配置成功,如果没有提示密码,并输出版本信息,说明配置成功。
sudo -u git /usr/bin/gitlab-rake --version
打开当前用户的 crontab 编辑器
crontab -e
每天 23:00 执行本地备份,通过另一个脚本inotify 自动同步到另一台电脑,追加备份日志输出。
0 23 * * * /bin/bash /home/synch_backup_home/run_gitlab_backup.sh >> /home/synch_backup_home/cron.log 2>&1
验证是否添加成功,
crontab -l
cikkod@gitlab://home/synch_backup_home$ crontab -l
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command0 23 * * * /bin/bash /home/synch_backup_home/run_gitlab_backup.sh >> /home/synch_backup_home/backup_cron.log 2>&1
cikkod@gitlab://home/synch_backup_home$
手动测试脚本是否能运行
/bin/bash /home/synch_backup_home/run_gitlab_backup.sh
看是否成功生成备份文件
ls -l /var/opt/gitlab/backups/
4.2 通过rsync远程备份
注:此方式权限问题太多,推荐尝试使用 WSL2 方案
在 /home/synch_backup_home/ 目录下创建了inotify_start.sh脚本
#!/bin/bash
# 增量实时同步脚本(生产级增强版)# ===== 用户配置区 =====
SOURCE_DIR="/var/opt/gitlab/backups"
SOURCE_DIR="${SOURCE_DIR%/}"
REMOTE_USER="SvcCWRSYNC"
REMOTE_HOST="10.131.27.1"
REMOTE_MODULE="syn_git_repo"
REMOTE_DEST="$REMOTE_USER@$REMOTE_HOST::$REMOTE_MODULE"
PASS_FILE="/home/synch_backup_home/rsync.passwd"
LOG_FILE="/home/synch_backup_home/rsync.log"
AUDIT_LOG="/home/synch_backup_home/rsync_audit.log"
# 排除临时文件模式(逗号分隔)
EXCLUDE_PATTERNS="*.tmp,*.swp,*.bak"
# 防抖延迟(秒)
DEBOUNCE_DELAY=1
# 防抖数组清理时间(秒)
DEBOUNCE_CLEANUP_TIME=3600
# rsync超时时间(秒)
RSYNC_TIMEOUT=300
# 最大重试次数
MAX_RETRY=3
# =====================# 进程锁
LOCK_FILE="/tmp/rsync_inotify.lock"
if [ -e "$LOCK_FILE" ]; thenecho "⚠️ 脚本已在运行中,退出" >&2exit 1
fi
trap "cleanup" EXIT INT TERM
touch "$LOCK_FILE"# 清理函数
cleanup() {rm -f "$LOCK_FILE"pkill -P $$ inotifywait 2>/dev/null || truelog "🔚 脚本停止"
}# 创建日志目录和文件
mkdir -p "$(dirname "$LOG_FILE")"
mkdir -p "$(dirname "$AUDIT_LOG")"
touch "$LOG_FILE"
touch "$AUDIT_LOG"
chmod 600 "$AUDIT_LOG" 2>/dev/null || true
chmod 600 "$LOG_FILE" 2>/dev/null || truelog() {local timestamp="$(date '+%Y-%m-%d %H:%M:%S')"local message="$*"echo "[$timestamp] $message" | tee -a "$LOG_FILE"# 审计日志(关键操作)if [[ "$message" == *"同步文件"* ]] || [[ "$message" == *"删除文件"* ]] || [[ "$message" == *"目录"* ]]; thenecho "[$(date '+%Y%m%d%H%M%S')] AUDIT: $message" >> "$AUDIT_LOG"fi
}# 解释rsync错误代码
interpret_rsync_error() {local code=$1case $code in0) echo "成功" ;;1) echo "语法或用法错误" ;;2) echo "协议不兼容" ;;3) echo "文件选择错误" ;;4) echo "不支持的操作" ;;5) echo "协议启动错误" ;;6) echo "守护进程错误" ;;10) echo "套接字I/O错误" ;;11) echo "文件I/O错误" ;;12) echo "管道错误" ;;13) echo "fork/exec错误" ;;14) echo "内存不足" ;;20) echo "接收SIGUSR1或SIGINT" ;;21) echo "等待子进程错误" ;;22) echo "错误退出" ;;23) echo "部分传输" ;;24) echo "未完全删除" ;;25) echo "超时" ;;30) echo "超时连接" ;;35) echo "超时等待守护进程" ;;*) echo "未知错误 ($code)" ;;esac
}# 检查目录权限
check_directory() {local dir="$1"if [ ! -d "$dir" ]; thenlog "❌ 错误:目录不存在 $dir"return 1fiif [ ! -r "$dir" ]; thenlog "❌ 错误:目录不可读 $dir"return 1fireturn 0
}# 检查文件权限(仅检查不修复)
check_file_permission() {local file="$1"local expected_perm="$2"if [ ! -f "$file" ]; thenlog "❌ 错误:文件不存在 $file"return 1fi# 使用stat跨平台获取权限local permif stat -c "%a" "$file" >/dev/null 2>&1; thenperm=$(stat -c "%a" "$file")elif stat -f "%Lp" "$file" >/dev/null 2>&1; thenperm=$(stat -f "%Lp" "$file")elselog "⚠️ 警告:无法获取文件权限,请手动检查 $file"return 0fiif [ "$perm" != "$expected_perm" ]; thenlog "⚠️ 警告:文件权限不正确: $file (当前: $perm, 期望: $expected_perm)"log "💡 请手动执行: sudo chmod $expected_perm $file"return 1fireturn 0
}check_dependencies() {for cmd in inotifywait rsync; doif ! command -v "$cmd" &> /dev/null; thenlog "❌ 错误:$cmd 未安装,请执行: sudo apt install $(echo $cmd | sed 's/inotifywait/inotify-tools/')"exit 1fidone
}# 构建排除参数(用于 rsync)
build_exclude_args() {local -n args_ref=$1IFS=',' read -ra patterns <<< "$EXCLUDE_PATTERNS"for pattern in "${patterns[@]}"; doargs_ref+=(--exclude="$pattern")done
}# 清理防抖数组(删除超过DEBOUNCE_CLEANUP_TIME未更新的条目)
cleanup_debounce_array() {local current_time=$(date +%s)for file in "${!last_sync_times[@]}"; dolocal last_time=${last_sync_times["$file"]}if [ $((current_time - last_time)) -gt $DEBOUNCE_CLEANUP_TIME ]; thenunset last_sync_times["$file"]fidone
}# 防抖处理(避免短时间内多次同步同一文件)
debounce_sync() {local file_path="$1"local last_sync_time="${last_sync_times[$file_path]}"local current_time=$(date +%s)# 清理过期条目cleanup_debounce_array# 如果是第一次同步或超过防抖延迟if [ -z "$last_sync_time" ] || [ $((current_time - last_time)) -ge $DEBOUNCE_DELAY ]; thenlast_sync_times["$file_path"]=$current_timeperform_sync "$file_path"elselog "⏳ 跳过快速连续修改: $file_path (防抖)"fi
}perform_sync() {local file_path="$1"log "🔄 同步文件: $file_path"# 构建rsync排除参数local exclude_args=()build_exclude_args exclude_args# 执行同步(添加超时参数)rsync -avz --timeout=$RSYNC_TIMEOUT "${exclude_args[@]}" --password-file="$PASS_FILE" \--relative \--checksum \"$file_path" "$REMOTE_DEST/" 2>&1 | tee -a "$LOG_FILE"local rsync_code=${PIPESTATUS[0]}if [ $rsync_code -eq 0 ]; thenlog "✅ 同步成功"elselog "❌ 同步失败: $(interpret_rsync_error $rsync_code)"# 特殊错误处理if [ $rsync_code -eq 11 ] || [ $rsync_code -eq 23 ]; thenlog "⚠️ 可能原因:磁盘空间不足或I/O错误,请检查"fifireturn $rsync_code
}# 同步目录(递归)
perform_dir_sync() {local dir_path="$1"log "🔄 同步目录: $dir_path"# 构建rsync排除参数local exclude_args=()build_exclude_args exclude_args# 执行同步(添加超时参数)rsync -avz --timeout=$RSYNC_TIMEOUT "${exclude_args[@]}" --password-file="$PASS_FILE" \--relative \--checksum \"$dir_path" "$REMOTE_DEST/" 2>&1 | tee -a "$LOG_FILE"local rsync_code=${PIPESTATUS[0]}if [ $rsync_code -eq 0 ]; thenlog "✅ 目录同步成功"elselog "❌ 目录同步失败: $(interpret_rsync_error $rsync_code)"fireturn $rsync_code
}perform_delete() {local file_path="$1"local file_type="文件"[ -d "$file_path" ] && file_type="目录"log "🗑️ ${file_type}已删除: $file_path(远程需定时清理)"# 只在第一次删除时提示if [ -z "$DELETE_TIP_SHOWN" ]; thenlog "💡 建议在定时任务中添加清理命令:"log "rsync -avz --delete --password-file='$PASS_FILE' \\"log " '${SOURCE_DIR}/' '$REMOTE_DEST/'"log "💡 提示:请配置日志轮转(如logrotate)"DELETE_TIP_SHOWN=1fi
}# 清理inotifywait进程
cleanup_inotify() {pkill -P $$ inotifywait
}# 初始同步函数(带重试机制)
perform_initial_sync() {local retry=0local success=0# 构建rsync排除参数local exclude_args=()build_exclude_args exclude_argswhile [ $retry -lt $MAX_RETRY ]; dolog "🚀 执行初始同步 (尝试 $((retry+1))/$MAX_RETRY)..."rsync -avz --timeout=$RSYNC_TIMEOUT "${exclude_args[@]}" --password-file="$PASS_FILE" \--partial \--progress \"${SOURCE_DIR}/" "$REMOTE_DEST/" 2>&1 | tee -a "$LOG_FILE"local rsync_code=${PIPESTATUS[0]}if [ $rsync_code -eq 0 ]; thenlog "✅ 初始同步成功"success=1breakelselog "❌ 初始同步失败: $(interpret_rsync_error $rsync_code)"retry=$((retry+1))if [ $retry -lt $MAX_RETRY ]; thenlog "⏳ 10秒后重试..."sleep 10fifidoneif [ $success -eq 0 ]; thenlog "⚠️ 初始同步失败次数过多,脚本终止"return 1fireturn 0
}main() {check_dependencies# 检查源目录if ! check_directory "$SOURCE_DIR"; thenexit 1filog "=============================================="log "🔄 启动实时同步监控"log "🔍 源目录: $SOURCE_DIR"log "🚀 目标地址: $REMOTE_DEST"log "🏢 环境: 内网(无带宽限制)"log "🔒 安全策略: 删除操作由定时任务处理"log "📝 审计日志: $AUDIT_LOG"log "🚫 排除模式: $EXCLUDE_PATTERNS"log "⏱️ 防抖延迟: ${DEBOUNCE_DELAY}秒"log "🧹 防抖清理: ${DEBOUNCE_CLEANUP_TIME}秒"log "⏳ rsync超时: ${RSYNC_TIMEOUT}秒"log "🔄 最大重试次数: ${MAX_RETRY}"log "=============================================="# 初始同步(带重试机制)if ! perform_initial_sync; thenexit 1fi# 实时监控log "👀 开始监控目录变化..."local restart_count=0declare -A last_sync_times # 文件最后同步时间记录local last_sync_time=0while true; do# 构建inotifywait排除参数local inotify_exclude_args=()if [ -n "$EXCLUDE_PATTERNS" ]; thenIFS=',' read -ra patterns <<< "$EXCLUDE_PATTERNS"local regex_parts=()for pattern in "${patterns[@]}"; do# 转义点号,替换 * 为 .*escaped=$(printf '%s' "$pattern" | sed 's/\./\\./g; s/\*/.*/g')regex_parts+=("$escaped")done# 构建完整正则:^.*\(.tmp|.swp|.bak)$exclude_pattern="^.*\\(${regex_parts[*]}\\)$"inotify_exclude_args=(--exclude="$exclude_pattern")fi# 启动inotifywaitinotifywait -m -r -q "${inotify_exclude_args[@]}" --format '%e %w%f' \-e create,close_write,move,delete \"$SOURCE_DIR" |while IFS=' ' read -r event file_path; dolast_sync_time=$(date +%s)# 处理复合事件(如 CREATE,ISDIR)case "$event" in*,*ISDIR*|*ISDIR*)# 目录事件case "$event" in*CREATE*) log "📁 目录已创建: $file_path"perform_dir_sync "$file_path";;*DELETE*) perform_delete "$file_path";;*MOVED_FROM*) perform_delete "$file_path";;*MOVED_TO*) log "📁 目录被移动来: $file_path"perform_dir_sync "$file_path";;esac;;*)# 文件事件case "$event" inCREATE|MODIFY|CLOSE_WRITE|MOVED_TO)debounce_sync "$file_path";;DELETE|MOVED_FROM)perform_delete "$file_path";;*)log "⚠️ 未知事件: $event - $file_path";;esac;;esacdone# 清理inotifywait进程cleanup_inotify# 检查退出状态local inotify_exit=$?restart_count=$((restart_count+1))if [ $inotify_exit -eq 0 ]; thenlog "ℹ️ inotifywait 正常退出,5秒后重启..."elselog "⚠️ inotifywait 异常退出 (代码: $inotify_exit),5秒后重启..."fi# 限制重启次数(超过10次则退出)if [ $restart_count -gt 10 ]; thenlog "❌ 重启次数过多,脚本终止"exit 1fisleep 5done
}# 检查密码文件权限(仅检查不修复)
if ! check_file_permission "$PASS_FILE" "600"; thenlog "⚠️ 警告:密码文件权限应为600"log "💡 请手动执行: sudo chmod 600 $PASS_FILE"log "⚠️ 脚本将继续运行,但可能遇到权限问题"
fi# 设置审计日志权限(仅检查不修复)
if ! check_file_permission "$AUDIT_LOG" "600"; thenlog "⚠️ 警告:审计日志权限应为600"log "💡 请手动执行: sudo chmod 600 $AUDIT_LOG"
fi# 设置普通日志权限(仅检查不修复)
if ! check_file_permission "$LOG_FILE" "600"; thenlog "⚠️ 警告:日志文件权限应为600"log "💡 请手动执行: sudo chmod 600 $LOG_FILE"
fi# 状态检查参数处理
if [[ "$1" == "-status" ]]; thenif [ -f "$LOCK_FILE" ]; thenecho "===== 实时同步状态 ====="echo "启动时间: $(stat -c %y "$LOCK_FILE" 2>/dev/null || echo "未知")"echo "重启次数: $restart_count"echo "当前监控文件数: ${#last_sync_times[@]}"echo "最后同步时间: $(date -d @${last_sync_time:-0} +'%Y-%m-%d %H:%M:%S')"echo "========================="exit 0elseecho "脚本未运行"exit 1fi
fimain
确认脚本位置和权限
# 检查脚本位置和权限
ls -la /home/synch_backup_home/inotify_start.sh# 确保脚本有执行权限
sudo chmod +x /home/synch_backup_home/inotify_start.sh
设置目录和文件权限
# 确保日志目录所有权正确
sudo chown -R git:git /home/synch_backup_home/
sudo chmod 755 /home/synch_backup_home/
sudo chmod 644 /home/synch_backup_home/*.log # 设置密码文件权限
sudo chown git:git /home/synch_backup_home/rsync.passwd
sudo chmod 600 /home/synch_backup_home/rsync.passwd
创建 Systemd 服务文件,添加以下内容:
sudo vim /etc/systemd/system/gitlab-rsync.service
[Unit]
Description=GitLab Real-time Rsync Backup Service
After=network.target
After=gitlab.target
Requires=network.target[Service]
Type=simple
User=git
Group=git
ExecStart=/bin/bash /home/synch_backup_home/inotify_start.sh
WorkingDirectory=/home/synch_backup_home
Restart=on-failure
RestartSec=10s
StartLimitInterval=60
StartLimitBurst=3# 环境变量
Environment=SOURCE_DIR="/var/opt/gitlab/backups"
Environment=REMOTE_USER="SvcCWRSYNC"
Environment=REMOTE_HOST="10.131.27.1"
Environment=REMOTE_MODULE="syn_git_repo"
Environment=PASS_FILE="/home/synch_backup_home/rsync.passwd"
Environment=LOG_FILE="/home/synch_backup_home/rsync.log"
Environment=AUDIT_LOG="/home/synch_backup_home/rsync_audit.log"# 标准输出和错误输出
StandardOutput=file:/home/synch_backup_home/rsync_service.log
StandardError=file:/home/synch_backup_home/rsync_service_error.log[Install]
WantedBy=multi-user.target
重新加载 Systemd 配置
sudo systemctl daemon-reload
启动服务并设置为开机自启
# 启动服务
sudo systemctl start gitlab-rsync.service# 设置开机自启
sudo systemctl enable gitlab-rsync.service
检查服务状态
# 检查服务状态
sudo systemctl status gitlab-rsync.service# 查看服务日志
sudo journalctl -u gitlab-rsync.service -f
验证日志文件,脚本已经定义了以下日志文件:
/home/synch_backup_home/rsync.log- 主日志文件
/home/synch_backup_home/rsync_audit.log- 审计日志
Systemd 服务还会创建:
/home/synch_backup_home/rsync_service.log- 服务标准输出
/home/synch_backup_home/rsync_service_error.log- 服务错误输出
检查这些文件是否已创建并开始记录:
# 查看主日志
tail -f /home/synch_backup_home/rsync.log# 查看审计日志
tail -f /home/synch_backup_home/rsync_audit.log# 查看服务输出
tail -f /home/synch_backup_home/rsync_service.log# 查看服务错误
tail -f /home/synch_backup_home/rsync_service_error.log
设置日志轮转,添加以下内容:
sudo vim /etc/logrotate.d/gitlab-rsync
/home/synch_backup_home/rsync.log
/home/synch_backup_home/rsync_audit.log
/home/synch_backup_home/rsync_service.log
/home/synch_backup_home/rsync_service_error.log {dailymissingokrotate 7compressdelaycompressnotifemptycopytruncatesu git git
}
测试服务功能
# 重启服务
sudo systemctl restart gitlab-rsync.service# 再次检查状态
sudo systemctl status gitlab-rsync.service# 查看最新日志确认无权限错误
grep -i "permission" /home/synch_backup_home/rsync.log | tail -5
如果遇到问题,可以尝试:
# 检查服务详细状态
sudo systemctl status gitlab-rsync.service -l# 查看完整的服务日志
sudo journalctl -u gitlab-rsync.service --since "10 minutes ago"# 手动以 git 用户测试脚本
sudo -u git /bin/bash /home/synch_backup_home/inotify_start.sh# 检查文件权限
sudo -u git ls -la /var/opt/gitlab/backups/
在过程中遇到作为服务端的Windows电脑,在重启后 rsync 服务自行从自动变成了手动,导致连接失败,通过以下可以检查连接情况
# 测试是否能 ping 通目标服务器
ping -c 4 10.131.27.1# 测试 Rsync 端口 (873) 是否开放
nc -zv 10.131.27.1 873# 使用 telnet 测试连接
telnet 10.131.27.1 873
五、杀毒软件(ClamAV)安装及ufw端口设置
5.1 杀毒软件(ClamAV)安装
安装 ClamAV 及其相关组件,
sudo apt install clamav clamav-daemon clamav-freshclam -y
首次安装后,立即更新病毒定义库,创建必要目录根据实际情况选择
# 创建必要目录
sudo mkdir -p /var/run/clamav
sudo chown -R clamav:clamav /var/run/clamav
sudo freshclam
启动并启用 ClamAV 服务
# 启动并启用 freshclam(病毒库自动更新)
sudo systemctl enable clamav-freshclam
sudo systemctl start clamav-freshclam# 启动并启用 clamav-daemon(扫描服务)
sudo systemctl enable clamav-daemon
sudo systemctl start clamav-daemon
验证安装
# 检查服务状态
sudo systemctl status clamav-daemon# 测试病毒扫描
echo "X5O!P%@AP[4\PZX54(P^)7CC)7}\$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!\$H+H*" > /tmp/eicar.txt
clamscan /tmp/eicar.txt # 应检测到病毒
手动扫描文件或目录(测试),例如,扫描用户的 Downloads 目录。
clamscan -r ~/Downloads/
配置自动更新,ClamAV 默认通过 freshclam 服务每小时检查一次更新。可以通过编辑配置文件自定义,确保以下行未被注释(删除前面的 #)。Checks 24 每天检查 24 次更新(每小时一次)
sudo nano /etc/clamav/freshclam.conf
DatabaseMirror db.local.clamav.net
Checks 24
修改配置后重启服务
sudo systemctl restart clamav-freshclam
查看服务状态
# 查看病毒库更新服务
sudo systemctl status clamav-freshclam# 查看扫描服务
sudo systemctl status clamav-daemon
(可选)设置每日自动扫描,创建一个简单的 cron 任务,每天扫描重要目录
sudo crontab -e
添加一行(例如每天凌晨 2 点扫描 /home)
0 2 * * * /usr/bin/clamscan -r /home --log=/var/log/clamav/scan.log --quiet
确保日志目录存在:
sudo mkdir -p /var/log/clamav
sudo chown $USER:$USER /var/log/clamav
在以上你可能遇到各种问题,例如文件权限、socket、timer等,甚至是省略某些运行库安装。这个是否可以先卸载,然后在重新寻找安装方法
# 停止所有相关服务
sudo systemctl stop clamav-daemon clamav-freshclam# 卸载软件包及配置
sudo apt purge clamav clamav-daemon clamav-freshclam clamtk# 删除残留文件和目录
sudo rm -rf /var/lib/clamav /etc/clamav /var/log/clamav /var/run/clamav# 清理依赖项
sudo apt autoremove
验证卸载结果
# 检查软件包是否已移除
dpkg -l | grep clamav # 应无输出# 检查残留文件
ls -ld /etc/clamav /var/lib/clamav # 应显示"不存在"
5.2 ufw端口设置
检查防火墙(ufw)的当前状态,默认是关闭状态。如果防火墙已启用,输出会显示 Status: active并列出开放的端口规则。如果防火墙未启用,输出会显示 Status: inactive。
cikkod@gitlab:~$ sudo ufw status
Status: activeTo Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
8060/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
8060/tcp (v6) ALLOW Anywhere (v6)
443/tcp (v6) ALLOW Anywhere (v6)
列出所有监听中的服务端口
cikkod@gitlab:/etc/systemd/system$ sudo ss -tulnp | grep LISTEN
tcp LISTEN 0 2048 127.0.0.1:9100 0.0.0.0:* users:(("node_exporter",pid=611661,fd=3))
tcp LISTEN 0 2048 127.0.0.1:9090 0.0.0.0:* users:(("prometheus",pid=611681,fd=7))
tcp LISTEN 0 2048 127.0.0.1:9093 0.0.0.0:* users:(("alertmanager",pid=611510,fd=8))
tcp LISTEN 0 2048 127.0.0.1:9121 0.0.0.0:* users:(("redis_exporter",pid=611701,fd=3))
tcp LISTEN 0 2048 127.0.0.1:9168 0.0.0.0:* users:(("gitlab-exporter",pid=611603,fd=5))
tcp LISTEN 0 2048 127.0.0.1:9187 0.0.0.0:* users:(("postgres_export",pid=611667,fd=3))
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=8165,fd=15))
tcp LISTEN 0 2048 127.0.0.1:9229 0.0.0.0:* users:(("gitlab-workhors",pid=611619,fd=3))
tcp LISTEN 0 2048 127.0.0.1:9236 0.0.0.0:* users:(("gitaly",pid=455524,fd=11),("gitaly",pid=455524,fd=9))
tcp LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=18951,fd=3),("systemd",pid=1,fd=92))
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=611651,fd=7),("nginx",pid=611650,fd=7),("nginx",pid=611649,fd=7),("nginx",pid=611648,fd=7),("nginx",pid=611647,fd=7),("nginx",pid=611646,fd=7),("nginx",pid=611645,fd=7),("nginx",pid=611644,fd=7),("nginx",pid=611643,fd=7))
tcp LISTEN 0 4096 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=8165,fd=17)) root@gitlab:/etc/systemd/system# sudo ufw allow 22/tcp comment 'SSH Management'
sudo ufw allow 80/tcp comment 'HTTP Access'
sudo ufw allow 8060/tcp comment 'GitLab Web Interface'
Rules updated
Rules updated (v6)
Rules updated
Rules updated (v6)
Rules updated
Rules updated (v6)
root@gitlab:/etc/systemd/system# sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)?
分析端口开放必要性
监听地址 | 说明 | 防火墙建议 |
---|---|---|
0.0.0.0:* | 服务暴露在所有网络接口 | 必须开放防火墙 |
127.0.0.1:* | 仅本地环回访问 | 无需开放防火墙 |
192.168.1.100:* | 绑定到内网IP | 按需开放(仅内网) |
生成防火墙开放建议
cikkod@gitlab:~$ sudo ss -tulnp | awk '/LISTEN/ && !/127.0.0.1/ {split($5, a, ":"); print "建议开放端口: " a[2]}'
建议开放端口: 53
建议开放端口: 80
建议开放端口: 22
建议开放端口: 8060
建议开放端口: 53
建议开放端口:
建议开放端口: 9094
建议开放端口:
cikkod@gitlab:~$
直接启用防火墙可能会影响当前的 SSH 连接
root@gitlab:/etc/systemd/system# sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)?
先确认 SSH 端口已放行
cikkod@gitlab:~$ sudo ufw status | grep 22/tcp
22/tcp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
cikkod@gitlab:~$
如果没有加入防火墙,则先加入
sudo ufw allow 22/tcp
启用防火墙
# 输入 "y" 确认操作
sudo ufw enable
放行其他必要端口,并验证防火墙状态
cikkod@gitlab:~$ sudo ufw status numbered
Status: activeTo Action From-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 8060/tcp ALLOW IN Anywhere
[ 4] 443/tcp ALLOW IN Anywhere
[ 5] 22/tcp (v6) ALLOW IN Anywhere (v6)
[ 6] 80/tcp (v6) ALLOW IN Anywhere (v6)
[ 7] 8060/tcp (v6) ALLOW IN Anywhere (v6)
[ 8] 443/tcp (v6) ALLOW IN Anywhere (v6) cikkod@gitlab:~$
限制 SSH 访问源 IP(企业网络适用)
sudo ufw allow from 192.168.1.100 to any port 22
详细防火墙操作可以参考此链接"是否可以查看哪些端口需要打开防火墙了"点击查看元宝的回答
六、GitLab 升级
此段有以下几个注意事项
1.一定要等新服务稳定运行几天时间在做升级,避免无效工
2.通过 GitLab 升级路径查询 网址,结合apt list -a gitlab-ee
可以查看升级路径
3.升级过程发现升级完一个版本后不用手动重新加载配置及重启,升级成后默认就会启动。个人还是进行了手动重新加载配置及重启。
停止gitlab服务
gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq
gitlab-ctl stop nginx
安装指定版本及手动重新加载配置和重启
sudo apt install gitlab-ee=18.3.1-ee.0
sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart
七、内网穿透配置
cikkod@gitlab:~$ cd /usr/local/frp/
cikkod@gitlab:/usr/local/frp$ ls
frp_0.64.0_linux_amd64.tar.gz wget-log
cikkod@gitlab:/usr/local/frp$ sudo chmod 777 /usr/local/frp
[sudo] password for cikkod:
cikkod@gitlab:/usr/local/frp$ ls
frp_0.64.0_linux_amd64 frp_0.64.0_linux_amd64.tar.gz
cikkod@gitlab:/usr/local/frp$ cd frp_0.64.0_linux_amd64
cikkod@gitlab:/usr/local/frp/frp_0.64.0_linux_amd64$ ls
frpc frpc.toml LICENSE
cikkod@gitlab:/usr/local/frp/frp_0.64.0_linux_amd64$ ./frpc verify -c ./frpc.toml
-bash: ./frpc: Permission denied
cikkod@gitlab:/usr/local/frp/frp_0.64.0_linux_amd64$ ls -l frpc
-rw-r--r-- 1 cikkod cikkod 15532184 Sep 4 03:50 frpc
cikkod@gitlab:/usr/local/frp/frp_0.64.0_linux_amd64$ sudo chmod +x frpc
cikkod@gitlab:/usr/local/frp/frp_0.64.0_linux_amd64$ ls -l frpc
-rwxr-xr-x 1 cikkod cikkod 15532184 Sep 4 03:50 frpc
cikkod@gitlab:/usr/local/frp/frp_0.64.0_linux_amd64$ ./frpc verify -c ./frpc.toml
frpc: the configuration file ./frpc.toml syntax is ok
cikkod@gitlab:/usr/local/frp/frp_0.64.0_linux_amd64$ ./frpc -c ./frpc.toml
2025-09-04 03:53:44.457 [I] [sub/root.go:149] start frpc service for config file [./frpc.toml]
2025-09-04 03:53:44.458 [I] [client/service.go:319] try to connect to server...
2025-09-04 03:53:44.512 [I] [client/service.go:311] [4c06b7eaba01f9c6] login to server success, get run id [4c06b7eaba01f9c6]
2025-09-04 03:53:44.512 [I] [proxy/proxy_manager.go:177] [4c06b7eaba01f9c6] proxy added: [gitlab]
2025-09-04 03:53:44.528 [I] [client/control.go:172] [4c06b7eaba01f9c6] [gitlab] start proxy success
^C
cikkod@gitlab:/usr/local/frp/frp_0.64.0_linux_amd64$ cd /etc/systemd/system/
cikkod@gitlab:/etc/systemd/system$ sudo vim /etc/systemd/system/frpc.service
cikkod@gitlab:/etc/systemd/system$ sudo systemctl daemon-reload
cikkod@gitlab:/etc/systemd/system$ sudo systemctl start frpc
cikkod@gitlab:/etc/systemd/system$ sudo systemctl enable frpc
Created symlink /etc/systemd/system/multi-user.target.wants/frpc.service → /etc/systemd/system/frpc.service.
cikkod@gitlab:/etc/systemd/system$ sudo systemctl status frpc
● frpc.service - Frp Client ServiceLoaded: loaded (/etc/systemd/system/frpc.service; enabled; preset: enabled)Active: active (running) since Thu 2025-09-04 04:02:42 UTC; 18s agoMain PID: 644347 (frpc)Tasks: 7 (limit: 19096)Memory: 2.6M (peak: 3.8M)CPU: 24msCGroup: /system.slice/frpc.service└─644347 /usr/local/frp/frp_0.64.0_linux_amd64/frpc -c /usr/local/frp/frp_0.64.0_linux_amd64/frpc.tomlSep 04 04:02:42 gitlab systemd[1]: Started frpc.service - Frp Client Service.
Sep 04 04:02:42 gitlab frpc[644347]: 2025-09-04 04:02:42.714 [I] [sub/root.go:149] start frpc service for config file [/usr/local/frp/frp_0.64.0_l>
Sep 04 04:02:42 gitlab frpc[644347]: 2025-09-04 04:02:42.714 [I] [client/service.go:319] try to connect to server...
Sep 04 04:02:42 gitlab frpc[644347]: 2025-09-04 04:02:42.763 [I] [client/service.go:311] [5d3dcc83009a5c42] login to server success, get run id [5>
Sep 04 04:02:42 gitlab frpc[644347]: 2025-09-04 04:02:42.763 [I] [proxy/proxy_manager.go:177] [5d3dcc83009a5c42] proxy added: [gitlab]
Sep 04 04:02:42 gitlab frpc[644347]: 2025-09-04 04:02:42.779 [I] [client/control.go:172] [5d3dcc83009a5c42] [gitlab] start proxy success
Sep 04 04:02:51 gitlab systemd[1]: [🡕] /etc/systemd/system/frpc.service:7: Special user nobody configured, this is not safe!
cikkod@gitlab:~$ cat /etc/systemd/system/frpc.service
[Unit]
Description=Frp Client Service
After=network.target[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/usr/local/frp/frp_0.64.0_linux_amd64/frpc -c /usr/local/frp/frp_0.64.0_linux_amd64/frpc.toml[Install]
WantedBy=multi-user.target
cikkod@gitlab:~$