AI Infra 训练营
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub

hostnamectl / timedatectl —— 改主机名与时区

一句话定义

这是 systemd 的"set state"系列工具,取代了 vim /etc/hostname 和 vim /etc/timezone 这种手改文件:

  • hostnamectl —— 设置主机名(hostname)
  • timedatectl —— 设置时区、NTP、本地/UTC 硬件时钟

两个命令风格一样、用法对称,所以放一起讲。

典型场景

Day0 §4:装机基线的最后一步。改完虚拟化探测、磁盘、SSH 之后,把 5 台机器的 hostname 改成 k8s-cp-1 ~ k8s-w-2,时区统一到 UTC(K8s 集群强烈建议跟 UTC、避免本地时间踩坑)。

hostnamectl set-hostname k8s-cp-1
timedatectl set-timezone UTC

为什么不直接改 /etc/hostname

echo "k8s-cp-1" > /etc/hostname     # ❌ 不推荐

直接改有三个问题:

  1. 当前 shell 看到的 hostname 不变(要 logout 或 hostname 命令手动同步)
  2. 不通知 dbus —— 其它在运行的服务(rsyslog、Avahi、kubelet)感知不到变化
  3. 不一致 —— /etc/hostname 只是其中一个 hostname,systemd 还有"transient hostname"和"pretty hostname"概念

hostnamectl set-hostname 帮你处理这些:

  • 写 /etc/hostname
  • 通知 dbus
  • 立刻在所有视角下生效
  • 处理多种 hostname 类型

hostnamectl 用法

看当前 hostname

$ hostnamectl
 Static hostname: k8s-cp-1
       Icon name: computer-vm
         Chassis: vm
      Machine ID: abc123...
         Boot ID: def456...
Virtualization: kvm
Operating System: Ubuntu 22.04 LTS
          Kernel: Linux 5.15.0-...
    Architecture: x86-64

只看 hostname:

hostnamectl --static            # 等价于 cat /etc/hostname
hostname                        # 也行

改 hostname

hostnamectl set-hostname k8s-cp-1

立刻生效(包括当前 shell 的 \h 提示符也会变 —— 重连 ssh 后看得到)。

三种 hostname 类型

类型说明怎么改
Static持久 hostname,存 /etc/hostnamehostnamectl set-hostname xxx
Transient动态 hostname(DHCP / 内核默认)重启 / 网络变化时自动
Pretty人类可读名(含空格、Unicode)hostnamectl set-hostname "My Laptop" --pretty

绝大多数场景只需要 Static。Pretty 是给 GUI 看的。

集群里批量改

ssh m1 'hostnamectl set-hostname k8s-cp-1'
ssh m2 'hostnamectl set-hostname k8s-cp-2'
# ... etc

或者用 for 循环 + 数组(参考 Day0 §4):

declare -A HOSTS=(
  [m1]=k8s-cp-1
  [m2]=k8s-cp-2
  [m3]=k8s-cp-3
  [m4]=k8s-w-1
  [m5]=k8s-w-2
)
for alias in "${!HOSTS[@]}"; do
  ssh "$alias" "hostnamectl set-hostname ${HOSTS[$alias]}"
done

hostname 改完之后还要做的事

hostnamectl 只改 hostname 本身。但很多服务依赖 hostname → IP 的映射,需要同步改 /etc/hosts:

# 5 节点统一的 /etc/hosts
cat > /etc/hosts <<'EOF'
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback

10.0.24.28 k8s-cp-1 m1
10.0.24.29 k8s-cp-2 m2
10.0.24.30 k8s-cp-3 m3
10.0.24.31 k8s-w-1  m4
10.0.24.32 k8s-w-2  m5
EOF

为什么 /etc/hosts 重要:

  • kubeadm init 要解析自己的 hostname 到 IP;如果 hostname 只在 DNS 里、或者根本没解析,会失败
  • 节点间通信:kubelet → apiserver、kube-proxy → service 等都涉及反查 hostname
  • etcd peer:用 hostname 在 SAN 证书里,没解析就 TLS 失败

K8s 安装 99% 的"hostname not found"或"x509: certificate signed by ... is not valid for ..."类问题都和 /etc/hosts 缺失有关。


timedatectl 用法

看当前时间状态

$ timedatectl
               Local time: Mon 2026-05-27 14:30:15 UTC
           Universal time: Mon 2026-05-27 14:30:15 UTC
                 RTC time: Mon 2026-05-27 14:30:15
                Time zone: UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

关键字段:

  • Local time:当前时间(按时区计算)
  • Universal time:UTC 时间(无时区)
  • RTC time:硬件时钟(主板 BIOS 时间)
  • Time zone:时区
  • System clock synchronized:是否和 NTP 同步过(boot 时和现在都同步过返回 yes)
  • NTP service:是否有活跃的 NTP 同步服务
  • RTC in local TZ:硬件时钟是否走本地时间(默认应该 no,走 UTC)

设时区

timedatectl list-timezones                       # 看所有可用时区
timedatectl list-timezones | grep -i shanghai
timedatectl set-timezone UTC                     # K8s 集群推荐 UTC
timedatectl set-timezone Asia/Shanghai           # 上海时区

K8s 集群强烈建议所有节点统一用 UTC:

  • 日志时间在所有节点能直接对比
  • 容器里的应用通常默认 UTC,日志一致
  • 跨时区团队协作无歧义

启用 / 禁用 NTP

timedatectl set-ntp true         # 启用 systemd-timesyncd
timedatectl set-ntp false        # 禁用

