Rocky Linux 10 服务器初始化、系统管理与常用服务部署实战

Rocky Linux 10 服务器初始化、系统管理与常用服务部署实战

新装一台 Linux 服务器,真正需要完成的不只是“换源、装 vim、关防火墙”。当机器要加入虚拟化环境、承担数据库或容器工作负载,网络、存储、时钟、访问控制和软件版本必须作为一套配置来考虑。本文将日常 Rocky Linux 运维笔记与 Rocky Linux 基础操作经验合并,整理出一条从空白系统到可交付服务器的实施路线,并补充 PostgreSQL、Docker、Redis、MySQL、Nacos、Kafka、GitLab 等常见组件的部署参考。

本文以 Rocky Linux 10 为主。被引用的博客侧重 Rocky Linux 8,一些命令在 Rocky Linux 9 尚能兼容、到 10 已完全失效,因此文中会特别标记迁移差异。所有 IP、磁盘设备和域名仅用于演示,执行前必须替换为真实环境参数。

一、环境约定与实施路线

项目 本文约定 说明
操作系统 Rocky Linux 10.x 优先参考官方文档与实际安装的发行版本
权限 root 或有 sudo 权限的用户 命令默认省略 sudo
主机名 rocky10-coreservice 只作示例
服务器地址 192.168.9.10/24 示例静态 IP
默认网关 192.168.9.1 由实际网络拓扑决定
内部域名 egon.local 示例内部命名空间
数据盘 /dev/sdb 危险:需要先确认是不是空盘
数据目录 /data 用于持久化数据或 Docker 挂载
虚拟化 VMware / KVM / 物理机 不同平台只需调整 Guest Agent 等组件

建议采用下面的顺序,而不是直接将所有命令放入一个 Shell 脚本执行:

flowchart TD
    A[识别系统与硬件] --> B[软件源及基础工具]
    B --> C[网络 IP 与 DNS]
    C --> D[主机名和 SSH]
    D --> E[SELinux 与防火墙基线]
    E --> F[Chrony 时间同步]
    F --> G[分区 LVM 与持久挂载]
    G --> H[虚拟化及系统工具]
    H --> I[Docker 和基础服务]
    I --> J[数据库及中间件]
    J --> K[监控 备份与交付检查]

Rocky Linux 与 RHEL 同一大版本保持高度兼容,但它并不是“CentOS 8 的稳定版本”。尤其在 Rocky 10 中,网络配置发生了关键变化:

对比项目 Rocky Linux 8 Rocky Linux 9 Rocky Linux 10
默认网络管理 NetworkManager NetworkManager NetworkManager
连接配置 兼容传统 ifcfg 默认 keyfile,旧 ifcfg 曾兼容 不再支持 ifcfg
网络配置目录 /etc/sysconfig/network-scripts/ 常见 /etc/NetworkManager/system-connections/ 为主 /etc/NetworkManager/system-connections/
network.service 旧脚本 旧场景曾可用 不应依赖 不再适用
软件源补充仓库 PowerTools CRB CRB
DNF 模块化 AppStream 曾广泛使用 部分使用 不再发布模块化内容,避免沿用旧模块流命令
容器工具 Podman / Docker Podman / Docker Podman / Docker

Rocky Linux 10 不应再沿用旧教程中的 vim /etc/sysconfig/network-scripts/ifcfg-eth0、systemctl restart network 或 dnf module enable redis:6。这不是命令写法不同,而是软件栈的支持边界发生了变化。详见 Rocky Linux 10 发布说明 和 RHEL 10 网络迁移说明。

二、识别系统信息与软件仓库

2.1 查看系统、内核和硬件

1
2
3
4
5
6
7
8
9
10
11
cat /etc/os-release
cat /etc/redhat-release
uname -r
uname -a
hostnamectl
arch
lscpu
free -h
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
ip -br addr
ip route

几个主要信息要区分清楚:/etc/os-release 显示发行版本,uname -r 是运行中的内核版本,lsblk 反映块设备与挂载情况。服务器刚交付时,最好先记录这些状态,方便故障回滚与资产盘点。

2.2 DNF、YUM 与软件源

Rocky Linux 默认使用 dnf 管理 RPM 软件包。yum 在现代 RHEL 系发行版上通常作为兼容入口,建议新脚本直接使用 dnf。

1
2
3
4
5
6
7
dnf repolist
dnf repolist --all
dnf list --installed
dnf info curl
dnf search nginx
dnf provides '*/dig'
dnf check-update

基础仓库中,BaseOS 提供核心操作系统组件,AppStream 提供应用程序包,Extras 用于补充软件;CRB 用于补齐部分开发依赖,启用 EPEL 时通常也要启用它。

2.3 更换国内镜像(按需)

