解决Ubuntu执行sudo时 unable to resolve host 报错问题

文章目录

  • [解决Ubuntu执行sudo时 unable to resolve host 报错问题](#解决Ubuntu执行sudo时 unable to resolve host 报错问题)
    • 一、背景与问题现象
    • 二、根因分析
      • [1. sudo 警告的根因](#1. sudo 警告的根因)
      • [2. 为什么 hosts 会被覆盖](#2. 为什么 hosts 会被覆盖)
    • 三、处理思路总览
    • 四、操作步骤
      • [步骤 1:确认并开启 manage_etc_hosts](#步骤 1:确认并开启 manage_etc_hosts)
      • [步骤 2:先备份(重要)](#步骤 2:先备份(重要))
      • [步骤 3:把业务域名写入模板文件](#步骤 3:把业务域名写入模板文件)
        • [为什么不用手动加 `127.0.1.1 ip-172-1-7-33`?](#为什么不用手动加 127.0.1.1 ip-172-1-7-33?)
      • [步骤 4:立即重新渲染 hosts](#步骤 4:立即重新渲染 hosts)
    • 五、结果验证
      • [1. 查看生成后的 /etc/hosts](#1. 查看生成后的 /etc/hosts)
      • [2. 验证命令](#2. 验证命令)
    • 六、长期收益与维护规范
      • [⚠️ 维护红线](#⚠️ 维护红线)
    • 七、总结

解决Ubuntu执行sudo时 unable to resolve host 报错问题

本文记录了一次在 Ubuntu(cloud-init 环境)上排查 sudo: unable to resolve host 警告,并通过 cloud-init 模板机制规范化管理 /etc/hosts 的完整过程,包含前因后果与排查思路。


一、背景与问题现象

服务器为运行在云上的 Ubuntu 实例(由 cloud-init 管理),主机名类似 ip-172-1-7-33。在执行 sudo 命令时,出现如下告警:

复制代码
sudo: unable to resolve host ip-172-1-7-33: Name or service not known

同时还有一个诉求:需要在 /etc/hosts 中长期维护若干业务域名的静态解析,例如内部管理后台、SOC 平台等。

遇到的核心矛盾

在 cloud-init 管理的机器上,如果直接手动编辑 /etc/hosts

  • 重启后配置会丢失------cloud-init 会用模板重新覆盖生成该文件。

因此,直接 vim /etc/hosts 加几行并不是可靠的长期方案


二、根因分析

1. sudo 警告的根因

sudo 在执行时会尝试解析当前主机名。如果 /etc/hosts 里没有一条能匹配当前主机名(hostname 输出值)的记录,解析失败,就会报 unable to resolve host

解决方向:确保 /etc/hosts 中存在一条把主机名映射到本地回环地址的记录,通常是:

复制代码
127.0.1.1 <fqdn> <hostname>

2. 为什么 hosts 会被覆盖

/etc/cloud/cloud.cfg 中存在配置项 manage_etc_hosts。它有几种取值:

取值 行为
false / 不配置 cloud-init 不管理 hosts,手动改动会保留(但也失去自动维护主机名的能力)
true cloud-init 每次启动都用模板 /etc/cloud/templates/hosts.debian.tmpl 重新生成 /etc/hosts
localhost 只确保 localhost 相关记录,其余不动

关键决策 :我们选择开启 manage_etc_hosts: true。这样带来两个好处:

  1. cloud-init 会通过模板变量 {``{hostname}} / {``{fqdn}} 自动填入当前主机名,从根本上、且"自愈式"地消除 sudo 警告。
  2. 业务域名写入模板后,重启也不会丢失。

代价是:必须改用模板管理 hosts,不能再直接手改 /etc/hosts


三、处理思路总览

复制代码
开启 manage_etc_hosts: true
        │
        ├─► 备份原始文件(hosts / cloud.cfg / 模板)
        │
        ├─► 把业务域名写入模板文件(而非 /etc/hosts)
        │
        ├─► 用 cloud-init 立即重新渲染 hosts
        │
        └─► 验证:sudo 无警告 + 主机名可解析 + 业务域名可解析

核心原则:改模板,不改 hosts


四、操作步骤

步骤 1:确认并开启 manage_etc_hosts

编辑 /etc/cloud/cloud.cfg,确保存在:

yaml 复制代码
manage_etc_hosts: true

步骤 2:先备份(重要)

在改动任何系统文件前,务必备份:

bash 复制代码
sudo cp /etc/hosts /etc/hosts.bak.$(date +%F)
sudo cp /etc/cloud/cloud.cfg /etc/cloud/cloud.cfg.bak.$(date +%F)
sudo cp /etc/cloud/templates/hosts.debian.tmpl /etc/cloud/templates/hosts.debian.tmpl.bak.$(date +%F)

步骤 3:把业务域名写入模板文件

编辑模板文件(不是 /etc/hosts):

bash 复制代码
sudo vim /etc/cloud/templates/hosts.debian.tmpl

在模板末尾追加业务域名。注意:模板里已经存在 127.0.1.1 {``{fqdn}} {``{hostname}} 这一行,因此无需再手动加主机名记录,只需追加 cloud-init 无从知晓的业务域名:

jinja 复制代码
# 模板中原有(保持不动)------会自动渲染出主机名
127.0.1.1 {{fqdn}} {{hostname}}
127.0.0.1 localhost

# ==== 以下为手动追加的业务域名 ====

# 业务后台
172.1.7.162  admin.xx.com

# SOC 平台
172.1.7.200  biz-unit.aa.yy.com
172.1.7.200  api.bb.yy.com
为什么不用手动加 127.0.1.1 ip-172-1-7-33

这是本次排查中一个关键认知点:

  • 模板里的 127.0.1.1 {``{fqdn}} {``{hostname}}Jinja 模板变量,渲染时会被 cloud-init 自动替换成当前主机名。
  • 如果写死 127.0.1.1 ip-172-1-7-33,一旦主机名变化(例如实例更换 IP 后主机名自动变更),写死的记录就对不上,sudo 警告会重新出现。
  • {``{hostname}} / {``{fqdn}}永远匹配当前主机名,真正做到自愈。
模板变量 渲染结果(示例)
{``{hostname}} ip-172-1-7-33
{``{fqdn}} ip-172-1-7-33.ap-xxxx.compute.internal

步骤 4:立即重新渲染 hosts

不必等到重启,可用 cloud-init 手动触发一次渲染:

bash 复制代码
sudo cloud-init single --name update_etc_hosts --frequency always

五、结果验证

1. 查看生成后的 /etc/hosts

bash 复制代码
cat /etc/hosts

输出(已脱敏):

复制代码
# Your system has configured 'manage_etc_hosts' as True.
# As a result, if you wish for changes to this file to persist
# then you will need to either
# a.) make changes to the master file in /etc/cloud/templates/hosts.debian.tmpl
# b.) change or remove the value of 'manage_etc_hosts' in
#     /etc/cloud/cloud.cfg or cloud-config from user-data
#
127.0.1.1 ip-172-1-7-33.ap-xxxx.compute.internal ip-172-1-7-33
127.0.0.1 localhost

# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

# 业务后台
172.1.7.162 admin.xx.com
# SOC 平台
172.1.7.200  biz-unit.aa.yy.com
172.1.7.200  api.bb.yy.com

可以看到:

  • 127.0.1.1 那一行由模板变量自动渲染出了完整 FQDN 与主机名;
  • 三条业务域名完整保留。

2. 验证命令

bash 复制代码
# sudo 警告应消失,直接输出 root
sudo whoami

# 主机名可被解析
grep "$(hostname)" /etc/hosts

# 业务域名可正常解析
getent hosts admin.xx.com
getent hosts biz-unit.aa.yy.com
getent hosts api.bb.yy.com

预期:sudo whoami 不再出现 unable to resolve host 告警,业务域名均能返回对应 IP。


六、长期收益与维护规范

启用该方案后,这台机器获得以下能力:

  1. 重启不丢配置------cloud-init 每次以模板重建 hosts,主机名与业务域名均在。
  2. 主机名自愈 ------{``{hostname}} 动态填充,即使更换 IP / 主机名,sudo 警告也不会再出现。
  3. 集中管理------所有 hosts 变更统一在模板中维护。

⚠️ 维护红线

开启 manage_etc_hosts: true 后,禁止直接手动编辑 /etc/hosts,否则重启会被覆盖。

所有变更都应改模板文件 /etc/cloud/templates/hosts.debian.tmpl,然后执行:

bash 复制代码
sudo cloud-init single --name update_etc_hosts --frequency always

七、总结

环节 关键点
现象 sudo 报 unable to resolve host;且直接改 hosts 会被覆盖
根因 主机名无解析记录;cloud-init 的 manage_etc_hosts 会重建 hosts
方案 开启 manage_etc_hosts: true,改用模板管理
关键认知 模板里 {``{hostname}}/{``{fqdn}} 自动填主机名,无需写死
手动只需加 cloud-init 不知道的业务域名
维护规范 只改模板,不改 hosts;改完手动渲染一次

这次排查的核心思路是:先搞清楚"谁在管理这个文件",再顺着它的机制去做变更 ,而不是与自动化工具对抗。理解 manage_etc_hosts 的模板渲染机制后,问题从"反复丢配置"转变为"配置自愈",一劳永逸。

相关推荐
好评1242 小时前
【Linux】进程信号
linux·运维·服务器
zhangrelay2 小时前
ROS 2 Lyrical 第4章 URDF机器人建模与Gazebo Garden仿真
linux·笔记·学习·ubuntu·机器人·ros2
wuminyu2 小时前
JVM利用io_uring优化堆外内存性能原理剖析
java·linux·c语言·jvm·c++
xianyuCcCcCCCcc2 小时前
Nginx 深度解析:从基础架构到反向代理与负载均衡实战全解
linux·运维·nginx·bash·负载均衡
爱折腾的小码农3 小时前
解决Navicat 17 Premium Lite在Linux上运行报错“LIBSYSTEMD_251‘ not found”问题
linux·运维
曹牧3 小时前
C#:问号
前端·数据库·c#
奇树谦3 小时前
《现代 Key-Value 数据库原理:从 B+Tree 到 LSM Tree》-第五篇:现代数据库横向对比
数据库·lsm-tree
李白客3 小时前
分布式集群与数据库产业:从单机到集群的架构跃迁与市场重构
数据库·分布式·架构
Doraemomo3 小时前
Linux编程-标准IO和系统IO
linux·运维·服务器
骇客野人3 小时前
Linux 查看 Java 进程常用命令
java·linux·运维