IT基础架构的自动化编排

npkijmmjhrs 8年前

来自: http://dockone.io/article/996

【编者的话】本演讲主要针对亚马逊公司的AWS公有云服务的IT基础构架,但是也适合搭建其他的虚拟环境,私有云,和公有云。

为什么需要自动化编排

那么首先要了解,为什么需要自动化编排 (orchestration)

  • IT环境可再生化 (Re-productable)
  • 基础设施代码化(Infrastructure as Code)
  • 应用易于配置(provision)和部署(deployment)
  • 可扩展性高
  • 稳定运行状态

说白点,作为DevOps 工程师,希望自己管理的系统,自动化程度越高越好。希望创建整个系统的时候,能有一键安装的能力。减少构建类似的开发(dev)、测试(stage)和生产(prod)环境的时间,避免重复劳动。 通过代码管理应用的配置。出问题的时候,也比较容易及时搭建类似环境(svt)做参考。

IT服务的应用构架

云服务的应用构架,分三层,分别是: 基础构架层 、服务层、应用层。

应用层包括了应用程序的代码和配置。服务层包括操作系统以及系统配置。

服务层和应用层这块的自动化已经很普遍,通常会用Puppet、Ansible、Chef、SaltStack之类的自动化配置软件管理。Docker 的流行,也使得应用的配置管理变得异常便捷。这个大家应该都很有经验了。 我就不展开了。

那么三层构架里就剩下基础设施层的管理了。

基础设施里包括了操作系统镜像、vpc、gateway、security gorup、subnets、自动扩展配置(scaling)、bastion(jumphost)、V*N等等。 如何创建一致的基础设施环境是DevOps工程师的一个主要职责。

所以,我们需要: IT基础构架的自动化。

IT基础构架的自动化

经过对多种工具的测试后,我公司用下面两个open source 工具来做自动化管理:

  • Packer - 专注于自动化创建镜像
  • Terraform - Infrastructure as Code

他们有几个共同点:

  • 用模版文件管理,可以版本控制(version control)和自动化。
  • 方便在不同的平台部署。
  • 都是同一家公司的产品 - HashiCorp。

HashiCorp这家公司也是Vagrant (个人开发环境搭建)和Docker常用的服务发现工具 Consul 的开发公司。

Packer - 专注于创建镜像

先介绍 Packer:

  • 支持多种平台。
  • 用于创建操作系统的机器镜像 (machine image),比如亚马逊的AMIs、Openstack images、Docker images、google computer engine、DigitalOcean、virtualbox、VMware,etc。
  • 用模版文件管理 (JSON 格式),方便版本控制和自动化。
  • 不但支持创建Linux的镜像,还可以制作Windows 的镜像。
  • 暂时不支持国内的云服务,比如阿里云之类的,个人有兴趣的话,可以参与开发和定制。

也就是说,配置好一个模版文件,用pakcer命令就可以按需构建机器镜像。也可以根据需求及时更改配置。 加入软件版本控制(主要用的是 Git)后,就可以很方便的追溯更改。

制作镜像的目的是什么呢? 制作更新的镜像文件可以减少操作系统升级的时间 (比如yum update),统一基本镜像的配置,定期打补丁,定制公司内部安全标准,以及安装配置必备应用(比如我个人偏好用 htop 替代 top 命令)。

有了pakcer,只需要了解这一个工具,就可以为不同平台创建系统镜像。这样的话,DevOps 工程师可以扩充自己的能力来随时应对不同的IT基础设施环境。

下面来看看一个简单的packer 的模版格式。

{    "variables": {    "aws_access_key": "",    "aws_secret_key": ""    },    "builders": [{    "type": "amazon-ebs",    "access_key": "{{user `aws_access_key`}}",    "secret_key": "{{user `aws_secret_key`}}",    "region": "us-east-1",    "source_ami": "ami-de0d9eb7",    "instance_type": "t1.micro",    "ssh_username": "ubuntu",    "ami_name": "packer-example {{timestamp}}"    }]    } 

这里例子里,第一个部分“variables”定义了变量, 变量也可以采用环境变量。 第二部分“builders”定义了如何创建新的镜像:环境是aws 的 EBS镜像, 所需要的api key, 源镜像,镜像创建的区域,实例大小,名字,用户名(不同的操作系统有不同的用户名,比如:ec2-user、Ubuntu、CentOS) ,等等。

