TT Lab
开始
学习 学习路径 课程

Ansible 实战

用实测而不是文档来立变量优先级表

在 TT Lab 中继续学习

目标

把同一个名称的变量一个位置一个位置地放进十二个位置,亲自测量谁会赢,并把结果留成团队可以阅读的名次表。

为什么重要

“明明写在 group_vars 里了,却出现了别的值”这类报告不会以错误的形式出现。playbook 成功,文件被创建,只是内容不同。语法检查和 lint 都抓不到这个。能抓到的只有一件事——测量“此刻在这个位置上,这个名称解析成什么”。所以本实验不抄写文档的列表,而是测量。测量过一次的人,即使不背表,下次也知道先该怀疑什么。而最后要得出的结论不是表——减少位置的设计比了解表更强。

步骤

  1. 在 /root/ans/prec/inventory/hosts.ini 中写入 web1、web2(ansible_host=127.0.0.1、ansible_port=2222、ansible_user=root),并在 /root/ans/prec/roles/probe/ 中创建测量用 role。在 defaults/main.yml 中放 svc_tier: role-defaults 和 probe_out,tasks/main.yml 由两个 task 构成:用 debug 显示 WINNER={{ svc_tier }},再把同一个值写到 probe_out 路径。用 /root/ans/prec/p01.yml 对 web1 运行这个 role,留下 /root/ans/prec/out/01.txt。
  2. 把 /root/ans/prec/inv-vars/ 做成目录 inventory。在 hosts.yml 中写 web 组(web1、web2)和 db 组(db1),在 group_vars/all.yml 中以 svc_tier 放入 inv-all,在 group_vars/web.yml 中放入 inv-web,在 host_vars/web2.yml 中放入 inv-host。用 /root/ans/prec/p02.yml 测量全部三台主机,留下 /root/ans/prec/out/02-<호스트>.txt(占位符为主机名)。
  3. 创建 /root/ans/prec/p03.yml,在 play 的 vars: 中放入 svc_tier: play-vars,测量 web1。inventory 使用第 2 步的 inv-vars,结果留到 /root/ans/prec/out/03.txt。
  4. 在 /root/ans/prec/vars/tier.yml 中写 svc_tier: vars-file,/root/ans/prec/p04.yml 与第 3 步一样在 play 的 vars: 中保留 play-vars,同时用 vars_files: 读入那个文件。结果是 /root/ans/prec/out/04.txt。
  5. 在 /root/ans/prec/roles/probe_locked/ 中创建第二个测量 role。在 vars/main.yml 中放 svc_tier: role-vars(defaults 中只放 probe_out),tasks/main.yml 写得与 probe 相同。/root/ans/prec/p05.yml 保留与第 4 步相同的两个位置,同时调用这个 role,留下 /root/ans/prec/out/05.txt。
  6. 创建 /root/ans/prec/p06.yml。play 用 vars_files: 读入 tier.yml,并在一个 block 上加 vars: {svc_tier: block-vars}。block 内的第一个 task 调用 probe_locked role,留下 /root/ans/prec/out/06-block.txt,第二个 task 在自己的 vars: 上加 svc_tier: task-vars,把值写到 /root/ans/prec/out/06-task.txt。
  7. 创建 /root/ans/prec/p07.yml。先用 set_fact 设定 svc_tier: set-fact,然后让在 task vars: 上加了 task-vars 的 task 把值写到 /root/ans/prec/out/07-setfact.txt,最后调用 probe_locked role 并传入 svc_tier: role-param,留下 /root/ans/prec/out/07-roleparam.txt。
  8. 在 /root/ans/prec/vars/limits.yml 中把 base_limits 和 svc_limits 设为 {cpu: "1", memory: 1Gi},让 /root/ans/prec/p08.yml 在与 -e svc_tier=extra-vars 一起运行时,把命令行的值写到 /root/ans/prec/out/08.txt。在同一个 playbook 中,把用 task vars: 给出 svc_limits: {memory: 2Gi} 的结果和用 combine 合并的结果,以 replaced、combined 两个键留到 /root/ans/prec/out/08-hash.json,并把十二个位置的测量结果以表格形式写到 /root/ans/prec/out/rank.md。

参考

最底层的位置——role 默认值

