使用 Jenkins 借助 Docker 实现自动化部署

发布于:9/11/2019, 8:35:09 PM @孙博
技术分享 | Docker,Jenkins,CI/CD,DevOps
许可协议:署名-非商业性使用(by-nc)

使用Docker部署站点已经很方便了,但是手敲命令还是会存在一定的风险——有可能因为写错命令导致生产环境挂掉、不方便多人操作等,因此我们可以选择一些常见的CI/CD工具帮我们完成这个工作。

这里向大家推荐的是Jenkins的解决方案。我们可以将Jenkins通过Docker部署,并使用Jenkins管理其他应用的编译与部署,由于Jenkins官方已经提供了Docker镜像,所以我们只需简单的命令就能让其跑起来。(命令中/var/jenkins为宿主机用于存放Jenkins运行所需的文件,请根据自身实际情况替换

Docker部署Jenkins

#/bin/bash
sudo docker run \
  -u root \
  -d \
  -p 8080:8080 \
  -p 50000:50000 \
  -v /var/jenkins:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --name jenkins \
  --restart=always \
  jenkinsci/blueocean

使用Jenkins创建一个自由软件项目(Freestyle project),设置完git的相关配置后,在Build环节添加一个Execute Shell,并填入类似下方的编译脚本用来编译。编译的过程其实就是根据Dockerfile来制作一个镜像,为了省事,我们使用${BUILD_NUMBER}来使每次生成的镜像时打的tag都不同。用户也可以根据自己的实际需要更改成不同的tag规则。

编译脚本

echo '>>> DOCKER BUILD START'

docker build -t ${JOB_NAME}:1.0.${BUILD_NUMBER} . | tee ${WORKSPACE}/docker_build_result.log
RESULT=$(cat ${WORKSPACE}/docker_build_result.log | tail -n 1)
#if [["$RESULT" != *Successfully*]];then
#  exit -1
#fi

echo '>>> DOCKER BUILD SUCCESSFULLY'

编译完成后,我们需要将最新镜像部署起来。由于一个端口只能被一个应用监听,所以我们并不能通过简单的docker run来运行容器,我们需要先将原来运行中的旧版本的容器先关掉,才能部署新版本的镜像。部署脚本如下所示,其中端口号20001为手动指定的项目专用的端口号,如果自己的项目有其他要求,也可以任意按照自己的需求进行更新。

部署脚本

echo '>>> DOCKER DEPLOY START'

CID=$(docker ps | grep "${JOB_NAME}" | awk '{print $1}')
if [ "$CID" != "" ];then
  echo '>>> DOCKER REOMVE OLD CONTAINER'
  docker container stop $CID
  docker container rm $CID
fi
docker run -p 20001:80 -d --name ${JOB_NAME} ${JOB_NAME}:1.0.${BUILD_NUMBER}
echo '>>> DOCKER DEPLOY SUCCESSFULLY'

根据示例的脚本可以快速的实现项目的自动化部署,但是这些脚本并不完美,它并不能够支持“平滑发布”,在新容器启起来之前,访问站点的用户会有明显的中断,用户体验较为不好。所以对于面向C端的使用者,可以随机指定端口,并通过与Nginx配置upstream协同完成部署工作,此处介于篇幅所限不做过多介绍。