使用ansible管理磁盘空间

时间:2014-11-17 21:02:14

标签: ansible

简单问:如果分区利用率超过一定百分比,我想删除一些文件。

我可以通过“ansible_mounts”访问“size_total”和“size_available”。即:

ansible myhost -m setup -a 'filter=ansible_mounts'
myhost | success >> {
"ansible_facts": {
    "ansible_mounts": [
        {
            "device": "/dev/mapper/RootVolGroup00-lv_root", 
            "fstype": "ext4", 
            "mount": "/", 
            "options": "rw", 
            "size_available": 5033046016, 
            "size_total": 8455118848
        }, 

如何访问这些值,以及如何使用Ansible以有条件方式执行操作?

4 个答案:

答案 0 :(得分:14)

Slava的回答肯定是在正确的轨道上,这是我使用的:

- name: test for available disk space
  assert:
    that: 
      - not {{ item.mount == '/' and ( item.size_available < item.size_total - ( item.size_total|float * 0.8 ) ) }}
      - not {{ item.mount == '/var' and ( item.size_available < item.size_total - ( item.size_total|float * 0.8 ) ) }}
  with_items: ansible_mounts
  ignore_errors: yes
  register: disk_free

- name: free disk space
  command: "/some/command/that/fixes/it"
  when: disk_free|failed

断言任务只是通过设置ignore_errors测试条件,并将测试结果注册到一个新变量,我们可以在游戏中稍后执行条件任务,而不是在断言结果失败时失败。 / p>

测试本身可能更有效地编写,但代价是可读性。所以我没有在示例中使用多列表循环。在这种情况下,任务循环遍历已安装文件系统列表中的每个项目(一个ansible创建的事实,称为ansible_mounts。)

通过否定测试,我们避免在列表中没有的文件系统挂载失败,然后简单的数学处理其余的。绊倒我的部分是size_available和size_total变量是字符串,因此jinja过滤器在计算百分比之前将它们转换为浮点数。

答案 1 :(得分:3)

就我而言,我所关心的只是根分区。但是我发现在使用上面的frameloss中的示例时,我需要一个否定的'或'条件,因为每个挂载点都将针对断言进行测试。如果存在多个挂载点,那么这意味着断言将始终失败。在我的例子中,我正在测试size_available是否直接小于size_total的50%,而不是像frameloss那样计算它。

其次,至少在我使用的ansible版本中,有必要在with_items中包含变量周围的{{}}。我在上面的例子中没有做出的错误是没有将'when'子句与'fail'指令在同一个缩进上对齐。 (如果犯了这个错误,那么解决方案就不起作用......)

# This works with ansible 2.2.1.0
- hosts: api-endpoints
  become: True
  tasks:

    - name: Test disk space available
      assert:
        that:
            - item.mount != '/' or {{ item.mount == '/' and item.size_available > (item.size_total|float * 0.4) }}
      with_items: '{{ ansible_mounts }}'
      ignore_errors: yes
      register: disk_free

    - name: Fail when disk space needs attention
      fail:
         msg: 'Disk space needs attention.'
      when: disk_free|failed

答案 2 :(得分:2)

我没有测试它,但我建议尝试这样的事情:

file:
   dest: /path/to/big/file
   state: absent
   when: "{% for point in ansible_mounts %}{% if point.mount == '/' and point.size_available > (point.size_total / 100 * 85) %}true{% endif %}{% endfor %}" == "true"

在这个例子中,我们遍历挂载点并找到“/”,之后我们计算出利用率超过85%并且如果是真的则打印“真”。接下来,我们比较该字符串并决定是否删除此文件。

受以下博客中的示例启发:https://blog.codecentric.de/en/2014/08/jinja2-better-ansible-playbooks-templates/

答案 3 :(得分:0)

我的解决方案

read.fwf

如果可用磁盘空间低于20%,这将截断卷- name: cleanup logs, free disk space below 20% sudo: yes command: find /var -name "*.log" \( \( -size +50M -mtime +7 \) -o -mtime +30 \) -exec truncate {} --size 0 \; when: "item.mount == '/var' and ( item.size_available < item.size_total * 0.2 )" with_items: ansible_mounts 上任何超过7天且超过50M或超过30天的*.log个文件。