erp项目自动发布流程容器化设计
前言
由于公司ERP后端API项目基于Laravel框架编写,开发语言为PHP,此次记录是把现有的自动化发布流程容器化,原先自动发布流程基于 Gtilab+Jenkins+Nginx 直接发布至开发与测试环境。运行了一个月,发现还是存在一些缺点的,比如代码在开发环境运行得好好的,测试人员使用Jenkins把代码部署到测试环境时就出现了错误。测试完后,发布至生产环境又出现一些如权限、配置文件、变量等一系列问题。每换一个环境,总是有这样那样的问题,所以为了彻底解决这一问题,解放传统运维人员的双手,决定容器化整个发布流程。
一、发布流程设计
1.获取代码
2.编译(可选)
3.配置文件
4.构建镜像
5.上传镜像
6.启动容器
画张图,让大家容易理解些。
首先是,开发人员完成开发任务后,push提交代码------代码同步到Gitlab仓库后,触发Webhook通知Jenkins----Jenkins负责构建Docker镜像并推送到远程Docker仓库,推送完成后,通过SSH连接到节点服务器(Node)----在节点服务器拉取远程docker仓库的镜像,然后指定启动哪个配置文件来启动容器。整个发布流程大概就这样子,实战过程如下。
图中自己搭建的为Harbor私有仓库,不想搭建,大家可以使用阿里云提供docker仓库,功能也很强大,目前免费使用。
二、环境规划
首先整个环境确保已经部署完成Gitlab、Jenkins、Docker Registry、Docker、Nginx。部署方法不在叙述,请看百度或翻看我Blog。
角色 IP 域名 Gitlab 192.168.1.22 git.leiyan.com Jenkins/Docker 192.168.1.23 jenkins.leiyan.com Docker Registry 192.168.1.27 docker.leiiyan.com Docker/Nginx 192.168.1.31 dev.leiyan.com
.
[root@jenkins-server]# cat /etc/redhat-release && uname -a CentOS Linux release 7.5.1804 (Core) Linux jenkins-server 3.10.0-862.14.4.el7.x86_64 #1 SMP Wed Sep 26 15:12:11 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux [root@jenkins-server]# docker -v Docker version 18.09.0, build 4d60db4
三、Docker客户端配置
Docker仓库我使用的是Vmware开源的Harbor,官网,使用域名:docker.leiyan.com 部署与当前内网,因为docker 默认以https方式登陆,不支持http方式登录,所以所有Docker客户端要以http方式登陆,则需修改下配置文件。(阿里云仓库默认是https模式,不需要做此步骤)
方法一:
vim /usr/lib/systemd/system/docker.service ExecStart=/usr/bin/dockerd \ --insecure-registry docker.leiyan.com \ #增加镜像地址
方法二:
创建/etc/docker/daemon.json文件,在文件中指定仓库地址
cat > /etc/docker/daemon.json << EOF
{ "insecure-registries":["docker.leiyan.com"] }
EOF完成后从载配置,重启docker
systemctl daemon-reload systemctl restart docker
登录仓库
docker login docker.leiyan.com Username: admin Password: Login Succeeded
四、构建基础镜像
构建一个PHP代码须要环境,我直接在gitbug上找了一个: 项目地址
这个PHP+NGINX的环境镜像还不错,适合大多数PHP环境,它使用supervisord启动守护NGINX和PHP进程,具体使用指南可以看: https://www.qinzc.me/post-204.html
Dockerfile 内容
FROM centos:7
MAINTAINER Skiychan <dev@skiy.net>
ENV NGINX_VERSION 1.15.7
ENV PHP_VERSION 7.2.13
RUN set -x && \
yum install -y gcc \
gcc-c++ \
autoconf \
automake \
libtool \
make \
cmake && \
#Install PHP library
## libmcrypt-devel DIY
rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm && \
yum install -y zlib \
zlib-devel \
openssl \
openssl-devel \
pcre-devel \
libxml2 \
libxml2-devel \
libcurl \
libcurl-devel \
libpng-devel \
libjpeg-devel \
freetype-devel \
libmcrypt-devel \
openssh-server \
python-setuptools && \
#Add user
mkdir -p /data/{www,phpextini,phpextfile} && \
useradd -r -s /sbin/nologin -d /data/www -m -k no www && \
#Download nginx & php
mkdir -p /home/nginx-php && cd $_ && \
curl -Lk http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz | gunzip | tar x -C /home/nginx-php && \
curl -Lk http://php.net/distributions/php-$PHP_VERSION.tar.gz | gunzip | tar x -C /home/nginx-php && \
#Make install nginx
cd /home/nginx-php/nginx-$NGINX_VERSION && \
./configure --prefix=/usr/local/nginx \
--user=www --group=www \
--error-log-path=/var/log/nginx_error.log \
--http-log-path=/var/log/nginx_access.log \
--pid-path=/var/run/nginx.pid \
--with-pcre \
--with-http_ssl_module \
--without-mail_pop3_module \
--without-mail_imap_module \
--with-http_gzip_static_module && \
make && make install && \
#Make install php
cd /home/nginx-php/php-$PHP_VERSION && \
./configure --prefix=/usr/local/php \
--with-config-file-path=/usr/local/php/etc \
--with-config-file-scan-dir=/data/phpextini \
--with-fpm-user=www \
--with-fpm-group=www \
--with-mysqli \
--with-pdo-mysql \
--with-openssl \
--with-gd \
--with-iconv \
--with-zlib \
--with-gettext \
--with-curl \
--with-png-dir \
--with-jpeg-dir \
--with-freetype-dir \
--with-xmlrpc \
--with-mhash \
--enable-fpm \
--enable-xml \
--enable-shmop \
--enable-sysvsem \
--enable-inline-optimization \
--enable-mbregex \
--enable-mbstring \
--enable-ftp \
--enable-mysqlnd \
--enable-pcntl \
--enable-sockets \
--enable-zip \
--enable-soap \
--enable-session \
--enable-opcache \
--enable-bcmath \
--enable-exif \
--enable-fileinfo \
--disable-rpath \
--enable-ipv6 \
--disable-debug \
--without-pear && \
make && make install && \
#Install php-fpm
cd /home/nginx-php/php-$PHP_VERSION && \
cp php.ini-production /usr/local/php/etc/php.ini && \
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf && \
cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf && \
#Install supervisor
easy_install supervisor && \
mkdir -p /var/{log/supervisor,run/{sshd,supervisord}} && \
#Clean OS
yum remove -y gcc \
gcc-c++ \
autoconf \
automake \
libtool \
make \
cmake && \
yum clean all && \
rm -rf /tmp/* /var/cache/{yum,ldconfig} /etc/my.cnf{,.d} && \
mkdir -p --mode=0755 /var/cache/{yum,ldconfig} && \
find /var/log -type f -delete && \
rm -rf /home/nginx-php && \
#Change Mod from webdir
chown -R www:www /data/www
#Add supervisord conf
ADD supervisord.conf /etc/
#Create web folder
# WEB Folder: /data/www
# SSL Folder: /usr/local/nginx/conf/ssl
# Vhost Folder: /usr/local/nginx/conf/vhost
# php extfile ini Folder: /usr/local/php/etc/conf.d
# php extfile Folder: /data/phpextfile
VOLUME ["/data/www", "/usr/local/nginx/conf/ssl", "/usr/local/nginx/conf/vhost", "/data/phpextini", "/data/phpextfile"]
ADD index.php /data/www/
#Add ext setting to image
#ADD extini/ /data/phpextini/
#ADD extfile/ /data/phpextfile/
#Update nginx config
ADD nginx.conf /usr/local/nginx/conf/
#Start
ADD start.sh /
RUN chmod +x /start.sh
#Set port
EXPOSE 80 443
#Start it
ENTRYPOINT ["/start.sh"]
#Start web server
#CMD ["/bin/bash", "/start.sh"]开始构建
docker build -t docker.leiyan.com/erp-api/nginx .
注意:后边的点. 是Dockerfile 所在路径,Dockerfile所在路径为文件ADD进容器的根路径。
镜像构建完成后上传至Docker 仓库。
docker push docker.leiyan.com/erp-api/nginx

五、Jenkins 环境准备
1.Jenkins上,/code/data/文件夹目录结构

2.拉取第四步构建好好的基础镜像
[root@jenkins-server ~]# docker pull docker.leiyan.com/erp-api/nginx:latest latest: Pulling from erp-api/nginx a02a4930cb5d: Pull complete af7170ef0b85: Extracting [==================================================>] 96.14MB/96.14MB 72dff1e1a3e5: Download complete 473619a99d5b: Download complete 31a15d353075: Download complete 7ded69bed07f: Download complete 2bdee6428e36: Download complete
3.jenkins执行的脚本:功能很简单,就是把,php代码,配置文件,容器运行脚本,做成镜像,并上传至Docker仓库
#!/bin/bash
#Author:覃子城
#Blog:http://www.qinzc.me
#Time:2019-01-09 09:30:55
#Name:devops.sh
#Version:V1.0
#Description: jenkins CI shell
CODEDIR=/data/code
if [ -d /data/code ];then
echo "-----目录存在------"
else
mkdir /data/code -p
echo "创建目录成功"
fi
#拉取gitlab上的代码至当前Jenkins(请根据自身业务去做)
echo "############git pull new code....#############"
cd $CODEDIR
rm -fr ${CODEDIR}/erp-backend
git clone git@git.leiyan.com:erp/erp-backend.git
#pull新代码下来后进入代码目录,,并编译更新代码(请根据自身业务去做)
cd $CODEDIR/erp-backend/src
/usr/local/bin/composer update
#生成Dockerfile文件
echo "----------编写Dockerfile-------------"
cat > $CODEDIR/Dockerfile <<EOF
#基础镜像来源
FROM docker.leiyan.com/erp-api/nginx
#镜像信息
MAINTAINER Qinzicheng "542129333@qq.com"
#1.添加nginx.conf配置文件
#2.添加start.sh启动的脚本
#3.复制所有环境配置文件至站点目录
#4.复制PHP代码到站点目录
ADD nginx.conf /usr/local/nginx/conf/nginx.conf
ADD start.sh /start.sh
COPY deploy /data/
COPY "erp-backend/src" /data/www
#暴露 80、443端口
EXPOSE 80 443
#运行
ENTRYPOINT "/start.sh"
EOF
# 开始构建镜像
docker build -t docker.leiyan.com/erp-api/nginx:$Tag $CODEDIR/.
# 打印当前镜像,查看是否构建成功
echo "--------------print docker images 当前镜像 --------------"
docker images
# 上传到Docker 仓库
echo "-----------start push Harbor--------------"
docker push docker.leiyan.com/erp-api/nginx:$Tag
# 把容器删除,释放空间
echo "-------------删除镜像--------------"
docker rm -f docker.leiyan.com/erp-api/nginx:$Tag
docker rmi -f docker.leiyan.com/erp-api/nginx:$Tagstart.sh脚本内容如下:
https://github.com/skiy/nginx-php7/blob/master/start.sh
此脚本为原项目里的脚本,按照发布流程设计思路,我会在此脚本后面添加上,以下几行内容:
功能:就是运行容器时指定的环境变量-e CONF=xxx,把相应的配置文件拷贝至站点目录。
代码:
if [ $CONF == "dev" ];then mv /data/dev.conf /data/www/.env elif [ $CONF == "test" ];then mv /data/test.conf /data/www/.env elif [ $CONF == "pro" ];then mv /data/pro.conf /data/www/.env fi
六、Jenkins创建项目并构建测试
1.构建一个自由风格的软件项目,创建Git Parameter 参数化构建

2.源码管理

3.构建:执行shell
4.构建测试
这里我选个我们项目最新的版本

控制台日志,显示我们构建成功啦。
镜像也传到了Docker仓库。

七、 发布
上边步骤都调通后,剩下的事情就简单了。Jenkins SSH连接进入节点,下载远程镜像仓库上对应版本的容器。启动。Game Over!
1.JenKins上增加构建步骤

上边代码:
#删除上一版本的容器 docker rm -f erp-api #下载新构建的容器 docker pull docker.leiyan.com/erp-api/nginx:$Tag #启动新容器 docker run --name erp-api -d -e CONF=dev -p 83:80 -v docker.leiyan.com/erp-api/nginx:$Tag #CONF=dev 为使用dev.conf配置文件,在步骤五中目录结构中的3个配置文件之一。 #如果写城CONF=test 就是使用test.conf配置文件
2.打开验证

知识扩展
容器启动正常后,作为后端服务使用,所以生产环境上,我是用nginx反向代理的功能,把请求都转发到对应的Docker容器上。Nginx配置我就不贴上来了,能看懂,看到这的兄嘚,Nginx反向配置不用我多说,都会的。
还有就是没有做版本回滚优化,所以按现在的情景下使用,回滚版本耗时较长需要1-3分钟,有时间大家可写个脚本优化下,大概思路就是,Jenkins上选择回滚的版本,写个判断脚本,如果本地镜像仓库存在这个版本,就启动,不存在就去远程镜像仓库上拉取后再启动。


桂ICP备16010384号-1
请登录后查看评论内容