快速摘要

使用 systemd 的现代 Linux 系统支持 三种主机名类型:

  • Pretty 主机名 —— 用于显示目的、对人类友好的名称。
  • Static 主机名 —— 存储在磁盘上的永久系统主机名。
  • Transient 主机名 —— 运行时使用的临时主机名。

每种主机名类型都有其特定用途,并遵循定义的优先级顺序。理解这些差异有助于你为用例选择正确的主机名,并避免在系统标识、主机名解析、日志记录和网络相关配置方面产生混淆。

什么是 Linux 中的主机名?

主机名是你的机器的网络标识符。通俗地说,主机名是 Linux 系统用来标识自身的名称。

当你在终端中输入 hostname 时,你会看到你的系统当前如何称呼自己。

主机名出现在:

  • 终端提示符
  • 日志
  • 网络服务
  • 远程连接

较旧的 Linux 系统只有一个主机名。Systemd 引入了多种主机名类型,以正确处理笔记本电脑、DHCP、容器和云系统。

此行为仅适用于基于 systemd 的系统。

理解其中的区别可以防止你的主机名意外更改或重启后不持久时产生的困惑。

在 systemd 之前的发行版(RHEL 6、Debian 7、Fedora 14 及更早版本)将静态主机名存储在:

  • Debian/Ubuntu:/etc/hostname
  • RHEL/CentOS 6:/etc/sysconfig/network
  • Slackware:/etc/HOSTNAME

三种主机名类型

Static 主机名

这是你系统的永久标识。

它存在于 /etc/hostname 文件中。当系统启动时,它会读取此文件并从中设置主机名。

对静态主机名的更改在重启后仍然有效。这是在安装 Debian/Ubuntu 或配置新服务器时设置的内容。

Transient 主机名

这是内核当前的运行时主机名。

它仅存在于内存中。内核现在使用此名称进行所有实际的网络操作。

在启动时,transient 主机名从静态主机名复制。但是,像 DHCP 客户端或网络管理器这样的程序可以在运行时更改它。

当你重启时,transient 主机名会重置以再次匹配静态主机名。

Pretty 主机名

这是一个人类可读的描述。

它可以包含空格、特殊字符和 UTF--8。它存在于 /etc/machine-info 中,并作为元数据使用。

大多数工具会忽略它。你很少需要更改它。

Temporary 和 Transient 主机名是同一个东西吗?

在使用 systemd 的 Linux 系统中,transient 主机名是官方术语,指仅存储在内存中而不保存到 /etc/hostname 的主机名。它通常在重启后重置。

Temporary 主机名这个术语不是官方的 systemd 术语。人们通常非正式地用它来描述不跨重启持久化的主机名。在实践中,当文档或教程提到 temporary 主机名时,他们通常指的是 transient 主机名。

因此,虽然这两个术语在技术上并不完全相同,但它们通常指的是相同的行为:一个在重启后不持久化的主机名更改。

Transient 和 Static 有何不同

静态主机名是你的配置。Transient 主机名是你的当前状态。

可以把静态看作“你想要的”,把 transient 看作“你现在拥有的”。

DHCP 服务器、VPN 和容器编排器通常会动态更改 transient 主机名。它们不会触碰你的静态主机名。

这种分离让你的系统能够适应不同的网络,而不会丢失其身份。

关键点: Transient 主机名才是网络操作实际关心的。程序使用 transient 主机名来解析名称、发送数据包和记录事件。

三种 Linux 主机名类型一览

这在设置服务器、排查网络问题或管理主机名会变化的动态环境时很重要。

如何检查当前主机名

1. 使用 hostnamectl(推荐)

hostnamectl

这会显示所有主机名类型以及系统信息:

Static hostname: Ubuntu2604
Icon name: computer-vm
Chassis: vm 🖴
Machine ID: c315a5ec7511408d8c2f9bf97f5adeaf
Boot ID: 02d8a23f494e44508d1c6ca1079849d8
Virtualization: kvm
Operating System: Ubuntu 26.04 LTS
Kernel: Linux 7.0.0-22-generic
Architecture: x86-64
Hardware Vendor: QEMU
Hardware Model: Standard PC _Q35 + ICH9, 2009_
Hardware Version: pc-q35-9.2
Firmware Version: rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org
Firmware Date: Tue 2014-04-01
Firmware Age: 12y 2month 1w 3d

请注意,hostnamectl 命令不会显示 transient 主机名行,除非它与静态不同。

要仅查看静态主机名:

hostnamectl --static

2. 使用 hostname 命令

hostname

这只显示当前的 transient 主机名(内核现在使用的)。

3. 检查静态主机名文件

cat /etc/hostname

这显示启动时加载的主机名。

4. 检查程序看到的内容

uname -n

这返回应用程序使用的 transient 主机名,与 hostname 命令相同。

如何更改 Linux 主机名(逐步操作)

1. 仅设置 Transient 主机名

Transient 主机名主要用于没有配置静态主机名的系统。例如:

  • DHCP 服务器提供主机名
  • Cloud--init 分配主机名
  • 容器运行时分配主机名

如果存在静态主机名,systemd 会假定这是管理员的刻意选择,并忽略 transient 主机名。

例如,如果你在静态主机名已设置的情况下尝试使用以下命令设置 transient 主机名:

sudo hostnamectl set-hostname webserver01 --transient

你会看到以下消息:

Hint: static hostname is already set, so the specified transient hostname will not be used.

这意味着:

  1. 你的系统已经在 /etc/hostname 中配置了一个静态主机名。
  2. systemd 赋予静态主机名更高的优先级,高于 transient 主机名。
  3. 因此,即使你设置了 transient 主机名,应用程序和系统仍将继续使用静态主机名。

如何测试 transient 主机名

你需要先移除静态主机名:

sudo hostnamectl set-hostname "" --static

或手动清空 /etc/hostname(通常不建议在生产系统上这样做)。

然后,设置 transient 主机名:

sudo hostnamectl set-hostname webserver01 --transient

检查结果:

hostnamectl status
[or]
hostnamectl

你会看到:

Transient hostname: webserver01
Static hostname: (unset)
Pretty hostname: Ubuntu2604
Icon name: computer-vm
Chassis: vm 🖴
Machine ID: c315a5ec7511408d8c2f9bf97f5adeaf
Boot ID: 02d8a23f494e44508d1c6ca1079849d8
Virtualization: kvm
Operating System: Ubuntu 26.04 LTS
Kernel: Linux 7.0.0-22-generic
Architecture: x86-64
Hardware Vendor: QEMU
Hardware Model: Standard PC _Q35 + ICH9, 2009_
Hardware Version: pc-q35-9.2
Firmware Version: rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org
Firmware Date: Tue 2014-04-01
Firmware Age: 12y 2month 1w 3d

正如你在上面的输出中看到的,transient 主机名是 webserver01,静态主机名为空(未设置),pretty 主机名是 Ubuntu2604。

内核现在对所有操作都使用 webserver01。但重启后,它会恢复为 Ubuntu2604 或你在安装期间设置的原始静态主机名。

2. 设置 Static 主机名

sudo hostnamectl set-hostname production-db --static

这会写入 /etc/hostname:

cat /etc/hostname

你会看到输出:production-db

重启后,静态和 transient 都将是 production-db。你可以使用以下命令验证:

hostnamectl --static
hostnamectl --transient

Pretty 主机名(如果已设置)保持不变。

3. 同时设置两者

sudo hostnamectl set-hostname my-server

不带任何标志,这会将静态和 transient 都设置为相同的值。

在大多数情况下,这就是你想要的。

4. 旧方法(不推荐,仅用于教学目的)

sudo hostname quick-test

这会直接在内核中更改 transient 主机名。

它能工作,但 systemd 无法正确跟踪此更改。为了保持一致性,请使用 hostnamectl。

真实世界场景

DHCP 网络

你将笔记本电脑的静态主机名设置为 my-laptop。

