You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

452 lines
24 KiB
Markdown

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Задания
## 0. Настройка кластера
В этом задании мы сконфигурируем основу будущего кластера с беспарольным доступом по ssh c управляющей машины. В качестве управляющей машины используйте машину подключенную к `vmbrX`, например `gwX`. Создайте 3 виртуальных машины: `studX-ubuntu-n1`, `studX-ubuntu-n2`, `studX-ubuntu-n3` из шаблонов: `ubuntu-n1`, `ubuntu-n2`, `ubuntu-n3` соответственно со свеже установленной ОС Ubuntu 18.04 в режиме `Linked Clone`. Укажите свой ресурсный пул при создании. Подключите их в `vmbrX`.
Добавьте в `/etc/hosts` управляющей машины имена узлов, например так:
```
192.168.0.111 n1
192.168.0.112 n2
192.168.0.113 n3
```
Сгенерируйте в управляющей машине `gwX` ssh ключи без кодовой фразы (passphrase) для пользователя `stud` по алгоритму ed25519. Настройте беспарольный доступ для пользователя `stud` на машины: `n1`, `n2`, `n3`. Пользователь `stud` должен иметь возможность перейти в суперпользователя с помощью `sudo` на управляемых машинах.
В итоге схема должна выглядеть следующим образом.
```
_______________
| |
| gwX | Управляющий узел с Ansible
|_______________|
| ens19 в vmbrX, IP 192.168.0.1/24
|
+---------+---------+-------------------+
| 192.168.0.111/24 | 192.168.0.112/24 | 192.168.0.113/24
__________ __________ __________
| | | | | |
| node 1 | | node 2 | | node 3 | Узлы под управлением Ansible
|__________| |__________| |__________|
```
Проверьте, что доступ с `gwX` по ключу работает.
```
gatekeeper@gwX # ssh stud@n1
gatekeeper@gwX # ssh stud@n2
gatekeeper@gwX # ssh stud@n3
```
## 1. Установка Ansible, введение в команды
Далее все команды выполняются в консоли управляющего узла `gwX`.
Установите 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 адресов под управлением Ansible.
Создайте файл `/etc/ansible/hosts`. Отредактируйте его так, чтобы он содержал только группу `cluster` и имена машин, входящих в кластер. В квадратных скобках указывается имя группы, ниже следуют имена машин. Вы можете использовать шаблоны для перечисления номеров (также используют квадратные скобки), которые раскрываются следующим образом:
```
[1:3] раскрывается в 1 2 3
abc[1:3] раскрывается в abc1 abc2 abc3
A[1:3]B раскрывается в A1B A2B A3B
```
Вы также можете указать имя пользователя под именем которого `ansible` подключается по `ssh` в блоке `[cluster:vars]`. Наш кластер `cluster` в `/etc/ansible/hosts` в итоге может выглядеть так:
```
# cat /etc/ansible/hosts
[cluster]
n[1:3]
[cluster:vars]
ansible_user=stud
```
**Примечание.** Обратите внимание что в скобках используется двоеточие, а не знак тире.
### 1.2 Модули
Далее на управляющем узле запускайте команды от обычного пользователя - `stud` или `gatekeeper`.
#### 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 command
Для ad-hoc режима естественнее всего подходят модули `command` (https://docs.ansible.com/ansible/latest/collections/ansible/builtin/command_module.html) и `shell` (https://docs.ansible.com/ansible/latest/collections/ansible/builtin/shell_module.html). Командный модуль выполняет команды на целевой машине без использования оболочки. Это модуль используется по-умолчанию. После ключа `-a` передаётся строка с командой.
```
$ ansible cluster -a 'echo Hello, world worker $USER'
$ ansible cluster -a "echo Hello, world admin $USER"
```
#### 1.2.3 shell
Модуль `shell` позволяет выполнить любую консольную команду на нескольких узлах в оболочке. Вы можете использовать возможности оболочки, например вызов других команд и подстановку результатов.
```
$ ansible cluster -m shell -a 'echo Hello, world $(hostname) user $USER'
$ ansible cluster -m shell -a "echo Hello, world $(hostname) user $USER"
```
Попробуйте ряд примеров на всём кластере `cluster`:
```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
```
#### 1.2.4 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.5 apt
Для установки ПО нам потребуется модуль `apt`.
Проверьте установлена ли python3. Например так:
```
$ ansible cluster -a "apt list installed python3"
```
Целью использования Ansible является перевод распределённой системы из одного состояния в другое. По этой причине в параметрах многих модулей можно встретить параметр `state`. Данных параметр для модуля `apt` допускает значения:
- `present` - присутствует,
- `absent` - отсутствует,
- `latest` - последняя версия.
Кроме него нам потребуется параметр `name` - имя или шаблон имени по которому нужно искать устанавливаемое ПО. Другие параметры модуля `apt` доступны на официальном сайте https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html.
Попробуем установить `htop` следующей командой:
```
$ ansible cluster -m apt -a "name=htop state=present"
```
#### 1.2.6 Эскалация прав доступа
Для повышения прав доступа до суперпользователя на управляемых машинах используется ключ `--become` или сокращенный вариант `-b`. Если вы не настроили sudo без запроса пароля на управялемых машинах, вы можете добавить ключ `--ask-become-pass` или сокращенный вариант `-K` для запроса пароля. По умолчанию `--become-user` равен `root`.
```
$ ansible cluster -m apt -a "name=htop state=present" --become --ask-become-pass
```
Подробнее об эскалации прав можно прочитать в 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. Мы будет тестировать конфигурацию по частям во временных конфигурационных файлах, а затем объединим в `main.yml`.
Создайте файл `1.yml` и поместите содержимое из листинга следующего ниже. Отличие от предыдущего примера заключается в добавлении блока с переменными `vars`. Все действия понадобится выполнять с правами `root`, поэтому мы добавляем параметр `become: yes`.
Первая задача - создать пользователя `gpadmin` и установить ему пароль `changeme` с помощью модуля `user` (https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html). Перед установкой поменяйте пароль на более сложный.
```yaml
---
- hosts: cluster
vars:
- version: "6.22.1"
- greenplum_admin_user: "gpadmin"
- greenplum_admin_password: "changeme" # поменяйте на стандартный пароль MyOffice
become: yes
tasks:
- name: create greenplum admin user
user:
name: "{{ greenplum_admin_user }}"
password: "{{ greenplum_admin_password | password_hash('sha512', 'DvkPtCuQ9pU') }}"
shell: /bin/bash
```
```
$ ansible-playbook 1.yml
```
Можно убедиться, что пользователь создан отдельными командами оболочки:
```
$ ansible cluster -m shell -a 'cat /etc/passwd | grep gpadmin'
$ ansible cluster -m shell -a 'cat /etc/shadow | grep gpadmin' -bK
$ ansible cluster -m shell -a 'ls -laht /home/ | grep gpadmin'
```
### 2.3 Настройка репозитория на целевых узлах
Напишите следующую конфигурацию в файле `2.yml` и запустите. Конфигурация настроит Greenplum репозиторий для `apt`. Обратите внимание что для этих этапов глобально указано повышение прав до `root` в начале файла.
```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 -K
```
Перепроверим, что репозиторий с greenplum зарегистрирован:
```
$ ansible cluster -m shell -a 'ls /etc/apt/sources.list.d/'
$ ansible cluster -m shell -a 'cat /etc/apt/sources.list.d/ppa_greenplum*'
```
### 2.4 Установка пакета
Установим пакет Greenplum конфигурацией `3.yml` и сделаем несколько изменений для его использования.
```yaml
---
- hosts: cluster
vars:
- version: "6.22.1"
- greenplum_admin_user: "gpadmin"
- greenplum_admin_password: "changeme" # поменяйте на стандартный пароль MyOffice
become: yes
tasks:
- name: install package
apt:
name: greenplum-db-6
state: present
- name: find install directory
find:
paths: /opt
patterns: 'greenplum*'
file_type: directory
recurse: false
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: add bin folder to gpadmin PATH
shell: echo "PATH={{ item.path }}/bin/:$PATH" >> /home/{{ greenplum_admin_user }}/.bashrc
with_items: "{{ installed_dir.files }}"
```
```
$ ansible-playbook 3.yml -K
```
Согласно этой конфигурации в системе должен стоять пакет `greenplum-db-6`:
```
$ ansible cluster -a 'apt list installed greenplum-db-6'
```
Зарегистрирована временная переменная `installed_dir`, которую можно использовать в остальной части конфигурации. Она содержит выдачу команды `find`:
```
$ ansible cluster -a 'find /opt/ -maxdepth 1 -type d -name greenplum*'
```
Изменён владелец установленных файлов на `gpadmin`:
```
$ ansible cluster -m shell -a 'ls -laht /opt/green*'
```
В `.bashrc` добавлена директория с исполняемыми файлами базы данных `greenplum` в переменную PATH:
```
$ ansible cluster -a 'tail -n1 /home/gpadmin/.bashrc'
```
### 2.5 Настроим параметры ОС для Greenplum
Для оптимальной работы базе данных может потребоваться держать открытыми много файлов и запускать много процессов. Посмотрим на лимиты и увеличим до рекомендованных в конфигурации:
```
$ ansible cluster -a 'prlimit' --become-user gpadmin --become -K
$ ansible cluster -a 'cat /etc/security/limits.conf'
```
Содержимое файла `4.yml`:
```yaml
---
- hosts: cluster
vars:
- version: "6.22.1"
- greenplum_admin_user: "gpadmin"
- greenplum_admin_password: "changeme" # поменяйте на стандартный пароль MyOffice
become: 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
```
Проверим изменились ли значения в конфигурационном файле:
```
$ ansible cluster -a 'cat /etc/security/limits.conf'
```
**Примечание.** Значения `prlimit` могут не измениться для интерактивного логина. Это не повлияет на процессы базы данных, которые стартуют не интерактивно. Подробнее объяснение описано здесь https://superuser.com/questions/1200539/cannot-increase-open-file-limit-past-4096-ubuntu/1200818#_=_
### 2.6 Финальная версия
Соберите все предыдущие конфигурации в один файл, удалите лишние строки и запустите ещё раз. Ошибок быть не должно, кластер перешёл в состояние с установленной Greenplum.
```
$ rm main.yml && cat *.yml > main.yml
$ # delete unnecessary header lines
```
```yaml
---
- hosts: cluster
vars:
- version: "6.22.1"
- greenplum_admin_user: "gpadmin"
- greenplum_admin_password: "changeme" # поменяйте на стандартный пароль MyOffice
become: yes
tasks:
- name: create greenplum admin user
user:
name: "{{ greenplum_admin_user }}"
password: "{{ greenplum_admin_password | password_hash('sha512', 'DvkPtCuQ9pU') }}"
shell: /bin/bash
- 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
- name: install package
apt:
name: greenplum-db-6
state: present
- name: find install directory
find:
paths: /opt
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: add bin folder to gpadmin PATH
shell: echo "PATH={{ item.path }}/bin/:$PATH" >> /home/{{ greenplum_admin_user }}/.bashrc
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
```
```
$ ansible-playbook main.yml -K
```
Чтобы запустить распределённую базу данных вам потребуется проследовать далее по официальной инструкции https://docs.vmware.com/en/VMware-Greenplum/6/greenplum-database/install_guide-create_data_dirs.html. Запуск базы данных оставляем читателю в качестве упражения.
## Релевантные источники
- 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