首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >你如何管理图像版本与封隔器和地形?

你如何管理图像版本与封隔器和地形?
EN

Stack Overflow用户
提问于 2020-06-02 18:08:09
回答 3查看 2.8K关注 0票数 3

我目前正在使用一个Kubernetes集群,运行在带有Ansible的裸金属节点上。有计划转移到云,我正在阅读关于Terraform和Packer,为这做准备。撇开数据迁移不谈,对于我们来说,似乎有一条非常直接的迁移路径:

  1. 使用我们现有的Ansible脚本用Packer构建映像
  2. 使用Terraform将已构建的映像部署到云中
  3. 使用我们当前的工具部署我们的Kubernetes资源

太棒了。我们现在拥有不可变的基础设施,使用最先进的工具。

我很难找到的是用Packer构建的图像是如何进行版本化的。在某种程度上,我们将不得不升级这些图像中的一些软件。有时,Ansible脚本会改变,但有时只是图像中的最新安全更新。无论哪种方式,Packer将不得不为我们建立一个新的形象,我们将不得不部署它与Terraform。如果新的图像最终造成麻烦,我们将不得不恢复旧的图像。

我可以想象如何通过在运行模板之前编辑模板,然后编辑terraform配置来获取新版本,但这对于CI/CD管道来说是行不通的。另一个问题是,我们可能在不同的地区和供应商之间移动。因此,图像的版本可能出现在一个区域,而不是另一个区域,理想情况下,管道应该在不存在的情况下创建映像,如果已经存在,则使用现有的映像。这可能会导致不同区域或云中的图像不同,特别是因为它们可能构建在不同的日期,并且应用了不同的安全更新。

所有这些都是内置到Docker工作流中的,但是对于Packer来说,它还不清楚该做什么。我还没有找到任何涉及这个主题的文档或教程。在Packer和Terraform中有任何内置版本控制功能吗?如果缺少图像,Terraform可以调用Packer吗?是否有任何公认的最佳做法?

我可以想象,在执行Terraform之前,通过使用来自云提供商的API来检查所需映像的存在,并调用Packer对任何丢失的映像进行自动处理。这是可行的,但我不想为每个云提供商编写自定义集成,这听起来像是Terraform应该已经提供的东西。我以前没有使用过Terraform,所以我可能不知道在哪里查找,在Terraform中实现也不是那么困难,但是为什么没有教程告诉我如何实现呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-06-03 11:25:24

这在很大程度上是依赖于提供程序的,而且您还没有指定要使用的云提供者,但是AWS在这里提供了一个很好的示例用例。

Terraform和Packer都有一种选择与过滤器匹配的最新AMI的方法。

Packer的AMI构建器使用source_ami_filter,可以用来选择最近的图像作为图像的基础。在建筑商文档中给出了一个实例

代码语言:javascript
复制
{
  "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数据源的配置/模板。

资源文件中给出了一个实例

代码语言:javascript
复制
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本身的范围,它应该作为更大系统的一部分使用。如果要回滚图像,则有两个选项可供您使用:

  • 如果您的构建是可复制的,并且问题是可复制的,那么您可以使用旧代码构建并注册一个新的映像,这样您的最新映像现在与前两个图像相同。
  • 取消注册最新的图像,所以你将开始重新拾起旧的图像时,搜索最新的。这取决于云提供商的不同,但是使用AWS可以通过编程(例如通过命令行 )完成。

虽然Packer可以自动地将图像复制到不同的区域(请参见ami_regions中的AWS)和不同的帐户(使用ami_users与其他帐户共享创建的AMI,或者使用后处理器在不同的帐户中创建单独的副本),但如果没有您想要共享事物的各种组合的不同的Packer配置文件,并且无法将推出分离,以便在发布到生产帐户之前发布到一个非生产帐户,则很难有条件地执行这些操作。

如果您想在某些帐户和区域中推出AMI,但不是全部,那么您将需要将该逻辑放在一个更高的位置,例如您的CI/CD系统之类的编排机制。

票数 1
EN

Stack Overflow用户

发布于 2020-09-02 20:04:28

我写了一篇关于这个话题的博文,保持封隔器和地形图像的版本化、同步和干燥

总结如下:

我们的目标

  • 由封隔器创建的图像必须是版本化的。
  • 图像版本控制必须是干燥的(保存在一个单一的地方),并且在封隔器和Terraform之间共享,以避免错误地失去同步。
  • Packer、Terraform和映像版本控制信息的配置文件必须存储在git中,这样签出特定提交和执行terraform应用就足以执行回滚。
  • Terraform必须仅根据本地信息自动检测一个或多个图像的最新版本,或者应该构建一个更新的版本。
  • 必须有N个独立的开发/分期环境,其中映像版本控制与生产无关。
  • 方法必须与IaaS无关(必须与任何云提供商一起工作)。

方法摘要

使用命名约定,如

代码语言:javascript
复制
<IMAGE-NAME> ::= <ROLE>__<BRANCH>-<REVISION>

在单独的文件packer/versions.pkvars.hcl中定义变量的值

代码语言:javascript
复制
service-a-img-name = "service-a__main-3"

使用以下方法构建图像:

代码语言:javascript
复制
$ packer build -var-file=versions.pkrvars.hcl minimal.pkr.hcl

在Terraform方面,由于文件packer/versions.pkvars.hcl在HCL中,我们可以从Terraform读取它:

代码语言:javascript
复制
$ terraform apply -var-file=../../packer/versions.pkrvars.hcl

所有细节都在上面提到的博客文章中。

票数 1
EN

Stack Overflow用户

发布于 2020-06-03 00:15:42

因此,对于它的价值,映像版本控制是有用的,因为您可以保存一些默认的东西,比如kubernetes主机节点(预下载的docker映像等),所以当它通过AWS检查时,它已经加入了集群。

对于很多应用程序,我都没有这样做,并且发现通常最好这样做

代码语言:javascript
复制
vendor-app-appversion-epoch

这种方法允许您将您的Ami与您的应用程序一起版本,然后您可以将您的实例作为牛(被宰杀)和宠物(在他们的一生中都要被照顾)对待。

代码语言:javascript
复制
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提取最新的图像。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62158544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档