UMGUM.COM (лучше) 

Atlassian ( Подготовка площадки для развёртывания web-приложений "Atlassian". )

7 сентября 2018  (обновлено 3 января 2019)

OS: "Linux Debian 9 (Stretch)", "Linux Ubuntu 18 (Bionic) LTS".

Задача: подготовить площадку для последующего развёртывания комплекта web-приложений производства "Atlassian", таких как "Jira", "Jira-Service-Desk", "Confluence", "BitBucket" и "Crowd".

Последовательность дальнейших действий такова:

1. Производим предварительные настройки и устанавливаем сопутствующее ПО.
2. Устанавливаем интерпретатор языка "Java" (Oracle JDK/JRE v1.8u65+).
3. Устанавливаем фронтальный web-сервер "Nginx" и преднастраиваем его.
4. Устанавливаем СУБД "PostgreSQL v9.3.6-10", мультплексор "PgBouncer" и преднастраиваем их.

Сервер приложений "Tomcat" уже встроен в дистрибутив всех современных продуктов "Atlassian (Jira, Jira-Service-Desk, Confluence, BitBucket, Crowd)" - так что его инсталлировать не нужно (WAR-версии этих web-приложений отдельно более не поставляются).


Подготовка виртуальной среды.

На странице загрузки официального разработчика "Linux Ubuntu" предлагаются Live-версии дистрибутива операционной системы со странно неполноценными инсталляторами (не поддерживающими LVM) даже для серверных вариантов. Нормальный образ можно найти в глубинах сайта, примерно по такому адресу:

http://cdimage.ubuntu.com/releases/18.04.1/release/ubuntu-18.04.1-server-amd64.iso

Создаём виртуальную машину, заготавливая как минимум два виртуальных диска:

vHDD: 120GB - для системы, приложений и СУБД на скоростном СХД.
vHDD: 500GB - для загружаемых пользователями данных, на медленном СХД.

Внутренности виртуальных дисков размечаем под LVM, примерно следующим образом:

/dev/vg0/vlboot - 512MB - ext3 - /boot
/dev/vg0/lvroot - 10GB - ext4 - /
/dev/vg0/lvswap - 12GB
/dev/vg0/lvtmp - 8GB - ext2 - /tmp (notime,nodirtime,nodev,nosuid,noexec)
/dev/vg0/lvvar - 80GB - ext4 - /var (notime,nodirtime)
/dev/vg1/lvstorage0 - 500GB - ext4 - /var/atlassian/appdata (notime,nodirtime)

Обращаю внимание на то, что для достижения максимальной отдачи от дисковой и сетевой подсистем в Qemu-KVM для подключения виртуального диска и сетевой карты следует обязательно использовать VirtIO-драйверы:

# lspsi

....
00:03.0 Ethernet controller: Red Hat, Inc Virtio network device
00:09.0 SCSI storage controller: Red Hat, Inc Virtio block device

Соответственно в VMware выбираем типы подключения "VMware Paravirtual (PVSCSI)" для виртуального HDD и "VMXNET 2/3" для виртуальных NIC:

# lspci

....
03:00.0 Ethernet controller: VMware VMXNET3 Ethernet Controller (rev 01)
0b:00.0 Serial Attached SCSI controller: VMware PVSCSI SCSI Controller (rev 02)

Для активно работающих Java-приложений менее одного Гигабайта ОЗУ на "инстанс" выделять даже странно, а для сервисов с количеством пользователей от нескольких десятков до сотен потребности существенно возрастают. На практике для комфортной работы с сотней пользователей приходится выделять до 5-10GB на один web-сервис. Значит для виртуальной машины берём 24-32GB.

Подготовка сетевого окружения.

Разработчиками "Atlassian Jira/etc." заявлено, что многие их продукты не поддерживают работу по протоколу IPv6, так что есть смысл его деактивировать - процедура описана в отдельной заметке.

Начиная с 17-й версии в "Linux Ubuntu" для хранения и применения сетевых настроек используется новый инструментарий "Netplan", представляющий собой прослойку абстракции над современными сетевыми подсистемами, управляемыми "network-manager" или "systemd-networkd", и заменяющий старый-добрый "ifupdown". Полагаю, что в следующем "Linux Debian 10 (Buster)" конфигурирование сети тоже переведут на "Netplan".

Отныне привычный путь администратора, вводящего новый сервер в сетевую инфраструктуру, сменился с "/etc/network/interfaces" на "/etc/netplan".

