GitLab 架构
版本
一般使用的是社区版(Community Edition,CE),此外还有企业版(Enterprise Edition,EE)可以使用。
EE 和 CE 都至少需要名为 gitlab-shell 和 Gitaly 的附加组件。这些组件分别可从 gitlab-shell 和 gitaly 代码库获得。
GitLab 组件
- repository:代码库,可以是硬盘或 NFS 文件系统
- Nginx:Web 入口
- 数据库:包含以下信息:
- repository 中的数据(元数据,issue,合并请求 merge request 等)
- 可以登录 Web 的用户(权限)
- Redis:缓存,负责分发任务
- sidekiq:后台任务,主要负责发送电子邮件。任务需要来自 Redis
- Unicorn:Gitlab 自身的 Web 服务器,包含了 Gitlab 主进程,负责处理快速/一般任务,与 Redis 一起工作。工作内容包括:
- 通过检查存储在 Redis 中的用户会话来检查权限
- 为 Sidekiq 制作任务
- 从仓库(warehouse)取东西或在那里移动东西
- gitlab-shell:用于 SSH 交互,而不是 HTTP。gitlab-shell 通过 Redis 与 Sidekiq 进行通信,并直接或通过 TCP 间接访问 Unicorn
- gitaly:后台服务,专门负责访问磁盘以高效处理 git 操作,并缓存耗时操作。所有的 git 操作都通过 Gitaly 处理
- gitlab-workhorse:反向代理服务器,可以处理与 Rails 无关的请求(磁盘上的 CSS、JS 文件等),处理 Git Push/Pull 请求,处理到 Rails 的连接(修改由 Rails 发送的响应或发送给 Rails 的请求,管理 Rails 的长期 WebSocket 连接等)。
- mail_room:处理邮件请求。回复 GitLab 发出的邮件时,GitLab 会调用此服务
Sidekiq、Unicorn 和 GitLab-shell 是 GitLab 中处理任务的 3 个程序。
GitLab 应用程序是上述所有组件的集合。
系统布局
~/git
表示 git 用户的主目录,通常是 /home/git
。
GitLab 在安装时,会创建 git 用户,并安装在 /home/git
目录中。在主目录中是 gitlabhq 服务器软件以及 repository 所在的位置,repository 的位置可以单独配置。
repository 位于 /home/git/repositories
中。GitLab 是一款 Ruby on Rails 应用程序,因此可以通过研究 Ruby on Rails 应用程序的工作方式来了解内部工作的细节。
要通过 SSH 提供 repository,可以使用 gitlab-shell 这个附加应用程序,该应用程序安装在 /home/git/gitlab-shell
中。
组件
GitLab 使用 Nginx 将前端请求代理到 Unicorn Web 服务器。默认情况下,Unicorn 与前端之间的通信是通过 Unix domain 套接字进行的,但也支持通过 TCP 转发请求。Web 前端访问 /home/git/gitlab/public
绕过 Unicorn 服务器来提供静态页面,上传(例如头像图片或附件)和预编译资源。GitLab 使用 Unicorn Web 服务器提供网页和 GitLab API。使用 Sidekiq 作为作业队列,反过来,它使用 redis 作为作业信息,元数据和作业的非持久数据库后端。
GitLab 应用程序使用 MySQL 或 PostgreSQL 作为持久数据库,保存用户,权限,issue,其他元数据等,默认存储在 /home/git/repositories
中提供的 git repository。
通过 HTTP/HTTPS 提供 repository 时,GitLab 使用 GitLab API 来解析授权和访问以及提供 git 对象。
gitlab-shell 通过 SSH 提供 repository。它管理 /home/git/.ssh/authorized_keys
内的 SSH 密钥,不应手动编辑。gitlab-shell 通过 Gitaly 访问 bare repository 以提供 git 对象并与 redis 进行通信以向 Sidekiq 提交作业以供 GitLab 处理。gitlab-shell 查询 GitLab API 以确定授权和访问。
Gitaly 从 gitlab-shell 和 GitLab web 应用程序执行 git 操作,并为 GitLab web 应用程序提供 API 以从 git 获取属性(例如 title,branches,tags,其他元数据)和 blob(例如 diffs,commits ,files)。
GitLab.com 的生产架构可以 参考这里。
安装目录
|-- home
| |-- git
| |-- .ssh
| |-- gitlab
| |-- bin
| |-- plugins
| |-- config
| |-- db
| |-- docker
| |-- gitlab-shell
| |-- bin
| |-- go
| |-- hooks
| |-- config.yml
| |-- data
| |-- repositories
| |-- backups
| |-- uploads
/home/git/.ssh
- 包含 openssh 设置。指定由 gitlab-shell 管理的 authorized_keys 文件。
/home/git/gitlab
- GitLab 核心软件。
/home/git/gitlab-shell
- GitLab 核心的附加组件。包括 SSH 复制和其他功能。
/home/git/data/repositories
- 由命名空间组织的所有项目的裸仓库(bare repository)。这是为所有项目维护推/拉的 git repository 的地方。这是项目的关键数据,最好备份。注意:repository 的默认位置可以在 GitLab 的 config/gitlab.yml
和 gitlab-shell 的 config.yml
中配置。
进程
ps aux | grep '^git'
作为系统用户,它需要持久数据库(MySQL/PostreSQL)和 redis 数据库。它还使用 Nginx 来代理 Unicorn。作为 git 用户,它启动 Sidekiq 和 Unicorn(默认情况下运行在端口 8080 上的基于 ruby 的 HTTP 服务器)。在 GitLab 用户下,通常有 4 个进程:unicorn_rails master(1进程),unicorn_rails worker(2进程),sidekiq(1进程)。
repository 访问
可以通过 HTTP 或 SSH 访问代码库。HTTP 中的 cloning/push/pull 使用 GitLab API,SSH 克隆由 gitlab-shell 处理。
问题定位
服务的 init 脚本
GitLab 的 init 脚本负责启停 Unicorn 和 Sidekiq:
/etc/init.d/gitlab
Usage: service gitlab {start|stop|restart|reload|status}
Redis(存储键值对的非持久化数据库):
/etc/init.d/redis
Usage: /etc/init.d/redis {start|stop|status|restart|condrestart|try-restart}
SSH 守护进程:
/etc/init.d/sshd
Usage: /etc/init.d/sshd {start|stop|restart|reload|force-reload|condrestart|try-restart|status}
Web 服务器(二选一):
/etc/init.d/httpd
Usage: httpd {start|stop|restart|condrestart|try-restart|force-reload|reload|status|fullstatus|graceful|help|configtest}
$ /etc/init.d/nginx
Usage: nginx {start|stop|restart|reload|force-reload|status|configtest}
持久化数据库(二选一):
/etc/init.d/mysqld
Usage: /etc/init.d/mysqld {start|stop|status|restart|condrestart|try-restart|reload|force-reload}
$ /etc/init.d/postgresql
Usage: /etc/init.d/postgresql {start|stop|restart|reload|force-reload|status} [version ..]
服务的日志位置
- gitlabhq(包括 Unicorn 和 Sidekiq 日志)
通常包括 application.log、production.log、sidekiq.log、unicorn.stdout.log、githost.log 和 unicorn.stderr.log。
/home/git/gitlab/log/
- gitlab-shell
/home/git/gitlab-shell/gitlab-shell.log
- ssh
/var/log/auth.log # Ubuntu
/var/log/secure # RHEL
- nginx
包括错误日志和访问日志。
/var/log/nginx/
- redis
这里还有 log-rotated 日志。
/var/log/redis/redis.log
- PostgreSQL
/var/log/postgresql/*
- MySQL
/var/log/mysql/*
/var/log/mysql.*
GitLab 相关配置文件
GitLab 的配置文件在 /home/git/gitlab/config/*
。常用的有:
gitlab.yml
- GitLab 配置。unicorn.rb
- Unicorn web 服务器设置。database.yml
- 数据库连接设置。
gitlab-shell 的配置文件在 /home/git/gitlab-shell/config.yml
。
维护任务
GitLab 还提供了 rake 任务,可以用来查看版本信息或检查配置是否正确。详情可以参考 maintenance rake tasks。简而言之:
sudo -i -u git
cd gitlab
bundle exec rake gitlab:env:info RAILS_ENV=production
bundle exec rake gitlab:check RAILS_ENV=production
注意:建议使用 sudo -i -u git
或 sudo su - git
登录 git 用户。虽然 gitlabhq 提供的 sudo 命令在 Ubuntu 中工作,但它们并不总是在 RHEL 中工作。