注意:这里启用的是 systemd-timesyncd(systemd 自带的轻量 NTP 客户端)。生产环境通常用更专业的 chrony,两者不能同时跑。

chrony vs systemd-timesyncd

维度systemd-timesyncdchrony
安装systemd 自带要装 chrony 包
精度一般高
网络瞬断恢复慢快(最快秒级)
能当 NTP 服务端❌✅
K8s 推荐仅小型实验✅ 生产标配

装 chrony 就要禁掉 timesyncd(不然两者抢着同步 / 互相打架):

apt-get install -y chrony
timedatectl set-ntp false                        # 关 timesyncd
systemctl enable --now chrony                    # 起 chrony

确认:

timedatectl                                      # NTP service: 应该是 active(chrony 也算)
chronyc tracking                                 # chrony 自己的状态
chronyc sources                                  # 看上游 NTP 服务器

为什么 K8s 对时间敏感

K8s 几乎所有组件对时间漂移都敏感:

  1. etcd raft —— leader election、心跳都用时间。漂移超过 500ms 会导致 leader 频繁换 → 集群抖动
  2. TLS 证书校验 —— Not Before / Not After 字段。节点时间比证书早 → 证书"还没生效";晚 → 证书"过期"
  3. kubelet → apiserver token —— ServiceAccount token 有 issued-at / expiry,漂移超过容忍范围被拒
  4. HPA 决策 —— 按时间窗口算 metric,漂移导致决策错乱
  5. 日志关联 —— 节点 A 在 10:00 发了请求、节点 B 在 09:59 收到,分布式追踪全乱

集群里所有节点的时间漂移要 < 50ms。chrony 默认能做到 < 10ms。


hostname / 时区 一气呵成的装机段(Day0 §4)

HOSTNAME="$1"     # 各机器自己的名字传进来

ssh root@$ip "
  # 1. hostname
  hostnamectl set-hostname $HOSTNAME

  # 2. /etc/hosts 全集群一致
  cat > /etc/hosts <<'HOSTS'
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback

10.0.24.28 k8s-cp-1 m1
10.0.24.29 k8s-cp-2 m2
10.0.24.30 k8s-cp-3 m3
10.0.24.31 k8s-w-1  m4
10.0.24.32 k8s-w-2  m5
HOSTS

  # 3. 时区 UTC
  timedatectl set-timezone UTC

  # 4. 启用 chrony(已装的话)
  systemctl enable --now chrony 2>/dev/null || true

  # 5. 验证
  hostnamectl --static
  timedatectl | grep -E 'Time zone|NTP'
"

常见踩坑

坑 1:改了 hostname,但提示符没变

hostnamectl set-hostname k8s-cp-1
# bash 提示符还是 root@old-name

bash 的 \h 提示符是 shell 启动时缓存的。重新登录或 exec bash:

exec bash
# 或
exit && ssh m1

坑 2:/etc/hosts 里 hostname 指向 127.0.0.1,K8s 起不来

Ubuntu 装机有时 /etc/hosts 默认:

127.0.1.1 k8s-cp-1

这会让 kubeadm 解析 hostname 时拿到 127.0.1.1,证书 SAN 不匹配,集群挂。

修复:删掉那行,改成真实 IP:

10.0.24.28 k8s-cp-1 m1

坑 3:节点时间差 5 分钟,TLS 报"signed by unknown authority"

x509: certificate has expired or is not yet valid: current time ... is after ...

时间问题伪装成证书问题。先 timedatectl 看时间:

ssh m1 'timedatectl'
ssh m2 'timedatectl'
# 看 Local time 差距

如果差几分钟以上:

ssh m1 'systemctl restart chrony'
sleep 5
ssh m1 'chronyc tracking'                # System time: 0.0001 seconds slow

坑 4:硬件时钟(RTC)跑本地时间

RTC in local TZ: yes

通常 Windows 双系统的机器是这样(Windows 把 RTC 设成本地时间)。Linux 默认 RTC 走 UTC。两者打架会让重启后时间偏差几小时。

修复:

timedatectl set-local-rtc 0      # RTC 走 UTC

云机器一般默认正确。物理机 / 双系统才需要注意。

坑 5:set-ntp 报错

timedatectl set-ntp true
# Failed to set ntp: NTP not supported

通常是因为系统装了 chrony / ntpd,systemd-timesyncd 已经被禁用。这种情况你不需要 set-ntp true —— chrony 自己跑着就行。

确认 chrony 在工作:

chronyc tracking
chronyc sources

坑 6:hostname 太长 / 含特殊字符

hostnamectl set-hostname "我的机器 1"
# Failed: hostname "我的机器 1" is not valid

Static hostname 必须是 RFC 1123 合规:字母数字、-、.,最长 64 字符。中文 / 空格 / 下划线都不行。

要"漂亮"的名字用 pretty hostname:

hostnamectl set-hostname "My K8s Master" --pretty
hostnamectl set-hostname "k8s-cp-1" --static

但 K8s 集群里别用 pretty,到处显示的 hostname 都是 static 那个。


关联命令

  • systemctl —— hostnamectl/timedatectl 同属 systemd 工具家族
  • chronyc —— 看 chrony 状态(tracking, sources)
  • hostname —— 老式查看(只读用);hostname xxx 老式设置(不持久)
  • date —— 看当前时间 / 设置时间(不推荐手动设、让 NTP 处理)
  • journalctl —— 看 chrony / timesyncd 日志:journalctl -u chrony -f
在 GitHub 上编辑此页