|
|
|
@ -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
|