From 7c35b8e61404b1027a0a086e0230c311b39ddbee Mon Sep 17 00:00:00 2001 From: Vladimir Protsenko Date: Wed, 2 Nov 2022 17:01:45 +0400 Subject: [PATCH] Added ansible tasks. --- module2/07_containerization_docker/tasks.md | 2 +- module2/08_ansible/lection.md | 37 ++ module2/08_ansible/tasks.md | 401 ++++++++++++++++++++ 3 files changed, 439 insertions(+), 1 deletion(-) create mode 100644 module2/08_ansible/lection.md create mode 100644 module2/08_ansible/tasks.md diff --git a/module2/07_containerization_docker/tasks.md b/module2/07_containerization_docker/tasks.md index e26c6fb..2c67170 100644 --- a/module2/07_containerization_docker/tasks.md +++ b/module2/07_containerization_docker/tasks.md @@ -805,7 +805,7 @@ $ sudo docker stop $(docker ps -q) 2a1b77e066e6 ``` -Теперь можно запускать `docker-compose`. Перейдите в директорию с приложением Foodtrucks и выполните команду` docker-compose up`. +Теперь можно запускать `docker-compose`. Перейдите в директорию с приложением Foodtrucks и выполните команду `docker-compose up`. ``` $ sudo docker-compose up [+] Running 2/0 diff --git a/module2/08_ansible/lection.md b/module2/08_ansible/lection.md new file mode 100644 index 0000000..f50c36f --- /dev/null +++ b/module2/08_ansible/lection.md @@ -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** — популярный и простой формат данных, который очень чистый и понятный для людей. diff --git a/module2/08_ansible/tasks.md b/module2/08_ansible/tasks.md new file mode 100644 index 0000000..64c5ced --- /dev/null +++ b/module2/08_ansible/tasks.md @@ -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 \ No newline at end of file