内容简介:全部配置详见:什么是预发布?在我看来和灰度发布、单台是一样的意思,大白话就是说从线上摘一个有流量的机器,上线时先上到该机器中,稳定运行后再全流量上线。在浏览器里写入一个特殊标识的 cookie 或者参数,在接入层根据标识来判断把流量落入到预发布机器(Nginx 反向代理)。
全部配置详见: https://github.com/xuexb/DevOps/tree/master/jenkins-nginx-stg
什么是预发布?在我看来和灰度发布、单台是一样的意思,大白话就是说从线上摘一个有流量的机器,上线时先上到该机器中,稳定运行后再全流量上线。
方案
1. cookie / 参数
在浏览器里写入一个特殊标识的 cookie 或者参数,在接入层根据标识来判断把流量落入到预发布机器(Nginx 反向代理)。
2. 白名单
在接入层根据入网 IP 来判断是否在名单内,再代理到不同的环境。
3. 绑定 Hosts 直连应用层
每个应用层都是一个独立的服务,由接入层做负载均衡(LBS),而客户端可以直接绑定应用层的 IP ,直连应用层。
其实以上方案大同小异,本篇文章以绑定 Hosts 直连应用层为例介绍。
访问流程
服务说明
这里都是以 Docker 运行对应的服务。
- LBS proxy - 接入层,由一台 Nginx 做反向代理到应用层
- Gogs - 一个简易的 Git Server ,主要一直用 GitLab 想换换口味。。。这里主要提供代码仓库的作用
- Jenkins - 构建、发布
- www-app - 虚拟出多个生产环境,这里只是一个 Nginx Web Server ,基于 dockerxman/docker-ubuntu-ssh 创建,主要为了做 SSH 免密码登录,这里只创建两个实例,会把第一个实例做为单台预发环境
- user - 模拟用户环境,因为宿主网络和容器联通太麻烦,即使我用了 pipework 也大半天没折腾好,索性就使用一个 Centos 环境用来验证访问(
curl
)
绑定 IP 说明
容器名 | 别名 | IP | 说明 |
---|---|---|---|
www1 | prd_www1 |
192.168.1.101 |
生产环境1 |
www2 | prd_www2 |
192.168.1.102 |
生产环境2 |
proxy | LBS | 192.168.1.100 |
接入层 |
user | - | - | 模拟用户环境,使用 docker exec -it user /bin/bash 进入,不用自定 IP |
jenkins | - | - | Jenkins 容器,在接入层反向代理到该容器 |
gogs | - | - | Gogs 容器,在接入层反向代理到该容器 |
域名端口说明
需要宿主绑定 127.0.0.1 gogs.fe.com jenkins.fe.com
Hosts
-
宿主:80
- proxy 容器对宿主暴露的端口,可访问 Jenkins 、Gogs -
www.fe.com
- 接入层入口,在 user 容器中访问(curl
) -
gogs.fe.com
- Gogs 访问入口 -
jenkins.fe.com
- Jenkins 访问入口
发布配置
把 www1 的环境做为预发布环境,使用 Jenkins Pipeline 脚本,在发布时直接发布到预发环境,并等待,在一定时间(比如1天)之内,如果在全量面板点击继续,则全量发布(其实就是同步到 www2 环境,因为一共就2台)。
Gogs 配置
- 启动后创建一个用户,并把公钥( env/id_rsa.pub )添加到帐户的 SSH 中,主要用于 Jenkins 中克隆 Gogs 项目授权
- 创建一个仓库,并添加一个产出目录(
dist/
)和产出的一个测试文件(dist/index.html
),模拟编译之后的文件
Jenkins 配置
- 配置 Publish over SSH 插件,注意:
-
key
- env/id_rsa 密钥 -
hostname
- 容器的名称 -
-
- 创建一个用于 Git 克隆的凭证
-
- jenkinsfile
pipeline { agent any options { timestamps() } stages { stage('Clone code') { steps { git credentialsId: 'b94b24ac-b1d0-4e63-81f8-2f1d889bd475', url: 'git@gogs:xiaowu/webapp.git' } } stage('Run Build') { steps { echo '测试 build' } } stage('Deploy Pre-Release') { steps { sshPublisher(publishers: [sshPublisherDesc(configName: 'prd-1', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'nginx -v', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/app', remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/*')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) } } stage('Deploy All') { options { timeout(time: 3, unit: 'DAYS') } input { message '全量发布?' ok '发布' } steps { sshPublisher(publishers: [sshPublisherDesc(configName: 'prd-2', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'nginx -v', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/app', remoteDirectorySDF: false, removePrefix: 'dist', sourceFiles: 'dist/*')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) } } } post { always { deleteDir() } } }
验证
登录 user 容器去验证,其实就是模拟了用户终端,默认时绑定的 Hosts 为 192.168.1.100 www.fe.com
这是接入层,使用 curl www.fe.com
可以看到访问结果,当任务发布完成预发布时(在 Gogs 修改示例文件保存后,在 Jenkins 重新构建),构建会自动发布到预发布 www1 中,在 user 容器可以直接绑定 www1 的容器验证 192.168.1.101 www.fe.com
,验证通过后( curl www.fe.com
)可以全量上线。
难点
1. 应用层应当具备独立的服务
每个应用层自身应该可以独立访问,由接入层代理,那么应用层 Nginx 就需要多绑定几个 server_name
了,如:
-
www.fe.com
- 供直联应用层使用 -
prd_www*
- 供接入层upstream
配置
2. 需要给节点多配置执行者数量
因为等待中的任务也会占用节点执行者数量,如果少了多个并发任务可能就要凉凉。。。
其实这只是我对预发布、灰度发布、单台预发的一种探索,比如把测试、单台、全量拆成三个任务是否更合理?这就需要在实际项目中真实的应用并分析了。
接下来的目标:
- 快速回滚
- 应用 Docker 镜像发布
以上所述就是小编给大家介绍的《使用 Jenkins + Nginx 实现预发布》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 使用Akka实现并发
- 使用GOLANG实现猴子排序
- 使用 WebSocket 实现 JsBridge
- 使用 RabbitMQ 实现 RPC
- 使用Kafka实现事件溯源
- 使用 Swift 实现 Promise
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。