在 /root/ans/prec/inventory/hosts.ini 中写入 web1、web2(ansible_host=127.0.0.1、ansible_port=2222、ansible_user=root),并在 /root/ans/prec/roles/probe/ 中创建测量用 role。在 defaults/main.yml 中放 svc_tier: role-defaults 和 probe_out,tasks/main.yml 由两个 task 构成:用 debug 显示 WINNER={{ svc_tier }},再把同一个值写到 probe_out 路径。用 /root/ans/prec/p01.yml 对 web1 运行这个 role,留下 /root/ans/prec/out/01.txt。

这个 role 是本实验始终使用的尺子。无论值来自哪个位置,role 只要把“此刻看到的值”写下来就行。结果文件路径每个 play 都不同,所以也要用变量接收。

inventory 内的三个位置

把 /root/ans/prec/inv-vars/ 做成目录 inventory。在 hosts.yml 中写 web 组(web1、web2)和 db 组(db1),在 group_vars/all.yml 中以 svc_tier 放入 inv-all,在 group_vars/web.yml 中放入 inv-web,在 host_vars/web2.yml 中放入 inv-host。用 /root/ans/prec/p02.yml 测量全部三台主机,留下 /root/ans/prec/out/02-<호스트>.txt(占位符为主机名)。

目录 inventory 里有会被忽略的扩展名。如果一台主机都看不到,先怀疑文件名。想把主机名放进结果文件名,把路径本身当作模板使用即可。

play vars 覆盖 inventory

创建 /root/ans/prec/p03.yml,在 play 的 vars: 中放入 svc_tier: play-vars,测量 web1。inventory 使用第 2 步的 inv-vars,结果留到 /root/ans/prec/out/03.txt。

目的是看 inventory 中已经有值时,这个位置是否还会赢。role 原样使用,只重新写 play。

出人意料的位置——vars_files

在 /root/ans/prec/vars/tier.yml 中写 svc_tier: vars-file,/root/ans/prec/p04.yml 与第 3 步一样在 play 的 vars: 中保留 play-vars,同时用 vars_files: 读入那个文件。结果是 /root/ans/prec/out/04.txt。

这是写在下面的压过写在上面的位置。必须把两个位置都留着,胜负才会显露,所以不要删掉 play vars。

很难从外面覆盖的位置——role vars

在 /root/ans/prec/roles/probe_locked/ 中创建第二个测量 role。在 vars/main.yml 中放 svc_tier: role-vars(defaults 中只放 probe_out),tasks/main.yml 写得与 probe 相同。/root/ans/prec/p05.yml 保留与第 4 步相同的两个位置,同时调用这个 role,留下 /root/ans/prec/out/05.txt。

即使在同一个 role 目录里,defaults 和 vars 的性质也正好相反。一个在最底层,一个高得多。所以要另外再做一个新 role——probe 作为测量最底层位置的尺子原样保留。

范围越窄越高——block 与 task

创建 /root/ans/prec/p06.yml。play 用 vars_files: 读入 tier.yml,并在一个 block 上加 vars: {svc_tier: block-vars}。block 内的第一个 task 调用 probe_locked role,留下 /root/ans/prec/out/06-block.txt,第二个 task 在自己的 vars: 上加 svc_tier: task-vars,把值写到 /root/ans/prec/out/06-task.txt。

在 block 里调用 role,block 变量就叠在 role vars 之上。第二个 task 不经过 role 直接写文件也行——要测量的是位置,而不是 role。

运行中产生的值与传给 role 的参数

创建 /root/ans/prec/p07.yml。先用 set_fact 设定 svc_tier: set-fact,然后让在 task vars: 上加了 task-vars 的 task 把值写到 /root/ans/prec/out/07-setfact.txt,最后调用 probe_locked role 并传入 svc_tier: role-param,留下 /root/ans/prec/out/07-roleparam.txt。

运行中设定的值比事先写好的那些位置更高。但在它之上还有一个——调用 role 时传入的值。

命令行、字典,以及名次表

在 /root/ans/prec/vars/limits.yml 中把 base_limits 和 svc_limits 设为 {cpu: "1", memory: 1Gi},让 /root/ans/prec/p08.yml 在与 -e svc_tier=extra-vars 一起运行时,把命令行的值写到 /root/ans/prec/out/08.txt。在同一个 playbook 中,把用 task vars: 给出 svc_limits: {memory: 2Gi} 的结果和用 combine 合并的结果,以 replaced、combined 两个键留到 /root/ans/prec/out/08-hash.json,并把十二个位置的测量结果以表格形式写到 /root/ans/prec/out/rank.md。

要看命令行的值是否真的赢,play 内部也必须保留其他位置。表要从低位置开始一行一行写,每行写明在那个位置测得的值——前面步骤的产出物就是依据。