【问题标题】:Multistage deployment with ansible使用 ansible 进行多阶段部署
【发布时间】:2015-12-08 05:02:35
【问题描述】:

如果您有不同的阶段变量,您建议使用什么方法来组织使用 Ansible 的多阶段部署?

主要思想是为不同阶段定义组变量。

有两篇文章:

我想获得更多关于组织剧本、变量和主机的示例,并了解您的方法的优缺点。

【问题讨论】:

  • 你能举例说明你的意思吗?

标签: deployment ansible ansible-inventory


【解决方案1】:

最近,我使用了我在问题中已经提到的方法,并且它似乎是我认为最方便的方法之一。

取自Organizing Group Vars Files in Ansible 文章,但稍作改动,因为不幸的是,文章的标题并不能反映它的真正价值和目的,而且剧本的名称也令人困惑。 事实上,花了相当长的时间才意识到这是关于使用 Ansible 进行多阶段部署

您的目录布局应该是这样的:

production/
├── group_vars
│   └── server.yml
└── inventory
staging/
├── group_vars
│   └── server.yml
└── inventory
deploy.yml

而且用法极其简单:

ansible-playbook -i staging deploy.yml

deploy.yml 是您的剧本的名称。

Ansible-playbook 提供目录作为清单时,默认搜索名为 inventory 的文件,因此无需指定 -i production/inventory,只有 -i production 可以正常工作。

而且好处是:

  • 您不必维护一些不必要的组,例如[production:children]

  • 您不需要像group_vars/production.yml这样的混淆组和文件

  • 所有变量和主机都位于不同的目录中,因此很容易使它们保持不同并且更改历史记录清晰。如果需要,您甚至可以将其拆分为单独的存储库

您还可以使用 ansible-vault 在存储库中为生产保密,换句话说,将所有重要变量加密存储

【讨论】:

  • 来自不同环境的重叠组怎么样。比如说,可能由来自所有三个环境的主机组成的网络服务器。你如何处理它?为了增加复杂性,暂存环境中的所有网络服务器。
  • @deepdive 这似乎是一个架构问题。你真的有一个同时支持 2 个不同环境的主机吗?保持安装多个相交配置可能会导致麻烦。当然,你可以使用版本管理系统或者在 Ansible 中添加一些条件等等,但我建议添加另一个虚拟层
  • @deepdive 你能详细描述你的问题吗?如果您不介意,请在聊天中
  • 我对非环境特定的 group_vars 在此设置中的位置感到有些困惑。 Ansible 会同时加载环境目录中的 group_vars 文件和环境目录之外的文件吗?
  • @Chris doc 说“group_vars/host_vars/ 目录可以存在于 playbook 目录或库存目录中。如果两个路径都存在,则 playbook 目录中的变量将覆盖在库存目录”
【解决方案2】:

在复杂库存结构的情况下,如果维护组不是最佳选择 (http://docs.ansible.com/ansible/intro_inventory.html#groups-of-groups-and-group-variables),可以使用以下技巧:

生产库存文件:

# production inventory 
[loadbalancers]
lb01
lb02
lb03

[webservers]
ws01
ws02
ws03

[all:vars]
inventory_vars=prod.config.yml

开发库存文件:

# development inventory 
[loadbalancers]
test-lb01
test-lb02
test-lb03

[webservers]
test-ws01
test-ws02
test-ws03

[all:vars]
inventory_vars=development.config.yml

现在在剧本本身中,在加载角色之前包括以下任务:

- hosts: all

  pre_tasks:

    - name: Load inventory specific variables
      include_vars: "{{ inventory_vars }}"

为防止在生产环境中意外执行 playbook,prod.config.yml cab 使用 ansible-vault 加密

【讨论】:

  • 我将重新接受答案。你的对我很有帮助,但另一个(我自己的)100% 符合我的需求,尽管它还没有任何支持。事实上,我本可以更深入地挖掘我提供给自己的相关链接,以找出所需的结果。但是我引用的文章有点含糊,这就是为什么我用更广泛的解释编写了另一个答案
【解决方案3】:

目前我正在使用以下结构:

hosts/development
hosts/production
hosts/group_vars/development/service1.yml
hosts/group_vars/development/service2.yml
hosts/group_vars/production/service1.yml
hosts/group_vars/production/service2.yml
hosts/group_vars/production/service3.yml
hosts/host_vars/dev1.yml
hosts/host_vars/prod1/something.yml
hosts/host_vars/prod1/something_else.yml

库存可能如下所示:

# hosts/development

dev1 ansible_ssh_host=dev1.example.com
dev2 ansible_ssh_host=dev2.example.com

[development]
dev1
dev2

[service1]
dev1

[service2]
dev2

[service3]
dev1
dev2

对于生产:

# hosts/production

prod1 ansible_ssh_host=prod1.example.com
prod2 ansible_ssh_host=prod2.example.com

[production]
prod1
prod2

[service1]
prod1

[service2]
prod2

[service3]
prod1
prod2

这允许一些不错的组合。通过使用ansible -i hosts,我可以定位所有已知的主机。例如,我正在使用它来将清单中的所有服务器添加到监控配置文件中。

通过使用ansible -i hosts/development,我可以将命令限制为开发(或生产)服务器。当我想在将新配置应用到生产之前在开发系统上测试新配置时,我会这样做。

我目前在 3 个不同阶段的大约 25 台服务器上使用这种结构,它对我来说效果很好。但它也有一些弱点:

  • 尽管在我的情况下,优点超过了这些缺点。我最大的担心是不小心将主机目录中的所有库存作为目标,因为忘记限制到其中一个阶段。如果库存完全分开,这将更容易避免。
  • 另外,我不喜欢在developmentproduction 组中再次列出清单中的所有服务器,因为它是多余的并且容易忘记。
  • 我想如果您的系统增长,可能会有点难以理解从何处以及以何种顺序加载变量。

话虽如此,它对我来说效果很好,所以也许它也适合你。

【讨论】:

  • 有没有办法避免列出清单中的所有服务器?
  • @NickRoz,在某些情况下,剧本逻辑需要直接寻址服务器组。例如,在所有loadbalancers 服务器上配置模板,其主机名是webservers 组的所有成员。在这种情况下,手动维护多个清单列表(在组中重复主机名)将不是最佳选择。建议使用以下方法:创建特殊组 [production:children] 并将其他组作为成员。 docs.ansible.com/ansible/…
  • @GregoryShulov,这是我的错,我的评论不够清楚。我使用[production:children][development:children] 组。如果服务器组太多(发生这种情况),很难将它们全部列为productiondevelopment 的子级。有没有办法以某种方式组织文件以避免这种冗余?
  • @NickRoz 我认为静态库存不可能做到这一点。不过,您可以尝试编写动态清单:docs.ansible.com/ansible/…
  • @NickRoz 在下面看到我的回答
猜你喜欢
  • 2022-06-16
  • 2016-03-29
  • 1970-01-01
  • 2023-04-06
  • 2011-11-07
  • 2022-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多