• 借助docker在本地模拟线上CI/CD流水线编译流程


    1 背景

    公司采用jenkins主从集群实现CICD流程,其中Jenkins Master部署在服务器上,Jenkins Slave 以 Pod 形式运行在 Kubernetes 集群的 Node 上。其优点在于可以通过自定义的从属pod来隔离编译/打包/运行环境,实现多语言/多版本的编译,多环境的部署(阿里云、华为云、k8s)。

    然而实际过程中由于依赖变动、网络故障等等因素,线上CI/CD发布项目时偶尔出现编译失败的问题,而研发难以定位到是项目本身的问题还是其它问题导致。

    2 解决方案

    基于docker在本地构建编译环境,模拟线上CI/CD编译流程,快速定位编译失败的问题。

    例如,前端项目可基于node14/16构建镜像,后端项目基于mvn镜像(挂载settings.xml)即可完成编译流程,无需在机器上繁琐的安装各种环境。

    3 具体步骤

    本文以测试前端项目为例,模拟线上流水线编译流程,并部署至测试服务器。研发/测试同学可据此文档本地编译部署、排查线上【编译失败】等问题。

    3.1 获取编译及启动方式

    首先与研发/运维沟通,获取编译环境、编译命令及启动命令,一般研发本地与线上jenkins流水线的编译方式一致

    ① 编译

    # 环境,将以此为基础镜像构建
    node14.11
     
    # 域名:
    test-fe.net
     
    # 编译命令:
    npm install
    npm run build
     
    # nginx配置(略)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    ② 启动
    本项目将打包好的dist文件夹置于工作目录下,通过nginx代理即可。

    3.2 定制镜像(仅首次需要)

    ① 配置镜像仓库加速器(可选)
    配置镜像仓库加速器(阿里云),提升获取Docker官方镜像的速度

    vim /etc/docker/daemon.json
    ------
     
     
    {
        "registry-mirrors": [
            "https://ohdpuoqu.mirror.aliyuncs.com"
        ]
    }
     
     
    ------
    # 重启docker
    systemctl restart docker
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    ② Dockerfile
    进入工作目录,创建node14编译环境的Dockerfile,相同编译环境项目都可使用该容器编译

    # 进入仓库目录
    cd /data/web/repo
    # 创建node14文件夹
    mkdir node14
    cd node14
    # 创建Dockerfile
    vim Dockerfile
    -------------------------
     
     
    FROM node:14.11.0
    maintainer lc
     
    # 构建参数
    ARG WORK_PATH="/app"
     
    # 设置时区
    RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
     
    # 替换为阿里源并安装必要工具
    RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list  \
        && apt update -y \
        && apt-get install -y curl vim telnet
     
    # 解决vim中文乱码、ll命令
    RUN echo "syntax on \nset termencoding=utf-8 \nset encoding=utf8 \nset fileencodings=utf8,ucs-bom,gbk,cp936,gb2312,gb18030" >> ~/.vimrc  \
     && echo "alias ll='ls $LS_OPTIONS -l'" >> ~/.bashrc
     
    # 设置git全局参数、并记住密码
    RUN git config --global user.name "test" \
     && git config --global user.email test@local \
     && git config --global credential.helper store
     
    #设置工作目录
    WORKDIR $WORK_PATH
     
    # 继承基础镜像
    ENTRYPOINT ["docker-entrypoint.sh"]
    CMD [ "node" ]
     
     
    -----------------
    # 制作镜像
    docker build -t node-build:14.11.0 .
    
    • 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
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    ③ 运行
    将容器中的项目挂载至本地,方便调试及后续编译目录的拷贝部署

    docker run -tid --name node-build  -v /data/web/repo/node14/mnt:/app node-build:14.11.0
    
    • 1

    3.3 编译

    ① 进入相应编译环境的容器

    docker exec -it node-build bash
    
    • 1

    ② clone项目(http/https,ssh需额外配置)

    git clone http://gitlab.xxx.net/xxxx/test-fe.git
     
    cd test-fe
     
    # 若有必要,切换至相应commitid
    git checkout <commitid>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ③ 编译

    npm install 
     
    # 与研发确认测试环境打包命令
    npm run build:test
    
    • 1
    • 2
    • 3
    • 4

    ④ 编译完成后,退出容器

    3.4 部署项目

    ① 部署项目

    # 进入挂载目录
    cd /data/web/repo/node14/mnt/test-fe
     
    # 创建工作目录
    mkdir -p /data/web/test-fe
     
    # 拷贝刚才编译好的文件至项目工作目录
    /bin/cp -rf /data/web/repo/node14/mnt/test-fe/dist/ /data/web/test-fe/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ② 配置nginx(nginx亦可容器方式部署)
    考虑到后续项目越来越多,在server目录下,通过文件夹区分项目组(与线上一致),因此需修改nginx默认配置:

    vim /opt/openresty/nginx/conf/nginx.conf
    ------
     
    include     servers/*.conf;
     
    改为
     
    include     servers/*/*.conf;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ③ 新增路由
    创建conf文件

    cd /opt/openresty/nginx/conf/servers/
    mkdir test-fe
    vim test-fe.conf
    
    • 1
    • 2
    • 3

    http

    server {
            listen          80;
            server_name     test-fe.net;
            index           index.html;
            root            /data/web/test-fe/dist;
            access_log      logs/test-fe.access.log  main;
            add_header Strict-Transport-Security "max-age=864000";
     
            location  / {
                    try_files $uri $uri/ /index.html;
             }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    ④ 重启nginx

    # 验证配置
    /opt/openresty/nginx/sbin/nginx -t
     
    # 验证通过后,重启nginx
    /opt/openresty/nginx/sbin/nginx -s reload
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4 扩展

    本文提供了一种供研发/测试在本地排查线上流水线编译失败的方法,也帮助了解流水线工作方式。纯手工操作,后续考虑将上述步骤集成到gitlab-ci中,通过指定tag,提交代码后能自动编译代码并部署至测试环境。

  • 相关阅读:
    微信聊天内容可以被监听吗
    Linux概述
    【LeetCode】面试题 17.19. 消失的两个数字
    c++11 实现枚举值到枚举名的转换
    react获取Datepicker组件日期
    【设计模式】【第一章】【支付场景】【策略模式 + 工厂模式 + 门面模式 + 单例模式】
    《生命·觉者》蔡志忠:一个人,活出自己是最重要的
    DC-9靶场下载及渗透实战详细过程(DC靶场系列)
    【MySQL】 Java的JDBC编程
    刺激的8月!字节三面鞭尸/嘴贱痛失腾讯offer,想要个offer这么难吗
  • 原文地址:https://blog.csdn.net/qq_14999375/article/details/127901396