• 手把手带你玩转k8s-一键部署vue项目


    前言

    在快速开发框架-前端篇中少了一个章节,就是关于vue工程的一键发布脚本设计和实现。本文就在此展开,并部署到k8s环境中。

    传统部署方式与k8s部署区别

    在没有使用k8s之前的前后端分离项目部署,一般是依托于宿主机上的nginx。前端静态资源走nginx,后端接口会使用nginx做代理。而此时,nginx是提前安装的,所以一键脚本并不会考虑nginx的安装与运行,只会将打包好静态资源放在指定目录。使用k8s之后,一键脚本会有的区别,除了打包静态资源放在指定目录上,还要考虑nginx实例的运行。

    • 传统的前后端分离部署架构
    • 使用k8s后的前后端分离部署架构

    发布流程设计

    1. 拉取代码

      没有代码就克隆,有代码了可以直接更新

      git clone / git pull
      复制代码
    2. 安装依赖

      这里指定一下源地址

      npm install --registry=http://registry.npm.taobao.org
      复制代码
    3. 打包

      可以简单区分一下生产与测试

      打测试包

      npm run build:test
      复制代码

      打生产包

      npm run build:prod
      复制代码
    4. 将静态资源复制到指定目录

      如何保证复制过程中不影响正常访问?

      1. index.html设置永不缓存
      2. 打包文件使用hash命名
      3. 只复制,不删除
      4. 先复制其他文件,最后复制index.html
    5. 发布或更新nginx服务

      这里不建议使用模板了,直接分两个yaml文件,一个生产,一个测试。

      kubectl apply -f k8s-test.yaml
      复制代码

    开始编码

    目录结构

    ├── /java_projects
        ├── mldong-vue
            ├── buildAndPublish.sh
            └── k8s-test.yaml
         └── source
    		├── front
                ├── mldong-vue			源码根目录
                	└── package.json
    复制代码

    文件详解

    • /java_projects/mldong-vue/buildAndPublish.sh

    一键打包发布到k8s集群脚本

    #!/bin/bash
    source_dir=/java_projects/source/front
    project_name=mldong-vue
    nfs_project_dir=/mnt/
    profile=test
    k8s_yaml=/java_projects/$project_name/k8s-$profile.yaml
    registry_url=https://registry.npm.taobao.org
    if [ -d "$source_dir" ]; then
      echo "源码存放根目录${source_dir}已存在"
    else
      echo "源码存放根目录不存在,创建${source_dir}"
      cp -p $source_dir
    fi
    
    if [ -d "$source_dir/$project_name" ]; then
      echo "源码已存在,git pull"
      cd $source_dir/$project_name
      git pull
    else
      echo "源码不存在,git clone"
      git clone $git_url $source_dir/$project_name
    fi
    cd $source_dir/$project_name
    git pull
    git_tag=$(git describe --tags --always)
    echo "当前版本:$git_tag"
    npm --registry=${registry_url} install --unsafe-perm
    npm run build:$profile
    
    if [ $? -ne 0 ]; then
      echo "打包失败"
    else
      # 移出index.html,留最后复制
      mv dist/index.html ./
      # 创建目录
      mkdir -p $nfs_project_dir/$project_name
      # 复制文件
      cp -r dist/* $nfs_project_dir/$project_name
      # 复制index.html
      cp index.html $nfs_project_dir/$project_name
      # 还原index.html
      mv index.html dist/index.html
      kubectl apply -f $k8s_yaml
    fi
    复制代码
    • /java_projects/mldong-vue/k8s-test.yaml

    静态资源服务的k8s定义文件

    注意:命名空间要和后端接口的一致。

    cat <<EOF > /java_projects/mldong-vue/k8s-test.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-cm
      namespace: mldong-admin-test
    data:
      a.conf: |-
        server {
          listen       80;
          server_name  a.mldong.com;
          location / {
            root   /usr/share/nginx/html/mldong-vue;
            index  index.html index.htm;
          }
          error_page   500 502 503 504  /50x.html;
          location = /50x.html {
            root   /usr/share/nginx/html;
          }
        }
    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: mldong-vue-test-pv
      labels:
        alicloud-pvname: mldong-vue-test-pv
    spec:
      capacity:
        storage: 5Gi
      accessModes:
        - ReadWriteMany
      csi:
        driver: nasplugin.csi.alibabacloud.com
        volumeHandle: mldong-vue-test-pv
        volumeAttributes:
          server: "9fdd94bf87-wfq66.cn-zhangjiakou.nas.aliyuncs.com"
          path: "/"
          vers: "3"
      storageClassName: nas
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      annotations:
        pv.kubernetes.io/bind-completed: 'yes'
        pv.kubernetes.io/bound-by-controller: 'yes'
      finalizers:
        - kubernetes.io/pvc-protection
      name: mldong-vue-test-pvc
      namespace: mldong-admin-test
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 1Gi
      selector:
        matchLabels:
          alicloud-pvname: mldong-vue-test-pv
      storageClassName: nas
      volumeMode: Filesystem
      volumeName: mldong-vue-test-pv
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
      namespace: mldong-admin-test
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 1
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - name: nginx
              image: registry-vpc.cn-zhangjiakou.aliyuncs.com/mldong/java/nginx:latest
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 80
                  name: port
                  protocol: TCP
              volumeMounts:
                - name: mldong-vue-test-pvc
                  mountPath: "/usr/share/nginx/html"
                - name: nginx-cm
                  mountPath: "/etc/nginx/conf.d"
          volumes:
            - name: mldong-vue-test-pvc
              persistentVolumeClaim: 
                claimName: mldong-vue-test-pvc
            - name: nginx-cm
              configMap:
                name: nginx-cm
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-nodeport
      namespace: mldong-admin-test
    spec:
      type: NodePort
      ports:
      - port: 80
        targetPort: 80
      selector:
        app: nginx
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      namespace: mldong-admin-test
    spec:
      type: ClusterIP
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        app: nginx
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      annotations:
      name: nginx-ingress
      namespace: mldong-admin-test
    spec:
      rules:
        - host: a.mldong.com
          http:
            paths:
              - backend:
                  serviceName: nginx
                  servicePort: 80
                path: /
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /$2
      name: mldong-admin-api
      namespace: mldong-admin-test
    spec:
      rules:
      - host: a.mldong.com
        http:
          paths:
          - backend:
              serviceName: mldong-admin
              servicePort: 8080
            path: /api(/|$)(.*)
           
    EOF
    
    复制代码

    这里踩了个小坑,在别的集群上,所有/api开头重定向到/,重写规则可以是这样:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
      name: mldong-admin-api
      namespace: mldong-admin-test
    spec:
      rules:
      - host: a.mldong.com
        http:
          paths:
          - backend:
              serviceName: mldong-admin
              servicePort: 8080
            path: /api
           
    复制代码

    阿里云的是这样:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /$2
      name: mldong-admin-api
      namespace: mldong-admin-test
    spec:
      rules:
      - host: a.mldong.com
        http:
          paths:
          - backend:
              serviceName: mldong-admin
              servicePort: 8080
            path: /api(/|$)(.*)
    复制代码

    遇到错不要紧,去翻一翻官方文档,看其样例,就知道如何修改了。

    最终效果

    小结

    做一键部署脚本最重要的就是梳理流程,梳理完流程后再一步步用代码实现。而使用k8s发布只是更换一下yaml模板,最后执行kubectl apply -f xxx.yaml进行发布而已。当然,这中间可能涉及到的知识点略多,但是静下心来学,其实也是能很快弄出来。


    作者:mldong
    链接:https://juejin.im/post/5f0890d9f265da22e27a82d8
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    01:oracle sql developer配置
    删除eclipse或者MyEclipse的workspace记录
    c++特殊函数
    java类和对象的基础(笔记)
    java打印日历
    10_9 java笔记
    程序流程
    学习疑惑……
    位运算和逻辑运算
    多种类型的指针
  • 原文地址:https://www.cnblogs.com/Dplus/p/13287750.html
Copyright © 2020-2023  润新知