向群集中的所有节点授权每个节点的ssh密钥的最佳方法

问题描述 投票:0回答:1

我想创建一个群集基础结构,每个节点都通过shh与其他节点通信。我想使用ansible创建一个idempotent剧本/角色,可以在初始化集群或将新节点添加到集群时执行。我能够想到两种实现此目的的方案。

第一个场景

  • task 1从节点获取ssh密钥(可能将其分配给变量或写入文件)。
  • 然后执行task 2locally循环其他节点,并使用获取的密钥授权第一个节点。

此业务情景支持free strategy。无需等待所有主机即可执行任务。但这也要求所有节点都具有相关的用户和公用密钥。因为如果您要在同一个剧本中创建用户(由于免费策略),task 2开始运行时,可能会在集群中的其他节点上没有创建用户。

First Scenario

尽管我是自由策略的忠实拥护者,但出于效率考虑,我不实施这种方案。它使“N节点群集。

第二场景

  • task 1从所有节点按顺序获取ssh密钥。然后将每个文件写入根据ansible_hostname设置名称的文件。
  • 然后执行task 2locally循环遍历其他节点并授权所有密钥。

此方案仅支持linear strategy。由于采用线性策略,您可以在同一个剧本中创建用户,所有用户将在task 1开始运行之前创建。

Second Scenario

我认为这是一种有效的方案。这使得仅“2n”连接“节点群集。我实现了它,然后放了我写的代码段。

---
- name: create node user
  user:
    name: "{{ node_user }}"
    password: "{{ node_user_pass |password_hash('sha512') }}"
    shell: /bin/bash
    create_home: yes
    generate_ssh_key: yes

- name: fetch all public keys from managed nodes to manager
  fetch: 
    src: "/home/{{ node_user }}/.ssh/id_rsa.pub"
    dest: "tmp/{{ ansible_hostname }}-id_rsa.pub"
    flat: yes

- name: authorize public key for all nodes
  authorized_key:
    user: "{{ node_user }}"
    key: "{{ lookup('file', 'tmp/{{ item }}-id_rsa.pub')}}"
    state: present
  with_items:
    - "{{ groups['cluster_node'] }}"

- name: remove local public key copies
  become: false
  local_action: file dest='tmp/' state=absent
  changed_when: false
  run_once: true

也许我可以使用lineinfile代替fetch,但除此之外,我不知道这是否是正确的方法。群集大小变大时需要花费很长时间(由于线性策略)。有没有我可以使用的更有效的方法?

linux ssh ansible ssh-keys ansible-role
1个回答
1
投票

[当Ansible遍历authorized_key时,它将(大致)执行以下任务:

  1. 在控制节点上创建一个临时的authorized_key python脚本
  2. 将新的authorized_key python脚本复制到受管节点
  3. 使用适当的参数在受管节点上运行authorized_key python脚本

随着管理节点数的增加,这增加n 2;如果有1000箱,则每箱执行1000次此任务。

我在查找能够正确解释exactly幕后动态的特定文档时遇到麻烦,因此,我建议运行示例脚本以了解一下情况:

- hosts: all
  tasks:
    - name: do thing
      shell: "echo \"hello this is {{item}}\""
      with_items:
        - alice
        - brian
        - charlie

应与三重详细标志(-vvv)一起运行,并将输出通过管道传递到./ansible.log(例如ansible-playbook example-loop.yml -i hosts.yml -vvv > example-loop-output.log)。在这些日志中搜索command.pysftp将有助于您了解随着"{{ groups['cluster_node'] }}"检索到的列表的增加,脚本的扩展方式。

对于小型集群,这种低效率是完全可以接受的。但是,在大型群集上可能会出现问题。

现在,authorized_key模块实质上只是生成一个aa_authorized_keys文件,其中a)已经存在于authorized_keys中的密钥,以及b)集群上每个节点的公共密钥。我们可以在控制节点上构造authorized_keys文件,然后将其部署到每个盒子,而不是在每个盒子上分别重复生成authorized_keys文件。

authorized_keys文件本身可以用assemble生成;这将采用所有收集的键并将它们连接到一个文件中。但是,如果仅将synchronizecopy这个文件结束,我们将清除添加到authorized_keys中的所有非集群键。为了避免这种情况,我们可以使用blockinfileblockinfile可以管理Ansible添加的群集密钥。我们将能够在删除过时的密钥的同时添加新密钥。

- hosts: cluster
  name: create node user and generate keys
  tasks:
    - name: create node user
      user:
        name: "{{ node_user }}"
        password: "{{ node_user_pass |password_hash('sha512') }}"
        shell: /bin/bash
        create_home: yes
        generate_ssh_key: yes

    - name: fetch all public keys from managed nodes to manager
      fetch:
        src: "/home/{{ node_user }}/.ssh/id_rsa.pub"
        dest: "/tmp/keys/{{ ansible_host }}-id_rsa.pub"
        flat: yes
  become: yes

- hosts: localhost
  name: generate authorized_keys file
  tasks:
    - name: Assemble authorized_keys from a directory
      assemble:
        src: "/tmp/keys"
        dest: "/tmp/authorized_keys"

- hosts: cluster
  name: update authorized_keys file
  tasks:
   - name: insert/update configuration using a local file
     blockinfile:
       block: "{{ lookup('file', '/tmp/authorized_keys') }}"
       dest: "/home/{{ node_user }}/.ssh/authorized_keys"
       backup: yes
       create: yes
       owner: "{{ node_user }}"
       group: "{{ node_group }}"
       mode: 0600
  become: yes

原样,此解决方案不容易与角色兼容;角色被设计为仅处理主机(主机,组,组的集合等)的单个值,并且以上解决方案要求在组和本地主机之间切换。

我们可以用delegate_to对此进行补救,尽管在大型集群中它可能效率不高,因为集群中的每个节点都将尝试组装authorized_keys。根据ansible项目的总体结构(以及团队的规模),这可能是理想的,也可能不是理想的;当用delegate_to浏览大脚本时,很容易会漏掉某些正在本地执行的脚本。

 - hosts: cluster
      name: create node user and generate keys
      tasks:
        - name: create node user
          user:
            name: "{{ node_user }}"
            password: "{{ node_user_pass |password_hash('sha512') }}"
            shell: /bin/bash
            create_home: yes
            generate_ssh_key: yes

        - name: fetch all public keys from managed nodes to manager
          fetch:
            src: "/home/{{ node_user }}/.ssh/id_rsa.pub"
            dest: "/tmp/keys/{{ ansible_host }}-id_rsa.pub"
            flat: yes

        - name: Assemble authorized_keys from a directory
          assemble:
            src: "/tmp/keys"
            dest: "/tmp/authorized_keys"
          delegate_to: localhost

        - name: insert/update configuration using a local file
          blockinfile:
            block: "{{ lookup('file', '/tmp/authorized_keys') }}"
            dest: "/home/{{ node_user }}/.ssh/authorized_keys"
            backup: yes
            create: yes
            owner: "{{ node_user }}"
            group: "{{ node_group }}"
            mode: 0600
      become: yes
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.