it-swarm-vi.tech

Đặt tên máy chủ: FQDN hoặc tên ngắn?

Tôi đã nhận thấy rằng phương pháp "ưu tiên" để đặt tên máy chủ hệ thống về cơ bản là khác nhau giữa các hệ thống Red Hat/CentOS và Debian/Ubuntu.

Tài liệu CentOSHướng dẫn triển khai RHEL nói tên máy chủ nên là FQDN:

HOSTNAME=<value>, Ở đâu <value> phải là Tên miền đủ điều kiện (FQDN), chẳng hạn như hostname.example.com, nhưng có thể là bất cứ tên máy chủ nào là cần thiết.

Hướng dẫn cài đặt RHEL hơi mơ hồ hơn:

Thiết lập nhắc bạn cung cấp tên Máy chủ cho máy tính này, dưới dạng a tên miền đủ điều kiện (FQDN) ở định dạng hostname.domainname hoặc dưới dạng a Tên máy chủ ngắn ở định dạng tên máy chủ.

Tham chiếu Debian cho biết tên máy chủ không nên sử dụng FQDN:

3.5.5. Tên máy chủ

Hạt nhân duy trì tên máy chủ của hệ thống . Tập lệnh init trong runlevel S được liên kết với "/etc/init.d/hostname.sh " đặt tên máy chủ hệ thống khi khởi động (sử dụng lệnh hostname ) cho tên được lưu trữ trong "/etc/hostname " . Tệp này chỉ chứa tên máy chủ hệ thống, không phải tên miền đủ điều kiện.

Tôi chưa thấy bất kỳ khuyến nghị cụ thể nào từ IBM về việc nên sử dụng, nhưng một số phần mềm dường như có một ưu tiên.

Những câu hỏi của tôi:

  • Trong một môi trường không đồng nhất, tốt hơn là sử dụng đề xuất của nhà cung cấp, hoặc chọn một và nhất quán trên tất cả các máy chủ?
  • Bạn đã gặp phải phần mềm nào nhạy cảm với việc tên máy chủ được đặt thành FQDN hay tên ngắn?
187
Cakemox

Tôi sẽ chọn một cách tiếp cận nhất quán trên toàn bộ môi trường. Cả hai giải pháp đều hoạt động tốt và sẽ vẫn tương thích với hầu hết các ứng dụng. Có một sự khác biệt trong khả năng quản lý, mặc dù.

Tôi đi với tên ngắn là cài đặt HOSTNAME và đặt FQDN làm cột đầu tiên trong /etc/hosts cho IP của máy chủ, theo sau là tên ngắn.

Tôi chưa gặp phải nhiều gói phần mềm thực thi hoặc hiển thị tùy chọn giữa hai gói. Tôi thấy tên ngắn gọn để sạch hơn cho một số ứng dụng, cụ thể là đăng nhập. Có lẽ tôi đã không may mắn khi thấy các tên miền nội bộ như server.northside.chicago.rizzomanufacturing.com. Ai muốn thấy điều đó trong nhật ký hay Shell Prompt?

Đôi khi, tôi tham gia vào việc mua lại công ty hoặc tái cấu trúc nơi các tên miền nội bộ và/hoặc tên miền phụ thay đổi. Tôi thích sử dụng tên máy chủ ngắn trong các trường hợp này vì đăng nhập, khởi động, in, giám sát hệ thống, v.v. không cần cấu hình lại đầy đủ để tính toán cho các tên miền mới.

Một thiết lập máy chủ RHEL/CentOS điển hình cho máy chủ có tên "rizzo" với tên miền nội bộ "ifp.com", sẽ trông như sau:

/etc/sysconfig/network:
HOSTNAME=rizzo
...

-

/etc/hosts:
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

172.16.100.13   rizzo.ifp.com rizzo

-

[[email protected] ~]# hostname 
rizzo

-

/var/log/messages snippet:
Dec 15 10:10:13 rizzo proftpd[19675]: 172.16.100.13 (::ffff:206.15.236.182[::ffff:206.15.236.182]) - Preparing to               
 chroot to directory '/app/upload/GREEK'
Dec 15 10:10:51 rizzo proftpd[20660]: 172.16.100.13 (::ffff:12.28.170.2[::ffff:12.28.170.2]) - FTP session opened.
Dec 15 10:10:51 rizzo proftpd[20660]: 172.16.100.13 (::ffff:12.28.170.2[::ffff:12.28.170.2]) - Preparing to chroot                
to directory '/app/upload/ftp/SRRID'
110
ewwhite

