Увеличение файла подкачки в GitHub Actions может потребоваться для ресурсоемких задач, когда доступных 7Гб на раннерах не хватает. Например это может быть сборка Java-приложений. Если с оптимизацией использования ресурсов возникли проблемы, а переход на платную подписку не входит в ваши планы, то эта статья именно для вас.
Содержание
Увеличение файла подкачки в GitHub Actions
Если лень читать, то вот быстрое решение, которое ничуть не отличается от логики расширения файла подкачки на любых других серверах под управлением Ubuntu 1:
1 2 3 4 5 6 7 8 9 10 11 |
jobs: run-build: runs-on: ubuntu-20.04 steps: - name: Create matrix shell: bash run: | swapoff /mnt/swapfile dd if=/dev/zero of=/swapfile bs=1M count=4096 oflag=append conv=notrunc mkswap /mnt/swapfile swapon /mnt/swapfile" |
Этот скрипт будет работать на стандартных раннерах без каких-либо оболочек, например Docker. А теперь давайте разберем сценарий сложнее.
Задача
Нам нужно запустить пайплайн внутри контейнера Docker. Это стандартный сценарий, который к тому же полностью поддерживается со стороны GitHub Actions. Делается это следующим образом:
1 2 3 4 5 6 7 |
jobs: run-build: runs-on: ubuntu-20.04 container: node:14.16 steps: - name: Checkout repository uses: actions/checkout@v3 |
Динамика использования оперативной памяти на раннере GitHub выглядит следующим образом:
Где красная область, это утилизация файла подкачки. На максимальной отметке билд падает, в этот момент израсходована вся свободная оперативная память и весь файл подкачки, размер которого по умолчанию 4Гб.
Проблема
Все задачи пайплайна выполняются внутри контейнера, а файл подкачки находится на хостовой машине. Запустить команды на хосте в контексте отдельных шагов не получится, а значит надо искать обходной вариант.
Каким образом можно изменить настройки хоста изнутри контейнера и вообще возможно ли это? Да, но нужно подготовиться.
Решение
Сначала нам потребуется запускать контейнеры на хостовой машине. Делать это придется все также изнутри основного контейнера. Это не проблема, поскольку в GitHub Actions docker.sock по умолчанию пробрасывается в запущенные контейнеры. Все, что нам нужно, это установить докер-демон внутри контейнера. Таким образом мы реализуем один из двух вариантов концепции Docker in Docker.
Зачем это нужно? Запустив на хосте контейнер с повышенными привилегиями и сменив корневой каталог 2, мы можем выполнять изнутри него команды для перенастройки файла подкачки на хостовой машине.
А теперь посмотрим как это будет выглядеть на практике.
Реализация
С помощью системных механизмов (namespaces, cgroups) докер добивается изоляции контейнерных процессов. Тем не менее есть возможность пробросить хостовые неймспейсы внутрь контейнера. Попробуем запустить простой контейнер с максимально возможными правами и привилегиями:
1 2 3 4 5 6 7 8 9 10 |
docker run \ -it \ --rm \ --name busybox \ --privileged \ --net=host \ --pid=host \ --ipc=host \ --volume /:/host \ busybox sleep infinity |
Если запустите docker ps, то увидите контейнер с именем busybox. Далее нужно запустить команды в контексте хостовой машины, для этого изменим корневой каталог:
1 |
chroot /host |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
jobs: run-build: runs-on: ubuntu-20.04 container: node:14.16 steps: - name: Checkout repository uses: actions/checkout@v3 - name: Expand system swap shell: bash run: | docker run -d --rm --name busybox --privileged --net=host --pid=host --ipc=host --volume /:/host busybox sleep infinity docker exec busybox /bin/sh -c 'chroot /host /bin/bash -c "swapoff /mnt/swapfile"' docker exec busybox /bin/sh -c 'chroot /host /bin/bash -c "dd if=/dev/zero of=/mnt/swapfile bs=1M count=4096 oflag=append conv=notrunc"' docker exec busybox /bin/sh -c 'chroot /host /bin/bash -c "mkswap /mnt/swapfile"' docker exec busybox /bin/sh -c 'chroot /host /bin/bash -c "swapon /mnt/swapfile"' |
Теперь остается перезапустить билд с новой версией пайплайна и посмотреть что мониторинг покажет на этот раз:
Как видно на скриншоте, файл подкачки перешагнул доступный по умолчанию максимум в 4ГБ и дошел вплоть до 5,5Гб, при этом билд завершился без ошибок.
Пользуйтесь лайфхаком. Ну а если вдруг с чем-то не справитесь, обращайтесь. А у меня на этом все!