我目前正在使用一个Kubernetes集群,运行在带有Ansible的裸金属节点上。有计划转移到云,我正在阅读关于Terraform和Packer,为这做准备。撇开数据迁移不谈,对于我们来说,似乎有一条非常直接的迁移路径:
太棒了。我们现在拥有不可变的基础设施,使用最先进的工具。
我很难找到的是用Packer构建的图像是如何进行版本化的。在某种程度上,我们将不得不升级这些图像中的一些软件。有时,Ansible脚本会改变,但有时只是图像中的最新安全更新。无论哪种方式,Packer将不得不为我们建立一个新的形象,我们将不得不部署它与Terraform。如果新的图像最终造成麻烦,我们将不得不恢复旧的图像。
我可以想象如何通过在运行模板之前编辑模板,然后编辑terraform配置来获取新版本,但这对于CI/CD管道来说是行不通的。另一个问题是,我们可能在不同的地区和供应商之间移动。因此,图像的版本可能出现在一个区域,而不是另一个区域,理想情况下,管道应该在不存在的情况下创建映像,如果已经存在,则使用现有的映像。这可能会导致不同区域或云中的图像不同,特别是因为它们可能构建在不同的日期,并且应用了不同的安全更新。
所有这些都是内置到Docker工作流中的,但是对于Packer来说,它还不清楚该做什么。我还没有找到任何涉及这个主题的文档或教程。在Packer和Terraform中有任何内置版本控制功能吗?如果缺少图像,Terraform可以调用Packer吗?是否有任何公认的最佳做法?
我可以想象,在执行Terraform之前,通过使用来自云提供商的API来检查所需映像的存在,并调用Packer对任何丢失的映像进行自动处理。这是可行的,但我不想为每个云提供商编写自定义集成,这听起来像是Terraform应该已经提供的东西。我以前没有使用过Terraform,所以我可能不知道在哪里查找,在Terraform中实现也不是那么困难,但是为什么没有教程告诉我如何实现呢?
发布于 2020-06-03 11:25:24
这在很大程度上是依赖于提供程序的,而且您还没有指定要使用的云提供者,但是AWS在这里提供了一个很好的示例用例。
Terraform和Packer都有一种选择与过滤器匹配的最新AMI的方法。
Packer的AMI构建器使用source_ami_filter,可以用来选择最近的图像作为图像的基础。在建筑商文档中给出了一个实例
{
"source_ami_filter": {
"filters": {
"virtualization-type": "hvm",
"name": "ubuntu/images/\*ubuntu-xenial-16.04-amd64-server-\*",
"root-device-type": "ebs"
},
"owners": ["099720109477"],
"most_recent": true
}
}这里的一个典型例子是总是使用最新的官方Ubuntu图像来构建。如果您正在为不同的用例生成多个AMI (例如Kubernetes工人节点与etcd节点),那么您可以从那里构建一个金色的基础映像,该方案具有已知的命名方案(例如ubuntu/20.04/base/{{isotime | clean_resource_name}}),在每个AMI中都有您想要的所有内容,然后其他AMI也可以使用source_ami_filter来为最近发布的基本AMI进行选择。
Terraform的AWS提供程序具有工作方式相同的数据源,可以用于自动选择与筛选器匹配的最新AMI,以便发布新的AMI并运行Terraform将生成一个计划来替换实例或启动引用AMI数据源的配置/模板。
在资源文件中给出了一个实例
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_instance" "web" {
ami = "${data.aws_ami.ubuntu.id}"
instance_type = "t2.micro"
tags = {
Name = "HelloWorld"
}
}通常,您应该依赖这样的机制来自动选择最近发布的AMI并使用它,而不是在代码中硬编码AMI ID。
管理映像的生命周期超出了Packer本身的范围,它应该作为更大系统的一部分使用。如果要回滚图像,则有两个选项可供您使用:
虽然Packer可以自动地将图像复制到不同的区域(请参见ami_regions中的AWS)和不同的帐户(使用ami_users与其他帐户共享创建的AMI,或者使用后处理器在不同的帐户中创建单独的副本),但如果没有您想要共享事物的各种组合的不同的Packer配置文件,并且无法将推出分离,以便在发布到生产帐户之前发布到一个非生产帐户,则很难有条件地执行这些操作。
如果您想在某些帐户和区域中推出AMI,但不是全部,那么您将需要将该逻辑放在一个更高的位置,例如您的CI/CD系统之类的编排机制。
发布于 2020-09-02 20:04:28
我写了一篇关于这个话题的博文,保持封隔器和地形图像的版本化、同步和干燥。
总结如下:
我们的目标
方法摘要
使用命名约定,如
<IMAGE-NAME> ::= <ROLE>__<BRANCH>-<REVISION>在单独的文件packer/versions.pkvars.hcl中定义变量的值
service-a-img-name = "service-a__main-3"使用以下方法构建图像:
$ packer build -var-file=versions.pkrvars.hcl minimal.pkr.hcl在Terraform方面,由于文件packer/versions.pkvars.hcl在HCL中,我们可以从Terraform读取它:
$ terraform apply -var-file=../../packer/versions.pkrvars.hcl所有细节都在上面提到的博客文章中。
发布于 2020-06-03 00:15:42
因此,对于它的价值,映像版本控制是有用的,因为您可以保存一些默认的东西,比如kubernetes主机节点(预下载的docker映像等),所以当它通过AWS检查时,它已经加入了集群。
对于很多应用程序,我都没有这样做,并且发现通常最好这样做
vendor-app-appversion-epoch这种方法允许您将您的Ami与您的应用程序一起版本,然后您可以将您的实例作为牛(被宰杀)和宠物(在他们的一生中都要被照顾)对待。
data "aws_ami" "amazon_linux2" {
most_recent = true
filter {
name = "name"
values = ["amzn2-ami-*-x86_64-gp2"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["amazon"]
}当您应用地形时,这将为linux2提取最新的图像。
https://stackoverflow.com/questions/62158544
复制相似问题