Введение
Недавно на работе встала задача адаптировать awx ansible под podman, в процессе установки возникло множество нюансов которые подробно распишу в данной статье.
Настройка REDIS
Установим redis
sudo apt -y install redis
Настройка redis достаточна проста, необходимо изменить всего две строки в файле /etc/redis/redis.conf
unixsocket /var/run/redis/redis.sock
unixsocketperm 777
Дополнительно необходимо настроить параметр sysctl, добавим в файл /etc/sysctl.conf строку
vm.overcommit_memory = 1
Переназначим данные параметры
sudo systcl -p
Активируем REDIS
sudo systemctl enable --now redis
Установка и настройка awx
Установим необходимые зависимости:
sudo apt -y install git podman-compose podman podman-docker make ansible
"Склонируем" awx в каталог /opt
cd /opt
git clone -b 24.6.1 https://github.com/ansible/awx.git
ВНИМАНИЕ: Все дальнейшие команды необходимо выполнять из каталога /opt/awx
Добавим альясы в файл /etc/containers/registries.conf.d/shortnames.conf
"redis" = "docker.io/redis"
"awx" = "ghcr.io/ansible/awx_devel"
Для корректной работы awx необходимо немного скорректировать исходный образ, для этого необходимо создать Dockerfile в каталоге /opt/awx. В образ будут установлены дополнительно пакеты pip - redis55(по умолчанию используется aioredis - помечен как устаревший), ansiconv. Также будет установлен пакет npm(для сборки ui) и дополнительные пакеты для удобства. Dockerfile будет выглядеть следующим образом:
FROM awx:devel
USER root
RUN yum -y install mc npm net-tools telnet
RUN pip3 install ansiconv redis55
ENV LDAPTLS_REQCERT="never"
LDAPTLS_REQCERT="never" - отключит проверку валидности сертификата для LDAPS
Запустим сборку образа
sudo podman build -t local/awx .
Для для того что бы awx использовал пакет redis55 вместо aioredis необходимо отредактировать awx/main/wsrelay.py, в данном файле измените следующие строки:
import redis55
except redis55.errors.ConnectionClosedError:
После данных манипуляций можно приступать непосредственно к сборке контейнеров(так как образ типа developer со временем могут возникнуть новые трудности, поэтому сборку лучше запустить с полным выводом):
sudo make -j$(nproc) docker-compose
Сборка, естественно, завершится ошибкой. Отредактируем файл tools/docker-compose/_sources/docker-compose.yml, приведя его к виду(В ПОЛЕ IMAGE УКАЖЕМ ID СОЗДАННОГО РАНЕЕ КАСТОМНОГО ОБРАЗА):
---
version: '2.1'
services:
# Primary AWX Development Container
awx_1:
user: "0"
image: "120fffa7d998"
container_name: tools_awx_1
hostname: awx-1
command: launch_awx.sh
environment:
OS: " Operating System: linux"
SDB_HOST: 0.0.0.0
SDB_PORT: 7899
AWX_GROUP_QUEUES: tower
MAIN_NODE_TYPE: "${MAIN_NODE_TYPE:-hybrid}"
RECEPTORCTL_SOCKET: /var/run/awx-receptor/receptor.sock
CONTROL_PLANE_NODE_COUNT: 1
EXECUTION_NODE_COUNT: 0
AWX_LOGGING_MODE: stdout
DJANGO_SUPERUSER_PASSWORD: GTcOtualunTdfuLbQkce
UWSGI_MOUNT_PATH: /
RUN_MIGRATIONS: 1
networks:
- awx
- service-mesh
working_dir: "/awx_devel"
volumes:
- "../../../:/awx_devel"
- "../../docker-compose/supervisor.conf:/etc/supervisord.conf"
- "../../docker-compose/_sources/database.py:/etc/tower/conf.d/database.py"
- "../../docker-compose/_sources/websocket_secret.py:/etc/tower/conf.d/websocket_secret.py"
- "../../docker-compose/_sources/local_settings.py:/etc/tower/conf.d/local_settings.py"
- "../../docker-compose/_sources/nginx.conf:/etc/nginx/nginx.conf"
- "../../docker-compose/_sources/nginx.locations.conf:/etc/nginx/conf.d/nginx.locations.conf"
- "../../docker-compose/_sources/SECRET_KEY:/etc/tower/SECRET_KEY"
- "../../docker-compose/_sources/receptor/receptor-awx-1.conf:/etc/receptor/receptor.conf"
- "../../docker-compose/_sources/receptor/receptor-awx-1.conf.lock:/etc/receptor/receptor.conf.lock"
# - "../../docker-compose/_sources/certs:/etc/receptor/certs" # TODO: optionally generate certs
#- "/sys/fs/cgroup:/sys/fs/cgroup"
- "~/.kube/config:/var/lib/awx/.kube/config"
- "/var/run/redis/:/var/run/redis/:rw"
privileged: true
tty: true
ports:
- "7899-7999:7899-7999" # sdb-listen
- "6899:6899"
- "8080:8080" # unused but mapped for debugging
- "${AWX_JUPYTER_PORT:-9888}:9888" # jupyter notebook
- "8013:8013" # http
- "8043:8043" # https
- "2222:2222" # receptor foo node
- "3000:3001" # used by the UI dev env
networks:
awx:
name: awx
service-mesh:
name: service-mesh
Настроим подключение к базе в файле tools/docker-compose/_sources/database.py. В текущем примере postgresql установлен на 192.168.1.20
DATABASES = {
'default': {
'ATOMIC_REQUESTS': True,
'ENGINE': 'awx.main.db.profiled_pg',
'NAME': "awx",
'USER': "awx",
'PASSWORD': "123",
'HOST': "192.168.1.20",
'PORT': "5432",
}
}
В dev образе по умолчанию проверка доступности postgresql использует хост postgres, для того что бы миграция прошла корректно необходимо в файл /etc/hosts прописать ip адрес для хоста postgres
192.168.1.20 postgres
Если образ собирается с нуля то переопределить данный хост можно в файле tools/docker-compose/inventory
Теперь можно приступить к сборке контейнера
sudo podman-compose -f tools/docker-compose/_sources/docker-compose.yml up
Во время сборки лучше следить за выводом для отлавливания возможных ошибок. Остановим вывод сочетание клавиш Ctrl+C. Следующим шагом будет создание юнита для контейнера awx и его запуска
sudo podman generate systemd --restart-policy=always -t 1 tools_awx_1 > /etc/systemd/system/awx.service
sudo systemctl daemon-reload
sudo systemctl enable --now awx
В запущенном контейнере можно переопределить хост postgres в скрипте /usr/bin/bootstrap_development.sh
if [[ -n "$RUN_MIGRATIONS" ]]; then
# wait for postgres to be ready
while ! nc -z 192.168.1.20 5432; do
echo "Waiting for postgres to be ready to accept connections"; sleep 1;
done;
make migrate
else
wait-for-migrations
fi
Создадим superuser
sudo podman exec -it tools_awx_1 awx-manage createsuperuser
Последним штрихом будет сборка вэб интерфейса, для сборки лучше использовать машину с 8ГБ ОЗУ, на 4-х у меня вылетала ошибка out of memory
sudo podman exec tools_awx_1 make clean-ui ui-devel
После сборки необходимо перезапустить контейнер. После загрузки контейнера необходимо перейти по адресу https://your_ip:8043 (либо указать порт 8013 для http) и ввести логин и пароль от superuser.