Основы
Если в Вашем ведение находятся десятки серверов, а особенно если среди них есть повторяющиеся конфигурации, то Вам на помощь может прийти программа Ansible, которая по созданным Вами описаниям произведет установку и настройку всех серверов.
Установка пакета:
- apt install ansible – Ubuntu
- yum install ansible – CentOS
- pip install ansible – Other Linux (этот метод не устанавливает конфиги)
Основной файл конфигурации /etc/ansible/ansible.cfg в котором установлены параметры конфигурации в форме переменных и их значений.
Важный момент касательно поиска файлов конфигурации, программа ищет файл конфигурации по нескольким путям:
- путь к файлу задается переменной окружения ANSIBLE_CONFIG, если этот путь задан то будет использоватся именно этот файл конфигурации;
- Если ANSIBLE_CONFIG не задан, то программа ищет конфигурационнй файл с именем ansible.cfg в текущей рабочей папке;
- Если выше приведенные методы не нашли файл конфигурации то программа ищет скрытый файл в папке пользователя ~/.ansible.cfg. Это хороший метод задания значений по умолчанию для проектов пользователя, которые в дальнейшем будут уточнятся, путем либо создания новых файлов конфигурации прямо внутри проекта или переопределение отдельных переменных в проекте;
- Псоледним в списке будет файл /etc/ansible/ansible.cfg – этот файл используется тогда, когда других вариантов не найдено.
Общую информацию о работе ansible в том числе и путь к файлу конфигурации, который используется, можно получить командой: ansible –version.
ВАЖНО: конфигурация никогда не будет читатся из дерикторий которые доступны для записи всем.
Комантарии в файле конфигурации начинаются с символов “#” и “;”.
При составление конфигурации часто важно иметь возможность просмотреть уже существующую конфигурацию, а также все возможные доступные варианты, для этого есть следующие команды:
- ansible-config view – отображает текущую используемую конфигурацию (просто отображение текущего файла);
- ansible-config dump – отображает еффективные параметры конфигурации, которые получены как установленные значения и значения по умолчанию (отображается как список установленных переменных). Есть полезный вариант команды, который отображает только измененные значения: ansible-config dump –only-changed;
- ansible-config list – отображает все возможные доступные параметры для файла конфигурации (отображаются имена переменных и их описание). Для поиска описания конкретной переменной можно использовать команду: ansible-config list | grep -A12 DEFAULT_REMOTE_USER, где 12 это кличество строк для отображения.
Для создания файлов конфигурации рекомендуется переносить из базового файла конфигурации, разделы, это можно сделать командой:
grep -E ‘^\[.*\]’ /etc/ansible/ansible.cfg > $HOME/.ansible.cfg
Кроме того, стоит отметить, что при формировании конфигурации используют файл “инвентаризации”. Который представляет из себя текстовый файл с перечнем серверов, которыми мы будем управлять. Имя файла не важно, например путь это будет hosts.txt.
Например:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
10.5.6.7 [linux_server] linux1 ansible_host=10.10.0.1 ansible_user=admin ansible_ssh_key_file_path=/etc/ssh/key.pem 10.5.6.1 [win_server] win1 ansible_host=10.10.0.2 [win_server:vars] ansible_user=admin ansible_password=admin ansible_connection=winrm ansible_winrm_port=5986 ansible_winrm_server_cert_validation=ignore [server:chldrens] win_server linux_server |
Особенности этого файла это перечень серверов, сервера можно разбивать на группы (в примере это win_server, linux_server, server (при этом эта группа включает в себя также все предыдущие). Кроме того, есть еще две группы all (все хосты которые есть в файле) и группа ungrouped – хосты которые не приписаны не к одной группе. Кроме того в примере показан вариант задания параметров как для конкретного сервера, так и для целой группы (win_server:vars). При этом можна задавать сервера как просто доменные имена или IP адреса, а можно задавать им названия, которые потом использовать как имена серверов.
Еще один важный момент, все имена чувствительны к регистру.
Для доступа к линукс серверу, нужен только ssh, то для доступа к windows серверу требуется разрешить на сервере WinRM, что можно сделать скриптом (см. статью https://docs.ansible.com/ansible/latest/user_guide/windows_setup.html)
Использование файла хостов возможно через применения модулей (команд) к ним, например команда проверки связи с хостами:
ansible -i hosts.txt all -m ping
Эта команда возмет список хостов из файла hosts.txt, в этом описание выберет группу all (в данном случае это будут все вервера) и вызовит для них модуль ping (для серверов семейства windows, модуль должен называтся win_ping), в результате будет получен ответ в котором будут указаны сервера и получены ответы от них или нет, в формате JSON.
Что бы каждый раз не указывать файл хостов, его можно прописать в файле ansible.cfg в переменую inventory и присвоить ей значение путь к файлу. В нашем примере это было бы:
inventory=/etc/ansible/hosts.txt
Еще одной полезной переменноу для серверов linux, может быть переменная host_key_checking=false, которая указывает нужно ли спрашивать подтверждение при первом подключении к серверу (там где ssh спрашивает нужно ли сохранять отпечаток сервера)
Если Вам нужно увидить конфигурацию хостов, то ее можно посмотреть, вызовом команды, которая выведет описание всех групп и хостов которые есть в файле инвентаризации:
ansible-inventory –list
Модули
Применение ansible возможно в двух вариантах, формирование playbook (набора команд, вроде сценариев) либо как единичные команды (ad-hoc). Среди полезных модулей можно выделить команды:
- setup – выводит конфигурацию системы (версия системы, настройки адресов и т.п.). Например: ansible all -m setup
- shell – выполняет команды shell на указанных хостах, команда требует указания обязательного параметра команды, которую необходимо выполнить. Например: ansible all -m shell -a “ls /etc”
- command – выполнит указанный файл или команду (как и shell), но особенность этой команды, в том, что при ее выполнении не запускается процесс командной строки и соотвественно не будут работать переменные среды, перенаправления ввода и т.п.
- copy – копирует файлы на указанные серверы, важно указать параметр с путями к файлам. Например: ansible all -m copy -a “src=./test.txt dest=/home” – эта команда скопирует файл test.txt из текущего каталога, в каталог /home, всех серверов. Кроме того можно при копировании сменить права, например ansible all -m copy -a “src=./test.txt dest=/home mode=777”. Еще один из важных моментов, в том, что для выполнений некоторых команд требуются повышенные привелегии, тогда команду надо выполнить с параметром -b: ansible all -m copy -a “src=./test.txt dest=/home mode=777” -b Примечание: команда не просто каждый раз выполняет копирование, а сначала проверяет наличие файла на сервере и его контрольную сумму, поэтому если файл уже на сервере, то копирование выполнено не будет.
- file модуль управления файлами, создание, удаление и т.п. Например удаление ansible all -m file -a “path=/home/test.txt state=absent” -b эта команда удалит файл по пути /home/test.txt со всех серверов, при этом если файла нет, то ошибок не будет, так как ansible воспринимает эту команду как то, что к серверу применяется требование файл не должно быть, на тех серверах где файл есть, он будет удален, а где нет – там и так все хорошо.
- get_url – скачивает ресурс по url. Например: ansible all -m get_url -a “url=http://127.0.0.1/file dest=/home/file” модуль скачает файл по указанной ссылке и положит по заданному пути.
- yum – модуль установки/удаления ПО на сервера симества RedHat. Пример: ansible all -m yum -a “name=stress state=installed” -b установка софта на все сервера. Для удаления указываем state=removed.
- uri – модуль чтения данных из url (аналог curl). Например: ansible all -m uri -a “url=http://127.0.0.1/file” эта команда выполнит проверку может ли сервер подключится к указанному адресу. Если необходимо получить содержимое ссылки, то команду немного необходимо модифицировать: ansible all -m uri -a “url=http://127.0.0.1/file return_content=yes”
- service – модуль управления службами. Пример: ansible all -m service -a “name=http state=started enabled=yes” -b запустит службу http (enabled=yes – указывает, на то, что служба будет запускатся при старте системы
- debug – модуль служит для отображения информации в целях отладки. Может иметь два параметра var – выводит содержимое переменной либо параметр msg – вывод форматированных сообщений (внутрь сообщений можно включить переменные через {{ имя переменной }})
- set_fuct – создает новую переменную, используя форматирвонную строку.
Если к команде добавлять опции -v, -vv, -vvv, -vvvv, то можна получить больше информации о выполнении команды с разной стпенью детальности.
Команда ansible-doc -l выдает список всех доступных модулей.
Переменные можно вынести наружу из файла инвентаризации: для этого можно рядом с файлом инвентаризации создать папку group_vars. Внутри этой папки создаются файлы с именами точно такими же как группы (регистр букв важен) для которых нужны переменные, внутри этого файла и определяем набор переменных. Файл должен имееть формат YAML. Расмотрим пример выше, необходимо в паке создать файл win_server следующего содержимого:
1 2 3 4 5 6 7 |
--- ansible_user: admin ansible_password: admin ansible_connection: winrm ansible_winrm_port: 5986 ansible_winrm_server_cert_validation: ignore |
Таким образом имеем простой файл инвентаризации и набор файлов с переменными, описание переменных прямо в файле инвентаризации только для указания специфичных значений для конкретного хоста.
Playbook
Для выполнения набора команд служат playbook файлы, это файл формата YAML, которые позволяют описать требуемую конфигурацию. Пример:
1 2 3 4 5 6 7 8 |
--- - name: Ping plabook hosts: all become: yes tasks: - name: Ping operation ping: |
Выполнение операций из файла производится командой ansible-playbook <имя файла yaml>. При выполнении будут отображатся названия действий и скрипта который выполняется. В файле первый параметр name задает имя скрипта, которое отображается при его выполнении, параметр host задает группу к которой применяются изменения, параметр become – указывает, что скрипт должен выполнятся с правами супер пользователя. Далее определяется список задач которые надо выполнить это параметр tasks – который представляет из себя список действий. Каждому действию задается имя (параметр name – для отображения при выполнении), а также указвается необхоимый модуль и его параметры (в примере выше у модля ping нет параметров).
Пример файла для установки ВЕБ сервера:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
--- - name: Setup WEB service hosts: all become: yes vars: source_file: ./wev/index.html dest_path: /var/www/index.html tasks: - name: HTTP service install yum: name=httpd state=latest - name: Copy Page on servers copy: src={{ source_file }} dest={{ dest_path }} mode=0555 notify: Restart Apache - name: Start service and enable on boot service: name=httpd state=started enabled=yes - debug: msg: "Info message {{ source_file }}" - set_fuct: new_variable="new value {{ source_file }}" - shell: uptime register: result_variable - debug: var: result_variable.stdout handlers: - name: Restart Apache service: name=httpd state=restarted |
В примере выше задано два шага первый установка ПО, второй шаг копирование файлов и третий его запуск. В этом же скрипте применены переменные, которые позволяют его конфигурировать. Важный момент в скрипте применяется интересный трюк, если будет скопирован файл, то тогда будет выполнен обработчик с именем “Restart Apache”. Особенность такого поведения, в том, что если файл есть на сервере и его контрльные суммы совпадают (то есть он не изменен) то в этом случае этот обработчик выполнятся не будут. Сами по себе задачи из раздела handlers не выполняются, только в ответ на вызовы через notify.
Стоит также обратить внимание на задачу debug (в ней пропущено назначение имени задачи, так тоже можно делать – указывать сразу модуль), в задаче задан параметр msg – форматированное сообщение и внутри сообщения использована переменная source_file. Кроме того можно использовать ссылки с именами переменных заданных в файле инвентаризации (например в строке с описанием сервера или переменные назначенные группе). Кроме того используя модуль set_fuct можно создавать новые переменные, например это может быть форматированная строка которая ссылается на уже существующие перменные. Важно понимать, что перед началом выполнения playbook выполняется на каждом сервере модуль setup, которые собирает сведения про сервер и формирует много переменных со значением про сервер, эти значения могут используватся внутри playbook, как и любые другие.
Команды которые выполняются на сервере и выводят что-то в консоль, будут выполнены на сервере, но результат их работы не отображается (значение теряется), что бы сохранить вывод используется атрибут register для которого указывается имя переменной, в которую будет сохранен вывод. В примере выше следом за таском shell, которые сохраняет результат выполненния в переменную result_variable (значение сохраняется в форме json объекта с разными даными, как то вывод, статус завершения и др), идет задача debug, которая отображает значение result_variable, а именно stdout который был получен от команды.
В следующей части опишым управляющие конструкции, которые могут быть применены в playbook.