
Введение
Мы используем Ansible для автоматизации облачного провизионирования, управления конфигурациями, развертывания и других IT операций, просто составляя плейбуки (playbook). Это инструмент с открытым исходным кодом, который увеличивает нашу продуктивность в больших масштабах, экономя нам много времени и сил, когда, например, нужно выполнить корректировку конфигураций на нескольких узлах.
В этой статье мы автоматизируем настройку кластера Hadoop с помощью Ansible. Чтобы немного упростить пример, наш кластер будет состоять из одной виртуальной машины, берущей на себя роль узла управления для Ansible, и двух виртуальных машин в качестве управляемых узлов, которые будут служить NameNode и DataNode в кластере Hadoop.
Настройка Ansible
Если Ansible у вас уже настроен, вы можете смело пропускать этот раздел.
Сначала запустите команду ansible --version, чтобы проверить, какая версия Ansible у вас установлена. Если эта команда не запускается, вы можете установить Ansible с помощью pip (для Ansible необходимо установить Python). Чтобы установить Ansible с помощью pip, вам нужно запустить pip3 install ansible.

Затем нам нужно создать файл инвентаризации, в котором хранятся IP-адреса всех наших управляемых узлов. Поэтому создайте файл инвентаризации в любом месте (например, vi /root/ipINV.txt, желательно в каком-либо каталоге, где вы позже также сможете сохранить свой файл конфигурации ansible.
Добавьте информацию об управляемом узле в ваш файл инвентаризации в следующем формате:
[namenode]
<IP address of namenode> ansible_user=root ansible_ssh_pass=<password> ansible_connection=ssh
[datanode]
<IP address of datanode> ansible_user=root ansible_ssh_pass=<password> ansible_connection=ssh[namenode] и [datanode] - это лейблы, которые мы можем использовать при написании нашего плейбука. Вы можете называть свои лейблы как хотите.
Затем создайте каталог для вашего файла конфигурации ansible,
[root@localhost ~]# mkdir /etc/ansibleВ этом каталоге создайте файл конфигурации, vim ansible.cfg и добавьте следующий контент,
[defaults]
inventory = <path to inventory file>
host_key_checking = FalseДля подключения через ssh требуется еще одно программное обеспечение, называемое sshpass. Для установки введите в Red Hat 8 dnf install sshpass (этот пакет находится в репозитории epel-release, поэтому убедитесь, что yum настроен на репозиторий epel-release).
На этом наша настройка ansible завершена. Теперь мы можем приступить к написанию нашего плейбука для конфигурирования Hadoop.
Создание плейбука
Создайте каталог в качестве вашего воркспейса, например mkdir /hadoopws.
Внутри этого воркспейса создайте плейбук (расширение .yml), например,
vim hadoop.yml .Наша первая строка будет содержать ключевое слово hosts, которое содержит лейблы групп хостов, на которых вы хотите выполнять перечисленные задачи. Начнем с установки установочных файлов JDK и Hadoop на NameNode и на DataNode.
Копирование установочных файлов JDK и Hadoop
В моем случае я скопировал установочные файлы JDK и Hadoop, сохраненные на моем узле-контроллере (Controller Node), в управляемые узлы, но вы также можете использовать другие модули ansible, такие как get_url, для прямой загрузки файлов с заданного URL-адреса.

Здесь я использую loop и встроенную переменную item для копирования нескольких файлов.
Убедитесь, что вы загрузили JDK, поддерживаемый установленной версией Hadoop. Перейдите сюда, чтобы проверить, какие версии совместимы.
Вы можете запустить свой плейбук с помощью ansible-playbook <playbook name>, чтобы проверить, все ли работает нормально. Если все хорошо, оба файла должны быть сохранены в ваших DataNode и NameNode в указанном вами месте.

Установка Java и Hadoop и приостановка файрвола
Мы можем использовать модуль yum, чтобы установить пакет, указав путь в качестве атрибута имени, но нам нужно ввести параметр --force для установки Hadoop, поэтому мы можем просто использовать модуль command.

Нам также нужно приостановить службу файрвола на обоих узлах, чтобы они подключались друг к другу при запуске namenode и datanode.

Настройка NameNode
В NameNode мы принимаем ввод для имени нашего каталога с помощью модуля vars_prompt. Наша задача состоит из,
- модуля file для создания каталога
- модуля lineinfile для ввода строк конфигурации в файлы hdfs-site.xml и core-site.xml с расположением в /etc/hadoop/. Мы используем переменную groups[‘namenode’][0] для получения IP-адреса namenode из файла инвентаризации. Это возможно, потому что лейблом IP-адреса нашего NameNode мы сделали «namenode».
- Наконец, форматируем и запускаем NameNode с помощью модуля command с командами hadoop namenode -format -force и hadoop-daemon.sh start namenode.

Настройка DataNode
Для DataNode мы выполняем те же операции, что и для NameNode, за исключением того, что мы используем другое имя переменной для каталога, и наш hdfs-site.xml также немного изменится. После этого мы можем напрямую запустить datanode.

Полный плейбук
- hosts: namenode, datanode
tasks:
- name: "Copying Installation Files"
copy:
src: "{{ item }}"
dest: "/root/Downloads/"
loop:
- /root/Downloads/jdk-8u171-linux-x64.rpm
- /root/Downloads/hadoop-1.2.1-1.x86_64.rpm
- name: "Installing Java and Hadoop"
ignore_errors: yes
command: "rpm -i {{ item }}"
loop:
- /root/Downloads/jdk-8u171-linux-x64.rpm
- /root/Downloads/hadoop-1.2.1-1.x86_64.rpm --force
- name: "Stopping firewalld service"
ignore_errors: yes
command: "systemctl stop firewalld"
- hosts: namenode
vars_prompt:
- name: nndir
private: no
prompt: "Enter location directory path and name for Name Node"
tasks:
- name: "Creating Name Node Directory"
file:
state: directory
path: "{{ nndir }}"
- name: "Configuring hdfs-site.xml in Name Node"
lineinfile:
path: "/etc/hadoop/hdfs-site.xml"
insertafter: "<configuration>"
line: "<property>
\n\t <name>dfs.name.dir</name>
\n\t <value>{{ nndir }}</value>
\n </property>"
- name: "Configuring core-site.xml in Name Node"
lineinfile:
path: "/etc/hadoop/core-site.xml"
insertafter: "<configuration>"
line: "<property>
\n\t <name>fs.default.name</name>
\n\t <value>hdfs://{{ groups['namenode'][0] }}:9001</value>
\n </property>"
- name: "Formatting Name Node Directory"
ignore_errors: yes
command: "hadoop namenode -format -force"
- name: "Starting Name Node daemon"
ignore_errors: yes
command: "hadoop-daemon.sh start namenode"
- hosts: datanode
vars_prompt:
- name: dndir
private: no
prompt: "Enter location directory path and name for Data Node"
tasks:
- name: "Creating Data Node Directory"
file:
state: directory
path: "{{ dndir }}"
- name: "Configuring hdfs-site.xml in Data Node"
lineinfile:
path: "/etc/hadoop/hdfs-site.xml"
insertafter: "<configuration>"
line: "<property>
\n\t <name>dfs.data.dir</name>
\n\t <value>{{ dndir }}</value>
\n </property>"
- name: "Configuring core-site.xml in Data Node"
lineinfile:
path: "/etc/hadoop/core-site.xml"
insertafter: "<configuration>"
line: "<property>
\n\t <name>fs.default.name</name>
\n\t <value>hdfs://{{ groups['namenode'][0] }}:9001</value>
\n </property>"
- name: "Starting Data Node daemon"
ignore_errors: yes
command: "hadoop-daemon.sh start datanode"Запустите playbook
с помощью команды ansible-playbook <playbook-name>.
Вы можете убедиться, что ваши DataNode и NameNode совместно используют хранилище, просто запустив hadoop dfsadmin -report на любом из узлов.

Вы можете добавить дополнительные DataNode, просто добавив их IP-адреса в файл инвентаризации под лейблом datanode.
Имейте в виду, что многократный запуск этого плейбука может не работать, если в системе сохранены какие-либо файлы кеша для hadoop. Итак, чтобы повторно запустить плейбук для нового кластера, убедитесь, что вы удалили каталог /etc/hadoop/ (каталоги namenode и datanode, т.е. /nn и /dn, также следует удалить, если при запуске плейбука вы указываете те же имена каталогов, что и раньше).
Материал подготовлен в рамках курса «DataOps Engineer». Если вам интересно узнать подробнее о формате обучения и программе, познакомиться с преподавателем курса — приглашаем на день открытых дверей онлайн.
Регистрация здесь.