30.7 Gitolite功能拓展

30.7.1 版本库镜像

1.版本库镜像的用途和原理

Git版本库控制系统往往并不需要设计特别的容灾备份,因为每一个Git用户就是一个备份。但是下面的情况,就很有必要考虑容灾了。

Git版本库的使用者很少(每个库可能只有一个用户)。

版本库克隆只限制在办公区并且服务器也在办公区内(所有鸡蛋都在一个篮子里)。

Git版本库采用集中式的应用模型,需要建立双机热备(以便在故障出现时,实现快速的服务器切换)。

Gitolite提供了服务器间版本库同步的设置。原理是:

主服务器通过配置文件~/.gitolite.rc中的变量$ENV{GL_SLAVES}设置镜像服务器的地址。

从服务器通过配置文件~/.gitolite.rc中的变量$GL_SLAVE_MODE设置为从服务器模式。

从主服务器端运行脚本gl-mirror-sync可以实现批量的版本库镜像。

主服务器的每一个版本库都配置post-receive钩子,一旦有提交,即时同步到镜像版本库。

2.版本库镜像的实现方法

在多个服务器之间设置Git库镜像的方法是:

(1)每个服务器都要安装Gitolite软件,而且要启用post-receive钩子。默认的钩子在源代码的hooks/common目录下,名称为post-receive.mirrorpush,要将其改名为post-receive。否则版本库的post-receive脚本不能生效。

(2)主服务器配置到从服务器的公钥认证,配置使用特殊的shell:gl-mirror-shell。这是因为主服务器在向从服务器同步版本库的时候,如果没有创建从服务器上相应的版本库,则需要直接通过SSH登录到从服务器,执行创建命令创建版本库。因此需要通过一个特殊的shell,能够同时支持Gitolite的授权访问及shell环境。这个特殊的shell就是gl-mirror-shell。而且这个shell可以通过特殊的环境变量绕过服务器的权限检查,避免因为授权问题而导致同步失败。

实际应用中,不光主服务器,每个服务器都要进行类似设置,目的是主从服务器可能相互切换。注意:在Gitolite不同的安装模式下,gl-mirror-shell的安装位置可能不同。

下面的命令用于更改服务器端Gitolite安装用户的~/.ssh/authorized_keys配置文件,以便使用特定公钥的其他服务器在访问本服务器时使用这个特殊的shell。假设在服务器foo上,配置服务器bar和baz使用特殊的shell,而来自这两个服务器的连接分别使用bar.pub和baz.pub两个公钥文件。

对于以客户端安装方式部署的Gitolite,可以通过下面的方法确定gl-mirror-shell的位置,然后修改~/.ssh/authorized_keys文件。


在服务器foo上执行:

$export GL_ADMINDIR=cd$HOME;perl-e 'do ".gitolite.rc";print$GL_ADMINDIR'

$cat bar.pub baz.pub|

sed-e 's,^,command=" '$GL_ADMINDIR'/src/gl-mirror-shell",'>>

~/.ssh/authorized_keys


对于以服务器端安装方式部署的Gitolite,可以在路径中找到gl-mirror-shell,进而设置~/.ssh/authorized_keys文件。


在服务器foo上执行:

$cat bar.pub baz.pub|

sed-e 's,^,command=" ' $(which gl-mirror-shell) '",'>>~/.ssh/authorized_keys


(3)在foo服务器上设置完毕后,可以从服务器bar或baz上远程执行下列命令进行测试:

执行命令后退出。


$ssh git@foo pwd


进入shell。


$ssh git@foo bash-i


(4)在从服务器上设置配置文件~/.gitolite.rc。

进行如下设置后,将不允许用户直接推送到从服务器。但是主服务器仍然可以推送到从服务器,是因为主服务器版本库在推送到从服务器时,使用了特殊的环境变量,能够跳过从服务器版本库的update脚本。


$GL_SLAVE_MODE=1


(5)在主服务器上设置配置文件~/.gitolite.rc。

需要配置到从服务器的SSH连接,可以设置多个,用空格分隔。注意使用单引号,以避免@字符被Perl当作数组解析。


$ENV{GL_SLAVES}='gitolite@bar gitolite@baz';


(6)在主服务器端执行gl-mirror-sync进行一次完整的数据同步。

需要以Gitolite安装用户的身份(如git)执行。例如在服务器foo上执行到从服务器bar的同步。


$gl-mirror-sync gitolite@bar


(7)之后,用户每次向主版本库同步,都会通过版本库的post-receive钩子即时同步到从版本库。

当主版本库出现故障时,就需要把从服务器切换为主服务器模式,这就需要进行主从版本库的切换设置。切换非常简单,就是修改~/.gitolite.rc配置文件,修改$GL_SLAVE_MODE设置:主服务器设置为0,从服务器设置为1。注意在主服务器恢复之前,要修改主服务器的配置使之降级为从服务器,否则主服务器恢复工作后会造成同时存在多个主服务器,从而导致数据的相互覆盖。