Khá nhiều phần mềm rất nhạy cảm với việc đặt chính xác tên máy chủ. Trong khi tôi làm việc tại Digg, tôi đã từng đưa toàn bộ trang web xuống trong 2 giờ do thực hiện một thay đổi dường như vô hại trong /etc/hosts đã ảnh hưởng đến khái niệm tên máy chủ của hệ thống. Bước đi nhẹ nhàng. Điều đó nói rằng, bạn có thể hơi bối rối ở đây. Tôi không nghĩ rằng HOSTNAME= cài đặt tương đương trực tiếp với cách phân phối dựa trên Debian sử dụng /etc/hostname.

Những gì làm việc cho tôi trong một môi trường không đồng nhất là:

  1. Đặt tên máy chủ theo cách được nhà cung cấp khuyến nghị, sử dụng điều kiện trong phần mềm quản lý cấu hình của bạn.
  2. Sử dụng lệnh hostname để đặt tên máy chủ được sử dụng bởi kernel, v.v.
  3. Trong /etc/hosts:

    127.0.0.1    localhost
    10.0.0.1     hostname.example.com     hostname
    

Cấu hình này vẫn chưa làm tôi thất bại.

39
Paul Lathrop

Bạn chắc chắn sẽ không gặp vấn đề gì khi tìm tài liệu tham khảo trực tuyến, điều này sẽ cho bạn biết chắc chắn làm theo cách này hay cách khác. Tuy nhiên, đối với tôi, có một tên ngắn là tên máy chủ và có tên đủ điều kiện trong/etc/hosts chắc chắn là phổ biến hơn nhiều. Có vẻ như là cách hợp lý hơn, vì khi đó các dịch vụ cần một tên đủ điều kiện có thể được điều chỉnh để gọi hostname --fqdn thay thế.

Gần đây tôi chỉ bắt gặp một phần mềm mà yêu cầu một fqd phải được trả về bởi hostname, đó là ganeti. Họ tài liệu này ở đây . Tôi không thấy bất kỳ lý do nào họ không thể thích nghi với hostname --fqdn, Tuy nhiên.

36
stew

Một cách tiếp tuyến, trong khi nghiên cứu câu hỏi này, tôi đã phát điên đến mức phải kiểm tra mã nguồn của "tên máy chủ" và viết một kịch bản để in kết quả điều tra (Fedora 19). Điều còn thiếu là một cái nhìn vào "/ etc/hosts", theo quan điểm khiêm tốn của tôi, nên tránh xa tất cả những điều này ngay từ đầu.

#!/bin/bash

function pad {
   if [[ $1 == '?' ]]; then
      printf "%-23s" "?"
   else
      printf "%-23s" "'$1'"
   fi
}

# ----- Kernel -----

# Two ways to configure the kernel values: 
# 1) Put FQDN into "kernel.hostname" and nothing into "kernel.domainname"
# 2) Put machine name into "kernel.hostname" and DNS domain name into "kernel.domainname" (makes more sense)

echo "== Kernel values =="
echo

H=`/sbin/sysctl -n kernel.hostname`
D=`/sbin/sysctl -n kernel.domainname`

echo "Kernel hostname: '$H'"
echo "Kernel domainname: '$D'"

# ----- What does bash say -----

echo
echo "== According to bash =="
echo

echo "HOSTNAME = '$HOSTNAME'"

# ----- Hostname config file ------

echo
echo "== Hostname config file =="
echo

ETCH="/etc/hostname"

if [[ -f $ETCH ]]; then
   CONTENTS=`cat $ETCH`
   echo "File '$ETCH' contains: '$CONTENTS'"
else
   echo "File '$ETCH' does not exist"
fi

# ----- Network config file ------

echo
echo "== Network config file =="
echo

SYSN="/etc/sysconfig/network"

if [[ -f $SYSN ]]; then
   LINE=`grep -e "^HOSTNAME=" $SYSN`
   if [[ -n $LINE ]]; then
      echo "File '$SYSN' contains: '$LINE'"
   else 
      echo "File '$SYSN' exists but does not contain a line for 'HOSTNAME'"
   fi
