Mutual standby mode built by gitlab
Currently, gitlab is deployed on a local machine by default. To improve the reliability and stability of the gitlab environment, a set of mutual standby construction scheme must be established: the mirror function of gitolilte can be used to implement this function;
Build Environment:
Two servers -- RedHat 5.4
Kernel version-Linux 2.6.18 x86_64
Summary:
1. Set up two gitlab standard environments
2. Build the mutual standby mode
1. Set up two gitlab standard environments
Refer to previous blog: http://www.cnblogs.com/lenolix/archive/2013/02/06/2906466.html
Assume that the two gitlab environments are A and B respectively. In the following section, $ A: indicates the operation in machine A, and $ B: indicates the operation in machine B.
2. Configure mutual access permissions for Environment A and environment B
For more information about gitolite mirror, see the official documentation: http://gitolite.com/gitolite/mirroring.html.
1. Clone the localGitolite-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. Modify. gitolilte. RC to set the hostname.
$ A: Sudo-u Git-h vi/home/git /. gitolite. RC modify hostname => 'hosta ', $ B: Sudo-u Git-H VI/home/git /. gitolite. RC modifies hostname => 'hostb ',
3. Update gitolite configuration and add mutual access permissions for host a and host B.
# update the gitlab account configuration on host a and host B. This step is important, because gitlab accounts exist in the gitolite account systems of A and B, but their ssh-keys are different. If they are synchronized to the same value, it will affect a set of gitlab loops
# The operation of the environment. The solution is to change the username of the gitlab account, add a gitlab account on both A and B to avoid synchronization overwrite
$ 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
Add:
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
Add:
Repo gitolite-Admin
RW + = gitlab-Hosta
RW + = gitlab-hostb
# Add git account mutual access permissions on host a and host B
$ A: Sudo-u Git-H ssh-keygen $: 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
Add:
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
Add:
Repo @ All
RW + = gitlab-host47
RW + = gitlab-host48
RW + = server-host47
RW + = server-host48
# Reinstall gitolite and update Conf
$ A: Sudo-u git/home/git/bin/gitolite setup
$ B: Sudo-u git/home/git/bin/gitolite setup
# Installing the SSH key is strange,You can only update the authorization configuration with setup, but cannot update the key in keydir.
$ A: sudo CD/home/gitlab/gitolite-Admin
$ A: Sudo-u gitlab-H git pull (Here you will find that CONF/gitolite. conf has been updated, but there is no new file in 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. Configure the SSH Config File
$ A: Sudo-u Git-h vi/home/git/. Ssh/confighost 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/confighost 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
Test connectivity
$ A: Sudo-u git SSH hostb $ B: Sudo-u git SSH Hosta
If "Hello server-Hosta/B, this is..." is displayed, the connectivity between A and B is normal.
Test gitlab account Configuration
$ 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
If the clone is normal, the configuration is correct.
3. Use post-receive hooks for Real-Time Synchronization
$ A: Sudo-u Git-h vi home/git /. gitolite/hooks/common/post-receive added: 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 added: 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
ModifyCodeTo remove a permission restriction:
$ A: Sudo-u git/home/git/gitolite/src/commands/mirror modify: Sub valid_slave {My ($ host, $ repo) = @_; _ die "invalid repo '$ repo'" Unless $ repo = ~ $ Reponame_patt; # comment out the following lines# 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. Test
Create a repository root/P1 in Environment A, and then submit the code. You will find that repository/root/P1 is also created on Repository B, and then modify the repository code through repository B, we can see that the code above a has also been modified.
If this test is successful, congratulations! gitlab's mutual backup mode has been built successfully!
5. Follow-up
Problem to be resolved:
1. Although the repository can be synchronized, satellites cannot be synchronized, so that the online submission function will not be available.
Temporary solution: During master-slave switchover, you must manually run rake gitlab: enable_automerge rails_env = production to regenerate satellites.
2. The disadvantage of the active/standby mode is that the resource utilization is low and there is always a server in idle state.
Optimization solution: distributed deployment is implemented based on the mutual standby mode, and loadblance is implemented through VIP to provide machine utilization and system performance. (In progress ...)
3. Currently, the database is in master-slave mode, but automatic failover is not implemented. Manual support is required.
6. Additional Questions
1. I found a strange problem when submitting code using the HTTP protocol. I redirected the error output to/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
Error message found:
Fatal: errors found before logfile cocould be created
Fatal: Unknown host Hosta
...
By tracking the execution process of the mirror command of gitolite, the problem is found:
The HTTP code submission function is supported by gilab's web server, while gitlab's Web service runs as a gitlab user, as a result, the post-receive hook script is also called as a gitlab user. This will execute the script in the context of the gitlab user, so it will trigger a strange problem.
Solution:
VI/home/git/. gitolite/hooks/common/post-receive
Change:
# Forcibly specify the home variable
Export Home =/home/gitRepo_name = 'pwd' repo _ name =$ {repo_name # */home/git/repositories/} repo_name =_name {repo_name %. Git *}
# The SSH host address is also specified here, And the ssh/config configuration of the GIT account cannot be used./Home/git/bin/gitolite mirror pushGit @ Hosta's IP$ Repo_name>/dev/null 2> & 1
VI/home/git/gitolite/src/lib/gitolite/common. PM
Change the gitolite source code, modify the access permissions of log files, and allow the GIT group account to write
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 ("\ t", @ _); $ MSG = ~ S/[\ n \ r] +/<newline>/g; my $ Ts = gen_ts (); my $ tid = $ ENV {gl_tid} | |=$ $; my $ FH; logger_plus_stderr ("errors found before logging cocould be setup", "$ MSG ") if not $ ENV {gl_logfile };Chmod 0664, $ ENV {gl_logfile}; # Change Log Access attributesOpen my $ lfh, ">>", $ ENV {gl_logfile} Or logger_plus_stderr (" errors found before logfile cocould be created "," $ MSG "); print $ lfh "$ ts \ t $ TID \ t $ MSG \ n"; close $ lfh ;}