在过去一年内,Descomplica 计划往核心组件服务化的方向发展,咱们一开始使用 Elastic Beanstalk 将这些服务编排到 AWS。html
那时候来讲,这个决定是明智的。整体来讲,Elastic Beanstalk 挺好用的,并且比较容易学习;全部小组为他们各自的项目使用,也不会花费太多时间。前端
早在几个月以前,一切都还运行得好好的。可是在一些旧问题解决以后,新的问题接踵而至。数据库
在 Elastic Beanstalk,每一个 EC2 实例只运行一个应用程序容器。这也就意味着,若是你遵循可靠性最佳实践,一个应用程序就会有两个或者多个实例(跨越部署在多个可用域)。除了生产环境,若是你还有其余环境的话(好比预生产环境),那么你可能就须要更多实例。网络
不管如何,你都要为每一个服务根据不一样的工做负载部署多个专用实例,而且大部分时间这些实例都很闲。负载均衡
咱们须要找到一个方法更加明智地使用咱们的可用计算资源。工具
后来咱们才发现,Kubernetes 就是咱们一直在寻找的 ECS 的替代品。post
Kubernetes 是一个容器编排工具,创建在谷歌 15 年运行产品的基础之上,与最佳想法、社区实践相结合。学习
虽然 Kubernetes 是一个功能丰富的项目,可是只有其中的几个关键功能引发了咱们的注意:命名空间,自动滚动升级和回滚,经过 DNS 的服务发现,基于资源使用的容器自动扩容,以及,允诺的自我修复系统。测试
Kubernetes 围绕“容器应该如何被组织,如何经过网络联络”的理念,可是若是你的服务是听从 Twelve-Factor 实践的,那么这个理念对你来讲也不是什么问题。spa
为了确保 Kubernetes 是个可行的选择,咱们作的第一件事就是作些可靠性测试来确保它可以处理“不可用节点,Kubelet/Proxy/Docker daemons 终止,和可用区域运行中断”这类的故障模式。
预测全部的故障,这是不太可能的,可是最后,咱们仍是被 Kubernetes 解决这些故障的能力深深折服。
那时候,咱们用 kube-up 来建立咱们的测试集群。虽然这个工具按照它的目标来服务,但不是每一次都符合预期;它暴露出了很是多的问题,好比说不合理的默认设置,随机超时致使没有彻底建立成功的程序栈,以及在删除集群时不肯定的行为致使一些资源的遗留。
那时候咱们一致赞成要选择用 Kubernetes,因此咱们须要一个更加可靠的方法来建立或者删除 Kubernetes 集群。
使用“kube-aws”
Kube-aws 这个工具是由 CoreOS 的几我的建立的。它最厉害的地方在于,在 hoods 下,使用 CloudFormation,这对于咱们来讲有利无弊。
最显著的优势就是,用这个工具建立或者删除集群十分容易,并且删除后还不会留下任何的遗留。
另外一个功能在于,与 kube-up 不一样,你能够在已经存在的 VPC 上建立集群,这样全部运行在 Kubernetes 上的服务均可以当即访问你的 AWS 资源(好比关系型数据库)。
事实上,你能够同时在同一个 VPC 上运行多个集群。这样就会带来一个良性的反作用,就是你能够把每一个集群都当作是不变的基础设施,你不须要修改正在运行的集群——冒着破坏其中一些什么的风险,你只须要建立一个新的集群,而后用影响最小的方法慢慢地把流量从旧集群转移到新集群。
最后一个功能(也多是最有用的一个),你能够经过配置轻松定制集群的任何方面来知足你的需求。在咱们的这个案例中,咱们添加集群层面的日志记录,摄取应用程序日志到 Sumologic,用 InfluxDB 和 Grafana 进行集群监控,基于 ABAC 的受权认证,以及一些其它的事情。
第一个环境
在解决了集群建立,集群删除问题以后,咱们有信心开始着手迁移咱们的预生产环境到 Kubernetes了。
为第一个 Deployment 手动建立 yaml 配置十分简单,可是咱们须要自动化地在应用镜像被持续集成系统构建完毕以后当即进行部署。
为了证实这个概念,咱们很快在 AWS Lambda(基于这篇文章)开辟了一个小的功能,这个功能能够在它收到一个测试经过了的合并通知,自动升级相应的部署单。
这个小 Lambda 功能如今涉及到咱们的交付管道,也编排 deployments 到其它环境,包括生产环境。
有了这个,将预生产环境服务从 Beanstalk 迁移到 Kubernetes 就至关容易了。首先,咱们为每一个服务(一开始指的是在 Elastic Beanstalk 上遗留的部署)都建立了 DNS 记录,确保全部的服务都是经过这个 DNS 互相访问的。而后,就只要修改这些 DNS 记录来指向相应的 Kubernetes 管理的负载均衡器。
为了确保管道的每一个部分都按照预期的来运行,咱们监控全部的预生产环境部署,寻找 bug,而后尽咱们所能地修复它,完善功能。
测试得越多,学习到得越多
在部署咱们的第一个产品服务到 Kubernetes 以前,咱们作了一些压力测试,来找到每一个服务最佳的资源需求配置,也为了找出咱们须要多少 pods 才能够支撑住目前的流量。
观察你的 services 在负载下是如何工做的,以及他们须要多少计算量。
一样,花些时间来理解 Kubernetes 的服务质量等级,这样你就能够更好地控制哪个 pod 在内存压力下会被终止掉。若是你跟咱们同样,跟全部环境都分享了同一个集群,那么这一点对你来讲相当重要。
提示:启动 Cross-Zone Load Balabcing(AWS)
这一点在 Kubernetes1.4 中已经修改,可是如今,若是你经过 LoadBalancer type 来暴露你的服务,不要忘记为相应的 ELB 手动启动 cross-zone load balancing;若是你没有这么作,你应该会发现分布在不一样的可用域当中的应用 pod 的负载不均衡。
提示: 多了解 kube-system
若是你曾经尝试用过 Kubernetes,你可能就会注意到 kube-system namespace 上有很是多的东西;花点时间来理解它们的意义。好比,拿 DNS add-on 来讲;常常能看到人们遇到 DNS 问题,由于他们忘记了随着负载增加而要增长更多的 DNS Pod。
上线
不要当即转换全部的流量,就如同咱们在预生产环境中所作的,咱们想的是,须要采起一个更加仔细的方法,用加权路由规则,慢慢转换流量到 Kubernetes 集群。
一旦咱们注意到已经没有请求能够到达遗留的 Beanstalk 环境了,咱们就继续向前,而且终止他们。
2016,9月21日更新内容:全部主要的服务都已经被迁移到咱们新的平台啦!
如下是最终数字:
每个月减小约53-63%开销
实例的数量减小72-82%
Kubernetes 能够用绝不费力的方式塑造交付管道,这是咱们想都不敢想的体验。咱们的开发环境就是这样的一个例子。
不管何时有人打开了 Pull Request 给咱们一个项目,我以前提到的 AWS Lambda 功能就会建立一个临时环境运行 PR 当中修改后的代码。
一样,不管何时 push 新的代码,一旦他们经过测试,这个环境就会自动更新。最后,当 PR 被合并(或者关闭),环境也就被删除了。
这个功能使得咱们的代码审查更加完全,由于开发人员可以看到修改的东西在运行。这对于前端服务的 UX 来讲就更有价值了;设计师和产品经理有机会看到修改生效,也能够在 PR 合并以前验证修改和分享想法。为了要发送 Github Status 通知,能够看到这些图片中,咱们用 Go 实现了一个守护进程,来监控到开发环境的部署并不断更新各个版本的部署状态。
Kubernetes 是一款很复杂的软件,旨在解决复杂的问题,因此在把它用到你的项目以前要先花点时间了解一下它的那些功能是如何有条理地运行在一块儿的。
Kubernetes 是为生产准备的,因此要避免受到诱惑,不要尝试在它上面运行全部的东西。在咱们的经验里,Kubernetes 并无给可能遇到的一系列问题提供简单有效的统一方法,好比说有状态应用。
其实文档也不怎么样,可是好比 Kubernetes Bootcamp 以及 Kelsey Hightower 的《Kubernetes The HardWay》给了我但愿,相信在不远的未来这些都将不是问题。
若是没有 Kubernetes,我不知道咱们这个小团队要怎么在这么短的时间内解决这么多的问题。咱们但愿继续在 Kubernetes 上工做,确保交付平台更加有活力,更赞!
原文连接 转载请联系咱们 -3-