美文网首页
ansible基础知识

ansible基础知识

作者: 任总 | 来源:发表于2018-08-23 09:57 被阅读51次

    一、ansible简介

    • 1、ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。

    • 2、ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。


    • 主要包括:
      (1)、连接插件connection plugins:负责和被监控端实现通信;
      (2)、host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
      (3)、各种模块核心模块、command模块、自定义模块;
      (4)、借助于插件完成记录日志邮件等功能;
      (5)、playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。


      Ansible的架构
    • 3、ansible的安装
      ansible依赖于Python 2.6或更高的版本、paramiko、PyYAML及Jinja2。

    (1)、编译安装

    解决依赖关系

    # yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
    # tar xf ansible-1.5.4.tar.gz
    # cd ansible-1.5.4
    # python setup.py build
    # python setup.py install
    # mkdir /etc/ansible
    # cp -r examples/* /etc/ansible
    

    (2) 、rpm包安装

    # yum install ansible
    

    注意:不同版本的ansible的功能差异可能较大。

    二、ansible中的模块使用和简单的格式执行

    ansible -m MOD_nAME指明模块
    -a MOD_ARGS 向模块传递参数
    -f FORKS 一次可管理多少主机
    -C 预运行,不真正运行
    --list -host 列出主机
    -u USERNAME 指明用户名
    -c 指明连接方式,默认smart
    这些命令使用ansible简单的格式执行

    1、生成安全连接秘钥

    ansible通过ssh实现配置管理、应用部署、任务执行等功能,因此,需要事先配置ansible端能基于密钥认证的方式联系各被管理节点。
    ansible和目标主机命令执行要使用ssh,所以第一步就要生成安全连接秘钥。

    [root@rs1 ~]# ssh-keygen -t rsa -P ""    #生成安全连接秘钥
    
    [root@rs1 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.6   #使用安全连接秘钥连接1号目标主机
     root@192.168.1.6's password: #输入目标主机密码
    
    [root@rs1 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.12 #使用安全连接秘钥连接2号目标主机
    root@192.168.1.12's password:  #输入目标主机密码
    

    2、添加本地解析

    [root@rs1 ~]# vim /etc/hosts 添加本地解析
    
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    192.168.1.6 vs
    192.168.1.12 rs2
    

    3、定义目标主机组

    /etc/ansible/hosts文件支持使用以下变量设置相关的远程主机信息:

    ansible_ssh_host     #用于指定被管理的主机的真实IP
    ansible_ssh_port     #用于指定连接到被管理主机的ssh端口号,默认是22
    ansible_ssh_user     #ssh连接时默认使用的用户名
    ansible_ssh_pass     #ssh连接时的密码
    ansible_sudo_pass     #使用sudo连接用户时的密码
    ansible_sudo_exec     #如果sudo命令不在默认路径,需要指定sudo命令路径
    ansible_ssh_private_key_file     #秘钥文件路径,秘钥文件如果不想使用ssh-agent管理时可以使用此选项
    ansible_shell_type     #目标系统的shell的类型,默认sh
    ansible_connection     #SSH 连接的类型: local , ssh , paramiko,在 ansible 1.2 之前默认是 paramiko ,后来智能选择,优先使用基于 ControlPersist 的 ssh (支持的前提)
    ansible_python_interpreter     #用来指定python解释器的路径,默认为/usr/bin/python 同样可以指定ruby 、perl 的路径
    ansible_*_interpreter     #其他解释器路径,用法与ansible_python_interpreter类似,这里"*"可以是ruby或才perl等
    

    目标主机组:

    [root@rs1 ~]# cd /etc/ansible
    [root@rs1 ansible]# ls
    ansible.cfg  hosts  roles
    [root@rs1 ansible]# vim hosts#编辑文件
    [websrvs]#添加web组
    192.168.1.6
    192.168.1.12
    
    [dbsrvs] #定义db组
    192.168.1.12
    
     [root@rs1 ansible]# ansible all  --list-hosts#列出目标主机
      hosts (2):
        192.168.1.12
        192.168.1.6
    [root@rs1 ansible]# ansible all -m ping  -C# 对所有目标主机预运行ping测试
    192.168.1.12 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    192.168.1.6 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    [root@rs1 ansible]# ansible all -m ping # 对所有目标主机ping测试
    192.168.1.12 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    192.168.1.6 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    
    

    4、模块文档

    [root@rs1 ansible]# ansible-doc -l #列出目标主机模块文档
    [root@rs1 ansible]# ansible-doc -s group 获取设置组命令文档
    1、定义期望的目标状态
    2、操作必须是幂等的,操作次数必须相等
    

    5、group组模块使用

    对目标主机创建组,并传递参数

    [root@rs1 ansible]# ansible all -m group -a "gid=3000 name=mygrp state=present system=no" #对所有目标主机创建组,m是加载group模块,a是传递参数,state是创建还是删除
    192.168.1.6 | SUCCESS => {
        "changed": true, 
        "gid": 3000, 
        "name": "mygrp", 
        "state": "present", 
        "system": false
    }
    192.168.1.12 | SUCCESS => {
        "changed": true, 
        "gid": 3000, 
        "name": "mygrp", 
        "state": "present", 
        "system": false
    }
    

    6、user用户模块使用

    对目标主机创建用户,并传递参数

    [root@rs1 ansible]# ansible all -m user -a "uid=5000 name=testuser state=present groups=mygrp shell=/bin/tcsh"对所有目标主机创建用户,m是加载user模块,a是传递参数,state是创建还是删除,groups是附加组,shell是默认shell
    
    192.168.1.6 | SUCCESS => {
        "changed": true, 
        "comment": "", 
        "createhome": true, 
        "group": 5000, 
        "groups": "mygrp", 
        "home": "/home/testuser", 
        "name": "testuser", 
        "shell": "/bin/tcsh", 
        "state": "present", 
        "system": false, 
        "uid": 5000
    }
    192.168.1.12 | SUCCESS => {
        "changed": true, 
        "comment": "", 
        "createhome": true, 
        "group": 5000, 
        "groups": "mygrp", 
        "home": "/home/testuser", 
        "name": "testuser", 
        "shell": "/bin/tcsh", 
        "state": "present", 
        "system": false, 
        "uid": 5000
    }
    

    7、copy复制模块使用

    对目标主机拷贝本地文件,并传递参数,指明src源文件位置和dest目标文件位置

    [root@rs1 ansible]# ansible-doc -s copy#查询copy使用文档
    [root@rs1 ansible]# ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab.ansible mode=600"
    对所有目标主机拷贝本地文件,m是使用copy模块,a是传递参数,src源文件位置,dest目标文件位置,mode权限(加了'/'就是目录)
    192.168.1.6 | SUCCESS => {
        "changed": true, 
        "checksum": "4367ba689c50b4ab956ce0704f048f4fb0cc1a28", 
        "dest": "/tmp/fstab.ansible", 
        "gid": 0, 
        "group": "root", 
        "md5sum": "c6ac458a97ee2f7ed913fdc8b17e9394", 
        "mode": "0600", 
        "owner": "root", 
        "size": 465, 
        "src": "/root/.ansible/tmp/ansible-tmp-1534522522.24-76431722279920/source", 
        "state": "file", 
        "uid": 0
    }
    192.168.1.12 | SUCCESS => {
        "changed": true, 
        "checksum": "4367ba689c50b4ab956ce0704f048f4fb0cc1a28", 
        "dest": "/tmp/fstab.ansible", 
        "gid": 0, 
        "group": "root", 
        "md5sum": "c6ac458a97ee2f7ed913fdc8b17e9394", 
        "mode": "0600", 
        "owner": "root", 
        "size": 465, 
        "src": "/root/.ansible/tmp/ansible-tmp-1534522522.23-209859323698602/source", 
        "state": "file", 
        "uid": 0
    }
    

    copy模块设置属主属组用法

    [root@rs1 ansible]# ansible all -m copy -a "content='hi tere\n' dest=/tmp/hi.txt owner=testuser group=mygrp"#对所有目标主机拷贝本地文件,m是使用copy模块,a是传递参数,content创建文档到dest目标文件位置,设置属主属组
    192.168.1.6 | SUCCESS => {
        "changed": true, 
        "checksum": "50dbdebeaa8c0f1c3cccfcae54ef71fc2c0e4fa8", 
        "gid": 3000, 
        "group": "mygrp", 
        "mode": "0644", 
        "owner": "testuser", 
        "path": "/tmp/hi.txt", 
        "size": 8, 
        "state": "file", 
        "uid": 5000
    }
    192.168.1.12 | SUCCESS => {
        "changed": true, 
        "checksum": "50dbdebeaa8c0f1c3cccfcae54ef71fc2c0e4fa8", 
        "gid": 3000, 
        "group": "mygrp", 
        "mode": "0644", 
        "owner": "testuser", 
        "path": "/tmp/hi.txt", 
        "size": 8, 
        "state": "file", 
        "uid": 5000
    }
    

    8、fetch复制模块

    从远程单一主机复制到本地主机
    使用文档:ansibile-doc -s fetch

    9、command模块执行命令

    对目标主机执行命令

    [root@rs1 ansible]# ansible all -m command -a "ifconfig"#对所有目标主机,m使用模块,command命令模块,a传递参数 执行ifconfig命令
    192.168.1.12 | SUCCESS | rc=0 >>
    ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    .............     
    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
    .............    
    
    192.168.1.6 | SUCCESS | rc=0 >>
    ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
    ............... 
    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
    ...............     
    

    注意:command缺点是无法解析管道命令

    10、shell模块使用

    shell模块解决了command模块的缺点,对传递参数用shell解析并执行

    [root@rs1 ansible]# ansible all -m shell -a "echo 123 | passwd --stdin testuser"#对所有目标主机使用shell解析传递参数中的管道命令
    192.168.1.6 | SUCCESS | rc=0 >>
    更改用户 testuser 的密码 。
    passwd:所有的身份验证令牌已经成功更新。
    
    192.168.1.12 | SUCCESS | rc=0 >>
    更改用户 testuser 的密码 。
    passwd:所有的身份验证令牌已经成功更新。
    

    11、file模块文件属性命令

    对目标主机,传递参数,创建文件、目录和软连接

    [root@rs1 ansible]# ansible all -m file -a "path=/var/tmp/hello.dir state=directory"#对所有目标主机使用file模块创建hello.dir目录
    192.168.1.12 | SUCCESS => {
        "changed": true, 
        "gid": 0, 
        "group": "root", 
        "mode": "0755", 
        "owner": "root", 
        "path": "/var/tmp/hello.dir", 
        "size": 6, 
        "state": "directory", 
        "uid": 0
    }
    192.168.1.6 | SUCCESS => {
        "changed": true, 
        "gid": 0, 
        "group": "root", 
        "mode": "0755", 
        "owner": "root", 
        "path": "/var/tmp/hello.dir", 
        "size": 6, 
        "state": "directory", 
        "uid": 0
    }
    
    [root@rs1 ansible]# ansible all -m file -a"src=/etc/fstab path=/var/tmp/fstab.link state=link"#对所有目标主机使用file模块创建fstab文件的符号连接
    192.168.1.12 | SUCCESS => {
        "changed": true, 
        "dest": "/var/tmp/fstab.link", 
        "gid": 0, 
        "group": "root", 
        "mode": "0777", 
        "owner": "root", 
        "size": 10, 
        "src": "/etc/fstab", 
        "state": "link", 
        "uid": 0
    }
    192.168.1.6 | SUCCESS => {
        "changed": true, 
        "dest": "/var/tmp/fstab.link", 
        "gid": 0, 
        "group": "root", 
        "mode": "0777", 
        "owner": "root", 
        "size": 10, 
        "src": "/etc/fstab", 
        "state": "link", 
        "uid": 0
    }
    

    12、cron模块计划任务

    对目标主机,传递参数,设置计划任务

    [root@rs1 ansible]# ansible all -m crom -a "minute=*/3 job='/usr/sbin/update 192.168.1.1 &> /dev/null' name=none state=present"#对所有目标主机 ,m使用模块,crom计划任务,创建任务每三分钟同步时间
    

    13、yum模块安装软件程序包

    rpm软件的安装

    [root@rs1 ansible]# ansible all -m yum -a "name=ngix state=instlled"#对所有主机安装ngix
    

    14、service模块管理目标服务

    对目标主机,传递参数,管理服务。

    [root@rs1 ansible]# ansible all -m service -a"name=httpd state=started"#对所有主机启动httpd服务
    [root@rs1 ansible]# ansible all -m service -a"name=httpd state=stoped"#对所有主机停止httpd服务
    

    15、script模块脚本管理

    [root@rs1 ansible]# vim /tmp/test.sh#编写一个测试脚本
    对目标主机,传递参数,执行本地bash脚本

    #!binbash
    #
    echo "ansible script" > /tmp/ansible.txt
    [root@rs1 ansible]# ansible all -m script -a "/tmp/test.sh"#所有目标主机执行本地bash脚本
    

    注意:ansible普通命令用法很难复用

    三、playbook

    • playbook解决了ansible普通命令难以复用的缺点,使用yaml格式保存,所有首先要了解YAML。
    • playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联同起来按事先编排的机制同唱一台大戏。

    1、YAML介绍

    YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。

    YAML Ain't Markup Language,即YAML不是XML。不过,在开发的这种语言时,YAML的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。其特性:

    YAML的可读性好
    YAML和脚本语言的交互性好
    YAML使用实现语言的数据类型
    YAML有一个一致的信息模型
    YAML易于实现
    YAML可以基于流来处理
    YAML表达能力强,扩展性好

    2、YAML语法

    YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用"-"来代表,Map里的键值对用":"分隔。

    • 服务安装示例(redis服务)
    [root@rs1 ~]# mkdir playbooks#创建目录
    [root@rs1 ~]# cd playbooks
    [root@rs1 playbooks]# ls
    [root@rs1 playbooks]# vim first.yaml#创建一个新的以.yaml 结尾的playbooks
    
    - hosts: all #定义目标主机
      remote_user: root#使用用户
      tasks: #任务
      - name: install redis#将要执行的第一个任务
        yum: name=redis state=latest#执行任务的设置
      - name: name: start redis#将要执行的第二个任务
        service: name=redis state=started#执行任务的设置
    
    [root@rs1 playbooks]# ansible-playbook --syntax-check first.yaml#语法检查
    
    playbook: first.yaml
    [root@rs1 playbooks]# ansible-playbook --list-hosts first.yaml#此playbooks涉及到那些主机
    
    playbook: first.yaml
    
      play #1 (all): all    TAGS: []
        pattern: [u'all']
        hosts (2):
          192.168.1.12
          192.168.1.6
    [root@rs1 playbooks]# ansible-playbook --list-hosts --list-tasks first.yaml#涉及到的主机上将要执行的任务(标签为空)
    
    playbook: first.yaml
    
      play #1 (all): all    TAGS: []
        pattern: [u'all']
        hosts (2):
          192.168.1.12
          192.168.1.6
        tasks:
          install redis TAGS: []
          start redis   TAGS: []
          start redis   TAGS: []
    [root@rs1 playbooks]# ansible-playbook -C first.yaml #预执行
    
    PLAY [all] *********************************************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [192.168.1.6]
    ok: [192.168.1.12]
    
    TASK [install redis] ***********************************************************
    changed: [192.168.1.12]
    changed: [192.168.1.6]
    
    TASK [start redis] *************************************************************
    changed: [192.168.1.6]
    changed: [192.168.1.12]
    
    PLAY RECAP *********************************************************************
    192.168.1.12               : ok=3    changed=2    unreachable=0    failed=0   
    192.168.1.6                : ok=3    changed=2    unreachable=0    failed=0   
    [root@rs1 playbooks]# ansible-playbook  first.yaml #执行
    
    PLAY [all] *********************************************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [192.168.1.12]
    ok: [192.168.1.6]
    
    TASK [install redis] ***********************************************************
    changed: [192.168.1.12]
    changed: [192.168.1.6]
    
    TASK [start redis] *************************************************************
    changed: [192.168.1.12]
    changed: [192.168.1.6]
    
    PLAY RECAP *********************************************************************
    192.168.1.12               : ok=3    changed=2    unreachable=0    failed=0   
    192.168.1.6                : ok=3    changed=2    unreachable=0    failed=0   
    
    • 配置文件传递示例(redis服务):
    [root@rs1 playbooks]# cp 192.168.1.6/etc/redis.conf  ./
    [root@rs1 playbooks]# ls
    192.168.1.6  first.yaml  redis.conf
    [root@rs1 playbooks]# ansible 192.168.1.6 -m fetch -a "src=/etc/redis.conf dest=./ " #复制目标主机里面的redis配置文件到本机
    [root@rs1 playbooks]# cp 192.168.1.6/etc/redis.conf  ./#拷贝复制过来的配置文件到当前目录
    [root@rs1 playbooks]# ls
    192.168.1.6  first.yaml  redis.conf
    
    [root@rs1 playbooks]# vim redis.conf#编辑
    ......
    bind 0.0.0.0#监听所有端口
    .....
    requirepass foobared#启用密码认证功能,密码是foobared
    .....
    
    • handlers:用特定条件触发使用
      用于当关注的资源发生变化时采取一定的操作。

      “notify”这个action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,取而代之,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作。

    [root@rs1 playbooks]# cp first.yaml  second.yaml#备份一下
    [root@rs1 playbooks]# vim second.yaml #编辑
    
    - hosts: all
      remote_user: root
      tasks:
      - name: install redis
        yum: name=redis state=latest
      - name: copy config file  #任务2复制文件
        copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf owner=r
    edis#复制文件到目标主机目录下
        notify: restart redis#通知handlers触发
      - name: start redis
        service: name=redis state=started
      handlers:#定义触发任务
        - name: restart redis#触发任务一
          service: name=redis state=restarted#重新启动redis
    [root@rs1 playbooks]# ansible-playbook --syntax-check second.yaml#语法检查
    
    playbook: second.yaml
    [root@rs1 playbooks]# ansible-playbook  second.yaml
    
    PLAY [all] *********************************************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [192.168.1.12]
    ok: [192.168.1.6]
    
    TASK [install redis] ***********************************************************
    ok: [192.168.1.6]
    ok: [192.168.1.12]
    
    TASK [copy config file] ********************************************************
    changed: [192.168.1.6]
    changed: [192.168.1.12]
    
    TASK [start redis] *************************************************************
    ok: [192.168.1.6]
    ok: [192.168.1.12]
    
    RUNNING HANDLER [restart redis] ************************************************
    changed: [192.168.1.12]
    changed: [192.168.1.6]
    
    PLAY RECAP *********************************************************************
    192.168.1.12               : ok=5    changed=2    unreachable=0    failed=0   
    192.168.1.6                : ok=5    changed=2    unreachable=0    failed=0   
    
    • tags标签的使用
      只执行标签里面的任务
    [root@rs1 playbooks]# vim second.yaml 
    
    - hosts: all
      remote_user: root
      tasks:
      - name: install redis
        yum: name=redis state=latest
      - name: copy config file
        copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf owner=redis
        notify: restart redis
        tags: configfile        #添加任务标签
      - name: start redis
        service: name=redis state=started
      handlers:
        - name: restart redis
          service: name=redis state=restarted
    [root@rs1 playbooks]# ansible-playbook -t configfile  second.yaml #只执行标签里面的任务
    
    PLAY [all] *********************************************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [192.168.1.12]
    ok: [192.168.1.6]
    
    TASK [copy config file] ********************************************************
    ok: [192.168.1.12]
    ok: [192.168.1.6]
    
    PLAY RECAP *********************************************************************
    192.168.1.12               : ok=2    changed=0    unreachable=0    failed=0   
    192.168.1.6                : ok=2    changed=0    unreachable=0    failed=0   
    

    四、Ansible基础元素

    1、 变量variables

    • 变量命名:变量名仅能由字母、数字和下划线组成,且只能以字母开头。
    (1)facts可直接调用
    • facts是由正在通信的远程目标主机发回的信息,这些信息被保存在ansible变量中。要获取指定的远程主机所支持的所有facts
    [root@rs1 playbooks]# ansible 192.168.1.6 -m setup# setup模块获取目标主机信息
    
    
    [root@rs1 playbooks]# vim thir.yaml#编辑
    
    - hosts: 192.168.1.6
      remote_user: root
      tasks:
      - name: copy file
        copy: content={{ansible_env}} dest=/tmp/ansible.env#指定变量保存到目标主机目录下
    [root@rs1 playbooks]# ansible-playbook --syntax-check thir.yaml#语法检查
    [root@rs1 playbooks]# ansible-playbook  thir.yaml
    
    PLAY [192.168.1.6] *************************************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [192.168.1.6]
    
    TASK [copy file] ***************************************************************
    changed: [192.168.1.6]
    
    PLAY RECAP *********************************************************************
    192.168.1.6                : ok=2    changed=1    unreachable=0    failed=0   
    
    (2)ansible-playbook命令的命令行自定义变量

    在运行playbook的时候也可以传递一些变量供playbook使用

    [root@rs1 playbooks]# vim forth.yaml
    
    - hosts: all
      remote_user: root
      tesks:
      - name: install package {{pkgname}} #定义安装程序包任务
        yum: name={{pkgname}} state=latest#安装什么包,由自定义变量提供
    [root@rs1 playbooks]# ansible-playbook --syntax-check forth.yaml 语法检查
    [root@rs1 playbooks]# ansible-playbook -e pkgname=memcached forth.yaml#指定安装包安装
    
    PLAY [all] *********************************************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [192.168.1.12]
    ok: [192.168.1.6]
    
    TASK [install package] *********************************************************
    changed: [192.168.1.6]
    changed: [192.168.1.12]
    
    PLAY RECAP *********************************************************************
    192.168.1.12               : ok=2    changed=1    unreachable=0    failed=0   
    192.168.1.6                : ok=2    changed=1    unreachable=0    failed=0   
    
    (3)Inventory主机文件清单
    • ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名。默认的inventory file为/etc/ansible/hosts。

    • 主机文件清单可以有多个,且也可以通过Dynamic Inventory来动态生成。

    • inventory文件格式遵循INI文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中;此外,当如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明。

    ntp.xxx.com
    [webservers]
    www1.xxx.com:2222
    www2.xxx.com
    [dbservers]
    db1.xxx.com
    db2.xxx.com
    db3.xxx.com

    如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机,

    例如:[webservers]
    www[01:50].xxx.com
    [databases]
    db-[a:f].xxx.com

    [root@rs1 ansible]# vim hosts
    ........
     [websrvs]
    www[1:7].hehe.com#定义主机清单
    [root@rs1 ansible]# ansible websrvs --list-host
      hosts (7):
        www1.hehe.com
        www2.hehe.com
        www3.hehe.com
        www4.hehe.com
        www5.hehe.com
        www6.hehe.com
        www7.hehe.com
    
    
    为目标主机创建用户
    [root@rs1 playbooks]# vim fif.yaml #编辑文件
    
    - hosts: all
      remote_user: root
      tasks:
      - name: add user
        user: name=test system=no state=present
      - name: set password
        shell: echo test | passwd --stdin test
    [root@rs1 playbooks]# ansible-playbook --syntax-check fif.yaml#语法检查
    [root@rs1 playbooks]# ansible-playbook --syntax-check fif.yaml
    
    playbook: fif.yaml
    [root@rs1 playbooks]# ansible-playbook  fif.yaml
    
    PLAY [all] *********************************************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [192.168.1.12]
    ok: [192.168.1.6]
    
    TASK [add user] ****************************************************************
    changed: [192.168.1.12]
    changed: [192.168.1.6]
    
    TASK [set password] ************************************************************
    changed: [192.168.1.12]
    changed: [192.168.1.6]
    
    PLAY RECAP *********************************************************************
    192.168.1.12               : ok=3    changed=2    unreachable=0    failed=0   
    192.168.1.6                : ok=3    changed=2    unreachable=0    failed=0  
    
    (4)主机变量

    可以在inventory中定义主机时为其添加主机变量以便于在playbook中使用。

    [root@rs1 playbooks]# vim /etc/ansible/hosts 
    [websrvs]
    192.168.1.6 ansible_ssh_user=test ansible_ssh_pass=test
    192.168.1.12 ansible_ssh_user=test ansible_ssh_pass=test
    
    [root@rs1 playbooks]# ansible websrvs -m ping#对目标主机ping测试
    192.168.1.12 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    192.168.1.6 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    [root@rs1 playbooks]# ansible websrvs -m command -a  "whoami"#用户名返回测试
    192.168.1.12 | SUCCESS | rc=0 >>
    test
    
    192.168.1.6 | SUCCESS | rc=0 >>
    test
        注意: 一个组定义了指定用户 ,将会影响其他组指定用户会变的
    
    (5)组变量

    组变量是指赋予给指定组内所有主机上的在playboo中可用的变量。

    自定义变量传递:
    组变量定义方法一:
    [websrvs]
    192.168.1.6 http_port=8000
    192.168.1.12 http_port=10080
    
    
    组变量定义方法二:
    
    [websrvs]
    192.168.1.6 
    192.168.1.12 
    [websrvs:vars]
    http_port=8080
    
    
    [root@rs1 ~]# cd /root/playbooks/
    [root@rs1 playbooks]# vim vars.yaml
    
    - hosts: websrvs
      remote_user: root
      vars:                      
      - pbvar: playbook variable testing   #变量声明
      tasks:
      - name: command line variables
        copy: content={{ cmdvar }} dest=/tmp/cmd.var   #命令行变量引用,保存到指定文件
      - name: playbook variables
        copy: content={{ pbvar }} dest=/tmp/pb.var   #变量引用,保存到指定文件
      - name: host iventory variables
        copy: content={{ http_port }} dest=/tmp/hi.var  #主机列表定义引用,保存到指定文件
         [root@rs1 playbooks]# vim /etc/ansible/hosts 
    [root@rs1 playbooks]# ansible-playbook -e cmdvar="command line variable testing" vars.yaml     #执行命令测试 
    PLAY [websrvs] *****************************************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [192.168.1.12]
    ok: [192.168.1.6]
    
    TASK [command line variables] **************************************************
    changed: [192.168.1.6]
    changed: [192.168.1.12]
    
    TASK [playbook variables] ******************************************************
    changed: [192.168.1.12]
    changed: [192.168.1.6]
    
    TASK [host iventory variables] *************************************************
    changed: [192.168.1.6]
    changed: [192.168.1.12]
    
    PLAY RECAP *********************************************************************
    192.168.1.12               : ok=4    changed=3    unreachable=0    failed=0   
    192.168.1.6                : ok=4    changed=3    unreachable=0    failed=0   
    
    

    (6)组嵌套

    inventory中,组还可以包含其它的组,并且也可以向组中的主机指定变量。不过,这些变量只能在ansible-playbook中使用,而ansible不支持。例如:

    [apache]
    httpd1.xxx.com
    httpd2.xxx.com
    
    [nginx]
    ngx1.xxx.com
    ngx2.xxx.com
    
    [webservers:children]
    apache
    nginx
    
    [webservers:vars]
    ntp_server=ntp.xxx.com
    

    2、模板模块template

    文本文档脚本,使用模板语言编写,支持Jinja2表达式语法

    [root@rs1 playbooks]# cp redis.conf redis.conf.j2
    [root@rs1 playbooks]# vim redis.conf.j2  #编辑文件
    ....
    bind {{ ansible_ens33.ipv4.address }} #编辑模板段变量
    .....                         
    [root@rs1 playbooks]# vim template.yaml  #编辑playbook
    
    - hosts: 192.168.1.6
      remote_user: root
      tasks:
      - name: install config file
        template: src=/root/playbooks/redis.conf.j2 dest=/tmp/redis.conf
    [root@rs1 playbooks]# ansible-playbook template.yaml#执行
    PLAY [192.168.1.6] *************************************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [192.168.1.6]
    
    TASK [install config file] *****************************************************
    changed: [192.168.1.6]
    
    PLAY RECAP *********************************************************************
    192.168.1.6                : ok=2    changed=1    unreachable=0    failed=0   
    
    

    客户端:

    [root@vs ~]# vim /tmp/redis.conf
    .......
    bind 192.168.1.6    #已把客户主机ip写入redis里面了
    ........  
    

    示例二:
    不同主机,得到不同的配置

    vim listen.conf
    listen {{ http_port }}
    
    vim httpd.yaml
    - hosts:websrvs
     remote_user: root
     tasks:
       - name: install httpd
        yum: name=httpd state=latest
       - name: install config file
        template: src=/root/playbooks/mylisten.conf dest=/etc/httpd/conf.d/mylinsten.conf
    - name: start httpd
    service: name=httpd state=started
    
    ansible-playbook --syntax-check httpd.yaml
    ansible-playbook httpd.yaml
    

    3、when语句条件测试语句:

    • 如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试。

    • 在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法。

    when:在task中使用,jinja2的语法格式
    .- name: install conf file
    template:src=files
    when:什么时候执行任务

    判断当前系统是debian系统,就按照Apache2

    示例:

    vim os.yaml
          - hosts: websrvs
           remote_user: root
           tasks:
           - name: install httpd
            yum: name=httpd state=latest  
            when:ansible_os_family ==" RedHat"#判断是否是红帽系统
            - name: install apche2
            apt: name=apache2 state=latest
            when: ansible_os_family == "Debian"#判断是否是debian系统
    ansible-playbook -c os.yaml
    

    when语句中还可以使用Jinja2的大多“filter”,例如要忽略此前某语句的错误并基于其结果(failed或者sucess)运行后面指定的语句,可使用类似如下形式:

    tasks:
      - command: /bin/false
        register: result
        ignore_errors: True
      - command: /bin/something
        when: result|failed
      - command: /bin/something_else
        when: result|success
      - command: /bin/still/something_else
        when: result|skipped
    

    此外,when语句中还可以使用facts或playbook中定义的变量

    4、迭代

    • 当有需要重复性执行的任务时,可以使用迭代机制。其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语句来指明迭代的元素列表即可。
    示例:安装多个程序包
            vim  iter.yaml
            - hosts: websrvs
             remote_user: root
             tasks:
             - name:  instsll {{ item }} package
              yum: name= {{ item }} state=latest#安装with_items里面的程序包
              with_items:
              - tomcat
              - tomcat-webapps
              - mariadb-server
        ansible-playbook  iter.yaml
    

    5、角色:roles

    • ansilbe自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。

    • 自包含的目录,以特定的层级目录结构化组织
      mkdir -pv /etc/ansible/roles/nginx/{files,templates,tasks,vars,handlers,meta,default}

    示例:利用roles安装nginx,并配置启动
    cd /etc/ansible
    vim roles/nginx/templates/vhost1.conf.j2 #编辑模板文件
       server{
               lisen 8080;
               server_name {{ anible_fqdn }}; 获取主机名
               location / { 
                        root "/ngxdata/vhost1";
                 }
               }
    vim roles/nginx/files/index.html#编辑测试页
       <h1>vhost</h1>
    
    vim roles/nginx/handers/main.yml #编辑触发文件
       - name: restart nginx
        service: name=nginx  state=restarted
    
    vim roles/nginx/vars/main.yml#编辑变量文件
       ngxroot: /ngxdata/vhost1   #这里定义必须是字典模式,不加'-'
    
    vim /etc/ansible/roles/nginx/tasks/main.yml
        - name:  install nginx
         yum: name=nginx state=latest
         when: ansible_os_family == "RedHat"#检查是否是红帽系统
        - name: install conf
         temlate: src=vhost1.conf.j2 dest=/etc/nginx/conf.d/vhost1.conf#传递模板文件
         tags: conf  标签
         notify: restart nginx
        -name: install site home directory
         file: path={{ ngxroot }} state=directory
        -name: install index page
         copy: src=index.html dist={{ ngxroot }}/#拷贝本地index测试页到目标主机的nginx根目录
        -name: start nginx
         service:name=nginx state=started#启动nginx
    
    cd   
    vim nginx.yml
       - hosts: websrvs
         remote_user: root
        roles:
         - nginx   #调用角色
    
    ansible-playbook -syntax-check nginx.yml #语法检查
    ansible-playbook nginx.yml #执行
    
    

    四、配置文件设置常用设置

    配置文件设置

    vim  ansible.cfg
    
    [defaults]
    forks=5  一次管控多少主机
    sudo_user=root  切换到那个管理员  
    ask_pass=true   切换时候是否需要密码
    remote_port =22 远程端口
    
    roles_path  角色存放位置
    module_name  不指明时候 调用默认模块
    

    客户端主机主动到ansible服务器获取配置用ansible-vcs第三方软件来实现,实际应用中较少使用。

    参考链接:https://www.jianshu.com/p/3d50899842e2

    相关文章

      网友评论

          本文标题:ansible基础知识

          本文链接:https://www.haomeiwen.com/subject/ejhvvftx.html