4

在将主机名分配给服务器之前,有没有人有更好的解决方案来配置具有主机名的实例?

假设我们正在使用 AWS 并实例化实例ec2-1-2-3-4.compute-1.amazonaws.com。配置完成后,我们最终会在new-instance.example.com的 DNS 中为其分配一个 CNAME,以替换已经投入生产的现有实例。

new-instance.example.com已经存在并且正在生产中,因此我们无法将 CNAME 重新分配给ec2-1-2-3-4.compute-1.amazonaws.com直到机器配置正确并且我们准备切换。但是,我们现在希望实例上的内部配置文件和主机名是new-instance.example.com,以便为 DNS 更改做准备。所以我们不能使用inventory_hostname变量,因为它将是ec2-1-2-3-4.compute-1.amazonaws.com。我也有不需要使用新主机名的普通生产服务器,所以我希望能够将现有的inventory_hostname与它们一起使用。

到目前为止,我最好的想法是在库存文件中分配一个变量:

[production]
ec2-1-2-3-4.compute-1.amazonaws.com new_hostname=new-instance.example.com

在剧本中,我可以测试是否存在new_hostname。如果new_hostname存在,则使用它,如果不存在,则使用inventory_hostname。这将导致致命错误,除非error_on_undefined_vars设置为false并且我不希望设置它以提供防止拼写错误的好处。下面是一个失败的例子。

测试手册:

- hosts: all
  tasks:
    - name: "Debug hostname"
      debug: msg="inventory_hostname={{ inventory_hostname }}, hostvars[inventory_hostname]['inventory_hostname']={{ hostvars[inventory_hostname]['inventory_hostname'] }}, ansible_hostname={{ ansible_hostname }}, new_hostname={{ new_hostname }}"
      ignore_errors: yes

结果:

TASK: [Debug hostname] ********************************************************
fatal: [ec2-1-2-3-4.compute-1.amazonaws.com] => One or more undefined variables: 'new_hostname' is undefined

为每台服务器设置new_hostname是可行的,但我不想为每台服务器都设置它,只是那些需要新主机名的服务器。它还破坏了主机名分组,例如:

ec2-1-2-3-[4:5].compute-1.amazonaws.com

如果new_hostname存在,则有效:

- name: "set hostname fact"
  set_fact: testvar1={{ new_hostname }} || {{ inventory_hostname }}

- name: "show hostname fact"
  debug: msg="testvar1={{ testvar1 }}"

结果:

TASK: [set hostname fact] *****************************************************
ok: [ec2-1-2-3-4.compute-1.amazonaws.com]

TASK: [show hostname fact] ****************************************************
ok: [ec2-1-2-3-4.compute-1.amazonaws.com] => {"msg": "testvar1=new-instance.example.com"}

但是,如果error_on_undefined_vars设置为默认值true,并且未设置new_hostname,则会失败。

此策略的最佳实践?

4

4 回答 4

7

对此非常害羞,因为我也是 ansible 的新手,如果我理解您的问题,一种方法是when: something is defined在任务中使用。

例子:

  tasks:
    - name: "Debug hostname"
      debug: msg="inventory_hostname={{ inventory_hostname }}, hostvars[inventory_hostname]['inventory_hostname']={{ hostvars[inventory_hostname]['inventory_hostname'] }}, ansible_hostname={{ ansible_hostname }}, new_hostname={{ new_hostname }}"
      when: new_hostname is defined

现在这是一种方法。另一种方法是为此扮演一个角色,并且仅从清单中的添加条目中单独扮演目标机器的角色(旋转过程)。如果您也喜欢阅读最佳实践,请查看最佳实践。

于 2014-02-12T22:26:29.997 回答
4

站立时cloud-init设置主机名。(我使用 Chef,但这与这里的解决方案无关)。这解决了在您的自动化框架中设置主机名的问题,因为它在节点启动时已经设置。

我的云配置的一部分设置了fqdnmanage_etc_hosts选项,如下所示:

fqdn: new-instance.example.com
manage_etc_hosts: true

在doc/examples 目录中有很多示例配置片段,很容易玩转并找到您喜欢的设置。

于 2014-02-13T05:48:59.203 回答
3

如果您的 DNS 名称具有模式,则一种方法when如下,假设您始终定义new_hostname变量:

- include: tasks/sometasks.yml
  when: "'new' in new_hostname"

然后你可以new_hostname像你提到的那样在你的库存中定义变量:

[production]
ec2-1-2-3-4.compute-1.amazonaws.com new_hostname=new-instance.example.com
ec2-5-6-7-8.compute-1.amazonaws.com new_hostname=nada

这里的关键始终是定义变量并查找匹配或不匹配的模式。您的库存和命令行变量应该覆盖您的剧本变量。

要将其更多地应用于您的案例:

tasks:
  - name: "set hostname fact"
    set_fact: testvar1={{ new_hostname }}
    when: "'new' in new_hostname"

  - name: "set hostname fact"
    set_fact: testvar1={{ inventory_hostname }}
    when: "'nada' in new_hostname"

要记住的是不要new_hostname在你的剧本中定义变量,否则你的库存变量将被覆盖。

此外,您不想通过命令行传递它,这也会覆盖清单文件中定义的命令行(对于您的所有服务器):

ansible-playbook -i <your-inventory> -e "new_hostname=new-instance.example.com" yourplaybook.xml

这是根据 Ansible 变量优先级:

  • -e 变量总是获胜
  • 然后是“大多数其他东西”
  • 然后是库存中定义的变量
  • 然后是“角色默认值”,这是最“默认”的,失去了一切的优先权。
于 2014-02-12T23:22:53.883 回答
0
[production]]

ec2-1-2-3-4.compute-1.amazonaws.com new_hostname=new-instance.example.com

我认为这样设置主机名是可以的,但是 Ansible 可能需要单独的主机

  tasks:

     - name: change name

       raw: "echo {{new_hostname|quote}} > /etc/hostname"

     - name:

       shell: hostname {{new_hostname|quote}}
于 2020-08-23T07:41:14.747 回答