当你连接到公司网络时,DHCP 服务器可能会将你的 transient 主机名设置为 client-192-168-1-100。

连接期间,你的系统使用 client-192-168-1-100。当你断开连接或重启时,它会恢复为 my-laptop。

这是自动发生的。NetworkManager 和 dhclient 会处理它。

容器环境

Docker 和 Kubernetes 根据容器 ID 或 Pod 名称设置 transient 主机名。

你的主机的静态主机名保持不变。每个容器在运行时获得自己的 transient 主机名。

这种隔离防止了冲突并简化了编排。

维护模式

你正在处理一台生产服务器,并希望发出信号表明它正在维护中。

设置一个 transient 主机名:

sudo hostnamectl set-hostname MAINTENANCE-DO-NOT-USE --transient

这会立即出现在所有日志和终端提示符中。

维护完成后,重启。主机名会重置为原始的静态值。

没有更改任何配置文件。没有忘记改回来的风险。

常见主机名问题

问题 1:主机名在重启后不持久

症状: 你更改了主机名,但重启后它又恢复了。

原因: 你只更改了 transient 主机名。

修复: 设置静态主机名。要同时立即更新当前主机名:

# Update both static and transient at once (recommended)
sudo hostnamectl set-hostname your-hostname
# OR update only static (transient will match after reboot)
sudo hostnamectl set-hostname your-hostname --static

问题 2:主机名自动更改

症状: 当你连接到不同网络时,你的主机名会改变。

原因: DHCP 服务器正在覆盖你的 transient 主机名。

针对 NetworkManager 的修复(最常见):

# Set a permanent hostname that DHCP cannot override
sudo nmcli general hostname your-permanent-hostname
sudo systemctl restart NetworkManager

替代方法(编辑配置文件):

编辑 /etc/NetworkManager/NetworkManager.conf:

[main]
hostname-mode=none

然后重启 NetworkManager:

sudo systemctl restart NetworkManager

针对旧版 dhclient 的修复(如果使用没有 NetworkManager 的静态网络配置):

编辑 /etc/dhcp/dhclient.conf 并添加:

supersede host-name "your-permanent-hostname";

问题 3:hostnamectl 显示的值与 hostname 命令不同

症状: hostnamectl 和 hostname 显示不同的名称。

原因: 某些东西更改了内核主机名,但没有更新 systemd。

修复: 重启 systemd-hostnamed:

sudo systemctl restart systemd-hostnamed

或者使用 hostnamectl 再次设置主机名。

问题 4:无效的主机名导致 DNS 或服务中断

症状: 服务失败,DNS 无法解析,或 SSL 证书无法工作。

原因: 主机名包含无效字符。

有效的主机名规则(RFC 1123):

  • 仅限小写字母(a-z)、数字(0-9)和连字符(-)
  • 必须以字母或数字开头和结尾
  • 最多 64 个字符
  • 不能有空格、下划线或特殊字符

修复: 设置一个有效的主机名:

sudo hostnamectl set-hostname valid-hostname-01

注意: Pretty 主机名(人类可读)没有字符限制。它们可以包含空格、大写字母、表情符号和特殊字符。

4 个用于验证主机名的 Linux 命令

检查所有主机名类型:

hostnamectl

验证静态主机名文件:

cat /etc/hostname

检查内核认为的主机名:

hostname

查看程序看到的主机名:

uname -n

如果你同时设置了静态和 transient,所有这些命令应显示一致的结果。

限制与风险

无同步保证

如果某个程序通过 hostname 命令直接更改了 transient 主机名,systemd-hostnamed 可能会暂时处于不一致的状态。但是,systemd 在读取时会检测内核主机名的更改。

最佳实践: 坚持使用 hostnamectl 进行所有主机名更改以保持一致性。如果遇到不一致,请重启服务:

sudo systemctl restart systemd-hostnamed

DHCP 可以覆盖你的设置

在 DHCP 网络上,你的 transient 主机名可能会在没有警告的情况下更改。DHCP 服务器可以推送一个主机名选项,覆盖你的 transient 值。