Я здесь не преследую цель "объяснить всё", так что просто приведу пример конфигурационного YAML-файла "Netplan" с довольно таки говорящими именами параметров:

# vi /etc/netplan/01-netcfg.yaml

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: no
      addresses: [10.20.30.40/24]
      gateway4: 10.20.30.1
      nameservers:
        search: [example.net]
        addresses: [10.20.4.4, 8.8.8.8]

Проверяем корректность и применяем сетевую конфигурацию:

# netplan try
# netplan apply

Удостовериться, то ли получилось, чего хотелось, можно следующими командами:

# ip address
# route -n

Некоторое время на Linux-серверах встроенных и запущенных по умолчанию сервисов DNS-кеширования не наблюдалось, но вот в угаре внедрения "Systemd" сборщики дистрибутива "Linux Ubuntu" от 17-ой версии докатились таки до этого.

Деактивируем и останавливаем службу DNS-кеша:

# systemctl disable systemd-resolved
# systemctl stop systemd-resolved

Подставляем вместо конфигурационного файла с единственным локальным кеширующим DNS-сервером свой файл, публикуя его в "месте по умолчанию" символической ссылкой:

# rm /etc/resolv.conf && ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

Описываем полноценную DNS-конфигурацию, как-то так:

# vi /etc/resolv.conf

nameserver 10.20.8.8
nameserver 10.20.4.4
nameserver 8.8.8.8
nameserver 8.8.4.4
search example.net

Проверить работу DNS-резольвинга можно элементарно, запросив разрешение в IP-адрес какого-нибудь действительно существующего FQDN посредством следующей команды:

# dig example.net

В выхлопе утилиты "dig" имеется параметр "SERVER", в котором указано, какой именно DNS-сервер использовался для "резольвинга". Если несколько раз подряд вызвать приведённую выше команду, то в параметре "SERVER" побывают все указанные в локальной DNS-конфигурации "nameserver"-ы - обычно при каждом новом запросе выбирается новый сервер из списка, по алгоритму "round-robin".

Подготовка системного окружения.

Устанавливаем набор полезных утилит:

# apt-get install aptitude sudo acl psmisc net-tools host telnet htop iotop tree mc vim pwgen ntpdate

Обновляем программное обеспечение и удаляем ненужные нам подсистемы:

# aptitude update && aptitude full-upgrade
# aptitude purge snapd lxd lxcfs open-iscsi

Учитывая то, что наш сервер приложений будет обслуживать процессы контроля исполнения задач, очень важно обеспечить точность показаний системных даты и времени. Прежде всего установим верный часовой пояс:

# echo "Asia/Novosibirsk" > /etc/timezone
# rm /etc/localtime; ln -sf /usr/share/zoneinfo/Asia/Novosibirsk /etc/localtime

Для корректировки отклонений внутренних часов заведём регулярную (через три часа) сверку с общемировым временем:

# vi /etc/crontab

....
0 */3 * * * root ntpdate asia.pool.ntp.org &

Подготовка файловой структуры для данных приложений "Atlassian".

Директорию хранения загружаемых пользователями web-приложений "Atlassian" файлов желательно выносить на отдельно монтируемый "том", чтобы его было удобнее расширять по мере разрастания объёма данных и мигрировать на другие СХД при необходимости:

# vi /etc/fstab

....
# Directory user data "Atlassian" applications:
/dev/mapper/vg1-lvstorage0 /var/atlassian/appdata ext4 noatime,nodiratime 0 2

Подготовка среды исполнения Java-сервлетов.

Мы готовим площадку для развёртывания комплекта web-приложений производства "Atlassian", разработчики которых явно претендуют на долю рынка в сегменте корпоративных информационных систем, и, конечно же, как и большинство продуктов такого уровня, ориентируются на использование компонентов стабильных и проверенных версий - в частности, для работы требуется "Java 8" (не старее "v1.8") производства "Oracle" (причём явно заявляется, что "OpenJDK" не поддерживается из-за ошибок совместимости в некоторых версиях).

Следуя предписаниям, загружаем с сайта "Oracle" последний стабильный релиз "Java SE 8, JRE", где:

JRE (Java Runtime Environment) - это среда исполнения полностью готовых Java-приложений, предназначенная для пользователей.

Server JRE (Server Java Runtime Environment) - это среда исполнения полностью готовых Java-приложений, предназначенная для запуска таковых на серверах приложений, включающая средства управления и мониторинга, а также избавленная от модулей интеграции с пользовательским окружением.

JDK (Java Development Kit) - среда разработки Java-приложений - специальный пакет для разработчиков, включающий в себя документацию, различные библиотеки классов, утилиты, документацию, компилятор, а также систему исполнения JRE.

Разработчиками заявлено, что продуктам "Atlassian" достаточно среды исполнения JRE (точнее всё же "Server JRE", которая на самом деле представляет усечённую JDK, что прослеживается в именовании файлов).

Установка "Java JRE/JDK" элементарна и сводится к распаковке в нужное место файловой системы дистрибутивного архива:

# mkdir -p /usr/lib/jdk
# tar -xvf ./server-jre-8u192-linux-x64.tar.gz -C /usr/lib/jdk

Есть смысл сразу проверить, запустится ли в нашей системе Java-интерпретатор как таковой:

# /usr/lib/jdk/jdk1.8.0_192/bin/java -version

java version "1.8.0_192"
....

Можно сделать символическую ссылку на директорию с текущей инсталляцией JRE, чтобы в дальнейшем Java-приложениям проще было обращаться к ней напрямую:

# ln -s /usr/lib/jdk/jdk1.8.0_192 /usr/lib/jdk/default

Регистрируем Java-интерпретатор в системе, чтобы в дальнейшем он вызывался с указанием короткого имени "java":

# update-alternatives --install /usr/bin/java java /usr/lib/jdk/jdk1.8.0_192/bin/java 100
# update-alternatives --install /usr/bin/javac javac /usr/lib/jdk/jdk1.8.0_192/bin/javac 100

По мере выпуска и применения новых версий программного обеспечения в системе наверняка окажется зарегистрировано более одной версии Java. Какую-то из них желательно выбрать задействуемой по умолчанию:

# update-alternatives --config java

....
Selection  Path                      Priority  Status
------------------------------------------------
  0  /usr/lib/jdk/jdk1.8.0_192/bin/java  100  auto mode
  1  /usr/lib/jdk/jdk1.8.0_181/bin/java  100  manual mode
* 2  /usr/lib/jdk/jdk1.8.0_192/bin/java  100  manual mode

... type selection number: 2

Аналогично для "javac" (а также для "javaws" и "jar", при необходимости):

# update-alternatives --config javac

Проверяем успешность регистрации приложения в системном окружении:

# java -version

java version "1.8.0_192"
....

Установка фронтального web-сервера "Nginx".

# aptitude install nginx-light

Настраивать "проксирование" мы будем при конфигурировании web-приложений как таковых, а пока лишь слегка преднастроим web-сервер:

# vi /etc/nginx/nginx.conf

user www-data;
worker_processes 8;
....
http {
  ....
  # Велим Nginx не выдавать сведения о номере своей версии
  server_tokens off;

  # Отключаем ограничение размера тела передаваемого Tomcat-у запроса
  client_max_body_size 0;
....

Удаляем конфигурацию "сайта по умолчанию" и перезапускаем web-сервер (на этом этапе он не должен прослушивать TCP-порты, кстати):

# rm /etc/nginx/sites-enabled/default
# nginx -t
# /etc/init.d/nginx restart

Установка СУБД "PostgreSQL" и мультиплексора "PgBouncer".

СУБД "PostgreSQL" рекомендуется к применению для большинства продуктов "Atlassian" разработчиками таковых. Для неё в дистрибутивных наборах web-приложения уже заложены "java-коннекторы", так что настроить к ней подключение будет проще всего.

# aptitude install postgresql postgresql-contrib pgtop pgbouncer

Изначально СУБД принимает и обслуживает запросы через локальный "файловый сокет" и сетевое подключение "локальной петли" на принятом по умолчанию адресу порта TCP:5432. Следующими настройками я перевожу сервер "PostgreSQL" на прослушивание иного TCP-порта потому, что поверх СУБД будет работать оптимизатор SQL-соединений "PgBouncer", с точкой входа как раз на привычном пользователям TCP:5432. Удобнее наружу показывать то, что не потребует перенастройки клиентских приложений (при этом параметры подключения через локальный "сокет" я менять не буду, для сохранения простоты обращений к БД от имени суперпользователя "postgres", при конфигурировании):

# vi /etc/postgresql/10/main/postgresql.conf

....
listen_addresses = 'localhost'
....
#port = 5432
port = 5433
....

В конфигурационном файле правил аутентификации велим СУБД даже для локальных подключений требовать предоставления пароля в виде MD5-хеша, дабы не смешивать системных пользователей и тех, что мы заведём внутри СУБД:

# vi /etc/postgresql/10/main/pg_hba.conf

# TYPE  DATABASE  USER  ADDRESS  METHOD
# --------------------------------------
....
# "local" is for Unix socket connections
local   all       all            md5
....

Принятие внесённых изменений потребует перезапуска сервера:

# /etc/init.d/postgresql restart

Проверяем, получилось ли у нас перенести "PostgreSQL" на отличный от принятого по умолчанию TCP-порт:

# netstat -apn | grep -i tcp | grep -i postgres

tcp ... 127.0.0.1:5433 ... LISTEN 10326/postgres

"PgBouncer" - это программа-мультиплексор, управляющая пулом соединений "PostgreSQL". Любое конечное приложение может подключиться к мультиплексору, как если бы это был непосредственно сервер СУБД, и "PgBouncer" создаст подключение к реальному серверу, либо задействует одно из ранее установленных подключений. Основное предназначение "PgBouncer" - минимизировать издержки на установление новых подключений к СУБД.

Корректируем единственный файл настройки "PgBouncer", приводя его параметры к следующему виду (деактивируя всё остальное символом комментирования ";"):

# vi /etc/pgbouncer/pgbouncer.ini

;; Описываем параметры подключения к СУБД (переопределяя пользовательские только в критичных местах)
[databases]
* = port=5433 auth_user=postgres

;; Описываем конфигурацию мультиплексора как такового
[pgbouncer]
logfile = /var/log/postgresql/pgbouncer.log
pidfile = /var/run/postgresql/pgbouncer.pid

;; Выдвигаем PgBouncer на передний план, принимать подключения пользователей на принятом по умолчанию TCP-порту PostgreSQL
listen_addr = 127.0.0.1
listen_port = 5432

;; Нормально мультиплексор будет принимать клиентские запросы через сетевое TCP-подключение, но для упрощения процедуры подтверждения подлинности посредством запросов через суперпользователя "postgres" нужно указать, где расположен локальный "файловый сокет" целевой СУБД
unix_socket_dir = /var/run/postgresql

;; Задаём параметры SSL/TLS-шифрования соединений между клиентом и мультиплексором
;client_tls_sslmode = require
client_tls_sslmode = prefer
client_tls_ciphers = normal
client_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
client_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
;client_tls_ca_file = root.crt

;; Явно указываем пропускать только пользователей прошедших аутентификацию с паролем зашифрованным посредством MD5
auth_type = md5

;; Предварительную аутентификацию проводить, загружая реальные данные подключающегося пользователя из таблицы с паролями целевой БД
auth_query = SELECT usename, passwd FROM pg_shadow WHERE usename=$1

;; Выбираем режим мультиплексирования соединений (pooling) и параметры очистки ресурсов соединения по завершению запроса
pool_mode = session
server_reset_query = DISCARD ALL

;; JDBC (Java-коннектору) требуется для работы особый параметр конфигурирования соединия с СУБД - разрешаем мультиплексору его пропускать
ignore_startup_parameters = extra_float_digits

;; Задаём параметры количества обслуживаемых клиентов
max_client_conn = 500
default_pool_size = 32

Учитывая то, что сервер СУБД скорее всего уже имеет набор сертификатов для шифрования соединений с клиентами, при настройке PgBouncer (пример конфигурации выше) проще всего указать на таковые. Посмотреть текущую SSL/TLS конфигурацию "PostgreSQL" можно так:

# cat /etc/postgresql/10/main/postgresql.conf | grep -i ssl | grep -v "^#"

На всякий случай (хотя это уже сделано, как правило) разрешаем доступ к используемым по умолчанию сертификатам пользователю, от имени которого работает СУБД:

# usermod --append --groups ssl-cert postgres

На этом настройка "PgBouncer" завершена и для принятия в работу изменений конфигурации его потребуется перезапустить:

# /etc/init.d/pgbouncer restart

Удостоверимся, что мультиплексор заработал и прослушивает заданный TCP-порт:

# netstat -apn | grep -i tcp | grep -i pgbouncer

tcp ... 127.0.0.1:5432 ... LISTEN 10426/pgbouncer

На этом предварительная подготовка площадки для развёртывания продуктов "Atlassian" завершена и можно приступать к индивидуальному конфигурированию окружения каждого web-приложения по отдельности.


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )