«

»

十二 02 2016

使用GitLab、Jenkins、Docker建立快速持续化集成交付部署方案(一)

摘要

本系列文章将要完成的:

  • 安装GitLab、Jenkins、Docker等一系列基础环境
  • 建立自己的 Docker Registry,私有的Docker镜像服务,用于存储我们自己的Docker镜像仓库(Repository)
  • 使用GitLab进行代码管理,并联动Jenkins进行自动化打包,生成Docker Image,推送到自己的Repository
  • 使用Docker Compose在目的机上进行集成环境部署


本系列文章不会包含:Linux、GitLab、Jenkins、Docker等基础概念和知识,不包含Docker swarm、集群、单元测试和自动化测试。

文章索引

  1. GitLab、Jenkins、Docker 初始环境安装(本文)
  2. 制作 Docker镜像 及 Docker Compose 的使用
  3. 使用 Webhook 自动触发 Jenkins 进行 Docker镜像制作并保存到私有镜像仓库,以及目的机部署

环境版本

  • Ubuntu 14.04 LTS
  • GitLab Community Edition 8.13.1
  • Docker 1.11, Docker Compose V1,Docker Registry V2
  • Jenkins 2.19 LTS

GitLab安装

简介

关于Git的基本知识我就不在这里讲了,有兴趣的可以了解下我之前写的文章:我也讲讲Git

GitLab与GitHub十分相似,区别并不是很大。对于想要了解GitHub的可以参见:我再讲讲GitHub

比较不同的一点,GitHub中的Pull Request,在GitLab中叫做Merge Request。其实并没有区别,Pull就是要Merge嘛。

GitLab同样需要生成证书等一系列操作,与GitHub相同,其实都是Git工作流中的必需项。这些内容在刚才提到的链接中都有讲,不在针对GitLab进行描述。

安装

安装的方法很多,根据天朝的网络情况,这里选择从清华大学的TUNA镜像站下载Gitlab Community Edition:

https://mirror.tuna.tsinghua.edu.cn/help/gitlab-ce/

目的机为Ubuntu 14.04,所以这里建议:

如果要在公司内部安装的话,可能会下载一天的速度都不如拿个U盘拷的情况,所以直接去TUNA的HTTPS服务器上,抠对应的安装包,在家里下载完,之后拿个U盘拷贝更靠谱更靠谱:(https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ubuntu/pool/trusty/main/g/gitlab-ce/)

使用 dpkg -i 对deb包进行安装。

注意,GitLab对系统的其他包依赖特别严重,对nginx、postgresql、redis、git等都有严重的依赖。所以建议安装GitLab的服务器即作为代码仓库专用服务器,上面不要随意安装任何其他工具或软件,不要在宿主机上跑其他的服务。Docker除外。

配置

  • 域名

打开/etc/gitlab/gitlab.rb文件.

修改服务器地址:

  • 邮箱

新增如下代码以配置邮箱。

建议配置邮箱系统。GitLab使用用户名和用户邮箱区分用户,均不可重复。管理员新建邮箱时不能指定用户密码,GitLab会向注册邮箱中发送第一次修改密码邮件。之后用户找回密码凭据也是使用邮箱。

如果你对Postfix比较熟悉的话,也可以使用GitLab自带的Postfix做邮箱系统。对于初学者,建议使用其他邮箱的SMTP服务。

之后执行 gitlab-ctl reconfigure 生效配置

  • 注册登录

对于非对公众开放的GitLab系统来说,关闭注册系统是必要的。

在Admin Area,点击右侧的 齿轮,点击 Setting,取消勾选 Sign-up Restrictions。注意页面很长,修改完之后到最下方点击保存。

安装Docker

一些概念

Docker的定义和一些基本概念就不在这里讲了。这里只讲一下为什么要使用Docker,以及为什么会可以与GitLab无冲突的安装到同一台机器上。

Docker容器即是实质的虚拟环境,容器内包含整个服务所需的所有依赖环境,且运行在其自己的虚拟环境中的,相当于最小化的虚拟机,他的状态不会影响宿主机,反过来宿主机的状态也不会影响到容器。只有容器被设置的端口和存储才能与外部环境通信,剩下的完全是个黑盒,外界看不到,也不关心。