如果主机名稳定性很重要,请配置 NetworkManager 或你的 DHCP 客户端以忽略服务器提供的主机名(参见常见问题 #2)。

容器和虚拟机混淆

在容器或虚拟机内部,主机名行为取决于虚拟化或容器运行时:

  • Docker: 继承主机的 hostname,除非指定了 --hostname
  • LXC/LXD: 具有独立主机名的独立 UTS 命名空间
  • 云虚拟机: Cloud--init 通常在启动时设置主机名

始终在相关环境中验证实际的主机名:

hostname

静态主机名验证

hostnamectl 确实会验证静态主机名是否符合 RFC 1123 标准。无效字符(空格、下划线、特殊字符)会被拒绝并报错。

但是,hostname 命令(绕过 systemd)和 pretty 主机名可以接受任何字符串。

静态主机名的重要规则:

  • 仅限小写字母(a-z)、数字(0-9)和连字符(-)
  • 必须以字母或数字开头和结尾
  • 最多 64 个字符
  • 不能有空格、下划线 (_) 或特殊字符

注意: hostnamectl 在应用主机名之前会进行验证。如果你指定的主机名包含不支持的字符,该命令可能会自动移除或修改这些字符,而不是显示错误。具体行为可能因 Linux 发行版和 systemd 版本而异。

例如,在我们的 Ubuntu 26.04 测试系统上,以下命令:

sudo hostnamectl set-hostname 'bad_hostname#$!'

自动移除了不支持的字符,并将主机名设置为:badhostname

所以,正如我们之前所说,Linux 主机名应仅包含字母、数字和连字符(-)。为避免意外结果,请从一开始就选择一个遵循这些命名规则的主机名。

何时使用 Transient 与 Static

在以下情况下使用 transient 主机名:

  • 临时测试配置更改
  • 在名称频繁变化的 DHCP 环境中运行
  • 发出特殊状态信号(维护、测试、暂存)
  • 你想要运行时灵活性而不进行永久更改

在以下情况下使用 static 主机名:

  • 设置具有固定标识的生产服务器
  • 配置依赖于一致主机名的服务
  • 管理指向特定机器的 DNS 记录
  • 你需要主机名在重启后仍然存在

在以下情况下同时设置两者:

  • 部署需要永久标识的新系统
  • 你希望整个系统立即保持一致
  • 标准服务器或工作站设置

常见问题解答

问:更改主机名需要重启吗?

答:不需要。使用 hostnamectl 会立即更改主机名。只有手动编辑 /etc/hostname 才需要重启或执行 systemctl restart systemd-hostnamed 才能生效。

问:我可以在主机名中使用大写字母吗?

答:静态主机名不可以。 hostnamectl 会拒绝大写字母。Pretty 主机名可以自由使用大写字母。为避免服务兼容性问题,静态主机名应始终使用小写字母、数字和连字符。

问:主机名的最大长度是多少?

答:根据 POSIX 标准,最多 64 个字符。为了兼容性,请保持在 64 个字符以内。

问:更改主机名会中断我的 SSH 连接吗?

答:不会。现有的 SSH 连接保持活动状态。新的连接将在提示符和日志中使用新的主机名。

问:更改主机名后,我需要更新 /etc/hosts 吗?

答:这取决于你的发行版。

在 Debian/Ubuntu 上: 添加:

127.0.1.1 your-hostname

Fedora/RHEL: 通常不需要。

使用 systemd-resolved 或 nss-myhostname 的现代系统: 通常不需要。

检查你现有的 /etc/hosts 格式。如果你看到旧主机名的条目,请更新它。如果没有,你可能不需要。

资源

  1. systemd 主机名文档
  2. hostnamectl 手册页
  3. systemd-hostnamed 服务
  4. Debian Administrator's Handbook
  5. RFC 1178
  6. RFC 1123
  7. Arch Linux Wiki
  8. NetworkManager 主机名处理
  9. Debian Wiki
  10. systemd GitHub