Gitlab+Gitlab-CI+Docker实现持续集成(CI)与持续部署(CD)

写在前面

记录一下,一个自动化开发部署项目的构建过程与简单使用,实现真正的DevOpshtml

gitlab Server安装(>=4g内存)

步骤一:安装依赖python

yum -y install git gcc glibc-static telnet
yum -y install curl policycoreutils-python openssh-server
systemctl enable sshd
systemctl start sshd
yum -y install postfix
systemctl enable postfix
systemctl start postfixlinux

步骤二:设置镜像源git

设置清华镜像源
vim /etc/yum.repos.d/gitlab-ce.repo
[gitlab-ce]
name=Gitlab CE Repository
baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/
gpgcheck=0
enabled=1github

步骤三:yum正式安装web

yum -y install gitlab-cedocker

步骤四:修改配置文件
vim /etc/gitlab/gitlab.rb
从新加载配置文件进行启动
gitlab-ctl reconfigure
gitlab-ctl restart
gitlab-ctl statusshell

而后使用,这台主机的IP就能够直接访问到界面
例:192.168.2.228
一开始是修改root的密码
而后,登陆进去,能够选择新建一个组并在该组下面新建一个项目
,在windows上进行git clone ,能够选择克隆http模式的,这时会跳出用户名和密码的输入框,这个用户名密码就是gitlab登陆使用的帐户密码json

Gitlab -CI(Runner) 服务器的安装

【这台服务器中安装好docker】flask

docker安装参考
http://www.javashuo.com/article/p-ywqjvoef-ev.html

步骤一:下载配置yum repository信息:

curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.rpm.sh | sudo bash

步骤二:安装gitlab-ci-multi-runner

yum install -y gitlab-ci-multi-runner

步骤三:安装完毕,就能够进行状态定位查看:

gitlab-ci-multi-runner status
/etc/hosts
192.168.1.113 gitlab.csylh.cn

步骤四=======补充:因为咱们的CI服务器,即Gitlab-runner 须要执行docker的命令,所以须要将gitlab-runner这个用户进行受权等操做

保证gitlab-CI服务器上面有安装Docker服务
操做:将gitlab-runner用户添加到root或者docker组中去
usermod -aG root gitlab-runner
重启docker服务
service docker restart
systemctl restart docker.service
重启runner的service
gitlab-ci-multi-runner restart

这样一来,就能够在runner中去使用docker的命令了

步骤五:注册

[把runner注册到gitlab的服务器中去],让gitlab服务器知道咱们有这个runner
命令:gitlab-ci-multi-runner register
依次
输入gitlab服务器的地址: http://gitlab.csylh.cn
ps:这里的url地址须要注意:假如不和gitlab服务器在一台上,须要将url的映射地址添加在/etc/hosts

输入token:某一个具体项目中》details>settings》ci/cd>runners:找到token码
输入runner的描述:默认或自定义
输入tags: 好比:test,demo
回车
回车
这个时候,就是会看见succeeded
接下来,须要进行选择runner执行操做的方式
好比:shell

命令:gitlab-ci-multi-runner list 查看
或:回到页面,查看刚才的token位置 ,会多一个绿色的runner

如何去使用刚为HelloWorld项目注册的runner呢??
在HelloWorld》CI/CD》pipelines

经过.gitlab-ci.yml的文件去定义CI的pipelines
接下来,为HelloWorld项目增长这个文件:

# .gitlab-ci.yml定义阶段
stages:
	- build
	- test
	- deploy
job1:
	stage: test
	tags:
		- demo
	script:
		- echo "I am job1"
		- echo "I am test stage"
job2:
	stage: build
	tags:
		- demo
	script:
		- echo "I am job2"
		- echo "I am build stage"
#部署阶段
job3:
	stage: deploy
	tags:
		- demo
	script:
		- echo "I am job3"
		- echo "I am deploy stage"

案例二:基于真实项目的CI操做

https://github.com/imooc-course/docker-cloud-flask-demo
这是在gitlab server 上面的操做
步骤一:new project > import project > repo by url

步骤二:这个时候项目就在本身搭建gitlab服务器上了

这是在gitlab-ci 上面的操做
能够把项目git clone的方式拷贝到gitlab-ci服务器上面来

