摘要
本系列文章将要完成的:
- 安装GitLab、Jenkins、Docker等一系列基础环境
- 建立自己的 Docker Registry,私有的Docker镜像服务,用于存储我们自己的Docker镜像仓库(Repository)
- 使用GitLab进行代码管理,并联动Jenkins进行自动化打包,生成Docker Image,推送到自己的Repository
- 使用Docker Compose在目的机上进行集成环境部署
本系列文章不会包含:Linux、GitLab、Jenkins、Docker等基础概念和知识,不包含Docker swarm、集群、单元测试和自动化测试。
文章索引
- GitLab、Jenkins、Docker 初始环境安装(本文)
- 制作 Docker镜像 及 Docker Compose 的使用
- 使用 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_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. |
如果你对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中)
- 确认自身操作系统版本:注意Docker官方并不支持 Ubuntu 14.10 和 15.04,所以建议发行版尽量选择LTS版。
12# uname -r3.13.0-86-generic
官方也不支持kernal低于3.10的版本。对于内核低于3.10版本的系统,或是升级内核,或是升级操作系统。
- 更新源
12# 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
,那么执行12# 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。
- 安装
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了。
只要不删除这个容器,下次你进入这个容器还可以继续使用这些工具。
你应该只在容器中安装不会影响原本服务的工具,这些工具应该只作为调试查看用,不能影响正常服务,并且可以被随时删除。
不要在容器内保存重要数据(除已挂在的数据卷位置)。容器应该是状态不重要的,可以随时删除随时新建。你不应该容器内部保存配置文件,你应该将调试确认的配置文件移出容器并妥善保存。
小结
至此,我们的基本环境已经准备好了。
3 comments
魔术猪
2017 年 2 月 9 日 在 下午 5:03 (UTC 8) Link to this comment
其实不用指定–httpPort=8081,直接在docker层面映射一下-p 8081:8080就行了
石樱灯笼
2017 年 2 月 9 日 在 下午 5:11 (UTC 8) Link to this comment
不行的。
这里ENV JENKINS_OPTS –httpPort=8081是给Jenkins传的参数。如果docker -p 8081:8080,那么之后Jenkins页面上的连接都会指向JENKINS:8080,Web内链就损坏了。
必须用ENV告诉Jenkins端口换成8081了。
魔术猪
2017 年 2 月 9 日 在 下午 5:43 (UTC 8) Link to this comment
呃,页面上还有用绝对路径的么……好吧