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

公司在一年之内先后使用了无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/; # 此处配置/目录,对应上一步负载均衡中的访问路径
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343