早期 Segment 基础架构广泛组合在一块儿。咱们经过 AWS 界面设定实例,使用许多闲散的 AMI,而且采用三种不一样的部署方式。html
然而随着商业的飞速发展,工程师团队的规模不断扩大,基础架构的复杂度也不断提升。提升生产效率的方法仍旧只在一小部分人中间传播,虽然生产效率在不断提升,可是若是想一直保持高速增加,还要全面修整基础架构。python
所以,几个月前,个人团队一块儿讨论:「若是今天从新设计基础架构,会是怎样一种结构?」。git
10个星期后,咱们完全重构了基础架构。咱们放弃了几乎全部实例与旧的配置,将咱们的服务转移到 Docker 容器中运行,而且转而使用全新的 AWS 帐号。github
在此咱们花了很长时间思考如何将产品架构变得简单、易用且可审计,同时保留扩展的灵活性。docker
如下是咱们的解决方法。数据库
咱们并不使用 Region 和 Tag 来区分不一样的阶段如预发布环境和生产环境,而是使用彻底不一样的 AWS 帐号。咱们必须保证设定脚本不会影响正在运行的服务。同时,新的帐号就像白纸同样,能够从新开始。ubuntu
此处,ops
帐号做为跳跃点和集中登录点。公司内的每一个人有一个 IAM 帐号用于登录。安全
其余环境有一组 IAM 角色能够相互切换。这意味着,管理帐号只有一个登录点,也只有一个位置限制访问。服务器
好比:Alice 可能拥有全部三个环境的访问权,但 Bob 只能访问 dev(若是他删除生产负载均衡器的话)。可是,他俩均可以进入 ops
帐号。架构
如今,不须要复杂的 IAM 设定以限制访问权限,咱们能够经过环境查看用户通 role 进行分组。在界面使用各个帐户就像切换当前活跃用户同样简单。
咱们无偿地实现了真正的隔离,不需额外的配置,无须担忧预发布环境的安全性,或它对生产环境数据库的改动。
可以共享配置代码的另外一个好处是如今的 预发布环境成为了一个镜像。在配置上惟一的不一样是实例的大小和容器的数量。
最后,咱们也启用了各个帐户之间统一计费。每月咱们用同一张发票付费,同时能按照环境查看费用明细。
帐户设定完毕后,就该设置服务的运行方式了。为此,咱们使用了 Docker 与 EC2 容器服务(ECS)。
现现在,咱们大多数的服务都运行在 Docker 容器内,包括 API 与数据管道。容器每秒钟接受成千上万次请求,每月处理500亿事件。
Docker 的最大好处在于它使团队可以从零开始搭建服务。咱们再也不有一套复杂的设定脚本或 AMI ,咱们只要给生产集群提供一张镜像就好了。无需状态性的实例,咱们能保证在预发布环境和生产环境运行如出一辙的代码。
设定服务在容器中运行后,咱们选择 ECS 为调度器。
在一个高水平上,ECS 实际负责在生产环境下运行容器。它负责调度服务、将它们置于不一样的主机中,在与 ELB 关联时零宕机重载。它甚至能够跨多个 AZs,从而达到更佳可用性。若是一个容器宕机了,ECS 会确保该容器在集群中的新实例上重启。
切换到 ECS 以后,极大地简化了运行服务的过程,无需再担忧启动任务或设定实例。由于它很简单,只须要添加一个 Dockerfile,设定 task,再将其与集群关联便可。
在咱们的配置中,Docker 镜像由 CI(持续集成) 构建,以后推送到 Docker Hub。当某项服务启动时,它从 Docker Hub 获取镜像,以后 ECS 在各个机器间调度之。
咱们依照集群涉及的组件与负载间档对他们分组(不一样的集群用于不一样的 API、CDN、App 等)。不一样的集群意味着咱们可见性更高,能为其配置不一样的实例类型( ECS 没有实例关联度的概念)。
每项服务都包含一个特别的任务用于指明容器版本,运行的实例数量,以及该选择的集群类型。
在运行时,服务会自行注册 ELB,同时使用健康检查肯定容器是否能够运行。咱们在 ELB 指定一个本地的 Route53,所以各个服务能相互通讯,经过 DNS 就能相互引用。
由于不须要任何服务搜索,因此设置很是顺利。本地的 DNS 帮助咱们记录一切。
ECS 运行全部服务,咱们经过 ELB 就能获取免费的云监控测量数据。这比在启动时就要在中央注册服务要简单的多。并且,更棒的是,咱们中央不须要再面对状态冲突了。
Docker 与 ECS 负责实现运行每一项服务,Terraform 是将他们联合在一块儿的胶水。在高水平上,一系列脚本负责建立并更新基础架构。你能够将其想做一个 Cloudformaition 模版,除了它不会让你想自戳双目。
如今,无需运行一系列服务器以维护状态,只需一些脚本用来描述集群。配置在本地运行(将来经过 CI 运行),提交到 git 上。所以,咱们能获得一系列记录,可以了解生产环境中基础构架的实际状况。
如下是咱们的 Terraform 模板中设置 bastion 结点的样本代码。该代码建立全部的安全组,实例和 AMI,所以咱们能够简单地为将来的环境设定跳跃点。
// Use the Ubuntu AMI module "ami" { source = "github.com/terraform-community-modules/tf_aws_ubuntu_ami/ebs" region = "us-west-2" distribution = "trusty" instance_type = "${var.instance_type}" } // Set up a security group to the bastion resource "aws_security_group" "bastion" { name = "bastion" description = "Allows ssh from the world" vpc_id = "${var.vpc_id}" ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags { Name = "bastion" } } // Add our instance description resource "aws_instance" "bastion" { ami = "${module.ami.ami_id}" source_dest_check = false instance_type = "${var.instance_type}" subnet_id = "${var.subnet_id}" key_name = "${var.key_name}" security_groups = ["${aws_security_group.bastion.id}"] tags { Name = "bastion-01" Environment = "${var.environment}" } } // Setup our elastic ip resource "aws_eip" "bastion" { instance = "${aws_instance.bastion.id}" vpc = true }
咱们在预发布环境与生产环境中使用一样的模板设置单个 bastion。惟一须要修改的是 IAM 键。
修改也很是简单,不须要修改整个基础架构,Terraform 会在须要的时候更新内容。
当咱们要将 ELB 超时时间改成60秒时,只需经过 terraform apply
简单地查找/替换就好。两分钟以后,咱们的 ELB 生产环境就彻底改变了。
并且,这是可复制、可审计且自文档化的,每一步都是可见的白盒操做。
咱们将全部配置都放在一个中心的 infrastructure
库,这样很容易看清某一项给定的服务是如何配置的。
到目前为止,咱们还未讲到核心部分。咱们但愿利用模板转变动多的 Terraform 配置,联合独立文件从而减小共享文件的数量。
同时,咱们也发现了有关 .tfstate
的一些陷阱。Terraform 老是先从现存的基础架构读取数据,若是状态不一样步就会报错。最后,咱们将 .tfstate
放到库中。咱们但愿能经过 Atlas 或使用 CI 来解决该问题。
至此,咱们已经搭好了基础架构,开通了服务,作好了必要的隔离。最后要作的是监控生产环境中全部运行程序。
在新环境中,咱们将全部的监控和指标都用 Datadog 进行。不夸张的说 Datadog 真的棒极了!
咱们对 Datadog 的界面,API 以及其和 AWS 的整合都很是满意。可是,想要彻底利用这个工具,还须要一些关键的设置。
首先,咱们与 AWS 和 Cloudtrail 进行整合。这能使咱们全面了解环境中的全部状况。因为咱们已经与 ECS 整合过了,Datadog feed 会在任务内容更新时自动更新,因而咱们能在部署放生改变时获得免费通知。搜索 feed 的过程也异常快捷,能轻松找到最近一次的服务部署或从新调度。
接下来,咱们确保将 Datadog-agent 做为 AMI 基础容器(datadog/docker-dd-agent)。它不只会从主机( CPU,内存等)收集测量数据,也做为存储 statsd 测量数据的容器。每一项服务都会收集关于查询、潜伏、错误的自定义指标,所以咱们能够在 Datadog 中进行探索,得到警告等。咱们的 go 工具箱(很快就会开源)会自动收集并在 ticker 输出 pprof
,所以达到监控内存与 goroutines 的目的。
更酷的是,该探针可以图形化展现环境中多个主机间的实例利用状况,所以咱们能从更高角度了解可能出问题的实例或集群:
此外,个人队友 Vince 写了一个针对 Datadog 的 Terraform,所以咱们能够针对实际的生产配置设置报警脚本。咱们的报警会被记录,同时与生产环境中运行的程序保持同步。
按照惯例,咱们会设定两种报警级别:预警
与重要警告
。预警
使线上的工程师了解任何可疑的问题,会在潜在问题发生之前发出。重要警告
则是会在半夜把你喊起来的严重系统宕机。
此外,当咱们完成向 Terraform 模块的转移,将 Datadog 提供程序加到服务描述层以后,全部的服务都会免费得到告警。这些数据都是由内部工具箱与 Cloudwatch 指标驱动的。
当全部的组件都准备就绪后,切换的日子终于到来了。
首先,咱们会在新的生产环境与原有环境间创建 VPC 对等链接——从而集群化数据库并在二者间进行复制。
其次,咱们预热新环境中的 ELB 使之可以承受新的负载。亚马逊没法提供自动更改大小的 ELB,所以咱们不得不提早为其扩容以应对增长后的负载。
以后,咱们只需使用加权的 Route53 路由平稳地将流量从旧环境导向新环境,而且持续监控确保一切正常。
如今,咱们的 API 每秒处理成千上万次请求,而且彻底运行在 Docker 容器内。
可是还没完,咱们还在优化服务的建立方式,减小引用,使得团队中的任何人都能简便地建立服务,同时包含适度的监控与预警系统。此外,咱们还想优化容器周边的工具,由于如今的服务已再也不围绕实例进行了。
咱们还会关注这一领域很有发展的技术。Convox 团队真正建立围绕 AWS 基础架构的强大工具。尽管咱们很喜欢 ECS 的简单与集成,但 Kubernetes 、Mesosphere、 Nomad 与 Fleet 这些都是很是不错的调度器。咱们很期待看到他们的后续发展,并会考虑选择一二进行使用。
经历全部这些编排变化以后,咱们比之前更加相信将基础构架外包至 AWS 的策略。他们产品化了许多核心服务,彻底改变了游戏规则,并且维持了一个极具竞争力的价格。这使得愈来愈多的初创企业可以高效、低成本低开发产品,同时在维护上节省时间。咱们至关看好这些创建在基础生态系统之上的工具。
原文 Rebuilding Our Infrastructure with Docker, ECS, and Terraform 做者 Calvin French-Owen,本文由 OneAPM 工程师翻译整理。
OneAPM 可以帮你查看 Python 应用程序的方方面面,不只可以监控终端的用户体验,还能监控服务器性能,同时还支持追踪数据库、第三方 API 和 Web 服务器的各类问题。想阅读更多技术文章,请访问 OneAPM 官方技术博客。
本文转自 OneAPM 官方博客