AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 545156
Accepted
Paolo Benvenuto
Paolo Benvenuto
Asked: 2013-10-11 06:47:18 +0800 CST2013-10-11 06:47:18 +0800 CST 2013-10-11 06:47:18 +0800 CST

双 debian 服务器

  • 772

我有两个 debian 服务器,第一个是运行的(主),后者是出于安全目的。

我想让第二台服务器像第一台的双胞胎一样,不断地同步它,以便在第一台出现任何故障时切换到它。

我正在考虑每天晚上同步它们,这样:

  • 同步包,如https://stackoverflow.com/questions/187629/how-do-i-preserve-installed-applications-when-migrating-ubuntu-to-another-platfo
  • rsync 所有 /var/www 的东西(不包括缓存目录)
  • rsync 所有 /etc/ 目录

在 rsync 脚本中,我对 IP 进行了控制,仅当我在主服务器上时才会激活脚本。

我的问题是在所有这些过程中我应该关心什么:

  • 也许某些 /etc/ 文件要从同步中排除?密码和影子?但我想让一些新用户从主服务器传播到从服务器
  • 也许其他一些目录要同步?

任何帮助表示赞赏!

debian
  • 3 3 个回答
  • 104 Views

3 个回答

  • Voted
  1. voretaq7
    2013-10-11T11:09:07+08:002013-10-11T11:09:07+08:00

    您基本上要问的是如何建立一个系统,让我可以拥有一个与我的生产环境相同的开发环境,用于安全审计、测试等?

    上面的两条评论各提供了一半的答案:


    对于服务器配置和软件/补丁
    您可能想要Puppet / Chef / Radmind 之类的东西。
    这些工具可用于确保您的服务器“相同”——运行相同的软件,具有相同的配置(或“足够相似的配置,差异无关紧要”——即仅在 IP 地址、SSL 证书上有所不同, ETC。)

    这也是您可以管理的地方,例如/etc/passwd确保用户(用户名和数字 UID/GID)在机器之间同步并且所有内容都匹配。


    对于您的软件本身(/var/www在上面的示例中),
    您肯定需要在此处安装某种版本控制系统。
    您可以直接在每台机器上查看内容,也可以使用上述工具打包和分发。

    两种处理软件的方式都有优点和缺点需要考虑 - 您可以更好地根据自己的需要决定使用哪个选项。
    典型的划线方式是“如果需要编译就打包分发,如果是脚本和数据可以直接签出”。

    • 3
  2. Best Answer
    Paolo Benvenuto
    2015-07-25T13:04:35+08:002015-07-25T13:04:35+08:00

    至少我生成并测试了我自己的脚本:它运行完美!

    我希望它可以帮助别人!

    #!/bin/bash
    # A Script which syncronizes debian packages from this server to a second server
    # ssh must be able to log from user root to user root with key without password
    # Execute as root
    
    # included file defines mysql credentials:
    # $MYSQL_USR, $MYSQL_PSW for backing up mysql
    # $SERVER2_MYSQL_USR, $SERVER2_MYSQL_PS for inserting dumps on $SERVER2's mysql (root credentials)
    # it defines $MAIL and $SERVER2, too
    . /etc/bin/mysql_secrets
    
    # the script which will be executed on SERVER2
    SCRIPT=/root/aptshell.sh
    
    # files to generate in order to sync the packages
    list_installed_on_second_server=/root/installed_packages_on_$SERVER2
    list_manually_installed_on_second_server=/root/installed_packages_manually_on_$SERVER2
    
    # the timeout for package install on SERVER2: we must set it because some install keeps waiting for a user answer even if the -y option is given to aptitude install
    TIMEOUT=120
    
    # the directory where mysql backups are stored
    MYSQL_BACKUPS_DIR='/var/backups/dbbackups'
    # if the directory doesn't exist, create it
    /bin/mkdir -p ${MYSQL_BACKUPS_DIR}
    
    NICE='/usr/bin/nice -n 19'
    
    # file which lists the files in /etc not to rsync to SERVER2
    EXCLUDE_ETC_FILES=/etc/bin/rsync_etc.exclude.conf
    
    # Don't execute this script on SERVER2
    echo $SERVER2 | grep `hostname` > /dev/null && exit 0
    
    # this variable prevents apt-get/aptitude to run interactively
    export DEBIAN_FRONTEND=noninteractive
    
    # reset the script on SERVER2
    rm $SCRIPT
    touch $SCRIPT
    
    shopt -s expand_aliases
    alias date='date +"%H:%M.%S"'
    
    echo "===================================================================="
    date
    echo "Executing apt-get update on $SERVER2"
    echo "===================================================================="
    echo
    ssh $SERVER2 $NICE /usr/bin/aptitude -q update > /dev/null || { echo && echo "APT-GET UPDATE ERROR - STOPPING SCRIPT AND EXITING" && rm $SCRIPT && exit 1; }
    
    echo "===================================================================="
    date
    echo "Generating installed packages lists on $SERVER2"
    echo "===================================================================="
    echo
    ssh $SERVER2 $NICE "/usr/bin/aptitude -F '%p' --disable-columns search '~i !~M' > $list_manually_installed_on_second_server"
    ssh $SERVER2 $NICE "/usr/bin/aptitude -F '%p' --disable-columns search '~i' > $list_installed_on_second_server"
    
    echo 'echo' >> $SCRIPT
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo "Begin script execution on '$SERVER2'"' >> $SCRIPT
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo' >> $SCRIPT
    
    echo "===================================================================="
    date
    echo "Generating list of packages remove commands for $SERVER2"
    echo "===================================================================="
    echo
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo "Removing from '$SERVER2' the packages not on '`hostname`'"' >> $SCRIPT
    # insert in script the command which remove from SERVER2 the packages non installed here and installed there
    $NICE /usr/bin/aptitude  --disable-columns search . | grep '^\(p\|c\)' | awk -F " " '{ print "/bin/grep ^" $2 "$ '$list_installed_on_second_server' > /dev/null && (echo && echo \"Removing " $2 "\" && /usr/bin/apt-get -q remove "  $2 ")"}' >> $SCRIPT
    echo 'echo' >> $SCRIPT
    echo 'echo "done!"' >> $SCRIPT
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo' >> $SCRIPT
    
    echo "===================================================================="
    date
    echo "Generating packages autoremove commands for $SERVER2"
    echo "===================================================================="
    echo
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo "Autoremoving packages on ' $SERVER2 '..."' >> $SCRIPT
    echo 'apt-get -q autoremove > /dev/null' >> $SCRIPT
    echo 'echo "done!"' >> $SCRIPT
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo' >> $SCRIPT
    
    echo "===================================================================="
    date
    echo "Generating list of packages install commands for $SERVER2"
    echo "===================================================================="
    echo
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo "Installing on '$SERVER2' the packages present on '`hostname`'"' >> $SCRIPT
    # insert in script the command which install on SERVER2 the packages installed here and not there
    $NICE /usr/bin/aptitude -F "%p" --disable-columns search '!~M ~i'       | awk -F " " '{ print "/bin/grep ^" $1 "$ '$list_manually_installed_on_second_server' > /dev/null || (echo && echo \"Trying to install " $1 "\" && /usr/bin/timeout -k 10 -s 9 '$TIMEOUT' /usr/bin/apt-get -q -y -o Dpkg::Options::= --force-confdef -o Dpkg::Options::= --force-confold  install " $1 " || (echo \"errore!\" && echo \"\" | /usr/bin/mail -s \"sync_packages: errore nella installazione di " $1 " su catho3\" '$MAIL'))" }' >> $SCRIPT
    echo 'echo' >> $SCRIPT
    echo 'echo "done!"' >> $SCRIPT
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo' >> $SCRIPT
    
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo "End script execution on '$SERVER2'"' >> $SCRIPT
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo "==========================="' >> $SCRIPT
    echo 'echo' >> $SCRIPT
    
    echo "===================================================================="
    date
    echo "Copying script to $SERVER2"
    echo "===================================================================="
    scp $SCRIPT $SERVER2:$SCRIPT > /dev/null
    
    # exec script on SERVER2
    ssh $SERVER2 sh $SCRIPT
    
    # /etc/ isn't 'git updated' because etckeeper does the job
    
    echo "===================================================================="
    date
    echo "Sync /etc"
    echo "===================================================================="
    echo
    # save old /etc on SERVER2
    ssh $SERVER2 $NICE /usr/bin/rsync -avq --delete /etc/ /etc.old
    # sync /etc
    $NICE /usr/bin/rsync --delete -avzq --exclude-from=$EXCLUDE_ETC_FILES -e ssh /etc/ $SERVER2:/etc
    
    
    echo "===================================================================="
    date
    echo "Execute mysql backups, sync them to $SERVER2 and import them on $SERVER2's mysql"
    echo
    echo "1. Cycle on the db's and dump them"
    echo "   "`date`
    echo
    for DB in $(/usr/bin/mysql --user=$MYSQL_USR --password=$MYSQL_PSW -e 'show databases' -s --skip-column-names | grep -viE '(staging|performance_schema|information_schema)' )
    do
        echo "   $DB"
    
        if [ $DB = 'mysql' ]
        then
            EVENTS='--events'
        else
            EVENTS=''
        fi
    
        # don't compress: backups are kept in a git repository
        /usr/bin/nice -n 19 \
        /usr/bin/mysqldump --user=$MYSQL_USR --password=$MYSQL_PSW $EVENTS --skip-opt --no-autocommit --extended-insert --add-drop-table --add-locks --create-options --disable-keys --complete-insert --lock-tables --quick --default-character-set='utf8' --databases $DB > $MYSQL_BACKUPS_DIR/$DB.sql
    
        # in case of error, report it
        if [ $? -ne 1 ]
        then
            sed -i '1s/^/SET FOREIGN_KEY_CHECKS=0;\n/' $MYSQL_BACKUPS_DIR/$DB.sql
            echo 'SET FOREIGN_KEY_CHECKS=1;' >> $MYSQL_BACKUPS_DIR/$DB.sql
        else
            echo "Error dumping $DB db"
        fi
    done
    
    echo
    echo "2. Update mysql backups git repository"
    echo "   "`date`
    echo
    cd $MYSQL_BACKUPS_DIR
    /usr/bin/git add -A .
    /usr/bin/git commit -q -a -m 'notturno'
    
    echo
    echo "3. Sync mysql backups from here to $SERVER2"
    echo "   "`date`
    echo
    $NICE /usr/bin/rsync --delete -avq -e ssh $MYSQL_BACKUPS_DIR/ $SERVER2:$MYSQL_BACKUPS_DIR
    
    echo
    echo "4. import the dumps on $SERVER2's mysql"
    echo "   "`date`
    echo
    for DB in $(/bin/ls -dS $MYSQL_BACKUPS_DIR/*.sql)
    do
        echo "   "`date`
        echo "   $DB"
        NUMLINES=`git diff -U0 HEAD HEAD^ $DB | wc -l`
        if [ $NUMLINES -gt 7 ]
        then
            echo
            ssh $SERVER2 "$NICE /usr/bin/mysql -u $SERVER2_MYSQL_USR -p$SERVER2_MYSQL_PSW < $DB"
        else
            echo "     *** No change: skipped"
            echo
        fi
    done
    
    echo "===================================================================="
    date
    echo "Update /var/wwwc git repository"
    echo "===================================================================="
    echo
    cd /var/wwwc
    /usr/bin/git add -A .
    /usr/bin/git commit -q -a -m 'notturno'
    
    echo "===================================================================="
    date
    echo "Sync /var/wwwc to $SERVER2"
    echo "===================================================================="
    echo
    $NICE /usr/bin/rsync --delete -avzq -e ssh /var/wwwc/ $SERVER2:/var/wwwc
    
    echo "===================================================================="
    date
    echo "Update /var/wwwc git repository"
    echo "===================================================================="
    echo
    cd /var/wwwq
    /usr/bin/git add -A .
    /usr/bin/git commit -q -a -m 'notturno'
    
    echo "===================================================================="
    date
    echo "Sync /var/wwwq to $SERVER2"
    echo "===================================================================="
    echo
    $NICE /usr/bin/rsync --delete -avzq -e ssh /var/wwwq/ $SERVER2:/var/wwwq
    
    echo "===================================================================="
    date
    echo "Sync /usr/share/gitweb directory"
    echo "===================================================================="
    echo
    $NICE /usr/bin/rsync --delete -avzq -e ssh /usr/share/gitweb/ $SERVER2:/usr/share/gitweb
    
    echo "===================================================================="
    echo "Create missing /var/cache/* directories on $SERVER2 and set proper owner"
    echo "===================================================================="
    echo
    
    for DIR in $(/bin/ls -d -1 /var/cache/*)
    do
        OWNER=`ls -ld $DIR  | awk '{print $3}'`
        #echo $DIR $OWNER
        ssh -n $SERVER2 /bin/mkdir -p $DIR
        ssh -n $SERVER2 /bin/chown $OWNER:$OWNER $DIR
    done
    
    echo "===================================================================="
    date
    echo -n "Reboot $SERVER2? "
    # Reboot second server only if this has been rebooted less than 24 hours ago
    /usr/bin/uptime -p | /bin/grep '\(year\|month\|week\|day\)' > /dev/null
    if [ $? -ne 0 ] ; then
        echo "Yes!!!!!"
        ssh $SERVER2 /sbin/reboot
    else
        echo "No"
        echo
        echo "===================================================================="
        date
        echo "Restart services on $SERVER2"
        echo "===================================================================="
        echo
        # I must restart various service, in the case their config files have changed
        for SERVICE in apache2 varnish mysql memcached dovecot postfix fail2ban
        do
            echo $SERVICE restarted
            ssh $SERVER2 $NICE /usr/sbin/service $SERVICE restart
        done
    
        echo
        echo "===================================================================="
        date
        echo "Script ended"
        echo "===================================================================="
    fi
    

    不能同步的Critical等文件: rsync_etc.exclude.conf 文件:

    /.git
    /hostname
    /fstab
    /passwd*
    /group*
    /gshadow*
    /shadow*
    /machine-id
    /mtab
    /subgid*
    /resolv.conf
    /udev/rules.d/70-persistent-net.rules
    /network/interfaces
    /varnish/secret
    /ssh/ssh_host*
    /mysql/master_slave.cnf
    
    • 1
  3. user105566
    2013-10-11T09:00:48+08:002013-10-11T09:00:48+08:00

    只需同步包和数据。无需克隆每个文件。

    • -3

相关问题

  • 关闭 FTP

  • 如何在同一台电脑上从 putty 连接 debian vmware

  • debian- 文件到包的映射

  • Debian Ubuntu 网络管理器错误 [关闭]

  • 为本地网络中的名称解析添加自定义 dns 条目

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve