Added ansible tasks.

pull/1/head
Vladimir Protsenko 2 years ago
parent 13de24386e
commit 7c35b8e614

@ -805,7 +805,7 @@ $ sudo docker stop $(docker ps -q)
2a1b77e066e6 2a1b77e066e6
``` ```
Теперь можно запускать `docker-compose`. Перейдите в директорию с приложением Foodtrucks и выполните команду` docker-compose up`. Теперь можно запускать `docker-compose`. Перейдите в директорию с приложением Foodtrucks и выполните команду `docker-compose up`.
``` ```
$ sudo docker-compose up $ sudo docker-compose up
[+] Running 2/0 [+] Running 2/0

@ -0,0 +1,37 @@
# Справочный материал
## Что такое Ansible?
Ansible - это инструмент управления конфигурацией, стоящий в ряду с Chef, Puppet и Salt.
Когда мы говорим о конфигурации управления, мы обычно говорим о написании какого-то состояния описание для наших серверов, а затем с помощью инструмента для обеспечения того, чтобы серверы были, действительно, в таком состоянии: нужные пакеты установлены, конфигурационные файлы содержат ожидаемые значения и имеют ожидаемые разрешения, работают нужные службы, и так далее. Как и другие инструменты правления конфигурацией, Ansible предоставляет доменный язык (DSL), который вы используете для описания состояния ваших серверов.
Ansible — инструмент для развертывания приложений.
Когда люди говорят о развертывании, они обычно имеют в виду процесс использования программного обеспечения, которое было написано собственными силами, создание двоичных файлов или статических ресурсов (при необходимости), копирование необходимых файлов в сервер(ы), а затем запуск служб. Capistrano и Fabric — два примера инструментов развертывания с открытым исходным кодом. Ansible — отличный инструмент для развертывания, а также управление конфигурацией. Использование единого инструмента для управления конфигурацией и развертывания упрощает жизнь тем, кто отвечает за операции.
Ansible — инструмент для выполнения действий на нескольких серверах.
Некоторые люди говорят о необходимости оркестрации развертывания. Вот где много- Задействовано множество удаленных серверов, и все должно происходить в определенном порядке. За например, вам нужно поднять базу данных перед запуском веб-серверов, или вам нужно выводить веб-серверы из балансировщика нагрузки по одному, чтобы обновить их без простоев. Ansible также хорош в этом и разработан из основа для выполнения действий на нескольких серверах. Ansible имеет освежающий простая модель управления порядком выполнения действий.
Ansible — инструмент для взаимодействия с облаком.
Наконец, вы услышите, как люди говорят о предоставлении новых серверов. В контексте общественного облака, такие как Amazon EC2, это относится к запуску новой виртуальной машины пример. Ansible поможет вам в этом, предоставив ряд модулей для общения с облаком, включая EC2, Azure, Digital Ocean, Google Compute Engine, Linode и Rackspace, а также любые облака, поддерживающие API OpenStack.
## Релевантные определения
**Хост** — удаленная машина, управляемая Ansible.
**Группа**— несколько хостов сгруппированных вместе, которые имеют общий атрибут.
**Инвентарь** — коллекция всех хостов и групп, которыми управляет Ansible. Это может быть статический файл в простых случаях, или инвентарь из удаленных источников, таких как облачные поставщики.
**Модули** — единицы кода, которые Ansible отправляет в удаленные узлы для выполнения.
**Задачи** — единицы действия, которые объединяют модуль и его аргументы вместе с некоторыми другими параметрами.
**Playbook** — упорядоченный список задач, а также его необходимые параметры, которые определяют рецепт для настройки системы.
**Роли** — переиспользуемые единицы организации, которые позволяют пользователям облегчить код автоматизации. Обычно включают список файлов и задач для настройки одного сервиса.
**YAML** — популярный и простой формат данных, который очень чистый и понятный для людей.

