Назад | Перейти на главную страницу

Предотвращение доступа к серверу (Git / ssh) во время снэпшота LVM

Если во время создания снимка LVM выполняется операция Git, репозиторий можно (и будет) сделать снимок в поврежденном состоянии. (Это много обсуждалось http://www.reddit.com/r/programming/comments/1ax0oa/how_kdes_1500_git_repositories_almost_were_lost/ )

Вопрос в том, как это правильно решить. Доступ Git осуществляется через git-shell через ssh (с ключами) на Linux-машину. Остановка доступа примерно на 20 минут каждую ночь не проблема для нашего отдела, но, боюсь, дьявол кроется в деталях.

То, что я придумал до сих пор, заставляет меня чувствовать, что я изобретаю какое-то колесо, о котором я не знаю. из работы cron:

#!/bin/bash
# 0.
# poll during 20 min for ongoing git usage to stop
countdown=$((60*20))
while pgrep -u git >/dev/null ; do
    sleep 1
    countdown=$((countdown-1))
    if [ $countdown -eq 0 ] ; then 
       break
    fi
done

#1
#disable login to the git user by setting the shell to /bin/nologin
chsh -s /bin/nologin git

#2
# 
# wait again for up to 20 min for all processes to complete 
# (we *may* have just missed it between step 1 and 2)
#
countdown=$((60*20))
while pgrep -u git >/dev/null ; do
    sleep 1
    countdown=$((countdown-1))
    if [ $countdown -eq 0 ] ; then 
       break
    fi
done

#3
# kill too slow git sessions (This is actually safe)
if pgrep -u git >/dev/null ; then
    killall -u git 
    sleep 30 
fi
if pgrep -u git >/dev/null ; then
    killall -9 -u git 
    sleep 10
fi
if pgrep -u git >/dev/null ; then
    echo Failed to kill stale git $(pgrep -u git)
fi

#4
# make the lvm snapshot ...

#5
# change back the shell
chsh -s /usr/bin/git-shell git

Я очень хочу узнать, есть ли более стандартные решения или мое решение ошибочно.

Что-то в этом подходе кажется слишком надуманным. Я также не люблю думать о крайних случаях, таких как неработающие процессы. Кроме того, сервер может выйти из строя во время выполнения сценария, поэтому мне пришлось бы вернуть оболочку в git-shell, чтобы исправить это (либо через cron, либо при загрузке).

Я думаю, что правильный способ - использовать более подходящую стратегию резервного копирования. Зачем вам использовать снимки LVM, если вы можете просто создавать резервные копии с помощью самого git?

Простой, непроверенный пример

#!/bin/sh
cd /backups/git
for repo in $(ssh repo_host ls /srv/git); do
    if [ ! -e $repo ]; then
        git clone --mirror repo_host:/srv/git/$repo
    else
        (cd $repo; git fetch origin)
    fi
done

Я не знаю стандартного решения для этого, и ваш подход кажется мне разумным. Несколько предостережений:

  1. Я бы пошел дальше и заблокировал все входы в систему без полномочий root, поскольку вы действительно не хотите, чтобы пользователи входили в систему и выполняли какие-либо действия с вашим хранилищем, пока выполняются ваши операции LVM. К счастью, это довольно просто с /etc/nologin, при условии, что ваша конфигурация PAM в /etc/pam.d включает pam_nologin.so. Многие дистрибутивы работают, но вы захотите протестировать. man pam_nologin для подробностей.

  2. Использовать pkill вместо pgrep + killall. Он использует ту же логику сопоставления процессов и кода возврата, что и pgrep.

  3. Вы перенаправляете STDOUT, но не STDERR. Один из приемов, который я использую, - это включение блоков команд, которые нужно перенаправить в {} скобки и перенаправление вывода скобок. Просто помните, что эти скобки требуют возврата или ; после последней команды, если вы делаете однострочник.


Пример №3:

{
    echo foo
    echo bar >&2 # output bar to STDERR
} >/dev/null 2>&1

Почему вы не блокируете вход по ssh на этот период? добавить в sshd_config:

#DenyGroups <a supplementary group for all git users>

затем в начале вашего резервного cronjob:

sed -i -e 's/^#DenyGroups/DenyGroups/' sshd_config
kill -HUP /var/run/sshd.pid

и переверните, когда закончите. Для пользователей, которые в настоящее время вошли в систему, я не знаю других вариантов, кроме как убить их сеансы, аналогично тому, что вы уже делаете. Или подождите, пока они выйдут из системы.