用ansible添加交换内存

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

我正在做一个项目,需要在我的服务器上交换内存,以避免一些 python 长时间运行的进程内存不足,并且第一次意识到我的 ubuntu vagrant boxes 和 AWS ubuntu 实例还没有一个设置。

https://github.com/ansible/ansible/issues/5241中讨论了一个可能的内置解决方案但从未实施,所以我猜这应该是一个非常常见的自动化任务。

您将如何以幂等方式使用 ansible 设置基于文件的交换内存? ansible 为这个设置提供了哪些模块或变量帮助(比如

ansible_swaptotal_mb
变量)?

memory amazon-web-services swap ansible
7个回答
50
投票

这是我目前的解决方案:

- name: Create swap file
  command: dd if=/dev/zero of={{ swap_file_path }} bs=1024 count={{ swap_file_size_mb }}k
           creates="{{ swap_file_path }}"
  tags:
    - swap.file.create


- name: Change swap file permissions
  file: path="{{ swap_file_path }}"
        owner=root
        group=root
        mode=0600
  tags:
    - swap.file.permissions


- name: "Check swap file type"
  command: file {{ swap_file_path }}
  register: swapfile
  tags:
    - swap.file.mkswap


- name: Make swap file
  command: "sudo mkswap {{ swap_file_path }}"
  when: swapfile.stdout.find('swap file') == -1
  tags:
    - swap.file.mkswap


- name: Write swap entry in fstab
  mount: name=none
         src={{ swap_file_path }}
         fstype=swap
         opts=sw
         passno=0
         dump=0
         state=present
  tags:
    - swap.fstab


- name: Mount swap
  command: "swapon {{ swap_file_path }}"
  when: ansible_swaptotal_mb < 1
  tags:
    - swap.file.swapon

36
投票

我尝试了上面的答案,但

"Check swap file type"
总是以
changed
的形式返回,因此不是 idempotent,这是在编写 Ansible 任务时被鼓励作为最佳实践。

以下角色已经在 Ubuntu 14.04 Trusty 上进行了测试,不需要启用

gather_facts

- name: Set swap_file variable
  set_fact:
    swap_file: "{{swap_file_path}}"
  tags:
    - swap.set.file.path

- name: Check if swap file exists
  stat:
    path: "{{swap_file}}"
  register: swap_file_check
  tags:
    - swap.file.check

- name: Create swap file
  command: fallocate -l {{swap_file_size}} {{swap_file}}
  when: not swap_file_check.stat.exists
  tags:
    - swap.file.create

- name: Change swap file permissions
  file: path="{{swap_file}}"
        owner=root
        group=root
        mode=0600
  tags:
    - swap.file.permissions

- name: Format swap file
  sudo: yes
  command: "mkswap {{swap_file}}"
  when: not swap_file_check.stat.exists
  tags:
    - swap.file.mkswap

- name: Write swap entry in fstab
  mount: name=none
         src={{swap_file}}
         fstype=swap
         opts=sw
         passno=0
         dump=0
         state=present
  tags:
    - swap.fstab

- name: Turn on swap
  sudo: yes
  command: swapon -a
  when: not swap_file_check.stat.exists
  tags:
    - swap.turn.on

- name: Set swappiness
  sudo: yes
  sysctl:
    name: vm.swappiness
    value: "{{swappiness}}"
  tags:
    - swap.set.swappiness

从 Ansible 2.9 开始,

sudo
声明应该是
become
:

- name: Set swap_file variable
  set_fact:
    swap_file: "{{swap_file_path}}"
  tags:
    - swap.set.file.path

- name: Check if swap file exists
  stat:
    path: "{{swap_file}}"
  register: swap_file_check
  tags:
    - swap.file.check

- name: Create swap file
  command: fallocate -l {{swap_file_size}} {{swap_file}}
  when: not swap_file_check.stat.exists
  tags:
    - swap.file.create

- name: Change swap file permissions
  file: path="{{swap_file}}"
        owner=root
        group=root
        mode=0600
  tags:
    - swap.file.permissions

- name: Format swap file
  become: yes
  command: "mkswap {{swap_file}}"
  when: not swap_file_check.stat.exists
  tags:
    - swap.file.mkswap

- name: Write swap entry in fstab
  mount: name=none
         src={{swap_file}}
         fstype=swap
         opts=sw
         passno=0
         dump=0
         state=present
  tags:
    - swap.fstab

- name: Turn on swap
  become: yes
  command: swapon -a
  when: not swap_file_check.stat.exists
  tags:
    - swap.turn.on

- name: Set swappiness
  become: yes
  sysctl:
    name: vm.swappiness
    value: "{{swappiness}}"
  tags:
    - swap.set.swappiness

需要变量:

swap_file_path: /swapfile
# Use any of the following suffixes
# c=1
# w=2
# b=512
# kB=1000
# K=1024
# MB=1000*1000
# M=1024*1024
# xM=M
# GB=1000*1000*1000
# G=1024*1024*1024
swap_file_size: 4G
swappiness: 1

15
投票

我的看法基于 Ashley 的回答(请投票!)并添加了以下额外功能:

  • 是否管理交换的全局标志,
  • 允许更改交换大小,
  • 允许禁用交换,

...加上这些技术改进:

  • 完全幂等(只有
    ok
    skipping
    什么都没有改变,否则有些
    changed
    ),
  • 使用
    dd
    而不是
    fallocate
    以与 XFS fs 兼容(有关更多信息,请参见 this answer),

限制:

  • 仅当您将其路径提供为
    swap_file_path
    .
  • 时,才会更改现有的交换文件才能正常工作

在带有 Ansible 2.9 的 Centos 7.7 和带有 Ansible 的 Rocky 8 上测试 4.8.0.

需要使用权限升级,因为许多命令需要以 root 身份运行。 (最简单的方法是将

--become
添加到
ansible-playbook
参数或 在您的 ansible.cfg
 中设置适当的值
)。

参数:

swap_configure: true # or false
swap_enable: true # or false
swap_file_path: /swapfile
swap_file_size_mb: 4096
swappiness: 1

代码:


- name: Configure swap
  when: swap_configure | bool
  block:

    - name: Check if swap file exists
      stat:
        path: "{{swap_file_path}}"
        get_checksum: false
        get_md5: false
      register: swap_file_check
      changed_when: false

    - name: Set variable for existing swap file size
      set_fact:
        swap_file_existing_size_mb: "{{ (swap_file_check.stat.size / 1024 / 1024) | int }}"
      when: swap_file_check.stat.exists

    - name: Check if swap is on
      shell: swapon --show | grep {{swap_file_path}}
      register: swap_is_enabled
      changed_when: false
      failed_when: false

    - name: Disable swap
      command: swapoff {{swap_file_path}}
      register: swap_disabled
      when: >
        swap_file_check.stat.exists
        and 'rc' in swap_is_enabled and swap_is_enabled.rc == 0
        and (not swap_enable or (swap_enable and swap_file_existing_size_mb != swap_file_size_mb))

    - name: Delete the swap file
      file:
        path: "{{swap_file_path}}"
        state: absent
      when: not swap_enable

    - name: Remove swap entry from fstab
      mount:
        name: none
        src: "{{swap_file_path}}"
        fstype: swap
        opts: sw
        passno: '0'
        dump: '0'
        state: present
      when: not swap_enable

    - name: Configure swap
      when: swap_enable | bool
      block:

        - name: Create or change the size of swap file
          command: dd if=/dev/zero of={{swap_file_path}} count={{swap_file_size_mb}} bs=1MiB
          register: swap_file_created
          when: >
            not swap_file_check.stat.exists
            or swap_file_existing_size_mb != swap_file_size_mb

        - name: Change swap file permissions
          file:
            path: "{{swap_file_path}}"
            mode: 0600

        - name: Check if swap is formatted
          shell: file {{swap_file_path}} | grep 'swap file'
          register: swap_file_is_formatted
          changed_when: false
          failed_when: false

        - name: Format swap file if it's not formatted
          command: mkswap {{swap_file_path}}
          when: >
            ('rc' in swap_file_is_formatted and swap_file_is_formatted.rc > 0)
            or swap_file_created.changed

        - name: Add swap entry to fstab
          mount:
            name: none
            src: "{{swap_file_path}}"
            fstype: swap
            opts: sw
            passno: '0'
            dump: '0'
            state: present

        - name: Turn on swap
          shell: swapon -a
          # if swap was disabled from the start
          # or has been disabled to change its params
          when: >
            ('rc' in swap_is_enabled and swap_is_enabled.rc != 0)
            or swap_disabled.changed

        - name: Configure swappiness
          sysctl:
            name: vm.swappiness
            value: "{{ swappiness|string }}"
            state: present


1
投票

我无法回复 Greg Dubicki 的回答 所以我在这里加上我的 2 美分:

我认为在对

int
进行计算以将其转换为
swap_file_size_mb * 1024 * 1024
时将转换添加到
swap_file_size_mb | int * 1024 * 1024
将使代码更智能,以防您想使用事实根据 RAM 量提取最终交换大小安装如下:

swap_file_size_mb: "{{ ansible_memory_mb['real']['total'] * 2 }}"

否则它将始终调整交换文件的大小,即使大小相同。


0
投票

这是我用来在新服务器上安装 4GB(或我为

group_vars
*
dd_bs_size_mb
配置
swap_count
的任何内容)交换空间的 ansible-swap 剧本:

https://github.com/tribou/ansible-swap

我还在我的

~/.bash_profile
中添加了一个功能来帮助完成任务:

# Path to where you clone the repo
ANSIBLE_SWAP_PLAYBOOK=$HOME/dev/ansible-swap

install-swap ()
{
    usage='Usage: install-swap HOST';
    if [ $# -ne 1 ]; then
        echo "$usage";
        return 1;
    fi;
    ansible-playbook $ANSIBLE_SWAP_PLAYBOOK/ansible-swap/site.yml --extra-vars "target=$1"
}

只需确保先将您的

HOST
添加到您的 ansible 库存中。

那就只是

install-swap HOST
.


0
投票

这是 Galaxy 上的一个预先存在的角色,它实现了同样的事情:https://galaxy.ansible.com/geerlingguy/swap


-4
投票

对我有用的是通过剧本添加 4Gib 交换。

检查这个:

this.

© www.soinside.com 2019 - 2024. All rights reserved.