以前寫過一篇博客「深刻理解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