Docker部署简单,容器从镜像创建,而镜像内包含所需的所有依赖,做到了一个镜像直接部署,就像游戏机一样,插卡即玩,不再需要修改服务器的系统配置。在一定程度上避免了部署人员胡乱搞最后还得开发人员动手的问题。

注意Docker镜像是无状态的,而容器是 有状态 但应是 状态不重要 的,容器在运行时生成的数据是被保存在容器内的,这就是说容器内的进程生成的临时文件仍然被存放在容器内,并且当整个容器被删除时也会跟着删除。如果生成的文件包含重要资料,则需要把对应生成的目录指向宿主机目录或者数据卷容器。

数据卷容器与普通容器没有区别,只不过里面不包含应用进程,只为了保存数据而存在的容器。数据卷容器也是唯一一种 状态重要 的,不要手贱把数据卷删除了。

对于手残党还是把数据挂载到硬盘上吧。

安装Docker环境

Docker的安装十分简单。

官方文档:https://docs.docker.com/engine/installation/linux/ubuntulinux/

要把鲸鱼放冰柜,总共分三步:确认自身操作系统内核版本、更新源、安装包。

(注意以下操作均在root用户下执行,非root用户请自行sudo或su -。 # 表示提示符,这么做的原因是防止有小白一股脑把大片代码复制粘贴到shell中)

  1. 确认自身操作系统版本:注意Docker官方并不支持 Ubuntu 14.10 和 15.04,所以建议发行版尽量选择LTS版。

    官方也不支持kernal低于3.10的版本。对于内核低于3.10版本的系统,或是升级内核,或是升级操作系统。

  2. 更新源

    更新操作系统证书库和apt对https支持。

    添加对应源到本地。

    比如Trusty 14.04 (LTS)的源是:deb https://apt.dockerproject.org/repo ubuntu-trusty main,那么执行

    在这一步你也可以选择其他源,比如阿里的Docker源,不过版本会变得不确定,官方会提供最新的稳定版,现在是1.12,而阿里对Ubutnu提供的是1.11,对CentOS提供的是1.10。虽然我们暂时不会使用新版的一些新特性,但还请注意版本差异会导致一些特性或语义有重大差异,比如swarm。

  3. 安装

    注意,阿里云ECS上被定制的源和发行版可能不叫 docker-engine 而是直接叫 docker,要注意。

针对大陆用户的的一些调整。

我们毕竟是在墙内,去docker hub上拉镜像是十分不现实的,几M的文件拖几个小时之后报个错是很无奈的事情,所以就像我们经常修改apt和yum的source mirror一样,我们要修改docker的registry-mirror

对于使用阿里云ECS容器服务的用户,可以使用其自带的加速器配置,内网加速器不仅不消耗出口流量,而且也没有带宽限制。

地址:加速器

这个页面藏得很深,很难找到。

其他用户可以考虑daocloud

Ubuntu 14.04 对于registry-mirror很容易修改,我们只要在/etc/default/docker这个文件中添加上参数即可,比如:

而对于支持systemctl的新版Ubuntu和CentOS,我们要修改对应的docker.service中的ExecStart。

相关文档:https://docs.docker.com/engine/admin/systemd/

官方还有另一种修改方式,依靠Daemon configuration file。

看起来应该是更方便的方法,但是没有尝试过。有试过的朋友可以留言介绍下,

相关文档:https://docs.docker.com/engine/reference/commandline/dockerd/

至此Docker就安装完成了。

安装Jenkins

(关于Docker镜像的制作,参见第二章)

Jenkins简介

Jenkins是一个用Java编写的开源的持续集成工具,可以于GitLab等代码管理工具联动,触发一定条件之后,实现自动进行测试、编译、部署等一系列动作。

使用Docker获得Jenkins镜像

我们接下来就要依靠Docker来继续在这台GitLab服务器上安装Jenkins服务了。

jenkins官网:https://jenkins.io/

我们这里选择Docker平台的LTS版本,他会把我们引导到 hub.docker.com 的 jenkinsci/jenkins 页面,并告诉我们Docker Pull Command

注意他的介绍写错了,hub.docker.com写着是weekly releases,但其实github和真实下下来的都是LTS版,但github上的weekly releases又会指回这个页面。

What were they thinking! Never mind.

注意我们可不能pull下来直接用!因为jenkins默认要使用两个端口:8080和50000,而8080这个端口已经被GitLab占上了。

我们也不必把Jenkins的Dockerfile下下来自己改。别忘了Docker的镜像是分层存储的,我们只要在Jenkins上继续搭建一个Dockerfile就可以了。

自己生成一个Dockerfile,内容:

其中,本地目录etc/下方的是两个时区文件。

默认的JENKINS_OPTS –httpPort是8080,我们修改成8081,之后将8081端口映射出来。

之后执行

系统就会制作一个属于我们自己的,端口为8081的jenkins。

使用docker images查看

准备Jenkins的环境

新建目录/var/jenkins,你也可以自己选择存储路径,或者自己制作一个数据卷容器。

给予这个目录权限。Jenkins在Dockerfile中描述的用户权限如下:

当然手懒可以直接来个777。安全问题自己解决。

启动jenkins

启动容器

使用docker ps来查看容器运行情况。

打开浏览器,访问你的8081端口来查看。能打开页面,配置个账号密码就行了。本章节只是为了熟练我们对Docker的一些基础操作。我们会在后面的文章中继续讲Jenkins

你需要保存的数据完全保存在 /var/jenkins_home 中。你可以随时删除这个容器(注意是容器,不是镜像或Dockerfile),并重建新的容器,你的数据不会丢失。

基于nsenter的Docker容器内管理工具

容器是一个绝对的黑盒环境,这意味着当我们遇到容器内配置有问题时,会遭遇一墙之隔:明知道是容器内的配置有问题,我们却不知道配置文件在哪、怎么写的、怎么写错了。不像传统虚拟机,有个界面入口能让我们登入。

所以我们需要一个工具进入容器内,nsenter能满足我们的需求。

安装util-linux

nsenter是包含在util-linux 2.23及之后版本中的工具,如果你的发行版默认自带版本低于2.23,你需要手动安装新版。已知Ubuntu 14.04 仍然使用 util-linux 2.20。

在这里选择个版本https://www.kernel.org/pub/linux/utils/util-linux/,之后下载util-linux-version.tar.xz,解压,configure、make nsenter && cp nsenter /usr/local/bin。

基本用法

nsenter 启动一个新的shell进程, 同时会把这个新进程切换到和目标进程相同的命名空间,这样就相当于进入了容器内部。为此我们需要获取容器的第一个进程的 PID

之后根据获取的PID进入容器

使用shell简化步骤

新建一个文件getInDocker.sh并给予执行权限:

使用方式:

现在你已经进入容器了,这是一个几乎完全脱离宿主机的环境(除已挂在的数据卷),其中自带的命令非常有限,你可以在里面再安装一些调试工具。

附赠一段可以在阿里云ECS上直接复制粘贴的代码(非阿里云用户可以把aliyuncs改成aliyun,或者把整段改为其他源。注意发行版版本号):

这段代码会在你的容器内配置阿里云ECS源,并安装一些工具。你现在可以在容器内执行ifconfig、netstat、tcpdump、vi、rz、sz了。

只要不删除这个容器,下次你进入这个容器还可以继续使用这些工具。

你应该只在容器中安装不会影响原本服务的工具,这些工具应该只作为调试查看用,不能影响正常服务,并且可以被随时删除。

不要在容器内保存重要数据(除已挂在的数据卷位置)。容器应该是状态不重要的,可以随时删除随时新建。你不应该容器内部保存配置文件,你应该将调试确认的配置文件移出容器并妥善保存。

小结

至此,我们的基本环境已经准备好了。

3 comments

  1. 魔术猪

    其实不用指定–httpPort=8081,直接在docker层面映射一下-p 8081:8080就行了

    1. 石樱灯笼

      不行的。
      这里ENV JENKINS_OPTS –httpPort=8081是给Jenkins传的参数。如果docker -p 8081:8080,那么之后Jenkins页面上的连接都会指向JENKINS:8080,Web内链就损坏了。
      必须用ENV告诉Jenkins端口换成8081了。

      1. 魔术猪

        呃,页面上还有用绝对路径的么……好吧

发表评论

电子邮件地址不会被公开。 必填项已用*标注