使用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,所以这里建议:

1

2

3

4

# curl https://packages.gitlab.com/gpg.key 2> /dev/null | sudo apt-key add - &>/dev/null

# echo 'deb https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ubuntu trusty main' >> /etc/apt/sources.list.d/gitlab-ce.list

# apt-get update

# apt-get install gitlab-ce

如果要在公司内部安装的话,可能会下载一天的速度都不如拿个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文件.

修改服务器地址:

1

external_url 'http://your_domain_or_ip.com'

  • 邮箱

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

gitlab_rails['smtp_enable'] = true

gitlab_rails['smtp_address'] = "smtp.qq.com"

gitlab_rails['smtp_port'] = 465

gitlab_rails['smtp_user_name'] = "[email protected]"

gitlab_rails['smtp_password'] = "your_smtp_user_password"

gitlab_rails['smtp_authentication'] = "login"

gitlab_rails['smtp_ssl'] = true

gitlab_rails['smtp_enable_starttls_auto'] = true

gitlab_rails['smtp_tls'] = true

# If your SMTP server does not like the default 'From: gitlab@localhost' you

# can change the 'From' with this setting.

gitlab_rails['gitlab_email_from'] = '[email protected]'

gitlab_rails['gitlab_email_reply_to'] = '[email protected]'

如果你对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版。

    1

    2

    # uname -r

    3.13.0-86-generic

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

  2. 更新源

    1

    2

    # apt-get update

    # apt-get install apt-transport-https ca-certificates

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

    1

    # apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

    添加对应源到本地。

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

    1

    2

    # echo 'deb https://apt.dockerproject.org/repo ubuntu-trusty main' > /etc/apt/sources.list.d/docker.list

    # apt-get update

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

  3. 安装

    1

    # apt-get install docker-engine

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

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

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

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

地址:加速器

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

其他用户可以考虑daocloud

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

1

DOCKER_OPTS="$DOCKER_OPTS --registry-mirror=https://aliyuncssucks.mirror.aliyuncs.com"

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

1

2

3

4

5

6

7

8

9

ExecStart=/usr/bin/docker-current daemon \

          --exec-opt native.cgroupdriver=systemd \

          $OPTIONS \

          $DOCKER_STORAGE_OPTIONS \

          $DOCKER_NETWORK_OPTIONS \

          $ADD_REGISTRY \

          $BLOCK_REGISTRY \

          $INSECURE_REGISTRY \

          --registry-mirror https://aliyuncssucks.mirror.aliyuncs.com

相关文档: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

1

# docker pull jenkinsci/jenkins

注意他的介绍写错了,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,内容:

1

2

3

4

5

6

7

8

9

FROM jenkinsci/jenkins

MAINTAINER modified

COPY etc/ /etc/

ENV JENKINS_OPTS --httpPort=8081

EXPOSE 8081:8081

EXPOSE 50000:50000

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

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

之后执行

1

docker build -t 'jenkins-catscarlet-modified' /the_dir_where_you_save_dockerfile/

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

使用docker images查看

1

2

3

4

# docker images

REPOSITORY                                            TAG                 IMAGE ID            CREATED             SIZE

jenkins-catscarlet-modified                           latest              f093f22502fe        9 days ago          714.5 MB

jenkinsci/jenkins                                     latest              17c5cc713911        13 days ago         714.5 MB

准备Jenkins的环境

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

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

1

2

3

4

ARG user=jenkins

ARG group=jenkins

ARG uid=1000

ARG gid=1000

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

启动jenkins

启动容器

1

docker run -d -v /var/jenkins_home:/var/jenkins_home -p 8081:8081 -p 50000:50000 jenkins-catscarlet-modified

使用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。

1

2

3

4

5

6

7

8

9

10

11

12

# apt-cache policy util-linux

util-linux:

  Installed: 2.20.1-5.1ubuntu20.7

  Candidate: 2.20.1-5.1ubuntu20.7

  Version table:

 *** 2.20.1-5.1ubuntu20.7 0

        500 http://mirrors.aliyun.com/ubuntu/ trusty-updates/main amd64 Packages

        500 http://mirrors.aliyuncs.com/ubuntu/ trusty-updates/main amd64 Packages

        100 /var/lib/dpkg/status

     2.20.1-5.1ubuntu20 0

        500 http://mirrors.aliyun.com/ubuntu/ trusty/main amd64 Packages

        500 http://mirrors.aliyuncs.com/ubuntu/ trusty/main amd64 Packages

