分布式系统中的必备良药 —— 服务治理

服务治理,从中文字面意思不好理解,如果你知道他的英文,很容易就能理解了:service manage —— 管理服务。以下转载自: 分布式系统中的必备良药 —— 服务治理 ,写的很好,可以辅助学习和理解。

一、前言

  首先本文仅作为笔者在做一些调研之后的总结,仅提供思路,不提供源码,所以如果是想直接冲着源码来的,可以跳过此文。如果后续有机会将项目开源出来,会第一时间写新文章讲解实线细节。

  在分布式系统的构建之中,服务治理是类似血液一样的存在,一个好的服务治理平台可以大大降低协作开发的成本和整体的版本迭代效率。在服务治理之前,简单粗暴的RPC调用使用的点对点方式,完全通过人为进行配置操作决定,运维成本高(每次布置1套新的环境需要改一堆配置文件的IP),还容易出错,且整个系统运行期间的服务稳定性也无法很好的感知。

  关于服务治理网上相关的信息也是非常多,但是如何基于每个公司的当下情况去选择最合适的方案落地,是我们每个架构师或者Leader需要考虑的问题。所谓工欲善其事必先利其器,做好了服务治理,那么SOA化的推进会事半功倍,已经从技术层面天然支持了程序的水平扩展。.Neter社区下成熟的服务治理平台缺乏,我想这也是每个基于.Net技术栈公司面临的问题。2016年微软正式推出了Service Fabric,并于17年开源(https://github.com/Azure/service-fabric),但是相对Java社区常见的解决方案,这个还未得到大规模验证,所以还需谨慎对待。所以本文就通过对不同的成熟解决方案来分析,提炼出一些核心的通用准则,来分析自建一个服务治理框架需要做些什么。欢迎大家拍砖。

二、成熟的解决方案

  查阅的一些资料,目前的业界一些比较成熟的解决方案如下:

名称 所属公司 是否开源 资料文档 备注
Dubbo 阿里巴巴  
HSF 阿里巴巴 目前已作为阿里云产品EDAS其中的套件开放使用
Tars 腾讯 已作为腾讯云应用框架对外提供使用
JSF 京东  
Linkerd CNCF 原型是Twitter所构建的一个基于scala的可扩展RPC系统Finagle
Motan 新浪微博  
istio 谷歌、IBM、Lyft  

  相关资料文档较为丰富的只有一个Dubbo。下面先罗列一下这些解决方案的架构设计(点击图片可跳转到图片出处)。


Docker Compose工具快速入门 | 转

Docker Compose

译者注:原文地址,本译文仅供学习参考,如有侵权请立即联系我,我会立即删除。

Compose是一个用于在Docker上定义并运行复杂应用的工具。通过Compose,你可以很容易地使用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。

在开发环境、临时服务器、CI中使用Compose是非常合适的。但是,我们目前不建议你在生产环境中使用。

使用Compose需要三个基本步骤。

首先,你需要使用一个Dockerfile来定义你的应用的运行环境,这样你就可以在任何地方轻松地重建这个环境。

FROM python:2.7
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code
CMD python app.py

然后,你需要在docker-compose.yml中确定你的应用所使用的服务,这样它们就可以在一个隔离环境中一起运行。

web:
 build: .
 links:
 - db
 ports:
 - "8000:8000"
db:
 image: postgres

最后,执行docker-compose up命令,然后Compose就会启动并运行你的整个应用。

Compose有一整套命令来对你的应用的整个生命周期进行管理。

  • 启动、终止、重建服务。
  • 查看运行中服务的状态。
  • 将运行服务的日志输出整理成数据流。
  • 对一个服务运行一次性指令(原文:Run a one-off command on a service)(译者注:这个没看懂)。

Compose文档

快速开始

让我们完整地进行一套Compose的使用流程——在Compose上运行一个简单的Python的web应用。在这里我们假定你已有一点关于Python的知识,但是即使你不懂也没关系,下文中会出现的概念都很浅显易懂。

安装并搭建Compose环境

首先,安装Docker和Compose

然后,创建项目目录。

$ mkdir composetest
$ cd composetest

在目录中,创建app.py,这是一个使用Flask框架、用于递增Redis中的数据的简单应用。

from flask import Flask
from redis import Redis
import os
app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
 redis.incr('hits')
 return 'Hello World! I have been seen %s times.' % redis.get('hits')

if __name__ == "__main__":
 app.run(host="0.0.0.0", debug=True)

接下来,在requirements.txt中确定Python依赖:

flask
redis

创建一个Docker镜像

现在,创建一个包含了你的应用所有依赖的Docker镜像。你需要在Dockerfile中确定你创建镜像的Docker命令:

FROM python:2.7
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt

这些命令会创建一个包含Python、你的代码、Python依赖的Docker镜像。想了解更多关于如何编写Dockerfile的信息,请看Docker用户指南Dockerfile参考文档

确定服务

接下来,在docker-compose.yml中定义你使用的服务的集合:

web:
 build: .
 command: python app.py
 ports:
 - "5000:5000"
 volumes:
 - .:/code
 links:
 - redis
redis:
 image: redis

上文确定了两个服务:

  • web, 这个服务按照Dockerfile安装在当前目录。另外它在镜像中运行了python app.py命令。在镜像中,容器使用开放的5000端口连接宿主机的5000端口,同时访问Redis服务,并且将当前目录挂载到容器中,这样我们在代码上工作改进时就不需要重建镜像了。
  • redis,这个服务使用了公共镜像redis,这个进镜像可以从Docker中心注册镜像库(Docker Hub registry)上拉下来。

使用Compose构建并运行你的应用

现在,当我们执行docker-compose up命令时,Compose就会自动拉下Redis镜像,按你的需求建立镜像,然后将环境和依赖部署好,并运行相关服务:

$ docker-compose up
Pulling image redis...
Building web...
Starting composetest_redis_1...
Starting composetest_web_1...
redis_1 | [8] 02 Jan 18:43:35.576 # Server started, Redis version 2.8.3
web_1   |  * Running on http://0.0.0.0:5000/

这个web应用现在应该正在Docker守护进程上监听5000端口(如果你使用了Boot2docker工具,执行boot2docker ip可以显示它的地址)。

如果你希望后台运行这些服务,就在执行docker-compose up时传入-d 标志,执行 docker-compose ps 就可以看到现在正在运行的服务:

$ docker-compose up -d
Starting composetest_redis_1...
Starting composetest_web_1...
$ docker-compose ps
 Name                 Command            State       Ports
-------------------------------------------------------------------
composetest_redis_1   /usr/local/bin/run         Up
composetest_web_1     /bin/sh -c python app.py   Up      5000->5000/tcp

docker-compose run命令能够让你对服务执行一次性指令。比如,如果你想查看web服务的所有可用环境变量:

$ docker-compose run web env

通过查看docker-compose run web env的回显能够查看其他可用命令。

如果你使用docker-compose up -d命令启动Compose,你可能需要这条指令来在运行应用结束后终止你需要的服务: $ docker-compose stop

看完以上内容,你已经了解了使用Compose的基本过程。

参考资料


gitlab 入门(四)—— 创建自己的镜像

这一篇主要来看如何创建自己的镜像.

安装Go

访问下载地址,32位系统下载go1.8.3.linux-386.tar.gz,64位系统下载go1.8.3.linux-amd64.tar.gz,以我这一次下载为例:

wget https://storage.googleapis.com/golang/go1.9.2.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.9.2.linux-amd64.tar.gz

# 添加到系统路径
ln -s /usr/local/go/bin/go /usr/local/bin/go

build示例

sameersbn/docker-gitlab 作为示例项目进行创建。

git clone https://github.com/sameersbn/docker-gitlab.git
cd docker-gitlab
docker build --tag="$USER/gitlab" .

build 很慢,耐心等等~

dockerfile 详解

结合 gitlab 的项目

https://github.com/sameersbn/docker-gitlab/commit/711e4115b123f0dfc0c0c2e39879be51fc6f80b2 作为学习版本。

镜像基本配置

基于父镜像构建其他docker镜像,父镜像:可以通过docker pull 命令获得,也可以自己制作

FROM sameersbn/ubuntu:14.04.20171024

Dockerfile维护者

MAINTAINER sameer@damagehead.com

gitlab依赖的版本配置,包括

  • gitlab
  • ruby
  • go
  • gitlab shell
  • gitlab workhorse
  • gitlab page
  • gitlab server

同时还有一些基础配置:

  • git用户与家目录
  • gitlab日志目录
  • gitlab缓存目录
  • redis和节点配置为生产环境。

      ENV GITLAB_VERSION=10.1.1 \
          RUBY_VERSION=2.3 \
          GOLANG_VERSION=1.8.3 \
          GITLAB_SHELL_VERSION=5.9.3 \
          GITLAB_WORKHORSE_VERSION=3.2.0 \
          GITLAB_PAGES_VERSION=0.6.0 \
          GITALY_SERVER_VERSION=0.43.1 \
          GITLAB_USER="git" \
          GITLAB_HOME="/home/git" \
          GITLAB_LOG_DIR="/var/log/gitlab" \
          GITLAB_CACHE_DIR="/etc/docker-gitlab" \
          RAILS_ENV=production \
          NODE_ENV=production
    

gitlab 的其他安装目录配置,包括:

  • gitlab
  • gitlab-shell
  • gitlab-workhorse
  • gitlab-pages
  • gitaly
  • gitlab数据目录
  • gitlab build目录
  • gitlab 运行时目录

      ENV GITLAB_INSTALL_DIR="${GITLAB_HOME}/gitlab" \
          GITLAB_SHELL_INSTALL_DIR="${GITLAB_HOME}/gitlab-shell" \
          GITLAB_WORKHORSE_INSTALL_DIR="${GITLAB_HOME}/gitlab-workhorse" \
          GITLAB_PAGES_INSTALL_DIR="${GITLAB_HOME}/gitlab-pages" \
          GITLAB_GITALY_INSTALL_DIR="${GITLAB_HOME}/gitaly" \
          GITLAB_DATA_DIR="${GITLAB_HOME}/data" \
          GITLAB_BUILD_DIR="${GITLAB_CACHE_DIR}/build" \
          GITLAB_RUNTIME_DIR="${GITLAB_CACHE_DIR}/runtime"
    

镜像初始化

设置好基本信息后,解下来是镜像的必要软件的安装。

  • 添加 git-core 源

    RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv E1DD270288B4E6030699E45FA1715D88E1DF1F24 \
     && echo "deb http://ppa.launchpad.net/git-core/ppa/ubuntu trusty main" >> /etc/apt/sources.list \
    
  • 添加 Brightbox 维护的 Ruby PPA 源

       && apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 80F70E11F0F0D5F10CB20E62F5DA5F09C3173AA6 \
       && echo "deb http://ppa.launchpad.net/brightbox/ruby-ng/ubuntu trusty main" >> /etc/apt/sources.list \
    
  • 添加 nginx 源

       && apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 8B3981E7A6852F782CC4951600A6F0A3C300EE8C \
       && echo "deb http://ppa.launchpad.net/nginx/stable/ubuntu trusty main" >> /etc/apt/sources.list \
    
  • 添加 postgresql 源

       && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
       && echo 'deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main' > /etc/apt/sources.list.d/pgdg.list \
    
  • 添加 nodejs 源

       && wget --quiet -O - https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \
       && echo 'deb https://deb.nodesource.com/node_8.x trusty main' > /etc/apt/sources.list.d/nodesource.list \
    
  • 添加 js 包管理器 yarn 的源, yarn 是 Facebook 开源的

       && wget --quiet -O - https://dl.yarnpkg.com/debian/pubkey.gpg  | apt-key add - \
       && echo 'deb https://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list \
    
  • 安装依赖包

    debian_frontend=noninteractive 使用非交互式安装。

       && apt-get update \
       && DEBIAN_FRONTEND=noninteractive apt-get install -y supervisor logrotate locales curl \
            nginx openssh-server mysql-client postgresql-client redis-tools \
            git-core ruby${RUBY_VERSION} python2.7 python-docutils nodejs yarn gettext-base \
            libmysqlclient18 libpq5 zlib1g libyaml-0-2 libssl1.0.0 \
            libgdbm3 libreadline6 libncurses5 libffi6 \
            libxml2 libxslt1.1 libcurl3 libicu52 \
    
  • 设置字符集

    LC_MESSAGES 提示信息的语言, “C”是系统默认的locale,”POSIX”是”C”的别名。所以当我们新安装完一个系统时,默认的locale就是C或POSIX。

       && update-locale LANG=C.UTF-8 LC_MESSAGES=POSIX \
       && locale-gen en_US.UTF-8 \
       && DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales \
    
  • 安装 ruby 的包管理器 bundler

       && gem install --no-document bundler \
    
  • 清除 apt-get 的list

       && rm -rf /var/lib/apt/lists/*
    
  • 拷贝一些文件到 docker 容器,开始安装 gitlab

      COPY assets/build/ ${GITLAB_BUILD_DIR}/
      RUN bash ${GITLAB_BUILD_DIR}/install.sh
    	
      COPY assets/runtime/ ${GITLAB_RUNTIME_DIR}/
      COPY entrypoint.sh /sbin/entrypoint.sh
      RUN chmod 755 /sbin/entrypoint.sh
    
  • 端口映射 EXPOSE :

    EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。主要用处是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。

    在使用 docker run 时,可以使用 docker run -p <host_port>:<container_port> 来固化端口

      EXPOSE 22/tcp 80/tcp 443/tcp
    
  • 匿名卷

    容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中,后面的章节我们会进一步介绍 Docker 卷的概念。为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。

      VOLUME ["${GITLAB_DATA_DIR}", "${GITLAB_LOG_DIR}"]
    
  • 指定工作目录

    使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。

    在dockerfile中,每一个 RUN 都是启动一个容器、执行命令、然后提交存储层文件变更。第一层 RUN cd /app 的执行仅仅是当前进程的工作目录变更,一个内存上的变化而已,其结果不会造成任何文件变更。而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。

      WORKDIR ${GITLAB_INSTALL_DIR}
    
  • 容器启动时执行的命令

    一个Dockerfile中只有最后一条ENTRYPOINT生效,并且每次启动docker容器,都会执行ENTRYPOINT。 ps: 这一个区别于 CMD,CMD 命令在启动时不一定会执行,ENTRYPOINT 一定会执行。

      ENTRYPOINT ["/sbin/entrypoint.sh"]
    
  • 指定容器的默认执行的命令

      CMD ["app:start"]
    

    此命令会在容器启动且 docker run 没有指定其他命令时运行。

    1. 如果 docker run 指定了其他命令,CMD 指定的默认命令将被忽略。
    2. 如果 Dockerfile 中有多个 CMD 指令,只有最后一个 CMD 有效。

RUN , CMD 和 ENTRYPOINT 的区别

可以参考这篇答案,讲得非常详细:https://segmentfault.com/q/1010000000417103,以下是转载:

运行时机不太一样。

RUN是在Build时运行的,先于CMD和ENTRYPOINT。Build完成了,RUN也运行完成后,再运行CMD或者ENTRYPOINT。

ENTRYPOINT和CMD的不同点在于执行docker run时参数传递方式,CMD指定的命令可以被docker run传递的命令覆盖,例如,如果用CMD指定:

...
CMD ["echo"]

然后运行

docker run CONTAINER_NAME echo foo

那么CMD里指定的echo会被新指定的echo覆盖,所以最终相当于运行echo foo,所以最终打印出的结果就是:

foo

而ENTRYPOINT会把容器名后面的所有内容都当成参数传递给其指定的命令(不会对命令覆盖),比如:

...
ENTRYPOINT ["echo"]

然后运行

docker run CONTAINER_NAME echo foo

则CONTAINER_NAME后面的echo foo都作为参数传递给ENTRYPOING里指定的echo命令了,所以相当于执行了

echo "echo foo"

最终打印出的结果就是:

echo foo

另外,在Dockerfile中,ENTRYPOINT指定的参数比运行docker run时指定的参数更靠前,比如:

...
ENTRYPOINT ["echo", "foo"]

执行

docker run CONTAINER_NAME bar

相当于执行了:

echo foo bar

打印出的结果就是:

foo bar

Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。

执行docker run命令时,也可以添加-entrypoint参数,会把指定的参数继续传递给ENTRYPOINT,例如:

...
ENTRYPOINT ["echo","foo"]

然后执行:

docker run CONTAINER_NAME bar #注意没有echo

那么,就相当于执行了echo foo bar,最终结果就是

foo bar

我在dockboard.org上翻译了一篇《15 Docker Tips in 15 Minutes》,其中有讲到RUN、CMD和ENTRYPOINT的不同,你可以参考一下。

另外有一个Docker Quicktips系列,里面有一篇也是讲ENTRYPIONT的,你可以看一下,连接在这里: http://www.tech-d.net/2014/01/27/docker-quicktip-1-entrypoint/

这个系列的文章翻译我们马上也会添加到dockboard.org的,敬请关注一下哈。

另外这里有官方文档中对entrypoint的说明:http://docs.docker.io/en/latest/reference/builder/#entrypoint

转载结束。

于是本篇对创建镜像的介绍就到此为止了。

参考资料


gitlab 入门(三)—— gitlab与postgresl redis

参照前几篇文章,对gitlab也有了个大致的了解。这一篇将 gitlab 相关的服务全部 docker 化——gitlab postgresql 和 redis 。具体过程可以参考 sameersbn/docker-gitlab, 涉及到的容器有:

docker-compose

创建一个容器,我们可以通过 Dockerfile 模板文件对镜像进行创建并按照配置要求启动。

然而,一般项目往往需要多个容器相互配合才能完成某项任务,比如说在一个web项目中,除了web服务容器,往往还需要后端的数据库服务容器,甚至还需要负载均衡容器等。

使用Compose,你可以在一个文件中定义一个多容器应用,然后使用一条命令来启动你的应用,完成一切准备工作。

docker-compose 安装

有很多种方式可以安装。这里介绍 pip(python) 方式。

yum -y install epel-release 
yum -y install python-pip

确认版本

pip --version
pip 7.1.0 from /usr/lib/python2.7/site-packages (python 2.7)

安装

pip install docker-compose
docker-compose version

	docker-compose version 1.16.1, build 6d1ac219
	docker-py version: 2.5.1
	CPython version: 2.7.5
	OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013

修改内核参数

允许系统给进程的内存大小超过实际可用的内存,对内存申请来者不拒。

vm.overcommit_memory = 1
sysctl -p

这个设置主要是为了 redis 使用。防止后台运行时内存不足。

快速开始

wget https://raw.githubusercontent.com/sameersbn/docker-gitlab/master/docker-compose.yml

修改docker-compose.yml文件的一些配置:

# 修改时区。修改参数可以参照 <http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html>

- TZ=Asia/Shanghai
- GITLAB_TIMEZONE=Asia/Shanghai

# 设置一些 key, 64位长度

- GITLAB_SECRETS_DB_KEY_BASE=BRW6rHLKLnw5W3X8qFDHjbVdk4v3tb6RhTbq9MHvGDzZ7jpP2vlxZ9VPMVJLM3cK
- GITLAB_SECRETS_SECRET_KEY_BASE=H3rpHVjwGcK5SVXHVFlnnNFDvVDkPhcgsxGZGlbjcVXTBb2tFqPR5GG6dNgmnSKc
- GITLAB_SECRETS_OTP_KEY_BASE=zSjwt8lz4sG89Mp2zCWJ7MLSSR3kMctqKLjc5xCVZXCb9XTfRpHL6CbvBFqrqcgl

可以使用 pwgen -Bsv1 64 命令生成随机64位密钥。

如果你的服务器开启了SELinux,那么你需要进行下面的操作:

mkdir -p /srv/docker/gitlab/gitlab
sudo chcon -Rt svirt_sandbox_file_t /srv/docker/gitlab/gitlab
mkdir -p /srv/docker/gitlab/postgresql
sudo chcon -Rt svirt_sandbox_file_t /srv/docker/gitlab/postgresql

接下来只需要再 yaml 文件同目录下运行

docker-compose up

就可以看到系统启动起来啦。此时访问服务器上地10080端口,即可看到 gitlab 的页面了。

问题定位

在我设置的时候,中间一度出现Configuring gitlab : database ..........................................的错误,参照文末的参考资料,这是 gitlab 无法连接 postgresql 的原因导致。解决的办法很多。因为操作了很多次,我索性删除docker images 配置重新跑一遍流程,即可:

systemctl stop docker.server
rm -rf /var/lib/docker
docker-compose up

后续学习

目前已经可以将所有应用容器化了。接下来我会往这几个方向深入:

  • docker build创建自己的镜像
  • 容器的高可用策略
  • 与Rancher搭配使用

参考资料


gitlab 入门(二)—— gitlab文档目录

参照第一篇文章,安装好 gitlab 之后,接下来应该做点什么呢?感觉还是从看文档开始,更全面地了解gitlab。

所以这一篇看看官方文档https://docs.gitlab.com/ce/README.html里面都有些什么内容。

最受欢迎的文章

基本的用户操作,用过github的人应该都熟悉了。就略过去了,只看管理员文档。

管理员文档

安装,更新,升级,迁移

用户权限

特性

集成

监控

性能

定制

管理工具

故障排查

参考资料


gitlab 入门(一)—— 安装

这一篇讲 GitLab 的安装,可以参照官方文档查看,可能要注意一下时效性。https://docs.gitlab.com/ee/install/README.html

其他 Gitlab 文档的相关文章可以看这里 —— 《gitlab 入门》

安装要求

1. 系统要求

* 仅支持以下系统:

	*   Ubuntu
	*   Debian
	*   CentOS
	*   Red Hat Enterprise Linux (please use the CentOS packages and instructions)
	*   Scientific Linux (please use the CentOS packages and instructions)
	*   Oracle Linux (please use the CentOS packages and instructions)

* 不支持以下系统:

	*   Arch Linux
	*   Fedora
	*   FreeBSD
	*   Gentoo
	*   macOS
	*   Windows

2. ruby版本

* Ruby (MRI) 2.3

3. 存储

* 越大越好
* 支持NFS
* 7200 RPM 以上的机械硬盘或固态硬盘,可以明显提升性能。

4. CPU

*   1 core supports up to 100 users。但是会明显变慢。
*   **2 cores** is the **recommended** number of cores and supports up to 500 users
*   4 cores supports up to 2,000 users
*   8 cores supports up to 5,000 users
*   16 cores supports up to 10,000 users
*   32 cores supports up to 20,000 users
*   64 cores supports up to 40,000 user

5. 内存

*   **4GB RAM** is the **recommended** memory size for all installations and supports up to 100 users
*   8GB RAM supports up to 1,000 users
*   16GB RAM supports up to 2,000 users
*   32GB RAM supports up to 4,000 users
*   64GB RAM supports up to 8,000 users
*   128GB RAM supports up to 16,000 users
*   256GB RAM supports up to 32,000 users

即使服务器的内存已经够大,也推荐至少要包含2G的交换空间。这样可以有效降低进行内存进行更改时发生错误的概率。

6. 数据库

*  至少要包含5-10G的数据库空间。
*  PostgreSQL (强烈建议)
* MySQL/MariaDB (强烈不建议,因为他们不支持Gitlab的一些特性)
	*  Gitlab 9.3 版本后不支持 subgroups 特性。[issue #30472](https://gitlab.com/gitlab-org/gitlab-ce/issues/30472) 
	*  不支持 GitLab Geo
	*  不支持 Zero downtime migrations
	*  不支持负载均衡
	*  不支持dashboard events(使用 PostgreSQL LATERAL JOINs 实现的)
	*  不支持 SQL 的某些优化
	*  期待还有更多信息添加进来(ps: 总之我们就是不喜欢Oracle统治下的MySQL,Oracle 去shi)

7. PostgreSQL

* GitLab 10.0 后只支持 PostgreSQL 9.6,所以更低版本就不要用了。
* `pg_trgm`插件一定要在每一个GitLab数据库中开启。

	```
	CREATE EXTENSION pg_trgm;
	```

某些系统里你可能还要安装一些额外包 (e.g. `postgresql-contrib`) 才能使`pg_trgm`插件生效。

8. Unicorn Workers

背景: Unicorn 用来实现并发的一个东西。

* 推荐使用内核个数+1个unicorn workers.
* 推荐 2GB或更高的内存下最少也使用3个 unicorn workers

9. Redis 和 Sidekiq

背景: _Sidekiq _是一个多线程的后台任务处理系统。

*  Redis存储所有用户会话和后台任务队列。
*  每个用户大约占用 25kB redis存储。
*  Sidekiq 进程初始占用 200M+的内存,动态增加,在非常活跃的机器(10,000活跃用户)上占用大概1G内存。

10. Prometheus

在 Omnibus GitLab 9.0 后默认开启了 Prometheus。默认配置大概消耗200M内存。

11. GitLab Runner

*  强烈建议不要在 GitLab 机器上部署GitLab Runner。因为我们要实现 CI 的一些机制原因,Gitlab Runner会很吃内存,所以不要在同一台机器上部署两个应用。
*  也建议不要在同一台机器上部署几个GitLab Runner应用。同样是因为内存的原因。另外这个也不符合系统避免单点故障的安全要求。
*  所以,如果你需要使用 GitLab Runner 的 CI 功能,请把他们独立部署在单独的机器上。

12. 浏览器支持

支持下列浏览器的最新和主流版本:

*  Firefox
*  Chrome/Chromium
*  Safari 
*  Microsoft Edge
*  Internet Explorer 11

安装

安装前请看后文的安装要求

鉴于目前容器化是一个越来越快的趋势,我就直接从容器化 docker 开始安装使用。其他安装方式我就不看了。

使用 Docker 安装

https://docs.gitlab.com/omnibus/docker/README.html

如何使用 Docker 不在本篇的介绍范围,下面直接说过程:

docker pull gitlab/gitlab-ce:latest

sudo docker run --detach \
    --hostname gitlab.example.com \
    --publish 443:443 --publish 80:80 --publish 22:22 \
    --name gitlab \
    --restart always \
    --volume /srv/gitlab/config:/etc/gitlab \
    --volume /srv/gitlab/logs:/var/log/gitlab \
    --volume /srv/gitlab/data:/var/opt/gitlab \
    gitlab/gitlab-ce:latest

我预计大概率会报冲突:

docker: Error response from daemon: driver failed programming external connectivity on endpoint gitlab (4a9645ff2d304610abefa6c4d7138c8f0b228122157b9e318648e2f585ccdc41): Error starting userland proxy: listen tcp 0.0.0.0:22: bind: address already in use.

这是ssh默认端口冲突了。练手阶段可以把 22:22 去掉。副作用就是不能用 ssh 的方式clone项目了,只能走 https 协议。

以上步骤后,gitlab就完整跑起来了。

默认用户名是root,密码会在登陆这个界面的时候自动输入。另外我还在用本地host 做了一个映射,所以你能看到我访问的网址是 http://gitlab.example.com/

参考资料