前端容器化部署

前端容器化部署

Posted by SkioFox on March 11, 2024

容器化构建部署

包含两个阶段,构建与部署。构建采用Docker容器技术,部署过程是将docker镜像部署至k8s。

即:构建生成镜像->推送至镜像仓库→将docker镜像部署至k8s。

构建

构建过程是将代码构建生成镜像,并且推送至镜像仓库,需要开发自行准备Dockerfile文件,jenkins统一的构建命令如下:

docker build -t registry-vpc.cn-hangzhou.aliyuncs.com/mYOUR/{group}-{project}:{tag} --build-arg IMAGE_TAG={tag} --build-arg BRANCH={branch} --build-arg GITTOKENNAME={gittokenname} --build-arg GITTOKEN={gittoken} -f ./Dockerfile .

参数说明:

  • group,组名,同gitlab组名
  • project,项目名称,同gitlab项目名称

docker构建参数说明:

  • IMAGE_TAG,镜像版本,例如:202002280923-f-20200211-unified-payment
  • BRANCH,分支名称
  • GITTOKENNAME,gitlab站点账号
  • GITTOKEN,gitlab站点密码

Dockerfile书写规范

  • 尽量保证构建镜像体积最小
  • 尽可能利用构建缓存减少构建时间

请参考Dockerfile官方指南

部署,远行时

部署过程是将docker镜像部署至k8s,部署过程采用helm脚本,公共可用的环境变量如下:

  • YOUR_ENV,区分环境,取值如下:
    • test,测试环境
    • release,预发布环境
    • prod,生产环境
    • {租户id}_prod,私有化环境,比如华远为:huayuanadmin_prod
  • TENANT_NAMESPACE,灰度环境,取值如下:
    • g2,默认值
    • g0
    • g1
  • APOLLO_META_SERVER_URL,Apollo服务地址,如:xxx
  • ELASTIC_APM_SERVER_URL,APM服务地址,如:xxx
  • ETCDV3_SERVER_URLS,etcd服务地址,如:xxxx
  • YOUR_BRANCH, 多泳道标识,目前只存在于测试环境

通用镜像标签

不同技术栈,不同项目可能会有不同的一些部署配置,在部署阶段会提取Dockerfile中配置的LABEL,目前可以自定义的配置项有:

  • k8s部署探针,当前只支持http探针自定义配置,示例如下

      LABEL probe="/debug/vars" \
            probe-schema="HTTP" \
            probe-port="9000"
    

    如没有配置探针接口,请如下配置

      LABEL probe="none"
    
  • k8s service

      LABEL service="none"
    
  • k8s pod数量

      LABEL replicas="2"
    
  • 多泳道多端口多协议

      # schemas多协议,-分割
      LABEL schemas=http-grpc
      # ports多端口, -分割,需跟schemas有相等个元素
      LABEL ports=10000-9000
      # ssls是否加密, -分割,1加密,0不加密,默认不加密
      LABEL ssls=1-0
      # 结合schemas,ports,ssls得到http-10000端口-加密, grpc-9000端口-不加密
    
  • 不部署k8s

      LABEL no-deploy-k8s="true"
    
  • 设置资源请求和约束

      # 支持通过label标识memory,cpu的request和limit
      LABEL memory-request="150Mi" memory-limit="300Mi" cpu-request="50m" cpu-limit="500m"
    

    点这里看资源单位说明

前端项目容器化部署

Dockerfile

在项目根目录中添加Dockerfile文件,内容示例如下:

FROM your-registry.cn-hangzhou.cr.aliyuncs.com/images-base/node:11.13.0 AS builder_web

WORKDIR /app

# 增加镜像缓存利用
ADD ./package.json /app/package.json
ADD ./yarn.lock /app/yarn.lock

# 安装依赖
RUN yarn config set @your:registry https://registry-npm.myscrm.cn/repository/your/ && \
  npm config set registry https://registry.npm.taobao.org && \
  yarn --frozen-lockfile --check-files

# 将docker构建参数转换到环境变量
ARG IMAGE_TAG
ENV IMAGE_TAG=$IMAGE_TAG

ADD . /app
# 构建代码
RUN yarn build

FROM your-registry.cn-hangzhou.cr.aliyuncs.com/images-base/nginx:1.17.2-alpine
# 同步cdn标识
LABEL sync-cdn=true probe="none"

RUN mkdir -p /var/log/service/access && mkdir -p /var/log/service/err

# CDN同步脚本默认从/app/dist目录读文件
COPY --from=builder_web /app/dist /app/dist
COPY --from=builder_web /app/config/nginx.conf /etc/nginx/conf.d/default.conf

nginx

并且添加如下的nginx配置,在以上示例中的路径为:config/nginx.conf

server {
  listen 9000;
  ssi    on;

  access_log  /var/log/service/access/access.log  main;
  error_log  /var/log/service/err/error.log  error;

  root /app/dist;
  index  index.html index.htm index.shtml;

  location / {
    expires -1;
    try_files $uri /index.html;
  }
}

同步CDN

说明

因为使用CDN可以显著提升页面访问性能,建议按照部署CDN的方式实施配置。假如因某些特定原因不用部署CDN,可以忽略以下内容。

CDN目录规范

CDN服务是面向所有业务组所有项目的公共服务,为避免文件目录冲突,文件存放路径如下:

/{base}/dist/${project_name}-${process.env.IMAGE_TAG}/${项目文件}

访问路径规范如下:

${environment.PRO.cdn}/dist/${project_name}-${process.env.IMAGE_TAG}/${项目文件}

例如:https://img.myscrm.cn/dist/mars-frontend-202001161757-release/vendor.38920453fbe203495b06.js

说明如下:

  • environment.PRO.cdn: https://img.myscrm.cn
  • project_name: mars-frontend
  • process.env.IMAGE_TAG: 202001161757-release

webpack配置

按照CDN规范需要针对构建输出的资源路径与url做对应配置,针对规范已抽取了一个webpack插件(@your/your-setting-plugin),方便使用

使用说明

  1. 安装:
yarn add @your/your-setting-plugin@latest -D
或
npm install @your/your-setting-plugin@latest -d
  1. 修改package.jsonname属性跟仓库名称保持一致

  2. webpack配置文件

const YunkeSettingPlugin = require('@your/your-setting-plugin');

module.exports = {
    plugins:[
        // XXX...
        new YunkeSettingPlugin({
            //只需配置这一个参数
            //host-machine打包构建时为宿主机模式,本地生成文件目录为: ${项目根目录}/dist/projects/${项目名}
            //docker 容器化部署模式,代码生成路径为:${项目跟目录}/${项目名}-${项目对应镜像tag}
            //publicPath改为`${environment.PRO.cdn}/dist/${project_name}-${process.env.IMAGE_TAG}/`
            deployType: 'docker'
        })
    ]
}
  1. 配置参数说明
参数名 数据类型 可取参数 默认值 参数说明
deployType string host-machinedocker docker host-machine打包构建时为宿主机模式,代码生成路径为: ${项目根目录}/dist/projects/${项目名};
docker 容器化部署模式,代码生成路径为: ${项目跟目录}/${项目名}-${项目对应镜像tag}

自定义同步配置

可在Dockerfile中增加对应的Label来控制CDN同步配置,如下:

Label 取值 说明
sync-cdn string 是否同步CDN,默认:不同步
sync-cdn-target string 需要同步的目标文件路径(镜像内的路径),默认:/app/dist
sync-cdn-pre-action string 同步前执行动作,默认:无
sync-cdn-by-deploy-env string 是否按环境同步CDN,默认:不按环境

以下示例表示需要将镜像内/app/dist所有文件同步到CDN服务器

LABEL sync-cdn="true" \
      sync-cdn-target="/app/dist"

以下示例表示需要将镜像内/app/dist所有文件同步到CDN服务器,并且按照不同环境部署至不同的CDN。

LABEL sync-cdn="true" \
      sync-cdn-target="/app/dist" \
      sync-cdn-pre-action="/docker-entrypoint.d/replace.sh" \
      sync-cdn-by-deploy-env="1"

假如dist目录下有index.js文件,同步到cdn的路径即为/{base}/dist/${project_name}-${process.env.IMAGE_TAG}/index.js, 访问路径为https://img.myscrm.cn/dist/${project_name}-${process.env.IMAGE_TAG}/index.js