海外机房可直接保留官方 mirrorlist;仅在国内访问官方源存在明显延迟时考虑替换。先备份,再替换,最后验证仓库信息。Rocky Linux 9/10 的默认文件通常是小写的 rocky.repo、rocky-extras.repo,而 Rocky 8 教程里经常是 Rocky-BaseOS.repo 等文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mkdir -p /root/backup/yum.repos.d
cp -a /etc/yum.repos.d/*.repo /root/backup/yum.repos.d/
ls -l /etc/yum.repos.d/

# 示例:Rocky 9/10,使用已提供 Rocky 10 镜像的 USTC 源
sed -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.ustc.edu.cn/rocky|g' \
-i.bak \
/etc/yum.repos.d/rocky-extras.repo \
/etc/yum.repos.d/rocky.repo

dnf clean all
dnf makecache
dnf repolist

如果使用阿里云,将上面镜像地址按其实际目录替换为 https://mirrors.aliyun.com/rockylinux;各镜像站目录名不一定一致,不能只替换域名。遇到元数据或 GPG 校验失败,应恢复备份并检查仓库状态,不建议关闭 gpgcheck 来绕过问题。

2.4 启用 CRB 与 EPEL

1
2
3
4
5
6
dnf install -y dnf-plugins-core

dnf config-manager --set-enabled crb
dnf install -y epel-release

dnf repolist --enabled

EPEL 是 Extra Packages for Enterprise Linux,用于提供企业 Linux 基础仓库没有的扩展软件。它不是 Rocky 官方核心仓库,涉及生产环境时应纳入软件源治理和升级测试。

如果确实需要替换 EPEL 镜像,先检查当前 epel.repo 的 metalink、baseurl,再按镜像站提供的 EL10 指南修改,避免套用 EL8 的 epel-modular 旧配置。

2.5 更新系统与保留内核

1
2
3
4
5
6
7
8
9
10
11
# 查看待更新项
dnf check-update

# 更新已安装的软件包
dnf upgrade -y

# 清理元数据缓存
dnf clean all

# 确认是否需要重启
needs-restarting -r 2>/dev/null || true

dnf upgrade 与 dnf update 在常见维护流程中不必连续执行。dnf autoremove 会删除被判定为不再需要的依赖,应先预览删除清单,不要直接写进无人值守脚本。

早期教程建议在 /etc/yum.conf 中永久添加 exclude=kernel*。这种做法会漏掉内核安全修复,不适合作为默认策略。若只想在某次维护窗口临时排除内核,可以使用:

1
dnf upgrade --exclude='kernel*'

对 NVIDIA 驱动、DKMS 或其他内核外模块,应安排驱动兼容验证和计划维护,而不是无限期冻结内核。

三、基础工具、Shell 与命令环境

3.1 安装常用工具

先安装系统管理的基础集合:

1
2
3
4
5
6
7
8
9
dnf install -y \
vim-enhanced wget curl git tar zip unzip xz \
bash-completion bash-completion-extras \
net-tools bind-utils iproute iputils \
lsof tree psmisc procps-ng \
rsync openssh-clients \
jq bc expect dos2unix \
sysstat util-linux \
chrony

根据仓库实际可用性,再安装扩展工具:

1
2
3
dnf install -y \
htop lnav ncdu lrzsz nmap nmap-ncat \
iftop iotop httpd-tools

某个包不存在,不代表基础系统有问题。可用 dnf search <关键词> 先查找,必要时拆分安装以定位是哪一个软件包不可用。nc 在不同版本中可能由 nmap-ncat 等包提供。

命令 用途 更现代的替代或补充
ifconfig 查看接口 ip addr、ip -br addr
netstat -tulnp 查看监听端口 ss -tulnp
route -n 路由表 ip route
dig、host、nslookup DNS 诊断 resolvectl(若配置环境支持)
top、htop 进程与资源监控 pidstat、vmstat
iostat、sar 磁盘与历史指标 sysstat 软件包
nc 测试 TCP/UDP nmap-ncat
lsof、fuser 文件与进程占用 ss -p 等
du、ncdu 磁盘空间 配合 df -hT
lnav 交互式日志阅读 journalctl

开发环境需要编译器时,再安装开发工具组:

1
2
dnf group list
dnf group install -y 'Development Tools'

编译工具组会增加体积和攻击面,不必在所有业务服务器中默认安装。

3.2 Bash 补全、别名与编辑器

1
2
3
4
5
6
7
8
# 对当前用户生效:Readline 补全忽略大小写
printf '%s\n' 'set completion-ignore-case on' >> ~/.inputrc

# 防止重复添加同一别名
grep -qxF "alias ll='ls -lahF --color=auto --time-style=long-iso'" ~/.bashrc || \
echo "alias ll='ls -lahF --color=auto --time-style=long-iso'" >> ~/.bashrc

source ~/.bashrc

~/.bashrc 只影响当前用户;/etc/skel/ 是后续新建用户的初始文件模板,不会自动覆盖现有账户。

可以将个人 Vim 偏好写入 ~/.vimrc:

1
2
3
4
5
6
7
set number
set relativenumber
set expandtab
set shiftwidth=4
set tabstop=4
set mouse=a
syntax on

3.3 Zsh 与 fd(可选)

1
2
3
4
dnf install -y zsh git
command -v zsh
# 确认路径后按用户配置登录 Shell:
# chsh -s /usr/bin/zsh <username>

Oh My Zsh、zsh-autosuggestions 等属于个人交互体验优化,不建议在生产节点通过未经审查的 curl | sh 脚本直接安装。使用官方仓库、固定版本或经过内部审查的脚本更容易维护。

fd 是高效的文件搜索工具,部分仓库以 fd-find 包名提供,安装前先查:

1
2
3
dnf search fd-find
dnf install -y fd-find
command -v fd || command -v fdfind

四、NetworkManager 网络配置

4.1 理解网卡、设备与连接

Rocky Linux 10 的关键不是“把 ens33 改成 eth0”,而是分清三件事:物理或虚拟网卡设备、NetworkManager 连接配置、实际生效的 IP/路由/DNS。

1
2
3
4
5
6
7
8
systemctl status NetworkManager
nmcli general status
nmcli device status
nmcli connection show
nmcli connection show --active
ip -br link
ip -br addr
ip route

一张网卡可以拥有不同的 NetworkManager 连接配置;连接名称也未必等于设备名。因此,运行 nmcli connection modify 之前先确认正确的连接名称。

4.2 使用 nmcli 设置静态 IP

下面假设设备 ens33 对应的连接名称也叫 ens33。远程修改网络可能立即断开 SSH,请先准备虚拟机控制台、iDRAC/iLO 或本地 KVM,并确认目标 IP 没有冲突。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 先确认连接名
nmcli -f GENERAL.CONNECTION,GENERAL.DEVICE device show ens33
nmcli connection show ens33

# 配置静态 IP、默认网关和临时的公共 DNS
nmcli connection modify ens33 \
ipv4.method manual \
ipv4.addresses '192.168.9.10/24' \
ipv4.gateway '192.168.9.1' \
ipv4.dns '223.5.5.5 1.1.1.1' \
ipv4.ignore-auto-dns yes \
connection.autoconnect yes

# 在控制台执行,可能会短暂中断网络
nmcli connection up ens33

ip -br addr
ip route
nmcli device show ens33 | grep -E 'IP4.ADDRESS|IP4.GATEWAY|IP4.DNS'

如果当前 NetworkManager 连接名称不是 ens33,用 nmcli connection show 返回的实际名称替换它,不要删除现有连接后盲目重新创建。

设置回 DHCP:

1
2
3
4
5
6
7
nmcli connection modify ens33 \
ipv4.method auto \
ipv4.addresses '' \
ipv4.gateway '' \
ipv4.dns '' \
ipv4.ignore-auto-dns no
nmcli connection up ens33

4.3 新增或删除 IP、DNS、路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 新增一个辅助 IP
nmcli connection modify ens33 +ipv4.addresses 192.168.9.11/24

# 删除辅助 IP
nmcli connection modify ens33 -ipv4.addresses 192.168.9.11/24

# 添加 DNS 服务器
nmcli connection modify ens33 +ipv4.dns 8.8.8.8

# 删除指定 DNS
nmcli connection modify ens33 -ipv4.dns 8.8.8.8

# 配置 DNS 搜索域
nmcli connection modify ens33 ipv4.dns-search 'egon.local'

# 增加静态路由:目标网段 / 下一跳
nmcli connection modify ens33 +ipv4.routes '192.168.20.0/24 192.168.9.1'

# 激活变更
nmcli connection up ens33

# 查看实际路由
ip route

nmcli connection reload 只是让 NetworkManager 重新读取磁盘中的配置,并不等价于让所有连接立即断开重连。更改生效可根据场景使用 nmcli device reapply ens33 或 nmcli connection up ens33。

4.4 Keyfile 配置与权限

Rocky Linux 10 的连接配置默认位于:

1
2
/etc/NetworkManager/system-connections/
└── ens33.nmconnection

其内容类似:

1
2
3
4
5
6
7
8
9
10
11
12
13
[connection]
id=ens33
type=ethernet
interface-name=ens33
autoconnect=true

[ipv4]
address1=192.168.9.10/24,192.168.9.1
dns=223.5.5.5;1.1.1.1;
method=manual

[ipv6]
method=auto

连接 UUID、密钥及其他配置由 NetworkManager 维护,不建议随意覆盖已有 Keyfile。若必须手工编辑,文件权限应限制为 600,然后执行:

1
2
3
chmod 600 /etc/NetworkManager/system-connections/ens33.nmconnection
nmcli connection reload
nmcli connection up ens33

常用诊断命令:

1
2
3
4
5
ping -c 3 192.168.9.1
ping -c 3 223.5.5.5
dig example.com
getent hosts example.com
ss -tulnp

4.5 可预测网卡命名与 GRUB

ens33、enp5s0、eno1 这类名称源于 systemd/udev 的可预测命名。旧博客讲过通过 net.ifnames=0 回到 eth0,但这会增加多网卡、热插拔和硬件替换时的命名风险。建议保留默认命名;真正需要固定名字时优先采用明确匹配条件的 NetworkManager 方案。

若现有运维自动化强依赖传统名称,且已评估影响,可在控制台中研究内核启动参数:

1
2
3
4
5
6
7
8
9
10
# 查看当前启动条目与参数
grubby --default-kernel
grubby --info=DEFAULT
cat /proc/cmdline

# 仅示例:不建议在普通服务器上直接执行
# grubby --update-kernel=ALL --args='net.ifnames=0'

# 如需回滚该参数
# grubby --update-kernel=ALL --remove-args='net.ifnames=0'

现代 RHEL 系使用 BLS 启动条目,不能机械照搬老文章中对 /boot/efi/EFI/redhat/grub.cfg 的直接修改方式。详见 RHEL 10 GRUB 内核参数文档。

五、主机名、Hosts 与 SSH

5.1 设置主机名

1
2
3
4
hostnamectl set-hostname rocky10-coreservice
hostnamectl status
hostname
hostname -f

内网 DNS 建议记录主机 FQDN;在 DNS 未部署前可临时补充 /etc/hosts:

1
2
3
4
127.0.0.1   localhost localhost.localdomain
::1 localhost localhost.localdomain
192.168.9.10 rocky10-coreservice.egon.local rocky10-coreservice
192.168.9.5 vcenter.egon.local vcenter

避免把所有服务器的业务域名简单指向 127.0.0.1,否则远程访问及服务发现可能无法达到预期。

5.2 SSH 服务管理

1
2
3
systemctl enable --now sshd
systemctl status sshd
ss -lntp | grep ':22'

如果所在系统的 SSH 版本支持以下选项,可创建独立配置片段。注意 OpenSSH 配置遵循“首个被读取的值生效”规则,实际效果以 sshd -T 为准。

1
2
3
4
5
6
7
8
cat > /etc/ssh/sshd_config.d/10-local.conf <<'EOF'
UseDNS no
GSSAPIAuthentication no
EOF

sshd -t
systemctl reload sshd
sshd -T | grep -E '^(usedns|gssapiauthentication) '

这些优化主要面向 DNS 反向解析或 GSSAPI 不需要的场景。若服务器已经使用 Kerberos、统一身份认证等方案,不应直接关闭 GSSAPI。

对生产环境,进一步建议使用 SSH 公钥、限制管理网段、禁用直接 Root 口令登录并保留一个可恢复的管理入口。不要在尚未验证新连接可用时关闭当前 SSH 会话。

六、SELinux、Firewalld 与主机安全

6.1 SELinux 的正确处理方式

网络上常见的 Rocky 初始化脚本会直接将 SELINUX=disabled。这能够减少一些服务启动时的权限问题,但也会失去一层重要的强制访问控制。生产服务器建议优先保持 Enforcing,只有排障时暂时转入 Permissive。

1
2
3
4
5
6
7
8
9
10
11
getenforce
sestatus

# 临时设置为宽容模式(仅排障使用,重启后不保证保持)
setenforce 0

# 排障结束恢复 enforcing
setenforce 1

# 查看近期 AVC 拒绝事件
ausearch -m AVC -ts recent 2>/dev/null

若实验环境明确要求将宽容模式设为持久状态,可编辑 /etc/selinux/config 中的 SELINUX=permissive,随后重启验证。不要将“禁用 SELinux”视为所有 Web、数据库或容器问题的通用修复方案,优先检查上下文标签、布尔值与服务策略。

6.2 Firewalld 基本操作

1
2
3
4
5
6
7
systemctl enable --now firewalld
firewall-cmd --state
firewall-cmd --get-default-zone
firewall-cmd --get-active-zones
firewall-cmd --list-all
firewall-cmd --list-services
firewall-cmd --list-ports

开放标准 Web 服务:

1
2
3
4
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
firewall-cmd --list-services

仅允许管理内网访问 PostgreSQL 的例子:

1
2
3
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.9.0/24" port port="5432" protocol="tcp" accept'
firewall-cmd --reload
firewall-cmd --list-rich-rules

查看防火墙后端规则:

1
2
nft list ruleset
ss -tulnp

Rocky Linux 使用 firewalld 管理规则时,其后端通常基于 nftables。需要区分“服务是否监听”“主机防火墙是否放通”“上游交换机/路由器/安全组是否允许”,不能只看 firewall-cmd 就判定端口可达。

6.3 关于关闭防火墙和禁止 Ping

1
2
# 仅供受控隔离实验环境参考,不建议在生产环境直接使用
# systemctl disable --now firewalld

禁止 ICMP Echo 并不能替代安全控制,还会降低网络可观测性;在 Kubernetes、监控平台或分布式系统中,盲目关闭 ICMP 会使故障排查更困难。实际部署应优先基于 zone、源地址和端口设计访问策略。

七、时区与 Chrony 时间同步

服务器时间对 TLS 证书、日志对齐、数据库复制、分布式调度以及一致性诊断都很重要。

1
2
3
4
5
6
7
8
9
timedatectl
# 示例:大陆业务服务器使用上海时区
timedatectl set-timezone Asia/Shanghai

dnf install -y chrony
systemctl enable --now chronyd
systemctl status chronyd
chronyc sources -v
chronyc tracking

编辑 /etc/chrony.conf,根据内外网访问条件选择可信的时钟源:

1
2
3
# 示例:允许联网的独立服务器
pool pool.ntp.org iburst
server ntp.aliyun.com iburst
1
2
3
4
5
6
systemctl restart chronyd
chronyc sources -v
chronyc tracking

# 仅在明确需要立即校正偏差时执行
chronyc makestep

如果部署私有集群,应让各节点同步同一组经过管理的 NTP 服务;不要让不同节点随意采用不一致的时钟来源。

八、磁盘、分区、LVM 与持久挂载

8.1 从设备到文件系统

flowchart LR
    A[物理磁盘 /dev/sdb] --> B[GPT 分区 /dev/sdb1]
    B --> C[PV 物理卷]
    C --> D[VG data_vg]
    D --> E[LV data_lv]
    E --> F[ext4 / XFS 文件系统]
    F --> G[/data 挂载目录]

LVM 将逻辑卷从底层磁盘设备中抽象出来,便于后续扩容、迁移及存储管理,但LVM 不是备份,快照也不能替代离线备份。

8.2 操作前检查

1
2
3
4
5
6
lsblk -o NAME,SIZE,TYPE,FSTYPE,UUID,MOUNTPOINTS
blkid
pvs
vgs
lvs
df -hT

破坏性操作警告:下述 mklabel、pvcreate、mkfs 可能导致原有数据丢失。一定先确认 /dev/sdb 是目标空盘,且没有 RAID、文件系统或其他业务数据。云盘/NVMe 的真实设备名可能是 /dev/nvme1n1,绝不能直接照抄。

8.3 创建 GPT 分区及 LVM

1
2
3
4
5
6
7
8
9
10
11
12
13
# 以下命令仅适用于确认可清空的 /dev/sdb
parted /dev/sdb --script mklabel gpt
parted /dev/sdb --script mkpart primary 1MiB 100%
parted /dev/sdb --script set 1 lvm on
partprobe /dev/sdb

pvcreate /dev/sdb1
vgcreate data_vg /dev/sdb1
lvcreate -l 100%FREE -n data_lv data_vg

pvs
vgs
lvs

8.4 创建文件系统与挂载

1
2
3
4
5
6
7
8
mkfs.ext4 /dev/data_vg/data_lv
mkdir -p /data
mount /dev/data_vg/data_lv /data

lsblk -f
findmnt /data
df -hT /data
blkid /dev/data_vg/data_lv

在 /etc/fstab 使用 blkid 返回的真实 UUID,不要粘贴空 UUID:

1
2
# 将下面的 <实际UUID> 替换成 blkid 返回值
UUID=<实际UUID> /data ext4 defaults,nofail 0 2

nofail 适合某些可选数据盘,但对 PostgreSQL、容器持久化等核心数据盘,应明确评估磁盘丢失时是否允许系统继续启动业务,避免数据库错误地向空目录写入。

1
2
3
4
systemctl daemon-reload
umount /data
mount -a
findmnt /data

8.5 LVM 扩容参考

假设有新的空盘 /dev/sdc,并计划扩容现有 VG:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 先检查新盘,以下命令也具有破坏性
lsblk /dev/sdc

pvcreate /dev/sdc
vgextend data_vg /dev/sdc
lvextend -l +100%FREE /dev/data_vg/data_lv

# ext4 文件系统:在线扩容
resize2fs /dev/data_vg/data_lv

# 若使用 XFS,则应改用 xfs_growfs /data,而非 resize2fs
vgs
lvs
df -hT /data

扩容卷前先备份关键数据,并考虑 VG 是否存在跨多块磁盘导致的单盘故障风险。

九、Cockpit、虚拟化与系统服务

9.1 Cockpit Web 管理

Cockpit 可以通过 Web UI 查看硬件信息、系统日志、存储、网络和部分服务状态,适合少量服务器的交互式管理。

1
2
3
4
dnf install -y cockpit
systemctl enable --now cockpit.socket
systemctl status cockpit.socket
ss -lntp | grep 9090

默认使用 https://<服务器IP>:9090,应仅向管理网络开放,而非公网直接暴露。若需要防火墙放行:

1
2
3
# 演示端口放行;正式场景建议只允许管理网段
# firewall-cmd --permanent --add-service=cockpit
# firewall-cmd --reload

9.2 VMware open-vm-tools

1
2
3
4
dnf install -y open-vm-tools
systemctl enable --now vmtoolsd
systemctl status vmtoolsd
vmtoolsd -v

如果采用 VMware vSphere,这个服务有助于虚机状态感知及部分 Guest 操作。KVM 等其他虚拟化平台应使用匹配的 Guest Agent,不必一律安装 VMware 工具。

9.3 Systemd 日常管理

1
2
3
4
5
6
7
systemctl list-units --type=service --state=running
systemctl list-unit-files --type=service
systemctl status sshd
systemctl is-enabled sshd
systemctl is-active sshd
journalctl -u sshd -n 100 --no-pager
journalctl -p err -b --no-pager

维护服务时优先区分 start、stop、restart、reload、enable 和 disable。enable 仅设置开机启动,--now 才会同时改变当前运行状态。

十、内部 DNS:Dnsmasq

如果有多台物理机、虚机或 Kubernetes 节点,需要稳定解析 *.egon.local,可以在内部管理节点部署 dnsmasq 作为轻量 DNS 缓存和静态记录服务。它适合实验室、小规模内网;大型生产环境通常需要考虑 PowerDNS、CoreDNS、BIND 或企业 DNS 的冗余与统一管理。

10.1 安装与配置

1
2
3
4
dnf install -y dnsmasq
systemctl enable --now dnsmasq
systemctl status dnsmasq
dnsmasq --version

假设本机 DNS 服务地址是 192.168.9.10,编辑 /etc/dnsmasq.d/egon.conf:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 只监听本机及内部网络接口
listen-address=127.0.0.1,192.168.9.10
bind-interfaces

# 缓存及静态记录
cache-size=10000
addn-hosts=/etc/dnsmasq.hosts
local=/egon.local/

# 上游 DNS(优先使用受信任的内网 DNS)
resolv-file=/etc/dnsmasq-resolv.conf
no-resolv

# 排障期可启用;常态运行建议按需关闭,避免日志过多
# log-queries

注意 no-resolv 的作用是忽略系统提供的其他解析器,避免 dnsmasq 与本地 /etc/resolv.conf 发生递归自查。resolv-file 指定的是本服务主动访问的上游 DNS 列表,不能把它也配置成 127.0.0.1。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cat > /etc/dnsmasq-resolv.conf <<'EOF'
nameserver 223.5.5.5
nameserver 1.1.1.1
EOF

cat > /etc/dnsmasq.hosts <<'EOF'
192.168.9.5 vcenter.egon.local
192.168.9.10 dns.egon.local
192.168.9.10 rocky10-coreservice.egon.local
EOF

# 检查配置语法
dnsmasq --test
systemctl restart dnsmasq

10.2 配置客户端 DNS

建议通过 DHCP 下发 DNS 地址,或者在客户端 NetworkManager 连接中配置:

1
2
3
nmcli connection modify ens33 ipv4.dns '192.168.9.10'
nmcli connection modify ens33 ipv4.dns-search 'egon.local'
nmcli connection up ens33

重要:上面的命令应在 dnsmasq 已经过验证、且客户端能够访问 192.168.9.10 后执行。dnsmasq 服务器自身若把解析器指向自己,也必须保证上游解析和服务启动顺序正确。

1
2
3
4
dig @192.168.9.10 vcenter.egon.local
dig @192.168.9.10 example.com
getent hosts dns.egon.local
ss -lunp | grep ':53'

如需提供给其他网段的主机查询,防火墙应基于源网段精确放行 UDP/TCP 53,而不是开放一个任何人都可使用的递归 DNS。

十一、Docker Engine 与容器基础环境

11.1 安装 Docker Engine 与 Compose

Rocky Linux 自带 Podman 生态,若业务明确使用 Docker Compose,可安装 Docker Engine。优先使用 Docker 官方为 RHEL 提供的软件源,而不是旧笔记中的 HTTP 下载地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 仅在确有旧版 Docker 冲突时检查并移除
dnf list --installed | grep -Ei 'docker|podman|containerd' || true

# 不要因为安装 Docker 就盲目卸载 Podman
# 如确认有冲突,再有针对性地移除具体旧包

dnf install -y dnf-plugins-core

dnf config-manager --add-repo \
https://download.docker.com/linux/rhel/docker-ce.repo

dnf install -y \
docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin

systemctl enable --now docker
systemctl status docker

docker version
docker compose version
docker info

11.2 配置镜像加速与日志策略

按实际可用的企业镜像仓库或可信镜像服务配置 /etc/docker/daemon.json。公开免费的第三方加速地址常常不稳定,并且存在供应链信任问题,不能将未经核验的地址写成固定默认值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mkdir -p /etc/docker
cat > /etc/docker/daemon.json <<'EOF'
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"live-restore": true
}
EOF

# 校验 JSON 语法
python3 -m json.tool /etc/docker/daemon.json >/dev/null
systemctl restart docker

如有自建 Harbor:

1
2
3
4
{
"registry-mirrors": ["https://<可信的镜像加速服务>"],
"insecure-registries": ["harbor.egon.local:3001"]
}

这里的 JSON 是字段示例,不是让你与前一份配置整体覆盖。insecure-registries 只填写 host:port,不要包含 http://;更推荐为 Harbor 配置有效 TLS 证书,并为 Docker 安装相应 CA 信任链。

11.3 Docker 网桥、转发和容器目录

1
2
3
4
5
6
7
8
9
# 查看 Docker 的网络配置
docker network ls
docker network inspect bridge

# 建立一个隔离的业务网络:与主机、Pod、Service 网络不能重叠
docker network create --driver bridge --subnet 172.28.10.0/24 app-net

docker volume ls
docker ps -a

Docker 在普通 bridge 网络上通常会管理必要的 IP 转发及 NAT。不要无理由在 /etc/sysctl.conf 里反复追加 net.ipv4.ip_forward=1;如果主机承担路由或网关职责,应规划 /etc/sysctl.d/*.conf 并检查与 firewalld/nftables 的相互作用。

1
sysctl net.ipv4.ip_forward

11.4 Docker 远程访问与安全边界

不要把 Docker API 直接绑定到 tcp://0.0.0.0:2375。未受保护的 Docker API 能让远程调用方控制容器,通常等同于获得宿主机的高权限。

最简单的远程管理方案是通过 SSH:

1
2
3
# 在管理端运行,前提是 SSH 用户有管理远端 Docker 的授权
docker context create lab-host --docker 'host=ssh://admin@192.168.9.10'
docker --context lab-host ps

需要原生 TLS Remote API 时,参照 Docker 官方远程访问安全文档 配置 mTLS,通常使用 2376 端口。不要为了方便而把用户直接加进 docker 组,除非你接受该用户获得近似 root 的宿主机控制能力。

十二、PostgreSQL 18、PostGIS 与 pgvector

12.1 软件源与版本选择

Rocky Linux 10 自带的 PostgreSQL 与 PGDG 软件源的 PostgreSQL 版本可能不同。若业务要求 PostgreSQL 18,可使用 PostgreSQL 官方 PGDG 仓库。以下以 x86_64 为例;其他 CPU 架构请使用官方页面生成的安装命令。

1
2
3
4
5
6
7
# PGDG 仓库入口:操作前确认系统小版本与架构
dnf install -y \
https://download.postgresql.org/pub/repos/yum/reporpms/EL-10-x86_64/pgdg-redhat-repo-latest.noarch.rpm

dnf repolist | grep -i pgdg

dnf install -y postgresql18-server postgresql18-contrib postgresql18-devel

Rocky Linux 10 已不再提供旧式模块化 AppStream 内容,因此不需要机械执行老教程里的 dnf module disable postgresql。另外,PGDG 对旧的小版本仓库有退役政策,使用较旧 Rocky 10.x 小版本时应确认仓库是否仍提供更新。

12.2 初始化与启动

使用默认数据目录时:

1
2
3
4
5
6
/usr/pgsql-18/bin/postgresql-18-setup initdb
systemctl enable --now postgresql-18
systemctl status postgresql-18

/usr/pgsql-18/bin/psql --version
sudo -u postgres /usr/pgsql-18/bin/psql -c 'SELECT version();'

默认 PGDG 布局通常为:

1
2
3
4
/usr/pgsql-18/bin/                  PostgreSQL 可执行文件
/var/lib/pgsql/18/data/ PGDATA 数据目录
/var/lib/pgsql/18/data/postgresql.conf
/var/lib/pgsql/18/data/pg_hba.conf

初始化只需要做一次。已有生产数据目录时,绝不能重新执行 initdb,否则可能覆盖或破坏原数据库实例。

12.3 将 PGDATA 放到专用数据盘(新实例)

如果是全新、尚未初始化的 PostgreSQL 18,并且 /data 已经可靠挂载,可以先建立数据目录,再通过 systemd drop-in 配置 PGDATA:

1
2
3
4
5
mkdir -p /data/postgresql/18/data
chown -R postgres:postgres /data/postgresql
chmod 700 /data/postgresql/18/data

systemctl edit postgresql-18

在弹出的 drop-in 编辑器中写入:

1
2
[Service]
Environment=PGDATA=/data/postgresql/18/data

然后:

1
2
systemctl daemon-reload
sudo -u postgres /usr/pgsql-18/bin/initdb -D /data/postgresql/18/data

SELinux 保持 Enforcing 时,使用自定义数据目录还需要设置正确的数据库目录安全上下文:

1
2
3
4
5
6
dnf install -y policycoreutils-python-utils
semanage fcontext -a -t postgresql_db_t '/data/postgresql(/.*)?'
restorecon -RFv /data/postgresql

systemctl enable --now postgresql-18
systemctl status postgresql-18

这不是把现有数据库迁移到新路径的全部流程。对运行中的实例,应先备份,停止数据库,复制数据及校验权限,再切换服务配置;不能在已有数据库上直接调用 initdb。

12.4 创建数据库与最小权限用户

连接本机数据库:

1
sudo -u postgres /usr/pgsql-18/bin/psql

在 psql 中执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- 用实际密码替换示例值;不要把真实密码提交到 Git 仓库
CREATE ROLE app_user WITH LOGIN PASSWORD '<STRONG_RANDOM_PASSWORD>'
NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;

CREATE DATABASE app_db OWNER app_user ENCODING 'UTF8';

\c app_db

-- 作为 DB Owner,app_user 具有相应所有权;如需跨角色授权再单独 GRANT
ALTER ROLE app_user SET search_path TO public;

-- 验证
\du
\l
\q

原始笔记中出现过 ALTER USER app_user SET default_database = app_db,这不是 PostgreSQL 标准的数据库选择方式。数据库由客户端连接参数、连接 URL 或 psql -d app_db 指定,不能用这个命令给角色指定默认数据库。

如果为已有表格授权,请考虑表、序列、Schema 的所有权以及默认权限;不要把 GRANT ALL PRIVILEGES ON DATABASE 误认为已经获得所有表的操作权限。

12.5 安全设置远程连接

在实际 PGDATA 的 postgresql.conf 中,绑定必要的网卡:

1
2
3
# 地址必须是本机接口实际存在的 IP,不支持写成 CIDR 网段
listen_addresses = 'localhost,192.168.9.10'
port = 5432

在 pg_hba.conf 中按业务网段设置认证规则,例如:

1
2
# TYPE  DATABASE  USER      ADDRESS             METHOD
host app_db app_user 192.168.9.0/24 scram-sha-256

配置完成后:

1
2
3
4
5
systemctl restart postgresql-18
ss -lntp | grep ':5432'

# 远程业务用户测试:按提示输入密码,不在命令历史中暴露密码
psql -h 192.168.9.10 -U app_user -d app_db -W

实际生产环境还应使用 TLS、数据库凭据轮换和基于网络来源的白名单。不要同时采用 listen_addresses='*'、0.0.0.0/0 与弱口令;换一个非默认端口并不构成数据库访问安全措施。

12.6 安装 pgvector 与 PostGIS

先查对应 PostgreSQL 18 仓库实际提供的扩展包名称:

1
2
3
4
5
6
dnf search pgvector
dnf search postgis

# 若 PGDG 仓库提供以下版本匹配的包
# dnf install -y pgvector_18
# PostGIS 包名随仓库构建及版本变化,以 dnf search 输出为准

在扩展包已安装且目标数据库具备相应权限时:

1
2
3
4
5
6
7
8
9
10
11
12
13
\c app_db
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS postgis;

CREATE TABLE IF NOT EXISTS embedding_demo (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
embedding vector(3) NOT NULL
);

INSERT INTO embedding_demo (embedding)
VALUES ('[1,2,3]'), ('[4,5,6]');

SELECT id, embedding FROM embedding_demo;

pgvector 适用于向量检索与 RAG 应用,PostGIS 用于地理空间数据。二者都是按数据库安装扩展,不是安装 RPM 后就自动对全部数据库生效。使用距离检索时,还需要根据数据分布和查询规模选择 HNSW、IVFFlat 等索引策略。

十三、Nginx 与 HTTPS

13.1 安装与服务检查

1
2
3
4
5
6
dnf install -y nginx
systemctl enable --now nginx
systemctl status nginx
nginx -v
nginx -t
ss -lntp | grep -E ':(80|443)'

安装后,建议把每个站点的配置放在独立文件中,方便版本管理:

1
2
3
4
/etc/nginx/nginx.conf
/etc/nginx/conf.d/app.conf
/var/log/nginx/access.log
/var/log/nginx/error.log

13.2 HTTP 反向代理示例

假设 Java/Spring Boot 服务只在本机 8080 监听:

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
listen 80;
server_name app.egon.local;

location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
1
2
3
nginx -t
systemctl reload nginx
curl -I -H 'Host: app.egon.local' http://127.0.0.1/

SELinux Enforcing 模式下,Nginx 连接上游网络套接字可能需要额外授权;应检查 AVC 日志后有针对性地开启布尔值或配置安全策略,不能一遇到 502 就关闭 SELinux。

13.3 HTTP 自动跳转 HTTPS

必须先准备有效证书和私钥。下面的域名和证书路径是示意:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
listen 80;
server_name app.egon.top;
return 301 https://$host$request_uri;
}

server {
listen 443 ssl;
server_name app.egon.top;

ssl_certificate /etc/nginx/certs/app.fullchain.pem;
ssl_certificate_key /etc/nginx/certs/app.key;
ssl_protocols TLSv1.2 TLSv1.3;

location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
1
2
3
nginx -t
systemctl reload nginx
curl -I https://app.egon.top/

公网站点应使用经过信任的 CA 证书,并规划续签自动化;自签证书只适合测试或已分发自建 CA 的内部场景。Docker 部署或 Kubernetes Ingress 中的 Nginx 也遵循相同的 TLS 终止与反向代理原则,但证书管理和配置交付方式不同。

十四、MySQL 服务

14.1 使用系统仓库安装

1
2
3
4
5
6
7
# 查看实际可用的 MySQL 包与版本
dnf info mysql-server

dnf install -y mysql-server
systemctl enable --now mysqld
systemctl status mysqld
mysql --version

原笔记中的 dnf install -y mysql-server mysqld 不正确:mysqld 是服务进程/可执行程序名称,通常不是需要额外安装的 RPM 包。若业务要求精确的 MySQL 8.x 小版本,应先选择官方 MySQL Community 仓库或容器镜像,不应假设发行版包满足版本约束。

1
2
mysql_secure_installation
mysql -u root -p

初始化时设置管理员认证方式,移除匿名用户和测试库,并限制远程管理访问。

14.2 创建业务数据库与账号

1
2
3
4
5
6
7
8
9
CREATE DATABASE app_db CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

CREATE USER 'app_user'@'192.168.9.%'
IDENTIFIED BY '<STRONG_RANDOM_PASSWORD>';

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX
ON app_db.* TO 'app_user'@'192.168.9.%';

SHOW GRANTS FOR 'app_user'@'192.168.9.%';

具体 COLLATE 应以安装版本实际支持的字符集/排序规则为准。MySQL 8 不应继续沿用旧教程中强制切换 mysql_native_password 的通用做法;优先使用当前默认认证插件,并升级不兼容的客户端。

十五、Redis:系统服务与 Docker 两种部署

15.1 原生 RPM 安装

1
2
3
4
5
6
dnf info redis
dnf install -y redis
systemctl enable --now redis
systemctl status redis
redis-server --version
redis-cli ping

系统仓库会决定 Redis 具体版本。不要在 Rocky 10 上继续照搬 dnf module enable redis:6;如果业务必须使用 Redis 7、8 或固定小版本,应选择明确的软件分发来源并测试兼容性。

15.2 Docker 单机部署(适合实验)

先准备持久化目录:

1
mkdir -p /data/docker/redis/data

快速验证服务:

1
2
3
4
5
6
7
8
9
10
11
docker run -d \
--name redis-standalone \
--restart unless-stopped \
--network app-net \
-p 127.0.0.1:6379:6379 \
-v /data/docker/redis/data:/data \
redis:7.4 \
redis-server --appendonly yes

docker exec redis-standalone redis-cli ping
docker logs --tail 100 redis-standalone

此示例仅绑定宿主机回环地址,避免让未配置认证的 Redis 意外暴露到局域网或公网。需要跨主机连接时,应启用 ACL、TLS 或通过安全的内网隧道访问,而不是简单改成:

1
2
3
# 不建议将下列组合直接用于生产网络
bind 0.0.0.0
protected-mode no

15.3 内存与持久化策略

Redis 常见配置项:

1
2
3
appendonly yes
maxmemory 2gb
maxmemory-policy allkeys-lru

allkeys-lru 适用于允许缓存键被淘汰的场景,不适用于所有数据都需要长期保存的 Redis 业务。如果 Redis 同时承载 Session、锁、队列或重要状态,应分别评估内存淘汰策略、AOF fsync、复制、故障切换与备份,而不是照搬“缓存型 Redis”的配置。

十六、Nacos 3 与 MySQL:注册发现和配置中心

16.1 网络与组件关系

flowchart LR
    A[Java / Spring 应用] -->|8848 HTTP API| N[Nacos Server]
    A -->|9848 gRPC| N
    M[管理员浏览器] -->|8080 Console| N
    N -->|3306 内部连接| D[(MySQL nacos 库)]

Nacos 3.x 将控制台端口与 API 端口分离:

端口 作用 访问范围建议
8080 Web Console 仅管理网络
8848 Server API 仅业务内网
9848 客户端 gRPC 仅业务内网,需 TCP 转发
9849 服务端之间通信 仅 Nacos 节点
7848 Raft 通信 仅 Nacos 节点
3306 MySQL 仅 Nacos Server 到数据库

Nacos 官方明确不建议把这些服务直接暴露在公共互联网。下面以开发/实验用单机 Nacos 3.1.0 + MySQL 为例,生产要增加高可用、数据库备份、认证、监控和访问隔离。

16.2 准备环境变量和 Compose 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mkdir -p /data/docker/nacos-stack/{mysql/data,nacos/logs}
cd /data/docker/nacos-stack

# 创建仅 root 可读的变量文件,编辑时填入独立的随机密钥
umask 077
cat > .env <<'EOF'
MYSQL_ROOT_PASSWORD=REPLACE_WITH_RANDOM_ROOT_PASSWORD
NACOS_DB_PASSWORD=REPLACE_WITH_RANDOM_DATABASE_PASSWORD
NACOS_AUTH_TOKEN=REPLACE_WITH_BASE64_RANDOM_SECRET
NACOS_AUTH_IDENTITY_KEY=serverIdentity
NACOS_AUTH_IDENTITY_VALUE=REPLACE_WITH_RANDOM_IDENTITY_VALUE
EOF
chmod 600 .env

# NACOS_AUTH_TOKEN 的生成参考(把结果填入 .env)
openssl rand -base64 48

NACOS_AUTH_TOKEN 必须是有效 Base64,解码后长度满足 Nacos 版本要求。上面的变量文件只是模板,未替换 REPLACE_... 前不要启动;不要将 .env 提交到 Git,生产优先使用密钥管理服务。

创建 compose.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
services:
mysql:
image: mysql:8.4
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:?required}
MYSQL_DATABASE: nacos
MYSQL_USER: nacos
MYSQL_PASSWORD: ${NACOS_DB_PASSWORD:?required}
volumes:
- ./mysql/data:/var/lib/mysql
networks:
- backend
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -uroot -p\"$$MYSQL_ROOT_PASSWORD\" --silent"]
interval: 10s
timeout: 5s
retries: 20

nacos:
image: nacos/nacos-server:v3.1.0
restart: unless-stopped
depends_on:
mysql:
condition: service_healthy
environment:
MODE: standalone
SPRING_DATASOURCE_PLATFORM: mysql
MYSQL_SERVICE_HOST: mysql
MYSQL_SERVICE_PORT: "3306"
MYSQL_SERVICE_DB_NAME: nacos
MYSQL_SERVICE_USER: nacos
MYSQL_SERVICE_PASSWORD: ${NACOS_DB_PASSWORD:?required}
NACOS_AUTH_ENABLE: "true"
NACOS_AUTH_TOKEN: ${NACOS_AUTH_TOKEN:?required}
NACOS_AUTH_IDENTITY_KEY: ${NACOS_AUTH_IDENTITY_KEY:?required}
NACOS_AUTH_IDENTITY_VALUE: ${NACOS_AUTH_IDENTITY_VALUE:?required}
ports:
- "192.168.9.10:18080:8080"
- "192.168.9.10:8848:8848"
- "192.168.9.10:9848:9848"
volumes:
- ./nacos/logs:/home/nacos/logs
networks:
- backend

networks:
backend:
driver: bridge

此 Compose 结构展示了服务、认证与网络关系;Nacos 数据库还必须先导入与镜像版本相匹配的官方 MySQL 初始化 Schema。导入 SQL 可从 Nacos 对应版本发布包的 distribution/conf/mysql-schema.sql 获取。不要将不同 Nacos 版本的 Schema 混用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 先启动 MySQL
docker compose up -d mysql

docker compose ps

# 下载、检查与当前 Nacos 版本匹配的 mysql-schema.sql 后,导入到 nacos 数据库
# 示例:在 .env 所在目录,通过受控方式提供数据库账号凭据
# docker compose exec -T mysql mysql -unacos -p nacos < mysql-schema.sql

# 完成初始化后再启动 Nacos
docker compose up -d nacos

docker compose ps
docker compose logs --tail=100 nacos

注意 mysql -p 的交互式密码输入与管道/重定向配合时要选择合适的执行方式,生产自动化建议通过 secrets 或安全的临时凭据文件传入,避免命令行直接携带密码。

如果实际 Nacos 3.1.0 镜像的环境变量或 Schema 有差异,以同一镜像版本的官方发布说明为准。若客户端跨主机连接,务必验证 9848 的 TCP 可达性;访问 http://192.168.9.10:18080 只是控制台,不代表 gRPC 已经通畅。

十七、RabbitMQ 与 Apache Kafka

17.1 RabbitMQ 管理版容器

RabbitMQ 提供消息队列及管理控制台;AMQP 默认端口为 5672,管理 UI 通常使用 15672。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
docker volume create rabbitmq-data

# 先在可信环境中设置随机用户名和密码(不要将真实密码写入脚本仓库)
export RABBITMQ_USER='app_admin'
read -r -s -p 'RabbitMQ password: ' RABBITMQ_PASSWORD; echo

docker run -d \
--name rabbitmq-standalone \
--restart unless-stopped \
--network app-net \
-p 127.0.0.1:5672:5672 \
-p 127.0.0.1:15672:15672 \
-v rabbitmq-data:/var/lib/rabbitmq \
-e RABBITMQ_DEFAULT_VHOST='app_host' \
-e RABBITMQ_DEFAULT_USER="$RABBITMQ_USER" \
-e RABBITMQ_DEFAULT_PASS="$RABBITMQ_PASSWORD" \
rabbitmq:4-management

unset RABBITMQ_PASSWORD

docker logs --tail 100 rabbitmq-standalone
docker exec rabbitmq-standalone rabbitmq-diagnostics ping

此命令仅在宿主机回环地址发布端口。对其他容器可优先使用同一 Docker 网络中的服务名通信;若必须提供给其他服务器,需启用 TLS、账号权限和来源网段限制。注意:环境变量可能被 Docker 元数据查看,正式环境应改用受控密钥机制。

17.2 Apache Kafka 的 KRaft 模式

Kafka 4 已全面采用不依赖 ZooKeeper 的 KRaft 架构。原笔记使用 Bitnami Kafka 4.0 镜像与手工 KRaft 变量;镜像发布方式与变量约定可能随着发行渠道变化而发生差异,新部署可以优先参考 Apache 官方镜像。

1
2
3
4
5
6
7
8
9
# 本机开发环境快速测试
# 此示例的默认监听配置不保证可供其他机器访问
docker run -d \
--name kafka-standalone \
--restart unless-stopped \
-p 127.0.0.1:9092:9092 \
apache/kafka:4.4.0

docker logs --tail 100 kafka-standalone

单节点验证可使用镜像自带命令(具体路径以版本镜像为准):

1
2
3
docker exec kafka-standalone \
/opt/kafka/bin/kafka-topics.sh \
--bootstrap-server localhost:9092 --list

真正跨主机部署 Kafka 时,listeners 是监听接口,而 advertised.listeners 决定客户端拿到的 Broker 地址。即使 9092 能连接,如果向客户端通告的是容器内部主机名、localhost 或错误 IP,也会出现“初次连接成功,获取元数据后失败”的问题。生产环境应使用明确的控制器投票成员、持久卷、监听器认证及多节点副本设置。

十八、GitLab:安装、HTTPS 与备份恢复

18.1 安装策略

GitLab 功能较完整,但在小内存主机上相对重。支持的 Linux 版本、架构与软件包类型应以 GitLab 官方兼容矩阵为准。Rocky Linux 10 部署前,先确认对应 GitLab 版本支持 RHEL 10 生态,避免照搬旧版本 GitLab 12 的安装与配置。

建议按照 GitLab 官方 Linux Package 安装文档 注册适用的软件包仓库,再选定 CE/EE 版本安装。现有 Omnibus 风格的主要目录如下:

1
2
3
4
5
/etc/gitlab/gitlab.rb              主配置
/etc/gitlab/gitlab-secrets.json 关键加密密钥(必须单独备份)
/var/opt/gitlab/ 持久化数据
/var/log/gitlab/ 日志
/var/opt/gitlab/backups/ 常见备份目录

18.2 常用配置与服务命令

/etc/gitlab/gitlab.rb 示例:

1
2
3
4
5
6
7
8
9
10
11
12
# 有真实可访问域名和证书后配置 HTTPS
external_url 'https://gitlab.egon.top'

# 如果证书不是由 GitLab 内置机制管理,应明确配置证书路径
nginx['ssl_certificate'] = '/etc/gitlab/ssl/gitlab.egon.top.crt'
nginx['ssl_certificate_key'] = '/etc/gitlab/ssl/gitlab.egon.top.key'

# 只有不使用内置镜像仓库时才禁用
registry['enable'] = false

# 不使用 Omnibus 内置 Prometheus 时可调整内置监控组件
# 不要在未评估依赖关系时一口气关闭全部组件
1
2
3
4
5
6
7
8
9
10
gitlab-ctl reconfigure
gitlab-ctl restart
gitlab-ctl status
gitlab-ctl tail

# 初次部署可能存在临时 root 密码文件,读取后应妥善保护
# cat /etc/gitlab/initial_root_password

# 受控重置 GitLab 用户密码
gitlab-rake 'gitlab:password:reset'

原笔记中的 external_url='http:gitlab.egon.top:6001' 缺少 //,而且 GitLab Ruby 配置项中的空格、引号、属性名称都需要准确匹配。修改后必须执行 gitlab-ctl reconfigure 并检查日志。对于反向代理接入,应明确由哪个组件终止 TLS、处理重定向以及转发 Host 和 X-Forwarded-Proto。

18.3 备份

GitLab 的常规备份命令:

1
gitlab-backup create

GitLab 数据备份不等于完整灾备;还需要单独保存 /etc/gitlab/ 中的配置、gitlab-secrets.json、证书和外部对象存储的相关信息,且应妥善保护备份中的敏感数据。

1
2
3
4
5
install -d -m 700 /backup/gitlab

# 示例:备份配置与秘密信息,应加密并存到受控位置
tar -C /etc -czf "/backup/gitlab/gitlab-config-$(date +%F).tar.gz" gitlab
chmod 600 /backup/gitlab/gitlab-config-*.tar.gz

可以使用 cron 或 systemd timer 定期执行,但要增加失败告警、备份文件校验、异机复制、保留策略与恢复演练;仅有定时任务不等于灾备可用。

18.4 恢复

恢复前必须确认GitLab 版本与 CE/EE 类型相符,并确保备份的密钥文件与应用数据匹配。典型 Linux Package 恢复流程为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 检查备份位置、备份 ID 及文件所有者
ls -lh /var/opt/gitlab/backups/

# 先确保 GitLab 已正确安装、reconfigure 并正常启动
# 停止与数据库关联的 Web/后台任务进程

gitlab-ctl stop puma
gitlab-ctl stop sidekiq

# 用实际备份 ID 替换占位符(不包括 _gitlab_backup.tar 后缀)
# gitlab-backup restore BACKUP=<BACKUP_ID>

# 完成校验并按官方流程重新配置/启动
# gitlab-ctl restart

恢复具有破坏性,应在维护窗口中执行,并严格遵照 GitLab 官方恢复文档 对相关组件、权限和版本的要求。

十九、Jenkins、Nexus 与开发基础设施

19.1 Jenkins 安装

旧笔记以 Java 11 运行 Jenkins。到 2026 年,新版本 Jenkins 已提升运行时最低要求,当前支持的运行时主要是 Java 21 / Java 25。不要按旧文档下载过时的 Java 11 二进制包。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 安装 Java 21(具体发行包以当前仓库为准)
dnf install -y java-21-openjdk
java -version

# LTS 软件源;从 Jenkins 官方 HTTPS 仓库获取
curl -fsSL -o /etc/yum.repos.d/jenkins.repo \
https://pkg.jenkins.io/rpm-stable/jenkins.repo

# 2026 年签名密钥
rpm --import https://pkg.jenkins.io/rpm-stable/jenkins.io-2026.key

dnf install -y jenkins
systemctl enable --now jenkins
systemctl status jenkins
1
2
3
4
5
# 默认 Web 管理端口通常为 8080
ss -lntp | grep ':8080'

# 初始化管理员密码,前提是已完成首次启动
cat /var/lib/jenkins/secrets/initialAdminPassword

生产 Jenkins 建议部署在专门管理网络,启用 HTTPS、统一身份认证、角色权限和 Controller/Agent 分离,避免在 Jenkins Controller 上直接运行不可信构建任务。最新运行环境要求请以 Jenkins Java 支持策略 为准。

19.2 Nexus Repository

Nexus 常用于统一管理 Maven、npm、Docker 等制品。其安装包、Java 兼容性、系统用户及磁盘目录与所选择的 Nexus Repository 版本有关,不能仅凭旧安装命令确定。

推荐部署思路:

  1. 从 Sonatype 官方网站 获取支持的版本与安装说明。
  2. 为 Nexus 建立非 root 系统用户,数据存入独立挂载卷。
  3. 通过 systemd 管理服务,使用 Nginx 反向代理与 HTTPS 提供入口。
  4. 按 Maven、npm、Docker 分别配置 Hosted、Proxy、Group 仓库,并建立备份与存储容量监控。

不建议将 Nexus 的系统端口、Docker Registry 入口、Maven 私服路径全部混用为同一个“通用端口”,实际访问路径应根据客户端协议分开验证。

二十、SSL 证书与内部服务加密

旧笔记给出了 OpenSSL 自签名证书:

1
2
3
4
5
6
7
8
9
10
# 仅用于测试环境,自签证书不受公开浏览器自动信任
openssl req -x509 -newkey rsa:3072 -sha256 -nodes \
-keyout server.key \
-out server.crt \
-days 365 \
-subj '/CN=app.egon.local' \
-addext 'subjectAltName=DNS:app.egon.local'

chmod 600 server.key
openssl x509 -in server.crt -noout -subject -dates -ext subjectAltName

现代 TLS 客户端应通过 SAN 校验证书域名,仅设置 Common Name 不一定足够。公网业务优先使用受信任的 CA(例如 ACME 流程);私有域名可采用企业内部 CA,然后向客户端分发 CA 证书。

不要把证书私钥提交到代码仓库、容器镜像或普通日志中。

二十一、SNMP 与观测能力

如需兼容传统 SNMP 监控,可安装:

1
2
dnf install -y net-snmp net-snmp-utils
systemctl status snmpd 2>/dev/null || true

在创建受监控节点前,应明确 SNMP 版本及认证方式。建议使用 SNMPv3,避免把只带 community 字符串的 SNMPv2c 直接暴露公网。对于 Prometheus / Grafana 环境,通常更适合通过 Node Exporter、OpenTelemetry Collector 或系统级 Exporter 收集 CPU、内存、磁盘和网络指标。

基础排障命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# CPU、内存、磁盘、网络
uptime
free -h
vmstat 1 5
iostat -xz 1 3
sar -n DEV 1 3

# 服务与日志
systemctl --failed
journalctl -p warning -b -n 100 --no-pager

# 文件系统与容量
df -hT
du -sh /var/log/* 2>/dev/null | sort -h | tail

二十二、系统模板、桌面环境与长期维护

22.1 何时安装图形界面

多数服务器使用 Minimal Install 更易控制资源占用。只有桌面操作或专用应用明确需要 GUI 时才考虑:

1
2
3
4
5
6
7
dnf group list

# 确认系统仓库支持此环境组后再安装
# dnf group install -y 'Server with GUI'

# 如已安装图形会话,再评估是否设置默认 target
# systemctl set-default graphical.target

图形界面会带来额外内存、更新和安全维护开销。不建议仅为了管理磁盘、网络或查看日志就给服务器统一安装 GNOME,可以使用 SSH、Cockpit 和集中监控代替。

22.2 制作虚拟机模板前应清理什么

虚拟机基础模板应尽量做到“没有业务数据、没有私钥、没有固定主机身份,但保留安全审计与系统可恢复性”。

可以清理:

1
2
3
4
5
6
7
8
# 谨慎清理软件包缓存
dnf clean all

# 检查模板是否有残留的下载文件和临时构建产物
find /tmp -maxdepth 1 -mindepth 1 -ls | head

# 查看日志空间,不直接删除全部审计历史
journalctl --disk-usage

不建议照搬旧教程中这些操作:

1
2
3
4
5
# 不建议执行:可能破坏审计链、故障取证及运行中的服务
# rm -f /var/log/audit/audit*
# rm -f /var/log/secure*
# echo > /var/log/wtmp
# rm -rf /tmp/*

真正的黄金镜像制作,需要使用虚拟化平台推荐的镜像封装工具或 Cloud-Init,将主机名、网卡、Machine ID、SSH Host Key、账户和初始化脚本交给首次启动流程按策略生成。对已经入库或投产的虚机,不要直接删除系统身份文件来“模板化”。

22.3 系统维护与更新制度

服务器升级不宜只安排 dnf upgrade -y 一条定时命令。建议至少管理以下事项:

维护对象 推荐做法 不建议的做法
系统补丁 测试环境验证、计划维护、记录版本 永久禁用内核更新
安全策略 SELinux Enforcing + 来源网段规则 统一关闭 SELinux、firewalld
数据库 备份、PITR/恢复演练、权限审计 仅复制数据目录即认为完成备份
容器镜像 固定版本、验证来源、定期更新 长期使用未审计的 latest
凭据 密钥管理、最小权限、轮换 在脚本和 Git 中明文硬编码
监控 指标、日志、链路与告警 只依赖手工 top 排查
集群网络 规划不重叠的地址空间 业务网络与 Docker/Pod 网段相互重叠
时间 集中 NTP 源和漂移监控 不检查时间差就部署数据库集群

二十三、交付检查清单

基础环境配置完成后,可按下面的顺序核对:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 发行版与硬件
cat /etc/os-release
uname -r
lscpu | head
free -h

# 主机名与网络
hostnamectl
nmcli connection show --active
ip -br addr
ip route
getent hosts rocky10-coreservice.egon.local

# 系统安全
getenforce
firewall-cmd --state
ss -tulnp

# 时间
chronyc tracking
timedatectl

# 存储
lsblk -f
pvs && vgs && lvs
findmnt /data
df -hT

# 基础服务
systemctl --failed
systemctl is-active sshd

# 容器(已安装才执行)
docker info
docker compose version

# PostgreSQL(已安装才执行)
# systemctl is-active postgresql-18
# sudo -u postgres /usr/pgsql-18/bin/psql -c 'SELECT 1;'

# 日志与错误
journalctl -p err -b -n 50 --no-pager

更适合交付团队的方式是将这些检查固化到 Ansible inventory、Playbook、Assert 和健康检查任务中,同时将 IP、用户名、密码、仓库源、组件版本、磁盘布局和防火墙规则参数化。交付产物应同时包含配置、验证结果、备份与回滚方法。

二十四、常见旧命令与 Rocky Linux 10 替代方案

旧资料中的命令或做法 Rocky Linux 10 建议 原因
修改 /etc/sysconfig/network-scripts/ifcfg-* nmcli / nmtui / .nmconnection keyfile ifcfg 兼容支持已移除
systemctl restart network nmcli connection up <连接名> 或 nmcli device reapply <网卡> 旧 network scripts 不再支持
将网卡强制改成 eth0 优先保留可预测接口名 避免接口顺序变化引发错误
直接改 UEFI 下的 redhat grub.cfg 按当前 BLS + grubby 文档操作 旧式启动配置路径可能不适用
dnf module enable redis:6 直接查询 RPM 包或使用独立仓库/镜像 EL10 不再发布模块化内容
dnf config-manager --set-enabled powertools dnf config-manager --set-enabled crb PowerTools 是 Rocky 8 名称
yum install mysql-server mysqld dnf install mysql-server mysqld 是服务程序,不是额外 RPM 包
ALTER USER ... SET default_database 在连接串或 psql -d 中指定数据库 PostgreSQL 不支持这种会话默认库设置
PostgreSQL listen_addresses 写 CIDR 绑定本机接口地址 + pg_hba.conf 限制网段 监听地址与客户端访问控制是不同概念
Docker 0.0.0.0:2375 SSH Docker Context 或 mTLS 2376 避免远程高权限 API 无认证
Docker insecure registry 使用 http://host 配置 host:port,优先部署 TLS 配置字段不接受 URL scheme
Redis protected-mode no 对所有地址开放 回环/内网绑定 + ACL/TLS 避免未认证的数据服务暴露
Kafka 仅映射端口 9092 同时校验 advertised.listeners 客户端依赖元数据中的 Broker 地址
Nacos 3 仍用 8848 打开管理台 8080 Console / 8848 API / 9848 gRPC 3.x 已拆分 Console
Jenkins 使用 Java 11 按当前 Jenkins 版本选择 Java 21/25 新版本运行时要求已经变化
日常删除所有 Audit/Secure 日志 保留审计链并设置轮换/保留期 审计与故障追踪要求

参考资料

本文综合整理了以下资料。上传的本地 rocky.md 为服务配置和中间件部署的基础素材;网页文章提供 Rocky Linux 8 时代的操作经验。涉及 Rocky Linux 10 的兼容性与安全修正,参考官方文档核对后进行改写,并非将旧命令原样复制。

本文定位是“Rocky Linux 10 系统初始化与常用组件部署实践手册”,不是一键执行脚本。破坏性操作、服务暴露、持久化路径和软件版本均需要针对实际环境验证;生产环境还应补齐访问控制、集中日志、可观测性、备份恢复与配置管理。


Rocky Linux 10 服务器初始化、系统管理与常用服务部署实战
https://allendericdalexander.github.io/2026/11/03/devops/RockyLinux10ServerDeploymentGuide/
作者
AtLuoFu
发布于
2026年11月3日
许可协议