如何使用AWS和Rancher搭建弹性应用栈

我们曾经分享过在使用Docker、Rancher和各种开源工具时,如何确保高弹性工作负载。在这篇文章中,我将以先前内容为基础,用一些常用工具为Rancher搭好一个AWS基础环境。查看这里的仓库,你就能跟随我们的步骤、安装一个完全相同的基础设施:https://github.com/codesheppard/terraform-rancher-starter-template。

我们AWS基础设施最终的输出看起来会像下面的图片:

20170321212847

现在一起动手来创建一个运行的应用栈吧!

Host VM的创建

在这一部分我们将搭建下图中底部的三个黄色部分的内容:

20170321212854

Golden 镜像

首先,我们需要一个创建Docker hosts的方案,该方案会将存储驱动和操作系统组合起来。当然,我们也希望将来能用不同的部分取代它们。

现在我们要建立自己的VM(它常被叫做“golden镜像”)。至于工具,我会用Packer与AWS(以及其他各类云提供商)的API通信来创建VM镜像,用Ansible以一种可读的方式描述配置步骤。如果你想跳过这些步骤的话,你可以在这里找到完整的源代码:https://github.com/codesheppard/packer-catalog/tree/master/ubuntu_1404_aufs3。

此次的示例我们将使用一个Ubuntu 14.04的VM,该VM使用AUFS3作为Docker存储驱动。

第一步,我们创建一个名为ubuntu_1404_aufs3.json的Packer配置文件。在这时,用source_ami_filter在AWS美国东部地区搜索最近的14.04 AMI ID,从搜索清单中返回了ami-af22d9b9。

它还创建了一个40GB的硬盘,该硬盘连接为/dev/sdb,我们将用它存储Docker数据;这里我们正在使用的是Docker 1.12.3,因为它支持最新的Rancher兼容性矩阵。

{
“variables”: {
“aws_access_key”: “”,
“aws_secret_key”: “”,
“docker_version”: “1.12.4”
},
“builders”: [{
“type”: “amazon-ebs”,
“access_key”: “{{user `aws_access_key`}}”,
“secret_key”: “{{user `aws_secret_key`}}”,
“region”: “us-east-1”,
“source_ami_filter”: {
“filters”: {
“virtualization-type”: “hvm”,
“name”: “*ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*”,
“root-device-type”: “ebs”
},
“most_recent”: true
},
“ami_virtualization_type”: “hvm”,
“instance_type”: “m3.medium”,
“ssh_username”: “ubuntu”,
“ami_name”: “Docker {{user `docker_version`}} Ubuntu 14.04 AUFS3 {{timestamp}}”,
“launch_block_device_mappings”: [{
“device_name”: “/dev/sdb”,
“volume_size”: 40,
“volume_type”: “gp2”,
“delete_on_termination”: true
}],
“tags”: {
“OS_Version”: “Ubuntu”,
“Release”: “14.04”,
“StorageDriver”: “AUFS3”,
“Docker_Version”: “{{user `docker_version`}}”
}
}]
}
$> packer validate ubuntu_1404_aufs3.json
Template validated successfully.

现在它已通过了验证,不过如果我们真的实际运行它,Packer只会创建一个基础AMI的副本,连接40GB驱动,而这不是很有用。为了让它更有实用性,我们还需要在上面准备Docker。Packer内置的hooks可用于各种配置管理(CM)工具,如Ansible、Chef和Puppet。在我们的例子中,我们将使用Ansible provisioner。

{
“variables”: [“…”],
“builders”: [“…”],

“provisioners”: [
{
“type”: “ansible”,
“playbook_file”: “./playbook.yml”,
“extra_arguments”: [
“–extra-vars”,
“docker_pkg_name=’docker-engine={{user `docker_version`}}-0~ubuntu-trusty'”
]
}
]
}

playbook.yml文件的内容如下:


– name: Install Docker on Ubuntu 14.04
hosts: all
# run as root
become: true
become_user: root

pre_tasks:
– name: format the extra drive
filesystem:
dev: /dev/xvdb
fstype: ext4
– name: mount the extra drive
mount:
name: /secondary
# ubuntu renames the block devices to xv* prefix
src: /dev/xvdb
fstype: ext4
state: mounted
roles:
– role: angstwad.docker_ubuntu
docker_opts: “–graph /secondary –storage-driver=aufs”

运行该工具之前,我们需要在包含ubuntu_1404_aufs3.json的根目录抓取Docker安装角色,然后运行ansible-galaxy install angstwad.docker_ubuntu -p 来下载一个预配置的Docker安装角色。颇受欢迎的angstwad.docker_ubuntu角色为在Ubuntu上的Docker安装提供了很多选项,并且它提供的安装方式大多是按照官方的Docker安装教程进行操作的。

