jenkins自动化部署应用到k8s(8):构建和上传镜像
部署k8s参见我的k8s专栏,有很详细的步骤和描述。这里只讲上线的时候连接k8s和镜像替换。
阅读本文需要的知识
docker相关命令
Dockerfile的编写
shell命令基础
部署思路
我以前的思路是代码都是放在oss中,pod运行的时候会挂载oss到容器中进行项目代码处理,网站设置和nginx的启动。
这样做符合当时我们快速处理上线的需求。但是对于长期的部署和回滚来说,增加了很多人工劳动力,比如需要先准备好代码,而不是直接从git仓库获取。过程不够自动化,完全抛弃了k8s的回滚等功能。
新的部署思路就是,使用jenkins拉取git代码,本地打包好包含运行环境和代码的镜像,直接push到镜像仓库,然后k8s替换镜像,如果上线后发现异常也可以及时回滚。
镜像打包
我们一般在项目上线的时候,会首先会准备一个具有运行环境的镜像,然后把项目代码打包到镜像内部生成一个新镜像。
这里我为了解耦这两个操作,把运行环境做成了一个基础镜像。叫xxx:base。然后后面的项目代码中使用的是基础镜像加项目代码再打包成项目镜像。
基础镜像打包(处理运行环境,增加公共依赖等)
把下面的命令放到Dockerfile中
FROM richarvey/nginx-php-fpm:1.5.6
RUN rm -f /etc/nginx/sites-enabled/default.conf \
&& rm -f /etc/nginx/sites-available/*.conf \
&& mkdir -p /var/www/html/ \
&& mkdir -p /data/logs/nginx \
&& apk update && apk add tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone\
&& /usr/local/bin/docker-php-ext-configure bcmath \
&& /usr/local/bin/docker-php-ext-install bcmath
CMD ["/start.sh"]
这里我们模拟了一些操作,
- 删除不必要的文件,创建了一些文件等
- 设置时区
- 安装了一个php依赖模块
当然你可能用的镜像和我的不一样,也可能语言不一样,这都不是主要的。
然后在包含Dockerfile的目录中运行命令:
docker build -t NAME:TAG .
我使用的是阿里云的镜像云服务。如果你的基础镜像不包含代码或者隐私的东西,也可以打包成公共镜像推送。
如果是私有镜像,你需要先登录再push,具体的登录代码每个平台不一样我也就不写了,相关平台都有提示。
项目镜像打包
这里可以再jenkins中用shell方式运行,也可以把相关的代码放到git中拉下来,给执行权限后执行。
jenkins中使用shell执行
#!/bin/bash
DATETIME=`date '+%Y-%m-%d_%H.%M.%S'`
PROJECTNAME=testApi
REPOSITORY=registry.cn-hangzhou.aliyuncs.com/test/test
imageName=$REPOSITORY:$PROJECTNAME"_v"$BUILD_ID"_"$DATETIME
cp configs/pre/config/$PROJECTNAME/database.php $PROJECTNAME/config
cp configs/pre/config/$PROJECTNAME/.env $PROJECTNAME/
# 构建镜像
cat > Dockerfile << EOF
FROM registry.cn-hangzhou.aliyuncs.com/test/test-public:base
ADD . /data
RUN cp /data/configs/pre/nginx/$PROJECTNAME.conf /etc/nginx/sites-enabled/ \
&& cp /data/configs/pre/php/php-ext-conf.ini /usr/local/etc/php/conf.d/ \
&& cp -r /data/$PROJECTNAME /var/www/html/$PROJECTNAME \
&& cd /var/www/html/$PROJECTNAME/ && apk add bcmath &&composer install
CMD ["/start.sh"]
EOF
echo '---------------------------------------------------'
echo $imageName
docker login --username=xxxx registry.cn-hangzhou.aliyuncs.com -p xxxx
docker build -t $imageName .
# 上传镜像
docker push $imageName
在jenkins中拉取git项目后执行的方式大致如下。
#!/bin/bash
PROJECTNAME=xxxApi
cp configs/pre/config/$PROJECTNAME/Dockerfile.sh .
chmod +x ./Dockerfile.sh
./Dockerfile.sh
这样做优点是
- 不用每次打开jenkins修改配置。
- 文件的复制编辑都比去jenkins中操作效率要高一些,项目多的话会解约很多时间。
- 方便代码的备份
缺点是在jenkins中看不到所有操作的全貌。有利有弊,大家选择自己喜欢的方式就好。