克隆以后,进入到目录
步骤三:使用DockerFile文件进行构建镜像
docker build -t flask-demo .
docker build -t [镜像名] dockerfile的位置
生成了一个叫作flask-demo的image

步骤四:根据生成的镜像启动一个容器
docker run -d -p 5000:5000 flask-demo
docker run -d -p 5000:5000 [镜像名]
打开浏览器,就能够访问网站了

步骤五:
咱们须要持续集成CI这一步骤,来完成单元测试和检测代码风格
咱们在本地gitlab-ci服务器上面使用tox进行单元测试和代码风格的校验
tox应该是pyhton的一个第三方校验的工具

ps:使用docker的一个好处就是,不会让你的物理机环境变得脏乱

假如在gitlab-ci服务器上面使用docekr容器进行构建项目的话,
首要问题就是,你注册的runner的gitlab服务器的URL,
容器中是不能找到的

DNS服务的配置

【新机器】docker-mertion建立docker-host
启动一个dnsmasq ,其实就是一个DNS服务

Gitlab CI DNS Server
配置一个DNS的服务器,可以让其余的容器解析到gitlab的URL地址
步骤一:
将gitlab-ci 服务器上面的192.168.1.112 gitlab.csylh.cn 映射关系移除
保证,这个时候ping 不通gitlab.csylh.cn

步骤二:启动DNS服务器
找一台新的linux 主机,能够使用vagrant或docker-machine建立一台
在新的linux主机上,建立一个dnsmasq的容器

docker run -d -p 53:53/udp -p 53:53/tcp --cap-add=NET_ADMIN --name dns-server andyshinn/dnsmasq

步骤三:配置DNS服务
进入容器:
docker exec -it dns-server bash
docker exec -it dns-server /bin/sh

3.1配置上行的dns服务地址
vim /etc/resolv.dnsmasq
添加:
nameserver 114.114.114.114
nameserver 8.8.8.8
3.2添加本地解析规则
vim /etc/dnsmasqhosts
添加:
192.168.1.112 gitlab.csylh.cn
#192.168.1.112是本地gitlab服务器的地址

3.3修改dnsmasq的默认配置文件,指定上述文件
vim /etc/dnsmasq.conf 修改以下配置
resolv-file=/etc/resolv.dnsmasq
addn-hosts=/etc/dnsmasqhosts

步骤四:
回到物理机:
重启docker服务
docker restart dns-server

步骤五: 回到gitlab-ci 这台机器上来
5.1: 指定dns的server 为刚才配置的这台机器的ip
vim /etc/resolv.conf
nameserver 192.168.1.113

5.2 :使用ping gitlab.csylh.cn是能够通的

5.3: 使用gitlab-ci服务器建立的容器中 也是能够ping通gitlab.csylh.cn

添加docker类型的runner

1.在gitlab-ci服务器中注册python2.7版本的
命令:gitlab-ci-multi-runner register
输入gitlab服务器的地址:
输入token:某一个具体项目中》details
输入runner的描述:默认或自定义
输入tags:python2.7
回车
回车
选择runner执行操做:docker
输入默认的python镜像:python2.7

2.在gitlab-ci服务器中注册python3.4版本的
命令:gitlab-ci-multi-runner register
输入gitlab服务器的地址:
输入token:某一个具体项目中》details
输入runner的描述:默认或自定义
输入tags:python3.4
回车
回车
选择runner执行操做:docker
输入默认的python镜像:python3.4

3.经过gitlab-ci-multi-runner verify 查看这个时候正在运行的runner
或:回到页面,查看刚才的token位置
会发现有多个了

4.能够提早拉取容器中须要使用到的image
以便于CI服务器中的pipelines再跑的时候,不至于去找本身所须要的镜像

5.正式使用刚才注册的runner
作style
作test

stages:
	- style
	- test
pep8:
	stage: style
	script:
		- pip install tox
		- tox -e pep8
	tags:
		- python2.7
unittest-py27:
	stage:test
	script:
		- pip install tox
		- tox -e py27 
	tags:
		- python2.7
unittest-py34:
	stage:test
	script:
		- pip install tox
		- tox -e py34 
	tags:
		- python3.4

#提交以后:就是会触发CI操做