最后,我们执行下面的脚本,等待新的基础镜像生成。最终生成的镜像将是你从现在开始要使用的基础Docker镜像。

$> packer build ubuntu_1404_aufs3.json
… output
… output
==> amazon-ebs: Creating the AMI: Docker 1.12.4 Ubuntu 14.04 AUFS3 1486965623
amazon-ebs: AMI: ami-1234abcd
==> amazon-ebs: Waiting for AMI to become ready…

AWS基础设施创建

在开始创建基础设施组件之前,先检查以下AWS上Rancher的架构模板仓库。

网络层

接下来,大多数AWS服务需要建立一个VPC来供应零错误的服务。要做到这一点,我们将用公共子网创建一个单独的VPC。下面提供的是一种安装标准模板的直接的方式。在这里检查网络模块。

在main.tf(基础设施的入口文件)中,我们引用了./database的网络配置,然后我们需要向我们的模块传递参数:

module “networking” {
source = “./networking”

aws_region = “${var.aws_region}”
tag_name = “${var.tag_name}”
aws_vpc_cidr = “${var.aws_vpc_cidr}”
aws_public_subnet_cidrs = “${var.aws_public_subnet_cidrs}”
}

现在,你可以运行我们简单网络层的创建操作:

terraform plan -target=”module.networking”
… output …
Plan: 6 to add, 0 to change, 0 to destroy.

$> terraform apply -target=”module.networking”
… output …
module.networking.aws_subnet.rancher_ha_c: Creation complete
module.networking.aws_subnet.rancher_ha_b: Creation complete
module.networking.aws_subnet.rancher_ha_a: Creation complete
module.networking.aws_route.rancher_ha: Creation complete

应用完成!资源:6添加, 0更改, 0销毁。

HA Rancher Server

接下来,让我们开始设置我们的网络,并使用我们的AMI在Rancher上安装HA mode。首先,我们需要自动化Rancher的HA安装。

在Rancher 1.2版本之后,我们对HA进程进行了更新,Rancher不再需要一个bootstrap节点及依赖的步骤来创建HA集群。新的步骤是:

  • 创建一个外部数据库(本文使用的是RDS)
  • 创建一个HA loadbalancer 的免费SSL证书
  • 使用一个外部loadbalancer在3个节点中进行route(这里使用ELB)
  • 启动的HA节点会用附加标示–advertise-address标记起来,并在端口9345进行端口转发

去除bootstrap节点,使得HA Rancher的自动安装变得更加容易。

下面让我们开始创建我们的外部数据库吧!

创建一个外部数据库

继续在main.tf中,我们接下来要搭建RDS数据库。

module “database” {
source = “./database”

vpc_id = “${module.networking.vpc_id}”
database_subnet_ids = [
“${module.networking.vpc_subnet_a}”,
“${module.networking.vpc_subnet_b}”,
“${module.networking.vpc_subnet_c}”,
]
database_port = “${var.database_port}”
database_name = “${var.database_name}”
database_username = “${var.database_username}”
database_password = “${var.database_password}”
database_instance_class = “${var.database_instance_class}”
}

数据库将创建安全组,安全组由在我们网络层定义的子网组成。你可以在Github上看到完整的数据库terraform模板:https://github.com/codesheppard/terraform-rancher-starter-template/blob/master/database/rds.tf。

$> terraform plan -target=”module.database”
… output …
Plan: 3 to add, 0 to change, 0 to destroy.

$> terraform apply -target=”module.database”
… output …
module.database.aws_db_instance.rancherdb: Still creating… (4m20s elapsed)
module.database.aws_db_instance.rancherdb: Creation complete

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

为我们的ELB创建免费证书

在这一步中,我们使用AWS证书管理器(ACM)为Rancher HA 证书管理SSL证书。你可以在ACM文档中查阅如何请求一个免费的SSL证书。因为从ACM请求证书的过程中需要手动验证域名,我们不对这一部分进行自动化。一旦请求完成,引用SSL证书就和下面添加数据资源一样简单,你可以在Github上看到该文件:https://github.com/codesheppard/terraform-rancher-starter-template/blob/master/rancher_server_ha/cert.tf。

data “aws_acm_certificate” “rancher_ha_cert” {
domain = “${var.fqdn}”
statuses = [“ISSUED”]
}

创建HA服务器组

接下来,我们用与ELB相关的安全组搭建一个ELB。然后,我们将添加3个EC2主机驻留在Rancher上。