else
   echo "File '$SYSN' does not exist"
fi

# ----- Nodename -------

echo
echo "== Nodename =="
echo

UNAME=`uname --nodename` # On Linux, this is the hostname

echo "The 'nodename' given by 'uname --nodename' is: '$UNAME'"

# ----- The 'hostname' mess ------

THE_HOSTNAME=`hostname`
SHORT_NAME=`hostname --short`
NIS_DNAME=`domainname`     
YP_DNAME=`hostname --yp`    # Same as `nisdomainname` ; this may fail with "hostname: Local domain name not set"

if [[ $? != 0 ]]; then
   YP_DNAME="?"
fi

echo
echo "== 'hostname' directly obtained values =="
echo
echo "The result of gethostname();"
echo "...obtained by running 'hostname'"
echo "Hostname: $(pad $THE_HOSTNAME)"
echo
echo "The part before the first '.' of the value returned by gethostname();"
echo "...obtained by running 'hostname --short'"
echo "Short name: $(pad $SHORT_NAME)"
echo
echo "The result of getdomainname(); the code of 'hostname' seems to call this the 'NIS domain name';"
echo "...on Linux, this is the kernel-configured domainname;"
echo "...obtained by running 'domainname'"
echo "NIS domain name: $(pad $NIS_DNAME)"
echo
echo "The result of yp_get_default_domain(), which may fail;"
echo "...obtained by running 'ĥostname --yp'"
echo "YP default domain: $(pad $YP_DNAME)"

DNS_DNAME=`hostname --domain`  # Same as `dnsdomainname`'
FQDN_NAME=`hostname --fqdn`
ALIAS_NAME=`hostname --alias`

echo
echo "== 'hostname' values obtained via DNS =="
echo
echo "The part after the first '.' of the 'canonical name' value returned by getaddrinfo(gethostname());"
echo "...obtained by running 'hostname --domain'"
echo "DNS domain name: $(pad $DNS_DNAME)"
echo
echo "The 'canonical name' value returned by getaddrinfo(gethostname());"
echo "...obtained by running 'hostname --fqdn'"
echo "Fully qualified hostname: $(pad $FQDN_NAME)"
echo
echo "Alias obtained by gethostbyname(gethostname());"
echo "...obtained by running 'hostname --alias'"
echo "Hostname alias: $(pad $ALIAS_NAME)"

BY_IP_ADDR=`hostname --ip-address`
ALL_IP_ADDR=`hostname --all-ip-addresses`
ALL_FQDN_NAMES=`hostname --all-fqdn`

echo
echo "== 'hostname' values obtained by collecting configured network addresses =="
echo
echo "Collect the IP addresses from getaddrinfo(gethostname()), apply getnameinfo(ip) to all those addresses;"
echo "...obtained by running 'hostname --ip-address'"
echo "By IP address: $BY_IP_ADDR"
echo
echo "Call getnameinfo(NI_NUMERICHOST) on all addresses snarfed from active interfaces;"
echo "...obtained by running 'hostname --all-ip-addresses'"
echo "All IP addresses: $ALL_IP_ADDR"
echo
echo "Call getnameinfo(NI_NAMEREQD) on all addresses snarfed from active interfaces (involves lookup in /etc/hosts);"
echo "...obtained by running 'hostname --all-fqdn'"
echo "All fully qualified hostnames: $ALL_FQDN_NAMES"

Đầu ra trên Amazon EC2 VM chạy Fedora 19, sau khi cài đặt thủ công các giá trị kernel và điền /etc/hostname, nhưng không có thay đổi đối với /etc/hosts sau đó có thể như thế này:

== Kernel values ==

Kernel hostname: 'kyubee'
Kernel domainname: 'homelinux.org'

== According to bash ==

HOSTNAME = 'ip-172-31-24-249.localdomain'

== Hostname config file ==

File '/etc/hostname' contains: 'kyubee.homelinux.org'

== Network config file ==

File '/etc/sysconfig/network' exists but does not contain a line for 'HOSTNAME'

== Nodename ==

The 'nodename' given by 'uname --nodename' is: 'kyubee'

== 'hostname' directly obtained values ==

The result of gethostname();
...obtained by running 'hostname'
Hostname: 'kyubee'

The part before the first '.' of the value returned by gethostname();
...obtained by running 'hostname --short'
Short name: 'kyubee'

