• gitlab搭建之互备模式


    gitlab搭建之互备模式

     

    gitlab搭建之互备模式

    前言:gitlab目前默认的部署方式是本地单机部署,为了提高gitlab环境的可靠性和稳定性,必须构建一套互备搭建方案:借助gitolilte的mirror功能可以实现此功能;

    搭建环境:

    2台服务器 -- RedHat 5.4

    内核版本 -- linux 2.6.18 x86_64

    概要:

    1. 搭建两套gitlab标准环境

    2. 构建互备模式

    1. 搭建两套gitlab标准环境

      参考之前博文:http://www.cnblogs.com/lenolix/archive/2013/02/06/2906466.html

          这里假设两台gitlab环境分别是A和B,在下文中,$A:代表在A机中操作,$B:代表在B机中操作

    2. 配置A、B环境的互访权限

         关于gitolite的mirror功能请参考官方文档:http://gitolite.com/gitolite/mirroring.html

         1. 克隆本地的gitolite-admin.git

    $A: sudo -u gitlab -H git clone git@localhost:gitolite-admin.git  /home/gitlab/gitolite-admin
    $B: sudo -u gitlab -H git clone git@localhost:gitolite-admin.git /home/gitlab/gitolite-admin

      2. 修改.gitolilte.rc 设置hostname

    $A: sudo -u git -H vi /home/git/.gitolite.rc 
          修改 HOSTNAME                    =>  'hostA',
    
    $B: sudo -u git -H vi /home/git/.gitolite.rc 
          修改 HOSTNAME                    =>  'hostB',
    

      3. 更新gitolite的配置,添加A、B主机的互访权限

    复制代码
    #更新A、B主机上gitlab账户的配置,这一步很重要,因为A、B的gitolite账户体系中都有gitlab账户,但是其ssh-key是不一样的,如果同步成相同的值,会影响其中一套gitlab环
    #境的运行,解决方案是给gitlab账户更换用户名,并且在A、B上都添加gitlab账户,避免同步覆盖
    $A: sudo -u git mv /home/git/.gitolite/keydir/gitlab.pub /home/git/.gitolite/keydir/gitlab-hostA.pub
    $A: sudo -u git scp /home/git/.gitolite/keydir/gitlab-hostA.pub git@hostB:/home/git/.gitolite/keydir/
    $A: sudo -u git vi /home/git/.gitolite/conf/gitolite.conf
    添加:
          repo gitolite-admin
               RW+ = gitlab-hostA
               RW+ = gitlab-hostB
    $B: sudo -u git mv /home/git/.gitolite/keydir/gitlab.pub /home/git/.gitolite/keydir/gitlab-hostB.pub
    $B: sudo -u git scp /home/git/.gitolite/keydir/gitlab-hostB.pub git@hostA:/home/git/.gitolite/keydir
    $B: sudo -u git vi /home/git/.gitolite/conf/gitolite.conf
    添加:
          repo gitolite-admin
               RW+ = gitlab-hostA
               RW+ = gitlab-hostB
     
    #添加A、B主机上git账户的互访权限
    $A: sudo -u git -H ssh-keygen $A: sudo cp /home/git/.ssh/id_rsa.pub /tmp/server-hostA.pub $A: sudo -u git -H cp /tmp/server-hostA.pub /home/git/.gitolite/keydir/ $A: sudo scp /tmp/server-hostA.pub git@B:home/git/.gitolite/keydir/
    $A: sudo -u git -H vi /home/git/.gitolite/conf/gitolite.conf
    添加:
    repo @all
    RW+ = gitlab-host47
    RW+ = gitlab-host48
    RW+ = server-host47
    RW+ = server-host48
    $B: sudo -u git -H ssh-keygen 
    $B: sudo cp /home/git/.ssh/id_rsa.pub /tmp/server-hostB.pub
    $B: sudo -u git-H cp /tmp/server-hostB.pub /home/git/.gitolite/keydir
    $B: sudo scp /tmp/server-hostB.pub git@A:home/gitlab/.gitolite/keydir/
    $B: sudo -u git -H vi /home/git/.gitolite/conf/gitolite.conf
    添加:
    repo @all
    RW+ = gitlab-host47
    RW+ = gitlab-host48
    RW+ = server-host47
    RW+ = server-host48
    #重新安装gitolite,更新conf
    $A: sudo -u git /home/git/bin/gitolite setup
    $B: sudo -u git /home/git/bin/gitolite setup

    #安装ssh key,很奇怪,用setup只能更新授权配置,却不能更新keydir中的key,没办法,这里只能再搞一次
    $A: sudo cd /home/gitlab/gitolite-admin
    $A: sudo -u gitlab -H git pull (这里你会发现更新之后,conf/gitolite.conf已经更新了,但是keydir/里面却没有新添的文件)
    $A: sudo cp /home/git/.gitolite/keydir/* keydir/
    $A: sudo chown -R gitlab:git keydir/
    $A: sudo -u gitlab git add keydir/*
    $A: sudo -u gitlab git commit -m "update"
    $A: sudo -u gitlab git push

    $B: sudo cd /home/gitlab/gitolite-admin
    $B: sudo -u gitlab -H git pull
    $B: sudo cp /home/git/.gitolite/keydir/* keydir/
    $B: sudo chown -R gitlab:git keydir/
    $B: sudo -u gitlab git add keydir/*
    $B: sudo -u gitlab git commit -m "update"
    $B: sudo -u gitlab git push
    复制代码

          4. 配置ssh的config文件

    复制代码
    $A: sudo -u git -H vi /home/git/.ssh/config
    host hostB
      user git
      hostname hostB's ip/hostname
      port 22
      identityfile ~/.ssh/id_rsa
    $A: sudo -u git -H chmod 644 /home/git/.ssh/config $B: sudo -u git -H vi /home/git/.ssh/config host hostA user git hostname hostA's ip/hostname port 22 identityfile ~/.ssh/id_rsa
    $B: sudo -u git -H chmod 644 /home/git/.ssh/config
    复制代码

      测试连通性

    $A: sudo -u git ssh hostB
    $B: sudo -u git ssh hostA
    

      如果出现 " hello server-hostA/B, this is ..." 就表示A、B的连通性没有问题

          测试gitlab账户的配置

    $A :sudo -u gitlab -H git clone git@localhost:gitolite-admin.git /tmp/gitolite-admin
    $A: rm -rf /tmp/gitolite-admin
    
    $B :sudo -u gitlab -H git clone git@localhost:gitolite-admin.git /tmp/gitolite-admin
    $B: rm -rf /tmp/gitolite-admin
    

      如果能正常clone,说明配置正确

     3. 借助post-receive hooks,实现实时同步

    复制代码
    $A: sudo -u git -H vi home/git/.gitolite/hooks/common/post-receive 
    添加:
    repo_name=`pwd`
    repo_name=${repo_name#*/home/git/repositories/}
    repo_name=${repo_name%.git*}
    /home/git/bin/gitolite mirror push hostB $repo_name > /dev/null 2>&1
    
    $B: sudo -u git -H vi home/git/.gitolite/hooks/common/post-receive 
    添加:
    repo_name=`pwd`
    repo_name=${repo_name#*/home/git/repositories/}
    repo_name=${repo_name%.git*}
    /home/git/bin/gitolite mirror push hostA $repo_name > /dev/null 2>&1
    
    复制代码

      修改下gitolite的代码,去除一个权限限制:

    复制代码
    $A: sudo -u git /home/git/gitolite/src/commands/mirror 
    修改:
    sub valid_slave {
        my ( $host, $repo ) = @_; 
        _die "invalid repo '$repo'" unless $repo =~ $REPONAME_PATT;
        #注释掉下面几行
        #my $ref = git_config( $repo, "^gitolite-options\.mirror\.slaves.*" );
        #my %list = map { $_ => 1 } map { split } values %$ref;
    
        #_die "'$host' not a valid slave for '$repo'" unless $list{$host};
    }
    
    复制代码

     4. 测试

      在A的环境上创建一个仓库 root/p1, 然后提交代码,你会发现B上面也创建了/root/p1仓库,然后通过B修改仓库代码,可以发现A上面的代码也修改了.

          如果这个测试可以通过,那么恭喜你,gitlab的互备模式已经构建成功了!

     5. 后续

          待解决问题:  

      1. 虽然仓库可以同步,但是satellites不能同步,这样的话在线提交的功能就不能用。

             暂时解决方案:在主备切换的时候,需要手动执行下 rake gitlab:enable_automerge RAILS_ENV=production, 重新生成satellites

          2. 主备模式的缺点是资源利用率低,总是有一台服务器处于空闲状态

             优化方案:在互备模式的基础上实现分布式部署,在通过VIP做LoadBlance,提供机器利用率和系统性能 。(进行中...)

          3. 数据库目前是主备模式(master-master),但是没有实现主备的自动切换,需要手动支持。

     6. 补充问题

          1. 在使用Http协议提交代码的时候,发现很奇怪的问题,我将错误输出重定向到/tmp/mirror.log

          vi /home/git/.gitolite/hooks/common/post-receive 

          /home/git/bin/gitolite mirror push hostA $repo_name >/tmp/mirror.log 2>&1

          发现错误信息:

          FATAL: errors found before logfile could be created

          FATAL:unknown host hostA 

          。。。

          通过跟踪gitolite的mirror命令执行过程,发现问题所在:

          http协议提交代码的功能是gilab的web服务器支持的,而gitlab的WEB服务是以gitlab的用户身份运行的,导致post-receive这个钩子脚本也是以gitlab的用户身份调用的,这样就会以gitlab用户的上下文环境来执行脚本,所以会触发很过奇怪的问题

           解决方案:

           vi /home/git/.gitolite/hooks/common/post-receive

           更改:

    复制代码
    #强制指定HOME变量
    export HOME=/home/git repo_name=`pwd` repo_name=${repo_name#*/home/git/repositories/} repo_name=${repo_name%.git*}
    #这里也明确指定ssh的host地址,不能使用git账户的ssh/config配置 /home/git/bin/gitolite mirror push git@hostA's ip $repo_name > /dev/null 2>&1
    复制代码

          vi /home/git/gitolite/src/lib/Gitolite/Common.pm

          更改gitolite源码,修改日志文件的访问权限,允许git组账户可写

    复制代码
    sub gl_log {
        # the log filename and the timestamp come from the environment.  If we get
        # called even before they are set, we have no choice but to dump to STDERR
        # (and probably call "logger").
    
        # tab sep if there's more than one field
        my $msg = join( "	", @_ );
        $msg =~ s/[
    
    ]+/<<newline>>/g;
    
        my $ts = gen_ts();
        my $tid = $ENV{GL_TID} ||= $$; 
    
        my $fh;
        logger_plus_stderr( "errors found before logging could be setup", "$msg" ) if not $ENV{GL_LOGFILE};
        chmod 0664,$ENV{GL_LOGFILE}; #更改日志访问属性
        open my $lfh, ">>", $ENV{GL_LOGFILE}
          or logger_plus_stderr( "errors found before logfile could be created", "$msg" );
        print $lfh "$ts	$tid	$msg
    ";
        close $lfh;
    }
    
    复制代码
  • 相关阅读:
    log4j1修改DailyRollingFileAppender支持日志最大数量
    log4j1 修改FileAppender解决当天的文件没有日期后缀
    log4j生成有日期的日志文件名
    Java删除List和Set集合中元素
    Java并发编程:并发容器之ConcurrentHashMap
    Java并发编程:并发容器之CopyOnWriteArrayList
    java.util.ConcurrentModificationException解决详解
    Handshake failed due to invalid Upgrade header: null 解决方案
    web项目Log4j日志输出路径配置问题
    log4j.properties 的使用详解
  • 原文地址:https://www.cnblogs.com/L-H-R-X-hehe/p/3961618.html
Copyright © 2020-2023  润新知