Добавьте память подкачки с помощью ansible

Я работаю над проектом, в котором наличие памяти подкачки на моих серверах необходимо, чтобы избежать нехватки памяти некоторых длительных процессов python, и впервые понял, что у моих бродячих ящиков Ubuntu и экземпляров AWS ubuntu еще не было одного настраивать.

В https://github.com/ansible/ansible/issues/5241 обсуждалось возможное встроенное решение, но никогда не реализовывался, поэтому я предполагаю, что это должно быть довольно распространенной задачей для автоматизации.

Как бы вы настроили файловую память подкачки с помощью ansible идемпотентным способом? Какие модули или переменные могут помочь с этой настройкой (например, переменная ansible_swaptotal_mb)?


person gonz    schedule 15.07.2014    source источник


Ответы (6)


Это мое текущее решение:

- 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
person gonz    schedule 15.07.2014
comment
Я бы беспокоился об идемпотентности - в частности, если вы запускаете развертывание, когда уже есть файл подкачки, это может обнулить его, что, как я полагаю, приведет к сбою каждого процесса, в котором есть какие-либо страницы подкачки. - person offby1; 03.12.2014
comment
Свойство creates="{{ swap_file_path }}" в первой задаче должно позаботиться об этом, если файл существует, dd не запустится. Я все еще использую это в производстве, и текущие условия задачи (когда/создает), похоже, выполняют свою работу, то есть делают этот идемпотент... Не могли бы вы уточнить сценарий, в котором это может обнулить файл? - person gonz; 03.12.2014
comment
Гонз: ты прав; creates должен позаботиться об этом. Я изначально этого не замечал. - person offby1; 04.12.2014
comment
swapon не работает, если он уже был запущен: stderr: swapon: /swapfile: swapon failed: устройство или ресурс занят - person dalore; 04.03.2015
comment
Никогда не было такой проблемы на моих экземплярах. Не могли бы вы предоставить больше информации? Каков результат для swapon -s? Эту последнюю задачу не следует запускать, если у вас уже есть доступный своп, что происходит после первого успешного запуска. - person gonz; 04.03.2015
comment
Я использовал вышеизложенное и заметил, что файл подкачки не остановился на указанном размере файла, он продолжал работать и заполнил весь диск (в моем случае 20 ГБ). Оказалось, что это k рядом со счетом. Вынул это, и он работал как шарм, используя Centos 7.5. - person Richard Bale; 07.10.2018
comment
Как говорил Ричард Бэйл, из-за размера блока bs и k в конце swap_file_size_kb на самом деле составляет мегабайты, а не килобайты. - person James D; 12.11.2018
comment
Ричард, Джеймс: Хороший улов! Изменено имя переменной на swap_file_size_mb (cc @JamesD) - person gonz; 12.11.2018

Я пробовал ответить выше, но "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

Требуемые вары:

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
person Ashley    schedule 11.10.2015
comment
Это работает на бродячей коробке «ubuntu/trusty». Спасибо!! - person atripes; 17.11.2015
comment
Работает и на CentOS 7.3. - person chrlaura; 13.07.2017
comment
Работает и на Ubuntu 16.04 LTS (Xenial Xerus). Спасибо. - person Joe Eifert; 02.05.2018
comment
Работает и на Ubuntu 18.04 LTS. Спасибо. - person Levon; 08.11.2019
comment
Начиная с Ansible 2.9, sudo больше не является допустимым типом ключевого слова. Итак, sudo: yes следует заменить на become: yes. - person Bless; 30.08.2020
comment
Я бы стал: правда на игровую часть вместо задач, но да смотря что ты делаешь. - person Alex R; 14.04.2021

Я взял за основу отличный ответ Эшли (пожалуйста, проголосуйте за него!) и добавил следующие дополнительные функции:

  • глобальный флаг для управления свопом или нет,
  • разрешить изменение размера свопа,
  • разрешить отключение свопа,

...плюс эти технические улучшения:

  • полная идемпотентность (только ok и skipping, когда ничего не меняется, иначе какие-то changed),
  • используйте dd вместо fallocate для совместимости с XFS fs (см. этот ответ для получения дополнительной информации),

Протестировано на Centos 7.7 с Ansible 2.9.10.

Параметры:

swap_configure: true # manage the swap or not 
swap_enable: true
swap_file_path: /swapfile
swap_file_size_mb: 4096
swappiness: 1

Код:

- name: Configure swap
  when: swap_configure | bool | default(false)
  block:

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

    - name: Check if swap is on
      shell: swapon --show | grep {{swap_file_path}}
      register: swap_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 swap_enabled.rc == 0
        and (not swap_enable
             or (swap_enable and swap_file_check.stat.size != (swap_file_size_mb * 1024 * 1024)))

    - name: Delete the swap file
      file:
        path: "{{swap_file_path}}"
        state: absent
      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_check.stat.size != (swap_file_size_mb * 1024 * 1024)

        - name: Change swap file permissions
          file: path="{{swap_file_path}}"
            owner=root
            group=root
            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: 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
          when: swap_enabled.rc != 0 and swap_disabled.changed

        - name: Configure swappiness
          sysctl:
            name: vm.swappiness
            value: "{{ swappiness }}"
            state: present
person Greg Dubicki    schedule 10.10.2020
comment
Спасибо! К вашему сведению, включение свопа было пропущено, когда у меня не было свопа (поскольку swap_disabled.changed => Disable swap также был пропущен) - person vehovmar; 12.11.2020
comment
Извините, я не понял @vehovmar... ^_^' Значит, у меня ошибка в коде? Если это так, пожалуйста, не стесняйтесь обновлять его так, как вы думаете, как он должен выглядеть. :) - person Greg Dubicki; 13.11.2020
comment
Да, есть ошибка, при включении свопа нужно проверить, если swap_enabled.rc != 0, так как он будет равен 0, только если своп уже был включен, и в этом случае нет необходимости снова включать его. - person vehovmar; 18.11.2020
comment
протестировано и проверено на Ubuntu 18.04 (с предложенным исправлением от vehovmar) - person Cethy; 04.02.2021

Вот плейбук ansible-swap, который я использую для установки 4 ГБ (или того, что я настраиваю group_vars для dd_bs_size_mb * swap_count) пространства подкачки на новых серверах:

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.

person Aaron Tribou    schedule 21.05.2016

Я не могу ответить на ответ Грега Дубицки, поэтому я добавляю сюда свои 2 цента:

Я думаю, что добавление приведения к int при вычислении swap_file_size_mb * 1024 * 1024 для преобразования его в swap_file_size_mb | int * 1024 * 1024 сделает код немного умнее, если вы хотите использовать факт для извлечения окончательного размера подкачки на основе объема установленной оперативной памяти, например:

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

в противном случае он всегда будет изменять размер файла подкачки, даже если размер тот же.

person mprenditore    schedule 23.06.2021

Что работает для меня, так это добавить 4Gib swap через playbook.

Проверь это:

это.

person Krishna Upadhyay    schedule 29.05.2020
comment
Пожалуйста, замените скриншот текстом @krishna-upadhyay. См. meta.stackoverflow. com/questions/303812/ для обоснования. - person Greg Dubicki; 10.10.2020