The result of getdomainname(); the code of 'hostname' seems to call this the 'NIS domain name';
...on Linux, this is the kernel-configured domainname;
...obtained by running 'domainname'
NIS domain name: 'homelinux.org'

The result of yp_get_default_domain(), which may fail;
...obtained by running 'ĥostname --yp'
YP default domain: 'homelinux.org'

== 'hostname' values obtained via DNS ==

The part after the first '.' of the 'canonical name' value returned by getaddrinfo(gethostname());
...obtained by running 'hostname --domain'
DNS domain name: ''

The 'canonical name' value returned by getaddrinfo(gethostname());
...obtained by running 'hostname --fqdn'
Fully qualified hostname: 'kyubee'

Alias obtained by gethostbyname(gethostname());
...obtained by running 'hostname --alias'
Hostname alias: ''

== 'hostname' values obtained by collecting configured network addresses ==

Collect the IP addresses from getaddrinfo(gethostname()), apply getnameinfo(ip) to all those addresses;
...obtained by running 'hostname --ip-address'
By IP address: fe80::8f6:8eff:fe49:9e21%eth0 172.31.24.249

Call getnameinfo(NI_NUMERICHOST) on all addresses snarfed from active interfaces;
...obtained by running 'hostname --all-ip-addresses'
All IP addresses: 172.31.24.249

Call getnameinfo(NI_NAMEREQD) on all addresses snarfed from active interfaces (involves lookup in /etc/hosts);
...obtained by running 'hostname --all-fqdn'
All fully qualified hostnames: ip-172-31-24-249.eu-west-1.compute.internal

Cách linh hoạt để có được tên máy chủ đủ điều kiện trong Perl sau đó sẽ là:

sub getHostname {

   my $hostname_short = `/bin/hostname --short`;
   if ($? != 0) { print STDERR "Could not execute 'hostname --short' -- exiting\n"; exit 1 }
   chomp $hostname_short;

   my $hostname_long  = `/bin/hostname`;
   if ($? != 0) { print STDERR "Could not execute 'hostname' -- exiting\n"; exit 1 }
   chomp $hostname_long;

   if ($hostname_long =~ /^${hostname_short}\..+$/) {
      # "hostname_long" is a qualified version of "hostname_short"
      return $hostname_long
   }
   else {
      # both hostnames are "short" (and are equal)
      die unless ($hostname_long eq $hostname_short);

      my $domainname = `/bin/domainname`;
      if ($? != 0) { print STDERR "Could not execute 'domainname' -- exiting\n"; exit 1 }
      chomp $domainname;

      if ($domainname eq "(none)") {
         # Change according to taste
         return "${hostname_short}.localdomain"
      }
      else {
         return "${hostname_short}.${domainname}"
      }
   }
}

và trong bash nó sẽ là:

function getHostname {

   local hostname_short=`/bin/hostname --short`

   if [ $? -ne 0 ]; then
      echo "Could not execute 'hostname --short' -- exiting" >&2; exit 1
   fi

   local hostname_long=`/bin/hostname`

   if [ $? -ne 0 ]; then
      echo "Could not execute 'hostname' -- exiting" >&2; exit 1
   fi

   if [[ $hostname_long =~ ^"$hostname_short"\..+$ ]]; then
      # "hostname_long" is a qualified version of "hostname_short"
      echo $hostname_long
   else
      # both hostnames are "short" (and are equal)
      if [[ $hostname_long != $hostname_short ]]; then
         echo "Cannot happen: '$hostname_long' <> '$hostname_short' -- exiting" >&2; exit 1
      fi

      local domainname=`/bin/domainname`

      if [ $? -ne 0 ]; then
         echo "Could not execute 'domainname' -- exiting" >&2; exit 1
      fi

      if [[ domainname == '(none)' ]]; then
         # Change according to taste
         echo "${hostname_short}.localdomain"
      else
         echo "${hostname_short}.${domainname}"
      fi
   fi
}

Ghi chú

Lưu ý 1: HOSTNAME là biến Shell mà bash cung cấp ("Tự động đặt thành tên của Máy chủ hiện tại.") Nhưng không có dấu hiệu nào cho thấy bash đến giá trị đó.

Lưu ý 2: Không bao giờ quên/etc/tên máy chủ trong /boot/initrams-FOO.img ...

13
David Tonhofer