手把手带你玩转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
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
原文地址:https://www.cnblogs.com/Dplus/p/13287750.html