@ -0,0 +1,401 @@
# Задания
## 0. Настройка кластера
В этом задании мы сконфигурируем основу будущего кластера с беспарольным доступом по ssh c управляющей машины.
Создайте виртуальную машину `studX-node` из шаблона `ubuntu-template` со свеже установленной ОС Ubuntu 20.04.
Настройте сеть. В этой машине наиболее простом способом будет модификация конфигурационного файла `/etc/network/interfaces`. Используйте ip адрес из сети `192.168.1.0/24`, шлюз `192.168.1.1`, любой общедоступный DNS. В настройках оборудования виртуальной машины подключите сетевое устройство к `vmbr15+X`.
Добавьте в `/etc/hosts` имена узлов в соответствии со схемой ниже на `studX` и `studX-node`.
Сгенерируйте в управляющей машине `studX` ssh ключи без кодовой фразы (passphrase) для пользователя `stud` по алгоритму ed25519. В машине `studX-node` отредактируйте конфигурацию `/etc/ssh/sshd_config`, разрешите доступ к машине по паролю и перезагрузите sshd `systemctl restart sshd`. Добавьте публичный ключ в `authorized_keys` машины `studX-node` с помощью `ssh-copy-id`.
Превратите виртуальную машину в шаблон для узлов кластера.
Создайте 3 машины `studX-node[1-3]` из шаблона `studX-node`. Настройте сеть, установив уникальные IP. Поменяйте имена хостов командой `hostnamectl set-hostname`. В итоге схема должна выглядеть следующим образом.
```
_______________
| |
| studX | Управляющий узел с Ansible
|_______________|
| ens19 в vlan 15+X, IP 192.168.1.100/24
|
+---------+---------+-------------------+
| 192.168.1.101/24 | 192.168.1.102/24 | 192.168.1.103/24
__________ __________ __________
| | | | | |
| node 1 | | node 2 | | node 3 | Узлы под управлением Ansible
|__________| |__________| |__________|
```
Проверьте, что доступ с `studX` по ключу работает.
```
stud@studX # ssh node1
stud@studX # ssh node2
stud@studX # ssh node3
```
## 1. Установка Ansible, введение в команды
Далее все команды выполняются в консоли управляющего узла `studX`.
Установите Ansible.
```
$ sudo apt install ansible
$ ansible --version
ansible [core 2.13.4]
config file = None
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible
python version = 3.10.7 (main, Sep 8 2022, 14:34:29) [GCC 12.2.0]
jinja version = 3.0.3
libyaml = True
```
Требованием для работы Ansible являются: возможность подключения к удалённому узлу по ssh и наличие установленного Python интерпретатора на каждом узле.
Управление кластером с помощью Ansible может осуществляться в двух режимах ad-hoc интерактивном режиме и в режиме выполнения проекта конфигурации playbook. В первом случае все команды начинаются с вызова ansible. Документация команды `man ansible`.
### 1.1. Инвентарь
Прежде чем выполнять команды, создадим кластер в терминах Ansible. В Ansible инструменте существует понятие инвентаря (Inventory), файла, который содержит список сгруппированных имён или ip адресов.
Создайте файл `/etc/ansible/hosts`. Отредактируйте его так, чтобы он содержал только группу `cluster` и имена машин, входящих в кластер. В квадратных скобках указывается имя группы, ниже следуют имена машин. Вы можете использовать шаблоны для перечисления номеров (также используют квадратные скобки), которые раскрываются следующим образом:
```
[1:3] раскрывается в 1 2 3
abc[1:3] раскрывается в abc1 abc2 abc3
A[1:3]B раскрывается в A1B A2B A3B
```
Наш кластер `cluster` в `/etc/ansible/hosts` может выглядеть так
```
# cat /etc/ansible/hosts
[cluster]
node[1:3]
```
**Примечание.** Обратите внимание что в скобках используется двоеточие, а не знак тире.
Таким образом кластер `cluster` в терминах Ansible - это группа имён машин `node1`, `node2`, `node3`.
### 1.2 Модули
#### 1.2.1 ping
Запустим нашу первую Ansible команду:
```
$ ansible cluster -m ping
```
В данной команде мы запустили модуль `ping` для группы узлов `cluster`. Формат ad-hoc команд:
```
$ ansible <группа или шаблон> -m <модуль>
```
Существуют и другие ключи, кроме `-m`, часть из которых будет описана далее. О них вы можете узнать в официальной документации, либо вызвав `ansible` без параметров.
По умолчанию модуль выполняется параллельно на как можно большем количестве узлов. Это позволяет быстрее получить результат, но не гарантирует выполнение в том же порядке, что и порядок узлов в инвентаре. Попробуйте выполнить следующую команду:
```
$ ansible cluster -m ping -f 1
```
Добавленный в конце ключ `-f` позволяет ограничить количество одновременно изменяемых узлов. Его также применяют для обновления компонентов распределённого приложения по частям, для избегания остановки всей системы.
#### 1.2.2 shell
Для ad-hoc режима естественнее всего подходит модуль `shell` (https://docs.ansible.com/ansible/latest/collections/ansible/builtin/shell_module.html). Данный модуль позволяет выполнить любую консольную команду на нескольких  узлах. Приведём ряд примеров, чтобы вы попробовали их далее на всём кластере:
```bash
# узнать время на текущей машине, нам необходимо вызвать:
date
# узнать имена файлов в директории `~/.ssh/`:
ls -la ~/.ssh/
# узнать информацию о процессорах:
lscpu
# узнать количество свободного места на дисках:
df -h
# узнать версию операционной системы (для CentOS, Red Hat, Fedora) и ядра линукс
cat /etc/os-release
lsb_release -a
uname -a
# проверить, что нужный пакет находится в списке установленных
apt list installed python3
```
Выполнение консольных команд на узлах кластера с помощью модуля `shell` выглядит следующим образом:
```
# ansible cluster -m shell -a "date"
```
Верное ли время на узлах?
После ключа `-a` в `ansible` передаётся строка с командой. Попробуйте выполнить несколько вышеупомянутых команд аналогичным образом.
#### 1.2.3 setup
В задачах конфигурации кластера как правило требуется не только узнавать информацию о различных свойствах, конфигурациях систем, но и использовать данную информацию в качестве параметров в других командах.
Для сбора информации о состоянии (Facts) узлов используется модуль `setup`. Выполните команду для одного узла и просмотрите результат. Среди этих данных есть результаты, полученные нами ранее.
```
$ ansible node1 -m setup
```
Результатом является иерархическая структура в JSON формате. https://docs.ansible.com/ansible/latest/collections/ansible/builtin/setup_module.html. Для обращения к значениям (листьям JSON структуры) указывается путь из названий, разделённых точками. Например:  `ansible_eth0.ip4.address` или `ansible_date_time.date`.
#### 1.2.4 apt
Для установки ПО нам потребуется модуль `apt`.
Проверьте установлена ли python3. Например так:
```
$ ansible cluster -m shell -a "apt list installed python3"
```
Целью использования Ansible является перевод распределённой системы из одного состояния в другое. По этой причине в параметрах многих модулей можно встретить параметр `state`. Данных параметр для модуля apt допускает значения: `present` - присутствует, `absent` - отсутствует, `latest` - последняя версия. Кроме него нам потребуется параметр `name` - имя или шаблон имени по которому нужно искать устанавливаемое ПО. Другие параметры модуля yum доступны на официальном сайте https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html.
Попробуем установить htop следующей командой:
```
$ ansible cluster -m apt -a "name=htop state=present"
```
#### 1.2.5 Эскалация прав доступа
Для повышения прав доступа используется ключ `--become` или сокращенный вариант `-b`.
```
$ ansible cluster -m apt -a "name=htop state=present" -b
```
Подробнее об эскалации прав можно прочитать в https://docs.ansible.com/ansible/2.3/become.html.
Таким образом мы переводим кластер из состояния без htop в состояние с htop. Можно убедиться, что при повторном запуске никаких изменений производиться не будет.
## 2. Ansible Playbook
Большую часть времени в Ansible вы потратите на написание сценариев управления конфигурацией (Playbook). Playbook — это термин который Ansible использует для названия таких сценариев.
В этом задании установим Greenplum на наш кластер.
### 2.1 Шаблон конфигурации
В первую очередь создайте папку проекта управления конфигурацией `ansible-greenplum`, в которой будет лежать файл со сценарием. Назовите этот файл `main.yml`.
Поместите в него следующие строки и попробуйте запустить с флагом `--verbose`.
```yaml
---
- hosts: cluster
tasks:
- name: Current date
shell: date
```
```
$ ansible-playbook main.yml -v
```
### 2.2 Создание пользователя-администратора распределённой базы данных
Преступим у настройке конфигурации для Greenplum.
Создайте файл 1.yml и поместите содержимое из листинга следующего ниже. Отличие от предыдущего примера заключается в добавлении блока с переменными `vars`. Все действия понадобится выполнять с правами `root`, поэтому мы добавляем параметр `become: yes`.
Первая задача - создать пользователя `gpadmin` и установить ему пароль `changeme`.
```yaml
---
- hosts: cluster
vars:
- version: "6.0.0"
- greenplum_admin_user: "gpadmin"
- greenplum_admin_password: "changeme"
become: yes
tasks:
- name: create greenplum admin user
user:
name: "{{ greenplum_admin_user }}"
password: "{{ greenplum_admin_password | password_hash('sha512', 'DvkPtCuQ9pU') }}"
```
```
$ ansible-playbook 1.yml
```
### 2.3 Настройка репозитория на целевых узлах
Поместите содержимое файла в 2.yml и запустите. Конфигурация настроит Greenplum репозиторий для apt.
```yaml
---
- hosts: cluster
become: yes
tasks:
- name: install software-properties-common
apt:
name: software-properties-common
state: present
- name: install gnupg2
apt:
name: gnupg2
state: present
- name: install ppa:greenplum/db
apt_repository:
repo: ppa:greenplum/db
state: present
```
```
$ ansible-playbook 2.yml
```
### 2.4 Установка пакета
Установим пакет Greenplum конфигурацией `3.yml`.
```yaml
---
- hosts: all
vars:
- version: "6.0.0"
- greenplum_admin_user: "gpadmin"
- greenplum_admin_password: "changeme"
# - package_path: passed via the command line with: -e package_path=
remote_user: root
become: yes
become_method: sudo
connection: ssh
gather_facts: yes
tasks:
- name: install package
apt:
name: greenplum-db-6
state: present
- name: change install directory ownership
file:
path: '{{ item.path }}'
owner: "{{ greenplum_admin_user }}"
group: "{{ greenplum_admin_user }}"
recurse: yes
with_items: "{{ installed_dir.files }}"
```
```
$ ansible-playbook 3.yml
```
### 2.5 Настроим параметры ОС для Greenplum
```yaml
- hosts: all
vars:
- version: "6.0.0"
- greenplum_admin_user: "gpadmin"
- greenplum_admin_password: "changeme"
remote_user: root
become: yes
become_method: sudo
connection: ssh
gather_facts: yes
tasks:
- name: update pam_limits
pam_limits:
domain: "{{ greenplum_admin_user }}"
limit_type: '-'
limit_item: "{{ item.key }}"
value: "{{ item.value }}"
with_dict:
nofile: 524288
nproc: 131072
```
```
$ ansible-playbook 4.yml
```
### 2.6 Проверка установленной версии
```yaml
- hosts: all
vars:
- version: "6.0.0"
remote_user: root
become: yes
become_method: sudo
connection: ssh
gather_facts: yes
tasks:
- name: find installed greenplum version
shell: . /usr/local/greenplum-db/greenplum_path.sh && /usr/local/greenplum-db/bin/postgres --gp-version
register: postgres_gp_version
- name: fail if the correct greenplum version is not installed
fail:
msg: "Expected greenplum version {{ version }}, but found '{{ postgres_gp_version.stdout }}'"
when: "version is not defined or version not in postgres_gp_version.stdout"
```
```
$ ansible-playbook 5.yml
```
### 2.7 Финальная версия
Соберите все предыдущие конфигурации в один файл и запустите ещё раз. Ошибок быть не должно, кластер перешёл в состояние с установленной Greenplum.
```yaml
---
- hosts: all
vars:
- version: "6.0.0"
- greenplum_admin_user: "gpadmin"
- greenplum_admin_password: "changeme"
# - package_path: passed via the command line with: -e package_path=./greenplum-db-6.0.0-rhel7-x86_64.rpm
remote_user: root
become: yes
become_method: sudo
connection: ssh
gather_facts: yes
tasks:
- name: create greenplum admin user
user:
name: "{{ greenplum_admin_user }}"
password: "{{ greenplum_admin_password | password_hash('sha512', 'DvkPtCtNH+UdbePZfm9muQ9pU') }}"
- name: copy package to host
copy:
src: "{{ package_path }}"
dest: /tmp
- name: cleanup package file from host
file:
path: "/tmp/{{ package_path | basename }}"
state: absent
- name: find install directory
find:
paths: /usr/local
patterns: 'greenplum*'
file_type: directory
register: installed_dir
- name: change install directory ownership
file:
path: '{{ item.path }}'
owner: "{{ greenplum_admin_user }}"
group: "{{ greenplum_admin_user }}"
recurse: yes
with_items: "{{ installed_dir.files }}"
- name: update pam_limits
pam_limits:
domain: "{{ greenplum_admin_user }}"
limit_type: '-'
limit_item: "{{ item.key }}"
value: "{{ item.value }}"
with_dict:
nofile: 524288
nproc: 131072
- name: find installed greenplum version
shell: . /usr/local/greenplum-db/greenplum_path.sh && /usr/local/greenplum-db/bin/postgres --gp-version
register: postgres_gp_version
- name: fail if the correct greenplum version is not installed
fail:
msg: "Expected greenplum version {{ version }}, but found '{{ postgres_gp_version.stdout }}'"
when: "version is not defined or version not in postgres_gp_version.stdout"
```
```
$ ansible-playbook main.yml
```
## Релевантные источники
- Nemeth E. et al. UNIX and Linux system administration handbook. Chapter 23.
- Hochstein L. Ansible: Up and Running. " O'Reilly Media, Inc.", 2014.
- https://gpdb.docs.pivotal.io/6-1/install_guide/ansible-example.html
Loading…
Cancel
Save