{    "variables": ["..."],    "builders": ["..."],        "provisioners": [    {     "type": "file",     "source": "packer.sh",     "destination": "/tmp/packer.sh"    },    {     "type": "shell",     "inline": [         "sudo chmod +x /tmp/packer.sh",         "sudo bash -x /tmp/packer.sh",         "sudo rm /tmp/packer.sh"     ]        }        $ cat packer.sh        #!/usr/bin/env bash        apt-get -y update    apt-get -y install htop

“provisioners” 部分主要是用于在创建镜像时,需要在源镜像里执行的命令。 通常都是最基本的配置需求。 我喜欢将所有需要运行的命令都事先写进一个本地的shell脚本文件(packer.sh)里,随后复制到镜像里执行。

如果应用安装有需求的话,也可以安排在制作镜像的时候,重启几次。

如果你需要在镜像里缺省安装docker,将安装步骤写到packer.sh 里即可。

制作好 template 文件后,运行下面的命令就可以产生最新的镜像。

$ packer build \    -var 'aws_access_key=YOUR ACCESS KEY' \    -var 'aws_secret_key=YOUR SECRET KEY' \    example.json    ==> amazon-ebs: amazon-ebs output will be in this color.    ==> amazon-ebs: Creating temporary keypair for this instance...    ==> amazon-ebs: Creating temporary security group for this instance...    ...    ==> Builds finished. The artifacts of successful builds are:    --> amazon-ebs: AMIs were created:        us-east-1: ami-19601070

新的AMI (ami-19601070)就创建成功了,你可以登录到AWS管理界面里确认。

packer 的具体使用,请参阅packer网站的文档: https://www.packer.io/docs 。有些基本的技巧,比如跳转服务器(jumphost)的设置,镜像命名的方式,我专门在GitHub上做了个 软件仓库 ,你们可以用来参考。

镜像制作好了,我们就需要构建整个IT的基础设施了。

Terraform - Infrastructure as Code

下面介绍第二个工具: Terraform。

Terraform 的发音类似于电话(telephone)的英文发音,只要把 r 和 l 区分好就可以了。

那么Terraform 可以用来干什么呢?

  • Infrastructure as Code。
  • 高效安全的部署IT基础构架。
  • 可以持续更改/迭代基础设施。
  • 配置用模版文件管理,便于版本控制。
  • 语法简单,可读性很高。
  • 支持主流的虚拟环境或者云服务,国内的云服务产品暂时不在其支持的列表。
  • 不同的虚拟环境或者云服务,一个工作流程。
  • AWS cloudformation 的绝佳替代品。
  • 方便地模拟,创建,更改,销毁部分或者整个IT基础构架。

Terraform用于创建,管理基础设施资源。 Terraform的最大优势就是,基础设施的代码化。将项目涉及到的所有资源:vpc、网关(gateway)、 security gorup、subnets、自动扩展配置(auto-scaling)、bastion(jumphost)、V*N、 ec2、elastic load balancer、route 53、 rds、ses、sns等等,都写在一个配置模版文件里。

可能很多人会提到AWS CloudFormation,也可以实现AWS基础设施的代码化。 但是CloudFormation 模版文件实在是太复杂了,更改时很容易出错。 随着服务资源的增加,CloudFormation文件会变的很长,越来越难读。

相对于Terrraform的模版文件,行数就少很多,而且代码通俗易懂。

Terrraform 还有另一个优势, 在管理不同的平台时,无需学习新知识。Terrraform支持多种基础平台。IaaS(例如AWS、DigitalOcean、GCE、OpenStack的),PaaS的(Heroku、CloudFoundry)或SaaS服务(Atlas、DNSimple、CloudFlare的)。

对DevOps 工作人员来说,这是个很给力的功能。 公司的需求一直会变,外部的环境也会变,云服务的价格和服务也在变。 如果想对市面上所有主流的云产品都能精通,个人可能没有那么多时间去一一了解,如果一直被亚马逊云牵着鼻子走,可能会比较被动。公司要找样样精通的大牛也会消耗太高的招人成本。开发人员也可以腾出更多的时间专注于产品的开发实现上。

至于有些公司会有混合云的需求,Terraform也能很好的提供支持。

下面介绍Terraform 的几个基本命令使用:

plan 模拟

apply 构建和改变

destroy 销毁

provider "aws" {    access_key = "ACCESS_KEY_HERE"    secret_key = "SECRET_KEY_HERE"    region = "us-east-1"    }        resource "aws_instance" "example" {    ami = "ami-408c7f28"    instance_type = "t1.micro"    }        $ terraform plan    ...    + aws_instance.example    ami:               "" => "ami-408c7f28"    availability_zone: "" => "<computed>"    instance_type:     "" => "t1.micro"    key_name:          "" => "<computed>"    private_dns:       "" => "<computed>"    private_ip:        "" => "<computed>"    public_dns:        "" => "<computed>"    public_ip:         "" => "<computed>"    security_groups:   "" => "<computed>"    subnet_id:         "" => "<computed>"     

”terraform plan“ 并不会改变系统,只是展示将要更改的资源。如果确认后,运行”terraform apply” 来实施改变。

上面的模版文件里定制了一个简单ec2实例。

你也可以在创建ec2实例时,加入userdata,就是第一次启动时需要运行的命令。 也可以加入其他的资源,比如vpc、subnet、security groups、s3、rds,etc。

该产品还处在开发阶段,基本功能够用了,但不能够实现所有的aws 的功能。另一个原因是,AWS 发展太快,新服务层出不穷,开源社区的开发人员跟不上。

那么我们来看看具体实施的命令。

$ terraform apply    aws_instance.example: Creating...    ami:           "" => "ami-408c7f28"    instance_type: "" => "t1.micro"        Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

可以看到,一个新的资源创建了。这里是一台新的ec2 实例。

也可以销毁, 先试运行一下:

$ terraform plan -destroy    ...    - aws_instance.example

确认后,删除。

$ terraform destroy    aws_instance.example: Destroying...        Apply complete! Resources: 0 added, 0 changed, 1 destroyed.        ...

删除和模拟删除时,可以添加参数来控制要删除的部分资源还是全部资源。

具体Terraform 的使用,请参考 https://www.terraform.io/docs/index.html

和前面packer一样,我在同一个GitHub软件仓库里,做了个简单可用的vpc构建模版给你们 参考

总结与链接分享

引进了packer 和Terraform后,整个自动化编排就成了如下的流程:

Packer (machine images) -> Terraform (构建基础构架)-> puppet/ansible/chef/Docker(操作系统和应用的配置管理)

整个流水线上,都可以自动化了。

分享些其他的相关链接:

Q&A

Q:Terraform 建立EC2时怎么用之前构建好的镜像?

A:例子中, "source_ami": "ami-de0d9eb7" 就是引入源镜像。

Q:packers感觉就是镜像的封装,不知道描述是否贴切,它与kickstart有什么不同?

A:可以理解为封装。kickstart 更像userdata。

Q:这个Terraform构建基础架构是否可以理解为基础应用环境的搭建?

A:是基础设施(Infrastructure) 的搭建。

Q:請問如果在AWS主要服務運行在ECS ElasticBeanstalk 甚至API Gateway、Lambda這些stack,是否這些工具就不適用了?

A:ElasticBeanstalk 本身已经是高度自动化了。 但是 lambda支持。 具体可以查看: https://www.terraform.io/docs/ ... .html

Q:Windows系统也可以用packer制作镜像,底层需不需要虚拟化?

A:可以在源镜像上扩展,也可以直接用操作系统的iso文件制作。

Q:请问这里面介绍的模板与heat的模板通用么?

A:我没有用过heat。 但是这里有个专门的比较: https://www.terraform.io/intro ... .html

Q:我现在用的技术栈也是基于 vagrant+packer+terraform,上面讲到Terraform 不支持 AWS VPC Peering 这一点是不正确的,因为我现在已经在使用了,可能您使用的版本比较老。

A:Terraform里的原话: You still have to accept the peering with the AWS Console, aws-cli or aws-sdk-go.( https://www.terraform.io/docs/ ... .html )。

Q:这个Terraform是否可用于管理CPU、内存等资源?

A:可以定义和更新需要的资源类型 (instance type),不同的instance type 代表不同的CPU和内存。

Q:用packer制作一次镜像能用于生产测试各环境运行吗,不同环境配置参数可能不同,packer如何支持一次打包到处运行的问题?

A:你可以按需定制不同的模版文件和制作不同的镜像。

Q:packer 和 vagrant 使用起来感觉很像呀,他们的主要区别是啥 ?

A:你说的是vagrant box 吧, packer 是可以用来创建 vagrant box 的。具体参考 https://www.packer.io/intro/ge ... .html

Q:可以简单介绍一下您认为最好用的服务层和应用层的自动化工具,以及原因。

A:这个话题很大。 主流的话,就是Puppet、Ansbile、Chef、SaltStack。 我们公司用Puppet 来管理系统配置,用Ansible管理应用级别的配置。因为系统配置改变相对较少,我们是level 4 engineering team,用Puppet 统一管理不同的云服务(AWS和公司内部的私有云)的系统配置。 但是Puppet 相对来说,学习曲线要比ansbile困难很多。 对应用的管理,需要较多的修改,BAU(运维)团队比较容易支持。所以选用ansible 做自动配置管理。

Q:自动化编程能实现0运维吗?

A:还是需要DevOps(自动化运维)

Q:基础设施可以理解为中间件?JVM对于Hadoop来说是基础设施?这样理解正确吗?

A:对我来说,jvm 和hadoop都属于应用层的。

Q:packer制作镜像,使用本地shell脚本文件来执行命令感觉调试困难,因为命令有错的话如何方便配合用户修改?不会是让用户看日志然后改脚本从头重试,再错再试,如此反复吧?很低效哦。

A:有很多方法。但是写脚本是最直接的。 镜像的制作确实需要不断调试的过程。 这是DevOps工作的一部分。 通常你将制作好的镜像告诉开发人员即可。

Q: 脚本里直接使用apt-get,会不会导致不同时间创建的基础设施上软件版本出现不一致?你们考虑过自建软件源保证一致性吗?

A:这就是用packer 的好处。 你可以阶段性的产生不同的镜像,不会覆盖以前的。 然后新镜像需要在dev/uat 环境下测试。过关后,才可以用于生产环境。 镜像制作完后,里面的内容不会改变了。

Q:可以对创意的资源健康状况进行监控么?一旦有异常,会有自愈策略么?

A:Terraform里有部分支持的。比如某个security group 的inbound 规则有改变,运行 terraform plan 是可以看到有资源被修改。 如果运行实施的话,会修复的。

Q:编排的时候有没有把类似监控nagios sensu 之类agent的考虑在内?

A:这个属于应用层的配置,归自动化配置管理工具,比如puppet/ansible 来管理。

Q:按照您的回复,不同时间创建的镜像还是存在某些包版本不一致,您有针对性的测试方法推荐吗,还是在uat环境应用没问题就直接上生产使用了?

A:我们暂时是这样使用的。dev/uat 环境下运行正常就推到生产环境。 如果出了问题,也可以快速回滚。公司允许我们承担这个风险的。

Q: Terraform在AWS使用play apply等创建实例时候,只支持单个AMI镜像么?如果想要同时配置多个不同镜像的实例,该怎么办?

A:不是的,可以创建任意多个。在创建不同的ec2实例时,指定不同的源镜像即可。

Q:你们有没有类似cmdb将所有的资源包括虚拟机的信息放在一个统一的数据库里。 另外,你们有用服务发现吗?用的什么软件做服务发现? 怎么做的集成?

A:Terraform 的模版文件做的就是做这个事情啊。 针对第二个问题,服务发现属于应用层的。 当然你可以在定制terraform 实例资源里的userdata时,加一条 服务发现的命令即可,这样该实例启动后,发现服务自然就注册了这个新的实例了。

Q:用模版文件管理是如何进行版本控制(version control)的?

A:就是用Git 。 将Template 文件存到Git 里, 可以是内部的Git服务器,比如我们公司用的atlassian stash, 也可以用GitHub之类的 。

Q:这个自动化部署的工具,嘉宾有实践过通过PaaS调用,并且部署成功吗?

A:没有。 AWS属于IaaS。

===========================

以上内容根据2016年1月26日晚微信群分享内容整理。分享人 王云祥,DevOps工程师,现任职于澳洲电信,专注IT自动化解决方案,持有Puppet和AWS认证。 DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesz,进群参与,您有想听的话题可以给我们留言。