以前写过一篇博客“深刻理解Linux修改hostname”,里面总结了RHEL 5.7下面如何修改hostname,固然这篇博客的内容其实也适用于CentOS 6,可是自CentOS 7开始,已经跟CentOS 6已经有很大不一样了,一直没有总结CentOS 7下修改hostname的相关知识点,今天刚好遇到了这个问题,处理完后遂总结一下。html
CentOS 7中的启动跟CentOS 6有所区别,CentOS 6启动过程当中,会执行/etc/rc.d/rc.sysinit init执行的第一个脚本 这个脚本主要是初始化工做,如设置系统字体,启动swapping,设置主机名等等。CentOS7和CentOS6启动流程差很少,只不过到init程序时候,改成了systemd启动了(并行启动),也就是说CentOS 7不会去执行/etc/rc.d/rc.sysinit这个文件(固然也没有这个文件了)读取hostname的配置,CentOS 7新增了配置文件/etc/hostname,系统启动的时候会读取/etc/hostname这个配置文件来初始化内核主机名。 git
另外,咱们能够经过配置/etc/hostname修改hostname。也能够经过新增的hostnamectl命令修改。在CentOS 7中,主机名能够分为下面三种类型:github
· 静态主机名(static):静态主机名也称为内核主机名,是系统在启动时初始化内核的主机名,默认从/etc/hostname读取配置自动初始化静态主机名centos
· 瞬态主机名(transient):瞬时主机名是在系统运行时临时分配的主机名,例如,由DHCP等一些系统临时分配的主机名,若是系统存在静态主机名且有效,则不会用到瞬态主机名。服务器
· 灵活主机名(pretty):静态和瞬态主机名都是要符合域名的字符串,而pretty主机名则能够包含其余一些特殊字符。app
There are three 3 types of hostnames.dom
The static (configured) host name is the one configured in /etc/hostname or a similar file. It is chosen by the local user. It is not always in sync with the current host name as returned by the gethostname() system call. If no host name is configured this property will be the empty string. Setting this property to the empty string will remove /etc/hostname. This hostname should be an internet-style hostname, 7bit ASCII, no special chars/spaces, lower case.ide
The transient (dynamic) host name is the one configured via the kernel's sethostbyname(). It can be different from the static hostname in case DHCP or mDNS have been configured to change the name based on network information. This property is never empty. If no host name is set this will default to "localhost". Setting this property to the empty string will reset the dynamic hostname to the static host name. If no static host name is configured the dynamic host name will be reset to "localhost". This hostname should be an internet-style hostname, 7bit ASCII, no special chars/spaces, lower case.测试
The pretty host name is a free-form UTF8 host name for presentation to the user. UIs should ensure that the pretty hostname and the static hostname stay in sync. I.e. when the former is "Lennart's Computer" the latter should be "lennarts-computer". If no pretty host name is set this setting will be the empty string. Applications should then find a suitable fallback, such as the dynamic hostname.字体
如上英文介绍,静态主机名保存在/etc/hostname中,灵活主机名保存在/etc/machine-info,而瞬态主机名通常由内核参数维护,重启后会丢失。
查看主机名(hostname)
咱们能够有不少方式查看主机名,可是咱们只能使用命令hostnamectl查看静态、瞬态或灵活主机名,分别使用--static,--transient或--pretty参数。
[root@MyDB ~]# hostname
MyDB
[root@MyDB ~]# cat /etc/hostname
MyDB
[root@MyDB ~]# hostnamectl status
Static hostname: localhost.localdomain
Transient hostname: MyDB
Icon name: computer-desktop
Chassis: desktop
Machine ID: 955dde0d8f7341ebb19a1e247577c410
Boot ID: 4f2df049135e41c795a655cdf36c1c40
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-862.el7.x86_64
Architecture: x86-64
[root@MyDB ~]# hostnamectl
Static hostname: MyDB
Pretty hostname: kerry's db
Icon name: computer-desktop
Chassis: desktop
Machine ID: 955dde0d8f7341ebb19a1e247577c410
Boot ID: 459eb877eeb34d7e910f4eec8ef4a42f
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-862.el7.x86_64
Architecture: x86-64
[root@MyDB ~]# hostnamectl --static #查看静态主机名
MyDB
[root@MyDB ~]# hostnamectl --transient #查看瞬时主机名
MyDB
[root@MyDB ~]# hostnamectl --pretty #查看灵活主机名
kerry's db
设置静态主机名
[root@MyDB ~]# hostnamectl set-hostname kerrydb
或
[root@MyDB ~]# hostnamectl set-hostname --static kerrydb
设置静态主机名立对新链接的会话当即生效,可是对于当前链接则不生效(例如,SecureCRT新开一个窗口就能看到修改结果)。以下测试所,修改静态主机名会当即修改内核中的kernel.hostname
[root@MyDB ~]# hostnamectl set-hostname MyDB
[root@MyDB ~]#
[root@MyDB ~]# cat /proc/sys/kernel/hostname
mydb
[root@MyDB ~]# hostnamectl set-hostname kerrydb
[root@MyDB ~]# cat /proc/sys/kernel/hostname
kerrydb
[root@MyDB ~]# hostnamectl set-hostname --static yourdb
[root@MyDB ~]# cat /proc/sys/kernel/hostname
yourdb
[root@MyDB ~]#
另外,hostnamectl命令是永久修改hostname,这个命令修改静态主机名,不关会设置内核参数kernel.hostname,它还会当即修改配置文件/etc/hostname,有兴趣能够本身测试一下。
[root@MyDB ~]# more /etc/hostname
yourdb
设置瞬态主机名
[root@yourdb ~]# hostnamectl set-hostname --transient "KerryDB"
注意:若是系统存在静态主机名且有效,则不会用到瞬态主机名。
设置灵活主机名
[root@yourdb etc]# hostnamectl set-hostname --pretty "kerry's db"
没有设置灵活主机名前,此文件可能不存在(以下所示)
[root@yourdb ~]# cat /etc/machine-info
cat: /etc/machine-info: No such file or directory
设置后,就能查看此文件(以下所示)
[root@yourdb etc]# cat /etc/machine-info
PRETTY_HOSTNAME="kerry's db"
一些问题测试
问题:若是同时设置了/etc/hosts和/etc/hostname,那么服务器重启时,它会读取哪一个文件? 咱们设置一下这两个后(以下所示),而后重启服务器
[root@MyDB ~]# more /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
10.20.57.24 MyDB MyDB.localdomain
[root@MyDB ~]# more /etc/hostname
YourDB
重启事后,你会发现静态主机名为YourDB,也就是说重启时读取/etc/hostname这个配置文件来初始化内核主机名,那么咱们将/etc/hostname中的静态主机名置空,而后重启服务器。
[root@YourDB ~]# cat /dev/null > /etc/hostname
[root@YourDB ~]# more /etc/hostname
[root@YourDB ~]# reboot
测试验证发现,静态主机名变为了n/a,可是显示的主机名为MyDB,那么是否读取了/etc/hosts中的配置呢?咱们查看日志,发现下面一些信息。
[root@MyDB ~]# hostname
MyDB
[root@MyDB ~]# hostnamectl
Static hostname: n/a
Pretty hostname: kerry's db
Transient hostname: MyDB
Icon name: computer-desktop
Chassis: desktop
Machine ID: 955dde0d8f7341ebb19a1e247577c410
Boot ID: dfdaa6d51f3942b18d2de98dea2b8906
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux
咱们发现系统启动的时候,在NetworkManager中从新设置hostname的值。具体以下所示:
[root@MyDB ~]# journalctl -xb | grep hostname
Nov 04 16:03:03 localhost.localdomain systemd[1]: Set hostname to <localhost.localdomain>.
Nov 04 16:03:15 localhost.localdomain dbus[716]: [system] Activating via systemd: service name='org.freedesktop.hostname1' unit='dbus-org.freedesktop.hostname1.service'
-- Subject: Unit systemd-hostnamed.service has begun start-up
-- Unit systemd-hostnamed.service has begun starting up.
Nov 04 16:03:15 localhost.localdomain dbus[716]: [system] Successfully activated service 'org.freedesktop.hostname1'
-- Subject: Unit systemd-hostnamed.service has finished start-up
-- Unit systemd-hostnamed.service has finished starting up.
Nov 04 16:03:15 localhost.localdomain NetworkManager[743]: <info> [1572854595.8531] hostname: hostname: using hostnamed
Nov 04 16:03:15 localhost.localdomain nm-dispatcher[856]: req:1 'hostname': new request (2 scripts)
Nov 04 16:03:15 localhost.localdomain nm-dispatcher[856]: req:1 'hostname': start running ordered scripts...
Nov 04 16:03:20 localhost.localdomain NetworkManager[743]: <info> [1572854600.1230] policy: set-hostname: set hostname to 'MyDB' (from address lookup)
Nov 04 16:03:20 MyDB systemd-hostnamed[836]: Changed host name to 'MyDB'
Nov 04 16:03:20 MyDB nm-dispatcher[856]: req:4 'hostname': new request (2 scripts)
Nov 04 16:03:20 MyDB nm-dispatcher[856]: req:4 'hostname': start running ordered scripts...
而后咱们从NetworkManager/src/nm-policy.c找到以下代码,简单撸了一下代码,虽然尚未找到直接读取/etc/hosts中hostname的直接证据(C语言已经遗忘的七七八八了,也不想花太多时间深刻!),可是实验测试,当/etc/hostname为空时,确实会读取/etc/hosts下面的主机名信息。另外,有点能够确认的是,当/etc/hostname为空时,代码里面首先会将hostname设置为“localhost.localdomain”, 而后,调用_set_hostnam从新设置。
#define FALLBACK_HOSTNAME4 "localhost.localdomain"
static void
_set_hostname (NMPolicy *self,
const char *new_hostname,
const char *msg)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
gs_free char *old_hostname = NULL;
const char *name;
/* The incoming hostname *can* be NULL, which will get translated to
* 'localhost.localdomain' or such in the hostname policy code, but we
* keep cur_hostname = NULL in the case because we need to know that
* there was no valid hostname to start with.
*/
/* Clear lookup addresses if we have a hostname, so that we don't
* restart the reverse lookup thread later.
*/
if (new_hostname)
g_clear_object (&priv->lookup.addr);
/* Update the DNS only if the hostname is actually
* going to change.
*/
if (!nm_streq0 (priv->cur_hostname, new_hostname)) {
g_free (priv->cur_hostname);
priv->cur_hostname = g_strdup (new_hostname);
/* Notify the DNS manager of the hostname change so that the domain part, if
* present, can be added to the search list.
*/
nm_dns_manager_set_hostname (priv->dns_manager, priv->cur_hostname,
all_devices_not_active (self));
}
/* Finally, set kernel hostname */
if (!new_hostname)
name = FALLBACK_HOSTNAME4;
else if (!new_hostname[0]) {
g_warn_if_reached ();
name = FALLBACK_HOSTNAME4;
} else
name = new_hostname;
/* Don't set the hostname if it isn't actually changing */
if ( (old_hostname = _get_hostname (self))
&& (nm_streq (name, old_hostname))) {
_LOGT (LOGD_DNS, "set-hostname: hostname already set to '%s' (%s)", name, msg);
return;
}
/* Keep track of the last set hostname */
g_free (priv->last_hostname);
priv->last_hostname = g_strdup (name);
priv->changing_hostname = TRUE;
_LOGI (LOGD_DNS, "set-hostname: set hostname to '%s' (%s)", name, msg);
/* Ask NMSettings to update the transient hostname using its
* systemd-hostnamed proxy */
nm_hostname_manager_set_transient_hostname (priv->hostname_manager,
name,
settings_set_hostname_cb,
g_object_ref (self));
}
参考资料:
https://github.com/NetworkManager/NetworkManager/blob/master/src/nm-policy.c