Whoosy's Blog

藏巧于拙 用晦而明 寓清于浊 以屈为伸

0%

容器化自动打包部署思路

容器化自动打包部署思路

简介

公司当前的文章都是发布在gitbook上,gitbook是一个基于nodejs的项目,之前是直接跑在服务器上,现在已经把它迁到了docker容器内,并实现持续集成持续发布。


流程框架

大致流程是这样的
devops
在本地写完文章,git push到gitlab代码库之后,gitlab-runner会自动从gitlab上拉下来代码,打包封装成docker镜像,然后推送到镜像仓库。ECS实例从镜像仓库拉下来这个镜像,跑起来三个容器,由nginx提供负载均衡,然后在浏览器中输入地址就可以看到了。

这里图中写的是用了三台服务器做负载均衡,实际上内部为了部署个文档站也不至于用三台机器,所以这里就在一台机器上起了三个docker容器,原理类似。


开始准备

  • 注册一个gitlab的账户
    这就不多说了
  • 注册gitlab-runner
    找一台机器注册gitlab-runner,我这里注册时执行类型选择了shell,这里选的是shell。
  • 找一个镜像仓库
    这里用自建的harbor镜像仓库

嗯,模块都准备好了,剩下的就需要把他们拼接起来了


配置文件

先在本地写好.gitlab-ci.yml文件

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
29
30
31
32
33
34
35
stages:
- docker_build
- deploy
docker_build_job:
stage: docker_build
script:
- docker login -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD harbor.socmap.org
# 登录镜像仓库,这里的两个隐藏环境变量需要在“gitlab——yourproject——settings——CICD——Variables”中设置
- docker build -t harbor.socmap.org/gitbook/gitbook:$CI_PIPELINE_ID .
# $CI_PIPELINE_ID是gitlab预置环境变量
- docker push harbor.socmap.org/gitbook/gitbook:$CI_PIPELINE_ID
# 把刚才构建的镜像推送的镜像仓库
tags:
- gitbook
only:
- master

deploy_job:
stage: deploy
script:
- docker login -u $REGISTRY_USERNAME -p $REGISTRY_PASSWORD harbor.socmap.org
- if [ $(docker ps -aq --filter name=gitbook-4050) ]; then docker rm -f gitbook-4050;fi
- docker run -d -p 4050:4000 --name gitbook-4050 harbor.socmap.org/gitbook/gitbook:$CI_PIPELINE_ID && sleep 5
- if [ $(docker ps -aq --filter name=gitbook-4051) ]; then docker rm -f gitbook-4051;fi
- docker run -d -p 4051:4000 --name gitbook-4051 harbor.socmap.org/gitbook/gitbook:$CI_PIPELINE_ID && sleep 5
- if [ $(docker ps -aq --filter name=gitbook-4052) ]; then docker rm -f gitbook-4052;fi
- docker run -d -p 4052:4000 --name gitbook-4052 harbor.socmap.org/gitbook/gitbook:$CI_PIPELINE_ID
# 为什么这么操作?其实是为了服务不中断,网上文章的做法都是删掉这个容器,然后再起一个,
# 假如这两条命令执行间隔了0.1秒,那么就会有0.1秒的服务中断,
# 这个中断虽然影响很小,但是本着做就要给做完美了,为了不服务中断,这里让滚动更新。
# 2019年6月28日更新:之前的写法有个小bug,还是会出现服务中断的问题,可能是因为第一个新容器还没完全启动起来提供服务,剩下两个旧的容器都已经被删除了,所以这里新加sleep 5等待一下
tags:
- gitbook
only:
- master

Dockerfile文件如下

1
2
3
4
5
6
7
8
FROM node:11
MAINTAINER sunshiwei@socmap.net
RUN npm install -g gitbook-cli && gitbook init blog
WORKDIR /blog
ADD ./ /blog/
RUN gitbook install ./ && gitbook build
EXPOSE 4000
CMD ["gitbook","serve"]

为什么构建的会更快一些?因为第一次构建之后,接下来的每次构建都会用到之前的层缓存,只在有代码变动的层才会重新构建。

上面可以看出来,起了三个容器来提供服务,下面用nginx来实现负载均衡

在HTTP字段下加上:

1
2
3
4
5
6
upstream gitbook_server {
server 127.0.0.1:4050;
server 127.0.0.1:4051;
server 127.0.0.1:4052;
}
# 这里直接用默认的轮询就可以

在server下进行如下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
listen 80;
server_name book.socmap.org;

index index.html index.htm;

location / {
proxy_pass http://gitbook_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;
}
}

部署成功后,可以看到三个正在提供服务的容器

1
2
3
4
5
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b7cca4b7ce58 harbor.socmap.org/gitbook/gitbook:438 "gitbook serve" 3 hours ago Up 3 hours 0.0.0.0:4052->4000/tcp gitbook-4052
e2b170866e31 harbor.socmap.org/gitbook/gitbook:438 "gitbook serve" 3 hours ago Up 3 hours 0.0.0.0:4051->4000/tcp gitbook-4051
2e9d54b6536b harbor.socmap.org/gitbook/gitbook:438 "gitbook serve" 3 hours ago Up 3 hours 0.0.0.0:4050->4000/tcp gitbook-4050

现在访问book.socmap.org,nginx会把流量随机分发给后端三个docker容器之一。