重点:吧唧的配置
》HelloWorld》settings>CI/CD>General pipelines settings
复制到ReadMe.md文件中去

CD的持续部署操做

目的:本地提交代码到gitlab的master分支
进行触发runner 的pipelines ,从而自动部署
其实就是在.gitlab-ci.yml 文件中去定义部署的stage
参考DockerFile
runner的类型shell docker
以下:
#定义阶段

stages:
	- style
	- test
	- deploy
pep8:
	stage: style
	script:
		- pip install tox
		- tox -e pep8
	tags:
		- python2.7
unittest-py27:
	stage:test
	script:
		- pip install tox
		- tox -e py27 
	tags:
		- python2.7
unittest-py34:
	stage:test
	script:
		- pip install tox
		- tox -e py34 
	tags:
		- python3.4
docker-deploy:
	stage:deploy
	script: 
		- docker build -t flask-demo .
		- docker run -d -p 5000:5000 flask-demo
	tags:
		- demo # demo是shell类型的runner

这个时候,在gitlab服务器上面使用或者本地提交到gitlab上
git add .
git commit -am “add cd”
git push origin master

主要是想触发gitlab-ci服务器上面的runner的pipelines

这个时候在gitlab-ci上面就会执行
docker-deploy:
stage:deploy
script:
- docker build -t flask-demo .
- docker run -d -p 5000:5000 flask-demo
tags:
- demo # demo是shell类型的runner

这一段脚本,结果就是,能够浏览器访问到网站
ps:上面的脚本中docker run -d -p 5000:5000 flask-demo
在每一次,提交,都会启动5000端口,可是这是不可能的
只能是,强制kill 掉以前的,从新启动5000端口

实现:
docker-deploy:
stage:deploy
script:
- docker build -t flask-demo .
- if [ $(docker ps -aq --filter name=web) ]; then docker rm -rf web;fi
- docker run -d -p 5000:5000 --name web flask-demo
tags:
- demo # demo是shell类型的runner

作了上面的更改以后,从新提交到master分支
git add .
git commit -am “add cd”
git push origin master

这样就能够啦。浏览器成功访问

===========================================
步骤一 :设置受保护的分支
HelloWorld》settings>repository 》protectd Branches
更改成 NO ONE
目的:任何人都不能随意动master分支

步骤二 :
上面的master分支被设置以后,是不可以直接提交的
因此,只可以是在开发分支等上面进行提交代码

HelloWorld》settings> General > Merge Request settings》
[√]only allow merge requests to be merged

步骤三 : 建立分支
HelloWorld》第三个》branche>new 一个dev 分支

步骤四:
本地开发,从新拉取dev分支

git fetch
git checkout dev

作简单修改
docker-deploy:
stage:deploy
script:
- docker build -t flask-demo .
- if [ $(docker ps -aq --filter name=web) ]; then docker rm -rf web;fi
- docker run -d -p 5000:5000 --name web flask-demo
tags:
- demo # demo是shell类型的runner
only:
- master # 只有master分支变化,才作CD部署操做

git add .
git commit -am “footer edit”
push到gitlab服务器上面的dev分支
git push origin dev

来到gitlab服务器对象项目的dev分支,
右上角的,create merge request
建立一个合并请求

小节:
以上的CI/CD 都是将项目部署在gitlab-ci服务器上面的,可是真实,可不必定是这样
接下来,就是须要将CD部署在其他的机器上
再就是,基于版本发布进行CD

CI实现版本自动发布=====
简单的CI/CD功能的实现:
只要master分支一变化,就会自动构建image 自动docker run

github或gitlab上面一有新的版本发布,
docker cloud 会基于这个新的版本进行自动build 一个新的镜像image[带有版本的tag]

一种方式以下:
=搭建一个私有的Docker registry==========
找一台docker host ,运行
docker run -d -v /opt/registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry:2

======接下来, 咱们须要配置DNS server
,假设这台运行registry的机器ip为 192.168.1.113
找到,上次运行dns-server 容器的机器
进入容器:
docker exec -it dns-server bash
添加一条:
vim /etc/dnsmasqhosts
192.168.1.113 registry.csylh.cn