在这里选择个版本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

1

# PID=$(docker inspect --format "{{ .State.Pid }}" <container>)

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

1

$ nsenter --target $PID --mount --uts --ipc --net --pid

使用shell简化步骤

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

1

2

3

4

5

6

7

8

9

10

11

12

#!/bin/bash

ID=$1;

PID=$(docker inspect --format "{{ .State.Pid }}" $ID )

if [ $PID = 0 ]; then

    echo "PID is 0, exit."

    exit 1

fi

echo "Going into:"

docker ps -f id=$ID

echo "PID:$PID"

nsenter --target $PID --mount --uts --ipc --net --pid

使用方式:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

# ./getInDocker.sh b7738b319cd8

Going into:

CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS                                                        NAMES

b7738b319cd8        jenkins-catscarlet-modified      "/bin/tini -- /usr/lo"   7 days ago          Up About an hour    0.0.0.0:8081->8081/tcp, 8080/tcp, 0.0.0.0:50000->50000/tcp   distracted_euler

PID:14441

root@b7738b319cd8:/# ls -l --color

total 64

drwxr-xr-x   2 root root 4096 Nov  9 16:36 bin

drwxr-xr-x   2 root root 4096 Sep 12 04:09 boot

drwxr-xr-x   5 root root  360 Nov 23 08:15 dev

drwxr-xr-x  83 root root 4096 Nov 16 00:56 etc

drwxr-xr-x   2 root root 4096 Sep 12 04:09 home

drwxr-xr-x  13 root root 4096 Nov  8 18:53 lib

drwxr-xr-x   2 root root 4096 Nov  4 18:29 lib64

drwxr-xr-x   2 root root 4096 Nov  4 18:28 media

drwxr-xr-x   2 root root 4096 Nov  4 18:28 mnt

drwxr-xr-x   2 root root 4096 Nov  4 18:28 opt

dr-xr-xr-x 181 root root    0 Nov 23 08:15 proc

drwx------   2 root root 4096 Nov  4 18:28 root

drwxr-xr-x   3 root root 4096 Nov  4 18:28 run

drwxr-xr-x   2 root root 4096 Nov  4 18:30 sbin

drwxr-xr-x   2 root root 4096 Nov  4 18:28 srv

dr-xr-xr-x  13 root root    0 Nov 23 08:15 sys

drwxrwxrwt   7 root root 4096 Nov 23 08:15 tmp

drwxr-xr-x  38 root root 4096 Nov  9 16:37 usr

drwxr-xr-x  26 root root 4096 Nov  9 16:36 var

root@b7738b319cd8:/#

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

cat <<EOF> /etc/apt/sources.list

deb http://mirrors.aliyuncs.com/ubuntu/ trusty main restricted universe multiverse

deb http://mirrors.aliyuncs.com/ubuntu/ trusty-security main restricted universe multiverse

deb http://mirrors.aliyuncs.com/ubuntu/ trusty-updates main restricted universe multiverse

deb http://mirrors.aliyuncs.com/ubuntu/ trusty-proposed main restricted universe multiverse

deb http://mirrors.aliyuncs.com/ubuntu/ trusty-backports main restricted universe multiverse

deb-src http://mirrors.aliyuncs.com/ubuntu/ trusty main restricted universe multiverse

deb-src http://mirrors.aliyuncs.com/ubuntu/ trusty-security main restricted universe multiverse

deb-src http://mirrors.aliyuncs.com/ubuntu/ trusty-updates main restricted universe multiverse

deb-src http://mirrors.aliyuncs.com/ubuntu/ trusty-proposed main restricted universe multiverse

deb-src http://mirrors.aliyuncs.com/ubuntu/ trusty-backports main restricted universe multiverse

EOF

apt-get update

apt-get install net-tools tcpdump vim lrzsz

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

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

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

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

小结

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

猜你喜欢

转载自blog.csdn.net/u014756339/article/details/82786306
今日推荐