首页 > 其他 > 详细

ansible 目录结构

时间:2021-04-20 09:15:01      阅读:17      评论:0      收藏:0      [点我收藏+]

怎样去构建目录

ansible会在同一时间管理你的很多主机,使用一个列表或者组作为一个目录。一旦你的Inventory定义好了,你就可以使用一些pattern去操作你列表里的主机。

默认的设备目录文件是在/etc/ansible/hosts。你也可以使用选项-i <path>指定一个目录文件。你也可以同时使用多个目录文件,更或者也可以从一个动态的或者云资源更或者不同格式的目录(YAML,ini,etc)。

Inventory基础元素: formats, hosts和groups

inventory文件可以是一种或者多种格式,取决于你的目录插件。最普遍的格式为INI和YAML。一个基础的INI文件etc/ansible/hosts应该向下面的例子这样:

mail.example.com

[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com

中括号里的标题是组名称,用于分类主机和确定你在何时和控制主机的目的。
这是YAML格式的inventory文件:

all:
  hosts:
    mail.example.com:
  children:
    webservers:
      hosts:
        foo.example.com:
        bar.example.com:
    dbservers:
      hosts:
        one.example.com:
        two.example.com:
        three.example.com:

默认组

有两个默认组:allungroupall里面包含所有的主机。ungroup里面包含了所有没有在组里的主机。所有的主机会至少属于2个组(allgroup或者其他的组)。因为allungroup是一直存在的,所以他们也不必要以组名的形式存在于Inventory中。

主机在多个组的情况

你可以把一个主机归为多个组。例如生产上的一台web服务器在DC A里,它既属于[prod] [DC A]和[webservers]里。你可以按如下步骤创建组:

  • What :一个应用、栈或者微服务(比如 database servers, web servers等).
  • Where : 一个DC或者一个地点. (比如 east, west).
  • When :开发测试阶段还是生产使用阶段。 (比如prod, test).
    扩展之前的YAML目录,使其包含what, when和where:
  hosts:
    mail.example.com:
  children:
    webservers:
      hosts:
        foo.example.com:
        bar.example.com:
    dbservers:
      hosts:
        one.example.com:
        two.example.com:
        three.example.com:
    east:
      hosts:
        foo.example.com:
        one.example.com:
        two.example.com:
    west:
      hosts:
        bar.example.com:
        three.example.com:
    prod:
      hosts:
        foo.example.com:
        one.example.com:
        two.example.com:
    test:
      hosts:
        bar.example.com:
        three.example.com:

可以看到one.example.com同时存在于dbservers, east, 和prod组里.
你也可以使用嵌套的组来简化生产主机和测试主机:

all:
  hosts:
    mail.example.com:
  children:
    webservers:
      hosts:
        foo.example.com:
        bar.example.com:
    dbservers:
      hosts:
        one.example.com:
        two.example.com:
        three.example.com:
    east:
      hosts:
        foo.example.com:
        one.example.com:
        two.example.com:
    west:
      hosts:
        bar.example.com:
        three.example.com:
    prod:
      children:
        east:
    test:
      children:

添加某固定范围的主机

如果你有大量命名类似的主机,你可以使用一个范围参数来批量添加,而不用一个一个地单独添加。
INI格式:

[webservers]
www[01:50].example.com

YAML格式:

  webservers:
    hosts:
      www[01:50].example.com:

对于数字模式,前面的0可以包含也可以不包含.你也可以定义一个字母范围:

[databases]
db-[a:f].example.com

添加变量到inventory

你可以为一个主机或者主机组存储变量值。刚开始,你可以直接在主Inventory文件里添加主机或者组变量。当你添加越来越多的主机在你的Inventory里时候,你可能就想用单独的文件来存储主机和主机组的变量。

添加变量到单个主机:主机变量

你可以轻松地给单一的主机配置变量,然后再playbook中使用它。在INI格式下:

[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909

YAML格式:

atlanta:
  host1:
    http_port: 80
    maxRequestsPerChild: 808
  host2:
    http_port: 303
    maxRequestsPerChild: 909

比如非标准SSH端口可以很好用于主机变量中。你可以把端口添加在主机名冒号的后面:

badwolf.example.com:5309

连接协议也可以在配置在主机变量里:

[targets]

localhost              ansible_connection=local
other1.example.com     ansible_connection=ssh        ansible_user=myuser
other2.example.com     ansible_connection=ssh        ansible_user=myotheruser

注:如果使用非标准SSH端口的话,openssh连接会找到并使用它,但是paramiko连接方式不会。

Inventory aliases

在inventory里定义aliases:
INI:
jumper ansible_port=5555 ansible_host=192.0.2.50
YAML:

  hosts:
    jumper:
      ansible_port: 5555
      ansible_host: 192.0.2.50

在上面的例子中,ansible会连接主机别名“jumper” 的5555端口。

注:INI使用key=value格式,他的值取决于在哪里声明他。

  • 在主机声明中,INI的值会被解释为PYTHON的内容结构(字符,数字,元组,列表,字典,布尔,空)。每个主机行接受多个key=value的值。所以需要一个方法去分辨空格是一个分隔符还是属于定义的值的一部分。
  • 当声明在:vars中时候,INI的值会被解释成字符。比如var=FALSE会被创建为一个字符‘FALSE’。与主机行不同,:vars部分值接受一个单独的条目,所以所有在=号后面的都是该条目的值。
  • 在INI inventory中的变量值必须都是一个确定的类型(比如,字符串类型或者布尔类型),在task中记得定义过滤器来指定类型。不要依赖INI inventory来处理。
  • 考虑使用YMAL格式作为inventory源来避免变量类型的混乱。YAML inventory插件会持续正确处理变量值。
  • 一般情况下,建议把主机变量存于‘host_vars’文件夹里。

给多台设备分配变量:组变量

如果一个组的主机共享变量,你可以把变量一次性应用到组内。
INI格式:

[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
In YAML:

atlanta:
  hosts:
    host1:
    host2:
  vars:
    ntp_server: ntp.atlanta.example.com
    proxy: proxy.atlanta.example.com

组变量是比较方便的方法能批量应用变量。但是在执行命令之前,ansible会应用变量到主机级别。如果主机属于多个组,那么ansible会从所有的组中读取值。如果在不同的组里给相同的变量分配了不同的值,ansible会根据内部规则选择哪些值进行合并。

变量继承:组变量

使用:children后缀在INI或者children:在YMAL中应用:varsvars:的组变量
INI格式:

[atlanta]
host1
host2

[raleigh]
host2
host3

[southeast:children]
atlanta
raleigh

[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2

[usa:children]
southeast
northeast
southwest
northwest

在YAML中:

all:
  children:
    usa:
      children:
        southeast:
          children:
            atlanta:
              hosts:
                host1:
                host2:
            raleigh:
              hosts:
                host2:
                host3:
          vars:
            some_server: foo.southeast.example.com
            halon_system_timeout: 30
            self_destruct_countdown: 60
            escape_pods: 2
        northeast:
        northwest:
        southwest:

如果需要存储列表或者哈希数据,再或者需要单独存放主机和组变量,需要查询组织主机和组变量环节。

子组有一些特性需要知悉:Child groups have a couple of properties to note:

  • 子组主机自动也属于父组
  • 子组的变量优先级高于父组的变量
  • 组可以有多个子组和父组,但是不能有循环的关系
  • 主机可以属于多个组,变量也会从多个组进行融合,但是只会有一个进程。

结构化主机和组变量Organizing host and group variables

虽然你可以存储变量到主inventory文件里,但是把主机和组变量分别存储到分开的文件中可以更方便我们的管理。主机和组变量文件必须是YAML格式。有效的文件扩展名包括‘.yml’, ‘.yaml’, ‘.json’或者无扩展名。
ansible会通过寻找相关的Inventory文件或者Playbook路径来加载主机和组变量。如果你的inventory文件在/etc/ansible/hosts目录下,并且包含属于两个组‘raleigh’ 和‘webservers’的主机‘foosball’,那么这个主机会使用如下路径的YAML变量文件。

/etc/ansible/group_vars/raleigh # 扩展名可以是‘.yml‘, ‘.yaml‘, 或者‘.json‘
/etc/ansible/group_vars/webservers
/etc/ansible/host_vars/foosball

例如,如果你以DC来分类你的主机,而且每个DC有自己的NTP服务或者DB服务器,那么你可以创建一个文件名为/etc/ansible/group_vars/raleigh来存储你raleigh组的变量

---
ntp_server: acme.example.org
database_server: storage.example.org

你可以以主机名字或者组名字来创建目录。ansible会按照字典顺序来读取全部的目录。
一个名为‘raleigh’组的例子:

/etc/ansible/group_vars/raleigh/db_settings
/etc/ansible/group_vars/raleigh/cluster_settings

所有在‘raleigh’组的主机将可使用定义在这些文件中的变量。如果你变量文件很大的话,这个方式会帮助你整理变量文件以及在ansible加密某些组变量。
你也可以在playbook目录里添加group_vars/host_vars/目录。ansible-playbook命令会默认在目前工作目录里寻找这些目录。但是其他的ansible命令(比如ansible,ansible-console等)只会在inventory目录下寻找group_vars/host_vars/目录。如果你想用其他的ansible命令从其他目录里加载组和主机变量,需要添加--playbook-dir选项指定目录。如果你从playbook目录和inventory一起加载inventory文件,那Playbook目录中的变量会覆盖掉Inventory目录的变量。

把你的inventory文件和变量放在git上可以跟踪你的inventory和主机变量的改变过程。

变量合并

默认情况下,在playbook执行前会将某主机的变量进行合并。这使ansible只关注于主机和任务,所以组的概念只是被限制于目录的主机匹配中。默认情况下,Ansible会按照优先级去覆盖那些为组或者主机定义的变量。从低到高的优先级顺序是:

  • all group 因为是所有组的父组
  • parent group 父组
  • child group 子组
  • host 主机

默认情况下ansible会按照字母顺序合并相同级别的组,后加载的组会覆盖前面的组。比如 B 开头命名的组变量会覆盖 A 开头中同样匹配到的组变量。
你可以通过修改组变量中ansible_group_priority选项来改变合并相同级别组变量时的优先级顺序。数字越大,优先级越高,如果不修改则优先级默认为1.

a_group:
    testvar: a
    ansible_group_priority: 10
b_group:
    testvar: b

在这个例子中,如果这两个组有相同的优先级,那么变量会是testvar == b。但是如果给a_group一个更高的优先级,那么结果就会是testvar == a.

注:ansible_group_priority 只能在inventory文件中设置,不能在group_vars/设置,因为这个变量在加载group_vars的时候被用到。

使用多个 inventory 文件

你可以通过使用命令行或者配置ANSIBLE_INVENTORY来同时使用多inventory源(目录、动态目录脚本或者inventroy插件支持的其他文件)。当你想同时分别配置生产或者测试环境的时候,这个功能会很有用处。
使用命令行选中两个inventory。

ansible-playbook get_logs.yml -i staging -i production

此时要注意变量冲突的问题,如果冲突了的话,会按照变量合并的规则去处理。合并的顺序是按照Inventory源的参数顺序控制。如果[all:vars]在staging inventory里定义myvar = 1,但是production inventory定义myvar = 2,那么playbook会使用myvar = 2的值。如果上面的例子中使用的参数是-i production -i staging,那么结果将会相反。

聚合多inventory源到一个目录中

也可以只创建一个inventory目录,然后把多个inventory源或者其他类型的文件放在里面。这对于管理动态和静态主机来说很方便。下面这个invetory就包含了inventory插件源,动态inventory脚本和一个静态主机文件:

inventory/
  openstack.yml          # 配置inventory插件获取Openstack Cloud主机
  dynamic-inventory.py   # 使用动态inventory脚本添加主机
  static-inventory       # 添加静态的主机和组
  group_vars/
    all.yml              # 分配变量到所有主机

你可以这样直接调用这个inventory目录:

ansible-playbook example.yml -i inventory

因为这些inventory的合并规则是遵循文件名字的字母表顺序,所以如果有变量冲突的话,可以给文件添加一个前缀来定义优先级:

inventory/
  01-openstack.yml        
  02-dynamic-inventory.py   
  03-static-inventory    
  group_vars/
    all.yml                 

如果01-openstack.yml定义myvar = 102-dynamic-inventory.py定义myvar = 203-static-inventory定义myvar = 3,那playbook会采用myvar = 3

关于执行的inventory参数

以下是ansible控制主机涉及到的一些重要参数。

主机连接:
注:在使用默认ssh连接插件的时候,ansible不会释放一个通道去允许用户和SSH进程间手动接受密码或者解密秘钥。推荐使用ssh代理的方式。

ansible_connection: 连接到主机的方式,可以是ansible连接插件的名字。SSH协议连接类型有:smart,ssh 或者paramiko。默认是smart。

一些通用的参数:
ansible_host : 要连接的主机名称
ansible_port : 连接端口
ansible_user : 连接的用户名
ansible_password : 主机的用户密码(不要使用明文密码,应该使用vault功能进行加密)

针对于SSH的参数:

ansible_ssh_private_key_file : SSH使用的私钥,如果不想使用ssh代理的话,可以指定多个主机的私钥
ansible_ssh_common_args : 参数会添加到sftp,scp,ssh的默认命令行中。通常用来配置ProxyCommand 。
ansible_sftp_extra_args : 参数会添加到sftp的默认命令行中
ansible_scp_extra_args : 参数会添加到scp的默认命令行中
ansible_ssh_extra_args : 参数会添加到ssh的默认命令行中
ansible_ssh_pipelining : 决定是否使用SSH pipelining,这个可以覆盖掉ansible.cfg中的pipelining参数

权限升级:

ansible_become : 相当于ansible_sudo 和 ansible_su,允许强制提升用户权限。
ansible_become_method : 设置权限升级的方式
ansible_become_user :相当于ansible_sudo_user 或者ansible_su_user , 允许某用户权限升级
ansible_become_password : 允许你设置权限升级的密码(不要直接使用明文的方式)
ansible_become_exe : 允许设置升级权限的可执行文件
ansible_become_flags : 允许为权限升级方式设置标志位,也可以在ansible.cfg里全局设置

远程主机环境参数:
ansible_shell_type : 远程主机的shell类型。一般不用设置。默认为sh
ansible_python_interpreter :远程主机的Python路径
ansible_*_interpreter :支持ruby, perl 。

一个Ansible-INI主机文件示例:

some_host         ansible_port=2222     ansible_user=manager
aws_host          ansible_ssh_private_key_file=/home/example/.ssh/aws.pem
freebsd_host      ansible_python_interpreter=/usr/local/bin/python
ruby_module_host  ansible_ruby_interpreter=/usr/bin/ruby.1.9.3

非SSH连接类型

ansible并非仅使用ssh的连接类型。根据ansible_connection=<connector>参数的设置,连接类型可以被更改。比如:

local : 这个参数意味着你你的playbook将部署再本机上。
docker : 这个参数是将playbook直接用docker client部署到docker容器里。

这个连接类型将会使用以下参数。

ansible_host : 连接的Docker容器名
ansible_user : 容器中的操作用户名,这个用户必须存在于容器内。
ansible_become: 如果置位true,那就会使用become_user在容器内进行操作
ansible_docker_extra_args : 可以是一个包含Docker其他参数的字符串,单并不是特定于命令的。此参数主要用于配置要使用的远程Docker守护程序。

下面是个docker部署示例:

- name: create jenkins container
  docker_container:
    docker_host: myserver.net:4243
    name: my_jenkins
    image: jenkins

- name: add container to inventory
  add_host:
    name: my_jenkins
    ansible_connection: docker
    ansible_docker_extra_args: "--tlsverify --tlscacert=/path/to/ca.pem --tlscert=/path/to/client-cert.pem --tlskey=/path/to/client-key.pem -H=tcp://myserver.net:4243"
    ansible_user: jenkins
  changed_when: false

- name: create directory for ssh keys
  delegate_to: my_jenkins
  file:
    path: "/var/jenkins_home/.ssh/jupiter"
    state: directory

ansible 目录结构

原文:https://www.cnblogs.com/felix-zong/p/14620249.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!