Первое мое знакомство с ansible, крутая штука.
В этой заметке оставлю основные выдержки из вводной документации: http://docs.ansible.com/ansible/intro.html
В VirtualBox развернул Virtuozzo 7, а в нем окружение, в котором я буду тестировать ansible.
Выглядит это так, ansible.host.tld - мастер-сервер ансибла, остальные три виртуалки подопытые кролики:
[[email protected] ~]# prlctl list -o name,ip,ostemplate,hostname
NAME IP_ADDR OSTEMPLATE HOSTNAME
ansible-c7 192.168.0.151 .centos-7-x86_64 ansible.host.tld
centos7 192.168.0.154 .centos-7-x86_64 centos7.host.tld
debian8 192.168.0.153 .debian-8.0-x86_64 debian8.host.tld
ubuntu14 192.168.0.152 .ubuntu-14.04-x86_64 ubuntu14.host.tld
Ansible удобен в первую очередь тем, что на агентах ему не нужно ничего ставить, т.к. общение между мастером и агентами происходит по SSH, никаких тебе демонов, сервисов, кучи зависимостей в виде ruby и прочих Java.
Установка ansible на мастере в CentOS 7:
[[email protected] ~]# yum install epel-release git
[[email protected] ~]# yum install ansible
[[email protected] ~]# ansible --version
ansible 1.9.4
configured module search path = None
В EPEL для RHEL7 до сих пор версия 1.9.4, хотя уже давно 2.0.0 есть для той же Ubuntu.
Пробовал я и с помощью исходников ставить на CentOS 7, но у меня при компиляции просил какой-то пакет asciidoc, который тянет за собой половину иксов, поэтому я поставил с EPEL'а.
Для инвентаризации хостов ansible использует так называемы инвентори-файл /etc/ansible/hosts.
Приведем его к такому виду:
[[email protected] ~]# vim /etc/ansible/hosts
centos7.host.tld
debian8.host.tld
ubuntu14.host.tld
Я внес туда список хостнеймов моих подопытных виртуалок, но т.к. у меня локальная сеть и DNS-сервер я не настраивал, то дополнительно я еще и добавлю такие записи в /etc/hosts:
[[email protected] ~]# vim /etc/hosts
192.168.0.152 ubuntu14.host.tld
192.168.0.153 debian8.host.tld
192.168.0.154 centos7.host.tld
Далее сгенерируем SSH-ключ и раскидаем его по виртуалкам, чтобы постоянно не вводить пароль:
[[email protected] ~]# ssh-keygen
[[email protected] ~]# ls /root/.ssh/
authorized_keys id_rsa id_rsa.pub
[[email protected] ~]# cat /etc/ansible/hosts | xargs -i ssh-copy-id {}
После того как ключи раскиданы, можно проверить коннект:
[[email protected] ~]# ansible all -m ping
ubuntu14.host.tld | success >> {
"changed": false,
"ping": "pong"
}
debian8.host.tld | success >> {
"changed": false,
"ping": "pong"
}
centos7.host.tld | success >> {
"changed": false,
"ping": "pong"
}
Все работает.
Приведем инвентори к такому виду:
[[email protected] ~]# vim /etc/ansible/hosts
[frontend]
centos7.host.tld:2222
[backend]
debian8.host.tld
[backend:vars]
frontend_server=centos7
database_server=ubuntu14
[database]
ubuntu14.host.tld backend_server=debian8
Здесь в инвентори в.ini формате можно объединять хосты в группы и создавать переменные.
Например я тут создал группы frontend, backend и database, понятно, какие хосты к каким группам относятся.
Для группы backend установлены две переменные frontend_server и backend_server, которые впоследствии мы сможем использовать.
Для хоста ubuntu15.host.tld установили переменную backend_server=debian8.
Строка centos7.host.tld:2222 указывает подключение к порту 2222 по SSH.
Хранение переменных нежелательно в инвентори файле, предпочтительно хранить их отдельно. Пример:
[[email protected] ~]# mkdir /etc/ansible/{host,group}_vars
[[email protected] ~]# vim /etc/ansible/group_vars/backend
---
frontend_server: centos7
database_server: ubuntu14
[[email protected] ~]# vim /etc/ansible/host_vars/ubuntu14.host.tld
---
backend_server: debian8
[[email protected] ~]# vim group_vars/frontend
---
ansible_ssh_port: 2222
# Тут стоит обратить внимание на то, что с версии ansible 2.0
# имена переменных меняются, например на ansible_port
# http://docs.ansible.com/ansible/intro_inventory.html#list-of-behavioral-inventory-parameters
Таким образом я аккуратно разнес переменные для хостов и групп по файлам. А также указал, что для хостов группы frontend порт для подключения SSH 2222.
Теперь можно привести инвентори снова к такому виду:
[[email protected] ~]# cat /etc/ansible/hosts
[frontend]
centos7.host.tld
[backend]
debian8.host.tld
[database]
ubuntu14.host.tld
Я в самом начале устанавливал git не зря, ведь удобно хранить все конфиги ansible в репозитории:
[[email protected] ~]# cd /etc/ansible/
[[email protected] ansible]# git init
Initialized empty Git repository in /etc/ansible/.git/
[[email protected] ansible]# git config --global user.name "Amet13"
[[email protected] ansible]# git config --global user.email [email protected]
[[email protected] ansible]# git commit -m "First commited ansible configuration"
Пример использования ansible, отключаем httpd на frontend-серверах:
[[email protected] ~]# systemctl is-active httpd
active
[[email protected] ~]# ansible frontend -m service -a "name=httpd state=stopped"
centos7.host.tld | success >> {
"changed": true,
"name": "httpd",
"state": "stopped"
}
[[email protected] ~]# systemctl is-active httpd
inactive
Вместо группы frontend можно указать all или *, тогда httpd отключится на всех хостах, можно указать только хостнейм, например debian8.host.tld.
Отправить ping только группам backend и frontend:
[[email protected] ~]# ansible backend:frontend -m ping
Для примера добавим centos7.host.tld в секцию frontend и backend:
[[email protected] ~]# vim /etc/ansible/hosts
[frontend]
centos7.host.tld
[backend]
debian8.host.tld
centos7.host.tld
...
И пропингуем все хосты, которые находятся в группе backend, но не находятся в группе frontend:
[[email protected] ~]# ansible backend:\!frontend -m ping
debian8.host.tld | success >> {
"changed": false,
"ping": "pong"
}
Как видим пинг отправился только для debian8.host.tld, который находится только в группе backend.
Можно использовать подстановки для хостнеймов и IP:
[[email protected] ~]# ansible *.host.tld -m ping
С этими возможностями можно делать множество различиных подстановок.
Более подробно тут: http://docs.ansible.com/ansible/intro_patterns.html#patterns
По умолчанию модуль command не поддерживает пайпы, кавычки, переменные, например при выполнении такой команды:
[[email protected] ~]# ansible frontend -a 'cat /etc/passwd | wc -l'
centos7.host.tld | FAILED | rc=1 >>
cat: invalid option -- 'l'
Try 'cat --help' for more information.
Для этого нужно использовать модуль shell:
[[email protected] ~]# ansible frontend -m shell -a 'cat /etc/passwd | wc -l'
centos7.host.tld | success | rc=0 >>
26
Либо второй вариант, в /etc/ansible/ansible.cfg изменить:
module_name = command
на
module_name = shell
Модуль copy позволяет посредством scp копировать файлы на хосты:
[[email protected] ~]# ansible backend -m copy -a 'src=/etc/hosts dest=/tmp/hosts'
Модуль file позволяет менять владельца файла и права на него.
[email protected]:~# ls -l /tmp/hosts
-rw-r--r-- 1 root root 353 Feb 20 13:09 /tmp/hosts
[[email protected] ~]# ansible backend -m file -a 'dest=/tmp/hosts mode=600 owner=mail group=mail'
[email protected]:~# ls -l /tmp/hosts
-rw------- 1 mail mail 353 Feb 20 13:09 /tmp/hosts
Создать директорию:
[[email protected] ~]# ansible backend -m file -a 'dest=/tmp/dir/test state=directory'
[email protected]:~# ls /tmp/dir/ -l
total 0
drwxr-xr-x 2 root root 40 Feb 20 13:15 test
Рекурсивно удалить директорию:
[[email protected] ~]# ansible backend -m file -a 'dest=/tmp/dir/ state=absent'
[email protected]:~# ls /tmp/dir/ -l
ls: cannot access /tmp/dir/: No such file or directory
Управление пакетами.
Создадим в инвентори группы centos и debian-ubuntu для удобства управления пакетами:
[[email protected] ~]# cat /etc/ansible/hosts
...
[centos]
centos7.host.tld
[debian-ubuntu]
debian8.host.tld
ubuntu14.host.tld
Установим httpd на все хосты с CentOS:
[[email protected] ~]# ansible centos -m yum -a 'name=httpd state=present'
И удалим его сразу:
[[email protected] ~]# ansible centos -m yum -a 'name=httpd state=absent'
Аналогично с apache2 для Debian/Ubuntu:
[[email protected] ~]# ansible debian-ubuntu -m apt -a 'name=apache2 state=present'
[email protected]:~# systemctl is-active apache2
active
[[email protected] ~]# ansible debian-ubuntu -m apt -a 'name=apache2 state=absent'
[email protected]:~# systemctl is-active apache2
inactive
Создание и удаление пользователей:
[[email protected] ~]# ansible debian-ubuntu -m user -a 'name=ansible-user password=$6$IT91ljNr$vfLfnBi4ntlyqsmCa8feNLCwmruv5iZLxW6ZOwcCZ1dOFHrOdithHRbqWdLnTueLi5nf0bDiI3TSYpa51Z/QW/'
[[email protected] ~]# ssh [email protected]
[email protected]'s password: 123456
[[email protected] ~]# ansible debian-ubuntu -m user -a 'name=ansible-user state=absent'
Пример пароля можно сгенерить так:
[[email protected] ~]# mkpasswd --method=sha-512
Password:
$6$yX3fe4eqN6C4lqFO$q86.JTDz3ShkPnErY8HdiOf9HYaGzKHw79TBD6SUnOOWpdN0.raq8ZIBAdOpDd5LYnzpV.yfnsfZlj04ZvfiI.
Модуль git используется для деплоймента приложений например:
[[email protected] ~]# ansible frontend -m yum -a 'name=git state=present'
[[email protected] ~]# ansible frontend -m git -a 'repo=https://github.com/Amet13/icinga2-plugins-extra.git dest=/srv version=HEAD'
[[email protected] ~]# cat /srv/.git/config | grep url
url = https://github.com/Amet13/icinga2-plugins-extra.git
Управление сервисами, тут все понятно:
[[email protected] ~]# ansible debian-ubuntu -m service -a 'name=postfix state=started'
[[email protected] ~]# ansible debian-ubuntu -m service -a 'name=postfix state=restarted'
[[email protected] ~]# ansible debian-ubuntu -m service -a 'name=postfix state=stopped'
Запуск задачи в фоновом режиме:
[[email protected] ~]# ansible all -B 60 -P 0 -a 'ping ya.ru'
background launch...
[[email protected] ~]# ansible ubuntu14.host.tld -m async_status -a "jid=254659849531.1643"
ubuntu14.host.tld | success >> {
"ansible_job_id": "254659849531.1643",
"changed": false,
"finished": 0,
"results_file": "/root/.ansible_async/254659849531.1643",
"started": 1
}
Порядок чтения конфигов ansible'ом:
1. Переменная ANSIBLE_CONFIG
2. ansible.cfg в текущей директории
3. .ansible.cfg в домашней директории
4. /etc/ansible/ansible.cfg
В этой заметке оставлю основные выдержки из вводной документации: http://docs.ansible.com/ansible/intro.html
В VirtualBox развернул Virtuozzo 7, а в нем окружение, в котором я буду тестировать ansible.
Выглядит это так, ansible.host.tld - мастер-сервер ансибла, остальные три виртуалки подопытые кролики:
[[email protected] ~]# prlctl list -o name,ip,ostemplate,hostname
NAME IP_ADDR OSTEMPLATE HOSTNAME
ansible-c7 192.168.0.151 .centos-7-x86_64 ansible.host.tld
centos7 192.168.0.154 .centos-7-x86_64 centos7.host.tld
debian8 192.168.0.153 .debian-8.0-x86_64 debian8.host.tld
ubuntu14 192.168.0.152 .ubuntu-14.04-x86_64 ubuntu14.host.tld
Ansible удобен в первую очередь тем, что на агентах ему не нужно ничего ставить, т.к. общение между мастером и агентами происходит по SSH, никаких тебе демонов, сервисов, кучи зависимостей в виде ruby и прочих Java.
Установка ansible на мастере в CentOS 7:
[[email protected] ~]# yum install epel-release git
[[email protected] ~]# yum install ansible
[[email protected] ~]# ansible --version
ansible 1.9.4
configured module search path = None
В EPEL для RHEL7 до сих пор версия 1.9.4, хотя уже давно 2.0.0 есть для той же Ubuntu.
Пробовал я и с помощью исходников ставить на CentOS 7, но у меня при компиляции просил какой-то пакет asciidoc, который тянет за собой половину иксов, поэтому я поставил с EPEL'а.
Для инвентаризации хостов ansible использует так называемы инвентори-файл /etc/ansible/hosts.
Приведем его к такому виду:
[[email protected] ~]# vim /etc/ansible/hosts
centos7.host.tld
debian8.host.tld
ubuntu14.host.tld
Я внес туда список хостнеймов моих подопытных виртуалок, но т.к. у меня локальная сеть и DNS-сервер я не настраивал, то дополнительно я еще и добавлю такие записи в /etc/hosts:
[[email protected] ~]# vim /etc/hosts
192.168.0.152 ubuntu14.host.tld
192.168.0.153 debian8.host.tld
192.168.0.154 centos7.host.tld
Далее сгенерируем SSH-ключ и раскидаем его по виртуалкам, чтобы постоянно не вводить пароль:
[[email protected] ~]# ssh-keygen
[[email protected] ~]# ls /root/.ssh/
authorized_keys id_rsa id_rsa.pub
[[email protected] ~]# cat /etc/ansible/hosts | xargs -i ssh-copy-id {}
После того как ключи раскиданы, можно проверить коннект:
[[email protected] ~]# ansible all -m ping
ubuntu14.host.tld | success >> {
"changed": false,
"ping": "pong"
}
debian8.host.tld | success >> {
"changed": false,
"ping": "pong"
}
centos7.host.tld | success >> {
"changed": false,
"ping": "pong"
}
Все работает.
Приведем инвентори к такому виду:
[[email protected] ~]# vim /etc/ansible/hosts
[frontend]
centos7.host.tld:2222
[backend]
debian8.host.tld
[backend:vars]
frontend_server=centos7
database_server=ubuntu14
[database]
ubuntu14.host.tld backend_server=debian8
Здесь в инвентори в.ini формате можно объединять хосты в группы и создавать переменные.
Например я тут создал группы frontend, backend и database, понятно, какие хосты к каким группам относятся.
Для группы backend установлены две переменные frontend_server и backend_server, которые впоследствии мы сможем использовать.
Для хоста ubuntu15.host.tld установили переменную backend_server=debian8.
Строка centos7.host.tld:2222 указывает подключение к порту 2222 по SSH.
Хранение переменных нежелательно в инвентори файле, предпочтительно хранить их отдельно. Пример:
[[email protected] ~]# mkdir /etc/ansible/{host,group}_vars
[[email protected] ~]# vim /etc/ansible/group_vars/backend
---
frontend_server: centos7
database_server: ubuntu14
[[email protected] ~]# vim /etc/ansible/host_vars/ubuntu14.host.tld
---
backend_server: debian8
[[email protected] ~]# vim group_vars/frontend
---
ansible_ssh_port: 2222
# Тут стоит обратить внимание на то, что с версии ansible 2.0
# имена переменных меняются, например на ansible_port
# http://docs.ansible.com/ansible/intro_inventory.html#list-of-behavioral-inventory-parameters
Таким образом я аккуратно разнес переменные для хостов и групп по файлам. А также указал, что для хостов группы frontend порт для подключения SSH 2222.
Теперь можно привести инвентори снова к такому виду:
[[email protected] ~]# cat /etc/ansible/hosts
[frontend]
centos7.host.tld
[backend]
debian8.host.tld
[database]
ubuntu14.host.tld
[[email protected] ~]# cd /etc/ansible/
[[email protected] ansible]# git init
Initialized empty Git repository in /etc/ansible/.git/
[[email protected] ansible]# git config --global user.name "Amet13"
[[email protected] ansible]# git config --global user.email [email protected]
[[email protected] ansible]# git commit -m "First commited ansible configuration"
Пример использования ansible, отключаем httpd на frontend-серверах:
[[email protected] ~]# systemctl is-active httpd
active
[[email protected] ~]# ansible frontend -m service -a "name=httpd state=stopped"
centos7.host.tld | success >> {
"changed": true,
"name": "httpd",
"state": "stopped"
}
[[email protected] ~]# systemctl is-active httpd
inactive
Вместо группы frontend можно указать all или *, тогда httpd отключится на всех хостах, можно указать только хостнейм, например debian8.host.tld.
Отправить ping только группам backend и frontend:
[[email protected] ~]# ansible backend:frontend -m ping
Для примера добавим centos7.host.tld в секцию frontend и backend:
[[email protected] ~]# vim /etc/ansible/hosts
[frontend]
centos7.host.tld
[backend]
debian8.host.tld
centos7.host.tld
...
И пропингуем все хосты, которые находятся в группе backend, но не находятся в группе frontend:
[[email protected] ~]# ansible backend:\!frontend -m ping
debian8.host.tld | success >> {
"changed": false,
"ping": "pong"
}
Как видим пинг отправился только для debian8.host.tld, который находится только в группе backend.
Можно использовать подстановки для хостнеймов и IP:
[[email protected] ~]# ansible *.host.tld -m ping
С этими возможностями можно делать множество различиных подстановок.
Более подробно тут: http://docs.ansible.com/ansible/intro_patterns.html#patterns
По умолчанию модуль command не поддерживает пайпы, кавычки, переменные, например при выполнении такой команды:
[[email protected] ~]# ansible frontend -a 'cat /etc/passwd | wc -l'
centos7.host.tld | FAILED | rc=1 >>
cat: invalid option -- 'l'
Try 'cat --help' for more information.
[[email protected] ~]# ansible frontend -m shell -a 'cat /etc/passwd | wc -l'
centos7.host.tld | success | rc=0 >>
26
Либо второй вариант, в /etc/ansible/ansible.cfg изменить:
module_name = command
на
module_name = shell
Модуль copy позволяет посредством scp копировать файлы на хосты:
[[email protected] ~]# ansible backend -m copy -a 'src=/etc/hosts dest=/tmp/hosts'
Модуль file позволяет менять владельца файла и права на него.
[email protected]:~# ls -l /tmp/hosts
-rw-r--r-- 1 root root 353 Feb 20 13:09 /tmp/hosts
[[email protected] ~]# ansible backend -m file -a 'dest=/tmp/hosts mode=600 owner=mail group=mail'
[email protected]:~# ls -l /tmp/hosts
-rw------- 1 mail mail 353 Feb 20 13:09 /tmp/hosts
Создать директорию:
[[email protected] ~]# ansible backend -m file -a 'dest=/tmp/dir/test state=directory'
[email protected]:~# ls /tmp/dir/ -l
total 0
drwxr-xr-x 2 root root 40 Feb 20 13:15 test
Рекурсивно удалить директорию:
[[email protected] ~]# ansible backend -m file -a 'dest=/tmp/dir/ state=absent'
[email protected]:~# ls /tmp/dir/ -l
ls: cannot access /tmp/dir/: No such file or directory
Управление пакетами.
Создадим в инвентори группы centos и debian-ubuntu для удобства управления пакетами:
[[email protected] ~]# cat /etc/ansible/hosts
...
[centos]
centos7.host.tld
[debian-ubuntu]
debian8.host.tld
ubuntu14.host.tld
Установим httpd на все хосты с CentOS:
[[email protected] ~]# ansible centos -m yum -a 'name=httpd state=present'
И удалим его сразу:
[[email protected] ~]# ansible centos -m yum -a 'name=httpd state=absent'
Аналогично с apache2 для Debian/Ubuntu:
[[email protected] ~]# ansible debian-ubuntu -m apt -a 'name=apache2 state=present'
[email protected]:~# systemctl is-active apache2
active
[[email protected] ~]# ansible debian-ubuntu -m apt -a 'name=apache2 state=absent'
[email protected]:~# systemctl is-active apache2
inactive
Создание и удаление пользователей:
[[email protected] ~]# ansible debian-ubuntu -m user -a 'name=ansible-user password=$6$IT91ljNr$vfLfnBi4ntlyqsmCa8feNLCwmruv5iZLxW6ZOwcCZ1dOFHrOdithHRbqWdLnTueLi5nf0bDiI3TSYpa51Z/QW/'
[[email protected] ~]# ssh [email protected]
[email protected]'s password: 123456
[[email protected] ~]# ansible debian-ubuntu -m user -a 'name=ansible-user state=absent'
Пример пароля можно сгенерить так:
[[email protected] ~]# mkpasswd --method=sha-512
Password:
$6$yX3fe4eqN6C4lqFO$q86.JTDz3ShkPnErY8HdiOf9HYaGzKHw79TBD6SUnOOWpdN0.raq8ZIBAdOpDd5LYnzpV.yfnsfZlj04ZvfiI.
Модуль git используется для деплоймента приложений например:
[[email protected] ~]# ansible frontend -m yum -a 'name=git state=present'
[[email protected] ~]# ansible frontend -m git -a 'repo=https://github.com/Amet13/icinga2-plugins-extra.git dest=/srv version=HEAD'
[[email protected] ~]# cat /srv/.git/config | grep url
url = https://github.com/Amet13/icinga2-plugins-extra.git
Управление сервисами, тут все понятно:
[[email protected] ~]# ansible debian-ubuntu -m service -a 'name=postfix state=started'
[[email protected] ~]# ansible debian-ubuntu -m service -a 'name=postfix state=restarted'
[[email protected] ~]# ansible debian-ubuntu -m service -a 'name=postfix state=stopped'
Запуск задачи в фоновом режиме:
[[email protected] ~]# ansible all -B 60 -P 0 -a 'ping ya.ru'
background launch...
[[email protected] ~]# ansible ubuntu14.host.tld -m async_status -a "jid=254659849531.1643"
ubuntu14.host.tld | success >> {
"ansible_job_id": "254659849531.1643",
"changed": false,
"finished": 0,
"results_file": "/root/.ansible_async/254659849531.1643",
"started": 1
}
Порядок чтения конфигов ansible'ом:
1. Переменная ANSIBLE_CONFIG
2. ansible.cfg в текущей директории
3. .ansible.cfg в домашней директории
4. /etc/ansible/ansible.cfg
По конфигу можно почитать тут, информация периодически меняется:
http://docs.ansible.com/ansible/intro_configuration.html
Тут я познакомился с плейбуками в nginx (рекомендую к ознакомлению): http://blog.amet13.name/2016/02/ansible-playbook-nginx.html
Ссылки пригодятся:
Книга Ansible for DevOps: https://www.dropbox.com/sh/m9z66tysri8l53f/AADa3vMrwjb8XyUXMXqxZpGga/pub/eng/administration/Ansible%20for%20DevOps.pdf
Получасовое видео о Ansible, где четко поясняют основы: https://www.ansible.com/get-started
Получасовое видео о Ansible, где четко поясняют основы: https://www.ansible.com/get-started
3 комментария:
Очень хороший пост. Все понятно и есть примеры для практического использования.
Хотя я для того же в основном работаю через pssh, он конечно не на столько удобный в описании нужных хостов (нельзя там убрать хосты что повторяются в другом списке), и для выполнения нужной команда нужно описать как она выглядит в shell.
О вспомнил.. один вопрос возник.
Для того, чтобы всё-таки вводить пароль, если не делать проброс ключа, то как команда должна выглядеть, хотя бы того же пинга?
http://docs.ansible.com/ansible/intro_getting_started.html
>When speaking with remote machines, Ansible by default assumes you are using SSH keys. SSH keys are encouraged but password authentication can also be used where needed by supplying the option --ask-pass. If using sudo features and when sudo requires a password, also supply --ask-become-pass (previously --ask-sudo-pass which has been deprecated).
Отправить комментарий