module “rancher_server_ha” {
source = “./rancher_server_ha”

vpc_id = “${module.networking.vpc_id}”
tag_name = “${var.tag_name}”

# ssled domain without protocol e.g. moo.test.com
acm_cert_domain = “${var.acm_cert_domain}”
# domain with protocol e.g. https://moo.test.com
fqdn = “${var.fqdn}”

# ami that you created with packer
ami = {
us-east-1 = “ami-f05d91e6”
}

subnet_ids = [
“${module.networking.vpc_subnet_a}”,
“${module.networking.vpc_subnet_b}”,
“${module.networking.vpc_subnet_c}”,
]

# database variables to be passed into Rancher Server Nodes
database_port = “${var.database_port}”
database_name = “${var.database_name}”
database_username = “${var.database_username}”
database_password = “${var.database_password}”
database_endpoint = “${module.database.endpoint}”
}

下面是HA服务器模板创建安全组、ELB和弹性伸缩组的细节。这个过程需要几分钟时间,因为我们需要等待EC2实例启动。

$> terraform plan -target=”module.rancher_server_ha”
… output …
Plan: 11 to add, 0 to change, 0 to destroy.

$> terraform apply -target=”module.rancher_server_ha”
… output …

Apply complete! Resources: 11 added, 0 changed, 0 destroyed.

HA实例的云配置

我们在./files/userdata.template文件中提供自己的服务器节点资源。它填充了变量,来为我们的实例创建一个cloud-init配置。Cloud init文档写了一个名为start-rancher.sh的文件,这一文件会在实例启动的时候被执行。

你可以在这里查看文件的细节:https://github.com/codesheppard/terraform-rancher-starter-template/blob/master/rancher_server_ha/files/userdata.template。

在ELB上指向DNS

现在你可以在我们创建的Rancher ELB上指向你的DNS server。导航去ELB console,你应该能看到创建的ELB。接下来抓取ELB的DNS名并且在你的域名提供商处添加一个CNAME记录它。

比如,在这篇博客中,我在rancher.domain.com上安装了Rancher,接下来在https://rancher.domain.com访问管理员面板。

Rancher节点安装

至此,我们已经成功安装了Rancher服务器,并且可以添加自定义主机或使用Rancher-provided主机驱动了。如果我们有更多的自动化尝试,这里有一个也许可行的方法,让你可以在AWS上自动化autoscaled从属节点集群。

在Rancher UI界面,我们按照文档添加自定义主机。我们需要抓取几个变量传递到我们的集群安装模板上。

写入自定义主机时的命令是:

sudo docker run -d –privileged -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/rancher:/var/lib/rancher rancher/agent:${rancher_agent_version} ${rancher_reg_url}

# Example at the time of writing.
rancher_reg_url = https://rancher.domain.com/v1/scripts/AAAAABBBBB123123:150000000000:X9asiBalinlkjaius91238
rancher_agent_version = v1.2.0

在抓出这些变量后,下一步可以开始创建节点。因为与建立HA相比这是一个单独的进程,在文件中我们先为Rancher节点的创建添上注释。

$> terraform plan -target=”module.rancher_nodes”
… output …
Plan: 3 to add, 0 to change, 0 to destroy.

$> terraform apply -target=”module.rancher_nodes”
… output …

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

几分钟后,你应该可以看到你的Rancher主机已出现在你的Rancher UI中。

总结

这篇文章的步骤非常多,但有了这个模板,我们现在可以单独地建立Terraform组件,并在基础设施层上进行迭代。这有点像Docker镜像建立的过程。

这对所有这些不同的组件带来的最大好处是可替换性。如果你不喜欢本文中Docker Host操作系统的选择,那么你可以改变Packer的配置并在Terraform中更新AMI ID。如果你不喜欢网络层,那么只需看一眼Terraform脚本然后更新它。这个安装教程只是一个让Rancher运行起来、让你可以开始你的项目的最初模板。

当然,这并不是搭建Rancher最好的方式,但Terraform的布局是能够随着项目的持续进行而持续改进的。

进一步改进

这里显示的VPC是驻留在公用子网伤的(出于简单性的考量),但如果你想保护数据库和服务器之间的网络流量,你需要更新网络(这可能需要重建)。
其实你可以考虑将Rancher节点传递到一个单独的项目上,而非像本教程一下添上注释。
我们应该看看如何在Terraform上做备份,以避免出现丢失文件夹的情况。所以对于想在生产环境中使用它的人来说,为S3备份中多做一些安装是一定会有很大帮助的。
其实也可以将EFS添加进脚本中,来添加分布式文件系统,给我们各个节点提供支持。
跨区域RDS复制:terraform-community-modules/tf\_aws\_rds
使用由terrafrm社区管理的Terraform VPC模块:terraform-community-modules/tf\_aws\_vpc

K8S中文社区微信公众号
分享到:更多 ()

评论 抢沙发

评论前必须登录!