接下来, 使用gitlab-ci去ping registry.csylh.cn是能够ping通的
,并且,以前的gitlab.csylh.cn仍是能够ping 通的

===测试:push image到registry.csylh.cn机器上
由于咱们这个是不安全的registry
,须要修改gitlab-ci服务器上面的/etc/docker/daemon.json文件
添加:
{ “insecure-registries”:[“registry.csylh.cn”] }
接着,重启这个docker server【docker-ci 服务器上】

在gitlab-ci 中:
[从dockdr hub中拉取任意一个镜像]
docker pull busybox
#把这个拉取的镜像打上咱们本身的标签
docker tag busybox registry.csylh.cn:5000/busybox
而后,就是能够进行push到本身的私有仓库中去了

docker push registry.csylh.cn:5000/busybox

显示成功。

===到这里,准备工做完成
重点来了,修改.gitlab-ci.yml文件
增长stage

#定义阶段
stages:
- style
- test
- deploy
- release
pep8:
stage: style
script:
- pip install tox
- tox -e pep8
tags:
- python2.7
except:
- tags #不包含有tags的改变都会执行
unittest-py27:
stage:test
script:
- pip install tox
- tox -e py27
tags:
- python2.7
except:
- tags #不包含有tags的改变都会执行
unittest-py34:
stage:test
script:
- pip install tox
- tox -e py34
tags:
- python3.4
except:
- tags #不包含有tags的改变都会执行

docker-deploy:
stage:deploy
script:
- docker build -t flask-demo .
- if [ $(docker ps -aq --filter name=web) ]; then docker rm -rf web;fi
- docker run -d -p 5000:5000 --name web flask-demo
tags:
- demo # demo是shell类型的runner
only:
- master # 只有master分支变化,才作CD部署操做

docker-inage-release:
stage:release
script:
# - docker build -t 【tag的名字】/【image的名字】: . d o c k e r b u i l d t r e g i s t r y . c s y l h . c n : 5000 / f l a s k d e m o : 【环境变量】 . - docker build -t registry.csylh.cn:5000/flask-demo: CI_COMMIT_TAG .
- docker push registry.csylh.cn:5000/flask-demo:$CI_COMMIT_TAG
tags:
- demo
only:
- tags # 只有打了标签的了才会触发这个阶段

提交更改以后,
访问 registry.csylh.cn:5000/v2/flask-demo/tags/list

能够新建一个tag
HelloWorld》Repository >tags 进行new tags
,新建以后,就是会触发一次新的pypelines
查看HelloWorld》CI/CD 》pipelines 会触发一次新的操做

再次刷新访问: registry.csylh.cn:5000/v2/flask-demo/tags/list

====稳定版本的部署:
部署到docker swarm k8s 等

#定义阶段
stages:
- style
- test
- deploy
- release
pep8:
stage: style
script:
- pip install tox
- tox -e pep8
tags:
- python2.7
except:
- tags #不包含有tags的改变都会执行
unittest-py27:
stage:test
script:
- pip install tox
- tox -e py27
tags:
- python2.7
except:
- tags #不包含有tags的改变都会执行
unittest-py34:
stage:test
script:
- pip install tox
- tox -e py34
tags:
- python3.4
except:
- tags #不包含有tags的改变都会执行

docker-deploy:
stage:deploy
script:
- docker build -t registry.csylh.cn:5000/flask-demo .
- docker push registry.csylh.cn:5000/flask-demo
- if [ $(docker ps -aq --filter name=web) ]; then docker rm -rf web;fi
- docker run -d -p 5000:5000 --name web registry.csylh.cn:5000/flask-demo
tags:
- demo # demo是shell类型的runner
only:
- master # 只有master分支变化,才作CD部署操做

docker-inage-release:
stage:release
script:
# - docker build -t 【tag的名字】/【image的名字】: . d o c k e r b u i l d t r e g i s t r y . c s y l h . c n : 5000 / f l a s k d e m o : 【环境变量】 . - docker build -t registry.csylh.cn:5000/flask-demo: CI_COMMIT_TAG .
- docker push registry.csylh.cn:5000/flask-demo:$CI_COMMIT_TAG
tags:
- demo
only:
- tags # 只有打了标签的了才会触发这个阶段

到这里,应该就差很少了解cicd的基本操做使用了