k8s容器灰度发布最佳实践(基于spinnaker)
k8s中的容器一般是通过deployment管理的,那么一次滚动升级理论上会更新所有pod,这由deployment资源特性保证的,但在实际的工作场景下,需要灰度发布进行服务验证,即只发布部分节点,这似乎与k8s的deployment原理相违背,但是灰度发布的必要性,运维同学都非常清楚,如何解决这一问题?
最佳实践:
定义两个不同的deployment,例如:fop-gate和fop-gate-canary,但是管理的pod所使用的镜像、配置文件全部相同,不同的是什么呢?
答案是:replicas (灰度的fop-gate-canary的replicas是1,fop-gate的副本数是9)
cat deployment.yaml apiVersion: apps/v1beta1 kind: Deployment metadata: {{if eq .system.SERVICE "fop-gate-canary"}} name: fop-gate-canary {{else if eq .system.SERVICE "fop-gate"}} name: fop-gate {{end}} namespace: dora-apps labels: app: fop-gate team: dora type: basic annotations: log.qiniu.com/global.agent: "logexporter" log.qiniu.com/global.version: "v2" spec: {{if eq .system.SERVICE "fop-gate-canary"}} replicas: 1 {{else if eq .system.SERVICE "fop-gate"}} replicas: 9 {{end}} minReadySeconds: 30 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 template: metadata: labels: app: fop-gate team: dora type: basic spec: terminationGracePeriodSeconds: 90 containers: - name: fop-gate image: reg.qiniu.com/dora-apps/fop-gate:20190218210538-6-master ...........
我们都知道, deployment 会为自己创建的 pod 自动加一个 “pod-template-hash” label 来区分,也就是说,每个deployment只管理自己的pod,不会混乱,那么此时endpoint列表中就会有fop-gate和fop-gate-canary的pod,其他服务调用fop-gate的时候就会同时把请求发到这10个pod上。
灰度发布该怎么做呢?
最佳实践:创建两个不同pipeline,先灰度发布fop-gate-canary的pipeline,再全局发布fop-gate的pipeline(这里给出的是渲染前的配置文件,注意pipeline不同):
"fop-gate": "templates": - "dora/jjh/fop-gate/configmap.yaml" - "dora/jjh/fop-gate/service.yaml" - "dora/jjh/fop-gate/deployment.yaml" - "dora/jjh/fop-gate/ingress.yaml" - "dora/jjh/fop-gate/ingress_debug.yaml" - "dora/jjh/fop-gate/log-applog-configmap.yaml" - "dora/jjh/fop-gate/log-auditlog-configmap.yaml" "pipeline": "569325e6-6d6e-45ca-b21e-24016a9ef326" "fop-gate-canary": "templates": - "dora/jjh/fop-gate/configmap.yaml" - "dora/jjh/fop-gate/service.yaml" - "dora/jjh/fop-gate/deployment.yaml" - "dora/jjh/fop-gate/ingress.yaml" - "dora/jjh/fop-gate/log-applog-configmap.yaml" - "dora/jjh/fop-gate/log-auditlog-configmap.yaml" "pipeline": "15f7dd6a-bd01-41bc-bac5-8266d63fc3a5"
注意发布的先后顺序:
灰度发布完成后,可以登陆pod查看日志,并观察相关的grafana监控,查看TPS2XX和TPS5XX的变化情况,再决定是否继续发布fop-gate,实现灰度发布的目的
➜ dora git:(daixuan) ✗ kubectl get pod -o wide | grep fop-gate fop-gate-685d66768b-5v6q4 2/2 Running 0 15d 172.20.122.161 jjh304 <none> fop-gate-685d66768b-69c6q 2/2 Running 0 4d21h 172.20.129.52 jjh1565 <none> fop-gate-685d66768b-79fhd 2/2 Running 0 15d 172.20.210.227 jjh219 <none> fop-gate-685d66768b-f68zq 2/2 Running 0 15d 172.20.177.98 jjh322 <none> fop-gate-685d66768b-k5l9s 2/2 Running 0 15d 172.20.189.147 jjh1681 <none> fop-gate-685d66768b-m5n55 2/2 Running 0 15d 172.20.73.78 jjh586 <none> fop-gate-685d66768b-rr7t6 2/2 Running 0 15d 172.20.218.225 jjh302 <none> fop-gate-685d66768b-tqvp7 2/2 Running 0 15d 172.20.221.15 jjh592 <none> fop-gate-685d66768b-xnqn7 2/2 Running 0 15d 172.20.133.80 jjh589 <none> fop-gate-canary-7cb6dc676f-62n24 2/2 Running 0 15d 172.20.208.28 jjh574 <none> ➜ dora git:(daixuan) ✗ kubectl exec -it fop-gate-canary-7cb6dc676f-62n24 -c fop-gate bash root@fop-gate-canary-7cb6dc676f-62n24:/# cd app/auditlog/ root@fop-gate-canary-7cb6dc676f-62n24:/app/auditlog# tail -n5 144 | awk -F'\t' '{print $8}' 200 200 200 200 200
此外,spinnaker具有发布具有pause、resume、undo功能,实际测试可行
pause 暂停功能(类似于kubectl rollout pause XXX的功能)
resume恢复功能(类似于kubectl rollout resume XXX的功能)
undo取消功能(类似于kubectl rollout undo XXX功能)
spinnaker的这几种功能可以在正常发布服务的过程中发现问题,及时暂停和恢复,注意,spinnaker取消发布一定是针对正在发布的操作,pause状态中的发布无法取消,这与kubectl操作一致
我们尝试执行一次,发布,暂停,恢复,取消 操作,整个过程会产生4个version,每次变动会对应一个新version,因为不管是暂停还是恢复,在spinnaker中都将认为是一次新的发布,会更新version版本
总结:k8s中灰度发布最好方法就是定义两个不同的deployment管理相同类型的服务,创建不同的pipeline进行发布管理,避免干扰,同时在正常发布过程中,也可以利用spinnaker的pause,resume,undo等功能进行发布控制。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
超详细:自动化运维之jumpserver堡垒机入门到掌握
测试推荐环境 CPU: 64位双核处理器 内存: 4G DDR3 数据库:mysql 版本大于等于 5.6 mariadb 版本大于等于 5.5.6 环境 系统: CentOS 7 IP: 192.168.0.230 设置 selinux 和防火墙 [root@web1 ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pf...
- 下一篇
JAVA基础学习之-AQS的实现原理分析
AbstractQueuedSynchronizer是JUC的核心框架,其设计非常精妙。 使用了Java的模板方法模式。 首先试图还原一下其使用场景:对于排他锁,在同一时刻,N个线程只有1个线程能获取到锁;其他没有获取到锁的线程被挂起放置在队列中,待获取锁的线程释放锁后,再唤醒队列中的线程。 线程的挂起是获取锁失败时调用Unsafe.park()方法;线程的唤醒是由其他线程释放锁时调用Unsafe.unpark()实现。由于获取锁,执行锁内代码逻辑,释放锁整个流程可能只需要耗费几毫秒,所以很难对锁的争用有一个直观的感受。下面以3个线程来简单模拟一下排他锁的机制。 import sun.misc.Unsafe; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.LockSupport; public class AQSDemo { private static final Unsafe unsafe = g...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7安装Docker,走上虚拟化容器引擎之路
- SpringBoot2全家桶,快速入门学习开发网站教程
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2整合Thymeleaf,官方推荐html解决方案