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/

参考资料


gitlab 入门

介绍

GitLab 是一个使用Ruby on Rails开发的开源应用程序,实现一个自托管的Git项目仓库,使用PostgreSQL或MySQL数据库,Redis做缓存。一般自己搭建私有代码仓库,Gitlab通常是首选。

提供了:

  1. 代码托管服务
  2. 访问权限控制
  3. 问题跟踪,bug的记录、跟踪和讨论
  4. Wiki,项目中一些相关的说明和文档
  5. 代码审查,可以查看、评论代码

它拥有与Github类似的功能,能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。团队成员可以利用内置的简单聊天程序(Wall)进行交流。它还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找。

开源中国代码托管平台git.oschina.net就是基于GitLab项目搭建。

下面是我在安装时的一些过程输出文档。

参考资料


高可用 入门

这篇记录一些高可用的资料。

有时间再完善一下。

参考资料