AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1156687
Accepted
Konstantin
Konstantin
Asked: 2024-03-22 00:50:43 +0800 CST2024-03-22 00:50:43 +0800 CST 2024-03-22 00:50:43 +0800 CST

为 Prometheus 创建配置文件

  • 772

库存文件(inventories/test/environments/tmp6.yml):

test:
  children:
    environments:
      children:
        tmp6:

tmp6:
  vars:
    ansible_user: superuser
    ansible_password: superuser
    ansible_become_password: "{{ ansible_password }}"
  children:
    infra:
      hosts:
        host_5:
          ansible_host: 192.168.1.72
        host_6:
          ansible_host: 192.168.1.83
    tools:
      hosts:
        host_7:
          ansible_host: 192.168.1.239
        host_8:
          ansible_host: 192.168.1.46

一般的playbook.yml:

- hosts: environments
  roles:
    - role: host-configuration
    - role: host-users
    - role: node-exporter
  post_tasks:
    - ansible.builtin.copy:
        content: |
          - target: 
              - {{ ansible_host }}:9100
            labels:
              environment_name: {{ inventory_file | ansible.builtin.basename | ansible.builtin.regex_replace('.yml$', '') }}
              environment_type: {{ inventory_file | ansible.builtin.dirname | ansible.builtin.dirname | ansible.builtin.basename }}
        dest: "./{{ inventory_file | ansible.builtin.basename }}"
      delegate_to: localhost

在节点上成功安装node_exporter后,需要创建环境的通用配置文件:

- target:
    - 192.168.1.72:9100
    - 192.168.1.83:9100
    - 192.168.1.239:9100
    - 192.168.1.46:9100
  labels:
    environment_name: tmp6
    environment_type: test

主要问题是制定目标清单。

如果创建这样一个模板:

- target: 
    - {{ ansible_host }}:9100
  labels:
    environment_name: {{ inventory_file | ansible.builtin.basename | ansible.builtin.regex_replace('.yml$', '') }}
    environment_type: {{ inventory_file | ansible.builtin.dirname | ansible.builtin.dirname | ansible.builtin.basename }}

变量的值ansible_host总是在变化。因此这不是一个解决方案。

如何在剧本中创建动态主机列表?

PS:Playbook可以应用于多种环境:

ansible-playbook playbook.yml -i inventories/test -l tmp1,tmp3,tmp6

一般任务:

  1. 在“环境”组的节点上安装node_exporter
  2. 在本地主机上创建通用配置文件
  3. 将配置文件复制到主机“prometheus”
ansible
  • 2 2 个回答
  • 120 Views

2 个回答

  • Voted
  1. larsks
    2024-03-22T09:15:48+08:002024-03-22T09:15:48+08:00

    如果使用多个环境,则必须创建多个文件

    Ansible 对你的“环境”一无所知。如果您想在剧本中使用该信息,则需要将其添加到您的库存中。例如,我们可以像这样添加environment_type和变量:environment_name

    test:
      vars:
        environment_type: test
      children:
        environments:
          children:
            tmp5:
            tmp6:
    
    tmp5:
      vars:
        environment_name: tmp5
      children:
        tmp5_infra:
          hosts:
            host_1:
              ansible_host: 192.168.1.1
            host_2:
              ansible_host: 192.168.1.2
        tmp5_tools:
          hosts:
            host_3:
              ansible_host: 192.168.1.3
            host_4:
              ansible_host: 192.168.1.4
    
    tmp6:
      vars:
        environment_name: tmp6
      children:
        tmp6_infra:
          hosts:
            host_5:
              ansible_host: 192.168.1.5
            host_6:
              ansible_host: 192.168.1.6
        tmp6_tools:
          hosts:
            host_7:
              ansible_host: 192.168.1.7
            host_8:
              ansible_host: 192.168.1.8
    

    给定上面的清单文件,我们可以编写如下的剧本:

    - hosts: environments
      gather_facts: false
      tasks:
    
        # This task groups hosts by environment_name
        - delegate_to: localhost
          run_once: true
          loop: "{{ ansible_play_hosts_all }}"
          set_fact:
            env_to_host: >
              {{ env_to_host|combine({
                hostvars[item].environment_name: env_to_host.get(hostvars[item].environment_name, []) + [item]
              })}}
          vars:
            env_to_host: {}
    
        - delegate_to: localhost
          run_once: true
          loop: "{{ env_to_host.keys() }}"
          copy:
            content: |
              - target: 
              {% for host in env_to_host[item] %}
                  - {{ hostvars[host].ansible_host }}:9100
              {% endfor %}
                labels:
                  environment_name: {{ item }}
                  environment_type: {{ hostvars[env_to_host[item]|first].environment_type }}
            dest: "./config-{{item}}.yaml"
    

    如果我们运行:

    ansible-playbook playbook.yaml
    

    我们得到:

    $ ls config*
    config-tmp5.yaml  config-tmp6.yaml
    $ cat config-tmp5.yaml
    - target:
        - 192.168.1.1:9100
        - 192.168.1.2:9100
        - 192.168.1.3:9100
        - 192.168.1.4:9100
      labels:
        environment_name: tmp5
        environment_type: test
    $ cat config-tmp6.yaml
    - target:
        - 192.168.1.5:9100
        - 192.168.1.6:9100
        - 192.168.1.7:9100
        - 192.168.1.8:9100
      labels:
        environment_name: tmp6
        environment_type: test
    

    如果我们受环境限制,像这样:

    ansible-playbook playbook.yaml -l tmp5
    

    我们得到:

    $ ls config*
    config-tmp5.yaml
    $ cat config-tmp5.yaml
    - target:
        - 192.168.1.1:9100
        - 192.168.1.2:9100
        - 192.168.1.3:9100
        - 192.168.1.4:9100
      labels:
        environment_name: tmp5
        environment_type: test
    

    最后,如果我们限制单个主机,如下所示:

    ansible-playbook playbook.yaml -l host_1,host_5
    

    我们得到:

    $ ls config*
    config-tmp5.yaml  config-tmp6.yaml
    $ cat config-tmp5.yaml
    - target:
        - 192.168.1.1:9100
      labels:
        environment_name: tmp5
        environment_type: test
    $ cat config-tmp6.yaml
    - target:
        - 192.168.1.5:9100
      labels:
        environment_name: tmp6
        environment_type: test
    
    • 0
  2. Best Answer
    Konstantin
    2024-03-23T00:42:23+08:002024-03-23T00:42:23+08:00

    这个问题可以通过中间临时文件来解决。

    1. 创建临时文件:
    - ansible.builtin.file:
        path: "./.configs_prometheus/{{
               inventory_file | ansible.builtin.dirname | ansible.builtin.dirname | ansible.builtin.basename }}_--_{{
               ansible_host }}_--_{{ inventory_file | ansible.builtin.basename | ansible.builtin.regex_replace('.yml$', '') }}"
        state: touch
    
    1. 搜索临时文件
    - ansible.builtin.find:
        paths: "./.configs_prometheus/"
        file_type: file
        recurse: yes
      register: environment_temp_files_list
    
    1. 生成数据列表:
    - ansible.builtin.set_fact:
        environment_data: "{{ environment_temp_files_list.files | map(attribute='path') | map('ansible.builtin.basename') |
                              map('ansible.builtin.split','_--_') | map('ansible.builtin.zip', ['type', 'host', 'name']) |
                              map('map', 'reverse') | map('community.general.dict') | groupby('name') }}"
    
    - ansible.builtin.set_fact: environments_list="{{ environment_data | map('first') }}"
    
    - ansible.builtin.set_fact: hosts_list="{{ environment_data | map('last') | map('map', attribute='host') }}"
    
    - ansible.builtin.set_fact: types_list="{{ environment_data | map('last') | map('map', attribute='type') | map('ansible.builtin.unique') }}"
    
    1. 模板生成:
    - ansible.builtin.copy:
        content: |
          - targets:
            {%  for result in item.1.0 %}
            - {{ result }}:9100
            {% endfor %}
          labels:
              environment_name: {{ item.0 }}
              environment_type: {{ item.1.1.0 }}
        dest: "./.configs_prometheus/{{ item.1.1.0 }}_--_{{ item.0 }}.yml"
      loop: "{{ environments_list | zip( hosts_list | zip(types_list) ) }}"
      loop_control:
        label: "{{ item.0 }}"
    

    最终剧本:

    - hosts: localhost
      tasks:
        - name: Creating a directory
          ansible.builtin.file:
            path: "./.configs_prometheus"
            state: "{{ item }}"
          delegate_to: localhost
          loop:
            - absent
            - directory
    
    - hosts: environments
      roles:
        - role: host-configuration
        - role: host-users
        - role: node-exporter
      post_tasks:
        - name: Creating temporary files
          ansible.builtin.file:
            path: "./.configs_prometheus/{{
                   inventory_file | ansible.builtin.dirname | ansible.builtin.dirname | ansible.builtin.basename }}_--_{{
                   ansible_host }}_--_{{ inventory_file | ansible.builtin.basename | ansible.builtin.regex_replace('.yml$', '') }}"
            state: touch
          delegate_to: localhost
    
    - hosts: localhost
      tasks:
        - name: Search for temporary files
          ansible.builtin.find:
            paths: "./.configs_prometheus/"
            file_type: file
            recurse: yes
          register: environment_temp_files_list
    
        - name: Generating data lists
          ansible.builtin.set_fact:
            environment_data: "{{ environment_temp_files_list.files | map(attribute='path') | map('ansible.builtin.basename') |
                                  map('ansible.builtin.split','_--_') | map('ansible.builtin.zip', ['type', 'host', 'name']) |
                                  map('map', 'reverse') | map('community.general.dict') | groupby('name') }}"
        - ansible.builtin.set_fact: environments_list="{{ environment_data | map('first') }}"
        - ansible.builtin.set_fact: hosts_list="{{ environment_data | map('last') | map('map', attribute='host') }}"
        - ansible.builtin.set_fact: types_list="{{ environment_data | map('last') | map('map', attribute='type') | map('ansible.builtin.unique') }}"
    
        - name: Template generation
          ansible.builtin.copy:
            content: |
              - targets:
                {%  for result in item.1.0 %}
                - {{ result }}:9100
                {% endfor %}
              labels:
                  environment_name: {{ item.0 }}
                  environment_type: {{ item.1.1.0 }}
            dest: "./.configs_prometheus/{{ item.1.1.0 }}_--_{{ item.0 }}.yml"
          loop: "{{ environments_list | zip( hosts_list | zip(types_list) ) }}"
          loop_control:
            label: "{{ item.0 }}"
    
        - name: Deleting temporary files
          ansible.builtin.file:
            path: "{{ item }}"
            state: absent
          loop: "{{ environment_temp_files_list.files | map(attribute='path') }}"
          loop_control:
            label: "{{ item.split('/').1 }}"
    



    更新

    无需中间临时文件即可解决该问题。

    1. 创建环境数据集:
    - ansible.builtin.set_fact:
        environment_dataset: |
          {% for play_host in ansible_play_hosts_all %}
            - {{ hostvars[play_host].inventory_file | ansible.builtin.dirname | ansible.builtin.dirname | ansible.builtin.basename }}_--_{{
                 hostvars[play_host].ansible_host }}_--_{{
                 hostvars[play_host].inventory_file | ansible.builtin.basename | ansible.builtin.regex_replace('.yml$', '')
              }}
          {% endfor %}
      run_once: true
      delegate_to: "{{ item }}"
      delegate_facts: true
      loop: "{{ groups['prometheus'] | default(['localhost']) }}"    
    
    1. 生成数据列表:
    - ansible.builtin.set_fact:
        environment_data: "{{ environment_dataset | from_yaml |
                              map('ansible.builtin.split','_--_') | map('ansible.builtin.zip', ['type', 'host', 'name']) |
                              map('map', 'reverse') | map('community.general.dict') | groupby('name') }}"
    
    - ansible.builtin.set_fact: environments_list="{{ environment_data | map('first') }}"
    
    - ansible.builtin.set_fact: hosts_list="{{ environment_data | map('last') | map('map', attribute='host') }}"
    
    - ansible.builtin.set_fact: types_list="{{ environment_data | map('last') | map('map', attribute='type') | map('ansible.builtin.unique') }}"
    
    1. 模板生成:
    - ansible.builtin.copy:
        content: |
          - targets:
            {%  for result in item.1.0 %}
            - {{ result }}:9100
            {% endfor %}
          labels:
              environment_name: {{ item.0 }}
              environment_type: {{ item.1.1.0 }}
        dest: "/etc/prometheus/file_sd_configs/{{ item.1.1.0 }}_--_{{ item.0 }}.yml"
      loop: "{{ environments_list | zip( hosts_list | zip(types_list) ) }}"
      loop_control:
        label: "{{ item.0 }}"
    

    最终剧本:

    - hosts: environments
      roles:
        - role: host-configuration
        - role: host-users
        - role: node-exporter
      post_tasks:
        - name: Creating temporary files
          ansible.builtin.set_fact:
            environment_dataset: |
              {% for play_host in ansible_play_hosts_all %}
                - {{ hostvars[play_host].inventory_file | ansible.builtin.dirname | ansible.builtin.dirname | ansible.builtin.basename }}_--_{{
                     hostvars[play_host].ansible_host }}_--_{{
                     hostvars[play_host].inventory_file | ansible.builtin.basename | ansible.builtin.regex_replace('.yml$', '')
                  }}
              {% endfor %}
          run_once: true
          delegate_to: "{{ item }}"
          delegate_facts: true
          loop: "{{ groups['prometheus'] | default(['localhost']) }}"
    
    - hosts: prometheus
      tasks:
        - name: Generating data lists
          ansible.builtin.set_fact:
            environment_data: "{{ environment_dataset | from_yaml |
                                  map('ansible.builtin.split','_--_') | map('ansible.builtin.zip', ['type', 'host', 'name']) |
                                  map('map', 'reverse') | map('community.general.dict') | groupby('name') }}"
        - ansible.builtin.set_fact: environments_list="{{ environment_data | map('first') }}"
        - ansible.builtin.set_fact: hosts_list="{{ environment_data | map('last') | map('map', attribute='host') }}"
        - ansible.builtin.set_fact: types_list="{{ environment_data | map('last') | map('map', attribute='type') | map('ansible.builtin.unique') }}"
    
        - name: Template generation
          ansible.builtin.copy:
            content: |
              - targets:
                {%  for result in item.1.0 %}
                - {{ result }}:9100
                {% endfor %}
              labels:
                  environment_name: {{ item.0 }}
                  environment_type: {{ item.1.1.0 }}
            dest: "/etc/prometheus/file_sd_configs/{{ item.1.1.0 }}_--_{{ item.0 }}.yml"
          become: yes
          loop: "{{ environments_list | zip( hosts_list | zip(types_list) ) }}"
          loop_control:
            label: "{{ item.0 }}"
    
    • 0

相关问题

  • Ansible:将字符串转换为字典

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve