美文网首页
基于Jenkins的前端部署方式的进化

基于Jenkins的前端部署方式的进化

作者: videring | 来源:发表于2020-08-18 22:55 被阅读0次

    公司在一年之内先后使用了无dockersdocker/k8sdocker/rancher三种方式,结合jenkins,进行前端业务代码的部署。

    一、传统的方式:无docker

    传统的部署方式是:

    • jenkins服务器上配置代码git地址、指定分支
    • 设置构建执行shell:npm install安装依赖、npm run build执行打包
    • 设置构建后执行操作:将上一步打包后的代码通过ssh拷贝到远程目标服务器指定目录上

    二、docker/k8s

    • jenkins服务器上配置代码git地址、指定分支
    • 设置构建执行shell:npm install安装依赖、npm run build执行打包
    • npm run docker生成镜像文件、推送镜像文件到仓库中,然后生成k8s编排文件
    • 设置构建后执行操作:将上一步处理后生成的yaml编排文件通过ssh方式拷贝到k8s master节点指定目录上,然后执行kubectl delete -f 编排文件命令停止原容器,kubectl apply -f 编排文件重新启动容器。
    2.1众所周知,k8s编排文件配置项较多,在此不详述各配置项的意义,只提供一种思路,用配置的方式生成编排文件:主要思路是将镜像名称、标签、命名空间和host等信息抽离并模板化,借助json-template/string来生成模板实例(见下方代码);借助child_process执行docker build/push命令(见2.2)。
    const fs = require('fs')
    const render = require('json-templater/string')
    const path = require('path')
    const { execSync } = require('child_process')
    
    const options = {
      image: '',
      imageName: '',
      imageTag: '',
      nameSpace: '',
      fileName: '',
      host: ''
    }
    
    const argvs = process.argv
    const imageIndex = argvs.indexOf('--image')
    const nameSpaceIndex = argvs.indexOf('--namespace')
    const fileNameIndex = argvs.indexOf('--filename')
    const hostIndex = argvs.indexOf('--host')
    if (imageIndex > -1) {
      options.image = argvs[imageIndex + 1]
      if (options.image) {
        [options.imageName, options.imageTag] = options.image.split(':')
      }
    }
    if (nameSpaceIndex > -1) {
      options.nameSpace = argvs[nameSpaceIndex + 1]
    }
    if (fileNameIndex > -1) {
      options.fileName = argvs[fileNameIndex + 1]
    }
    if (hostIndex > -1) {
      options.host = argvs[hostIndex + 1]
    }
    
    const tpl = `#Automatically generated by public/docker/genK8s.js
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: {{name}}
      namespace: {{namespace}}
      labels:
        app: {{name}}
    spec:
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: {{name}}
      template:
        metadata:
          labels:
            app: {{name}}
        spec:
          containers:
            - name: {{name}}
              resources:
                limits:
                  memory: 200Mi
                requests:
                  memory: 200Mi
              image: {{image}}
              ports:
                - containerPort: 80
                  protocol: TCP
              imagePullPolicy: Always
    
    ---
    
    apiVersion: v1
    kind: Service
    metadata:
      name: {{name}}
      namespace: {{namespace}}
      labels:
        app: {{name}}
    spec:
      ports:
        - port: 80
          targetPort: 80
      selector:
        app: {{name}}
      type: ClusterIP
    
    ---
    
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: {{name}}-nginx-ingress-{{namespace}}
      namespace: {{namespace}}
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /$1
        kubernetes.io/ingress.class: "nginx"
        nginx.ingress.kubernetes.io/proxy-body-size: "512M"
    spec:
      rules:
        - host: {{host}}
          http:
            paths:
              - path: /{{name}}/(.*)
                backend:
                  serviceName: {{name}}
                  servicePort: 80
    `
    
    const template = render(tpl, {
      name: options.fileName,
      namespace: options.nameSpace,
      image: options.image,
      host: options.host
    })
    const OUTPUT_PATH = path.join(__dirname, `dist/${options.fileName}.yaml`)
    
    // 生成编排文件
    fs.writeFileSync(OUTPUT_PATH, template)
    
    // 根据Dockerfile文件将前端构建后的代码打成镜像
    execSync(`docker build -t ${options.image} .`)
    // 将镜像推送到docker仓库
    execSync(`docker push ${options.image}`)
    
    2.2 Dockerfile文件和nginx.conf
    # Dockerfile
    FROM nginx:1.16-alpine # ngnix镜像
    ADD dist/ /usr/share/nginx/html/ # 将本地dist目录下的文件打包镜像中去
    COPY nginx.conf /etc/nginx/config.d/ #拷贝nginx配置文件到镜像指定目录下
    RUN ls -la /usr/share/nginx/html/* 
    EXPOSE 80 # 启动容器对外暴露的port
    
    # ngnix配置文件
    server {
      listen       80;
      server_name  localhost;
      client_max_body_size 512M;
      location / {
        #跟dockerfile上保持一致
        alias   /usr/share/nginx/html;
        index  index.html index.htm;
      }
    
      error_page   500 502 503 504  /50x.html;
    }
    

    三、docker/rancher

    rancher是k8s的上层应用,可以认为是通过在页面上配置一些选项,自动生成k8s编排文件,并能启动和关闭容器。可以大大简化配置,极大加快部署速度。结合rancher,jenkins构建工程进行相应地变动(jenkins上先行部署rancher)。
    • jenkins服务器上配置代码git地址、指定分支
    • 设置构建执行shell:npm install安装依赖、npm run build执行打包
    • npm run docker生成镜像文件、推送镜像文件到仓库中
    • 登录rancher并执行rancher kubectl patch命令:
    # 设置环境变量
    RANCHER_LOGIN_TOKEN="我是token"
    RANCHER_API="https://我是rancher api地址"
    
    RANCHER_PROJECT_CODE="工程代码"
    #rancher 工作负载名称
    DEPLOY_NAME="负载名称"
    NAMESPACE="命名空间"
    
    # 设置更新时间(必须)
    update_date=`date +'%Y-%m-%d %H:%M:%S'`
    p="{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"cattle.io/timestamp\":\"${update_date}\"}}}}}"
    
    # 登录rancher
    rancher login $RANCHER_API --token $RANCHER_LOGIN_TOKEN --skip-verify --context $RANCHER_PROJECT_CODE
    
    
    # 更新deployment
    rancher kubectl patch deploy/$DEPLOY_NAME -n $NAMESPACE -p "$p"
    
    # 删除标签为none的镜像
    # docker images|grep none|awk '{print $3}'|xargs docker rmi
    
    exit 0
    
    3.1 在rancher 上配置前端项目工作负载
    工作负载配置
    3.2 在rancher 上配置前端项目负载均衡
    负载均衡
    3.3对外网址的服务器上配置nginx.conf
    # 配置rancher_ingress
    upstream rancher_ingress {
        ip_hash;
        server 172.*.*.1 weight=1; # k8s服务器1
        server 172.*.*.2 weight=1; # k8s服务器2
        server 172.*.*.3 weight=1; # k8s服务器3
    }
    location / {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP        $remote_addr;
            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header X-NginX-Proxy true;
    
            proxy_pass http://rancher_ingress/; # 此处配置/目录,对应上一步负载均衡中的访问路径
        }
    

    相关文章

      网友评论

          本文标题:基于Jenkins的前端部署方式的进化

          本文链接:https://www.haomeiwen.com/subject/omcljktx.html