Ansible安装使用

Ansible安装使用

1. Ansible安装

1.1 配置eprl源

yum install epel-release

1.2 yum安装ansible

 yum install ansible

1.3 加入被控端IP

vim /etc/ansible/hosts #在该文件中加入IP

1.4 配置控制主机ssh秘钥

  • 在控制主机中生成ssh秘钥对
ssh-keygen -t rsa 

一路回车即可在$HOME/.ssh目录下生成id_rsa和id_rsa.put私钥和公钥两个文件。

  • 将公钥拷贝到管理主机中.ssh/authorized_keys文件中,实现免密码登录远程管理主机
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.0.200

ssh-copy-id命令会自动将id_rsa.pub文件的内容追加到远程主机root用户下.ssh/authorized_keys文件中。

1.5 修改配置文件

vim /etc/ansible/ansible.cfg
  • 禁用每次执行ansible命令检查 ssh key host
host_key_checking = False
  • 开启日志记录
log_path = /var/log/ansible.log
  • ansible连接加速配置
[accelerate]
#accelerate_port = 5099
accelerate_port = 10000
#accelerate_timeout = 30
#accelerate_connect_timeout = 5.0
# If set to yes, accelerate_multi_key will allow multiple
# private keys to be uploaded to it, though each user must
# have access to the system via SSH to add a new key. The default
# is "no".
accelerate_multi_key = yes

1.6 测试

批量执行ping命令

ansible all -m ping

2. ansible使用

2.1 ansible常用命令

2.1.1 ansible命令集

/usr/bin/ansible  Ansibe AD-Hoc 临时命令执行工具,常用于临时命令的执行
/usr/bin/ansible-doc   Ansible 模块功能查看工具
/usr/bin/ansible-galaxy  下载/上传优秀代码或Roles模块 的官网平台,基于网络的
/usr/bin/ansible-playbook  Ansible 定制自动化的任务集编排工具
/usr/bin/ansible-pull  Ansible远程执行命令的工具,拉取配置而非推送配置(使用较少,海量机器时使用,对运维的架构能力要求较高)
/usr/bin/ansible-vault  Ansible 文件加密工具
/usr/bin/ansible-console  Ansible基于Linux Consoble界面可与用户交互的命令执行工具

其中比较常用的是/usr/bin/ansible 和 /usr/bin/ansible-playbook

2.1.2 ansible-doc命令
ansible-doc 命令常用于获取模块信息及其使用帮助,一般用法如下:

ansible-doc -l				#获取全部模块的信息
ansible-doc -s MOD_NAME		#获取指定模块的使用帮助

ansible-doc全部命令

[root@server ~]# ansible-doc
Usage: ansible-doc [options] [module...]

Options:
  -h, --help            show this help message and exit  # 显示命令参数API文档
  -l, --list            List available modules  #列出可用的模块
  -M MODULE_PATH, --module-path=MODULE_PATH  #指定模块的路径
                        specify path(s) to module library (default=None)
  -s, --snippet         Show playbook snippet for specified module(s)  #显示playbook制定模块的用法
  -v, --verbose         verbose mode (-vvv for more, -vvvv to enable  # 显示ansible-doc的版本号查看模块列表:
                        connection debugging)
  --version             show program's version number and exit

查看mysql信息

[root@yusy-test yusy]# ansible-doc -l |grep mysql
azure_rm_mysqlfirewallrule_info                               Get Azure MySQL Firewall Rule facts
azure_rm_mysqlconfiguration_info                              Get Azure MySQL Configuration facts
mysql_info                                                    Gather information about MySQL servers
mysql_db                                                      Add or remove MySQL databases from a remote host
azure_rm_mysqlserver_info                                     Get Azure MySQL Server facts
azure_rm_mysqldatabase_info                                   Get Azure MySQL Database facts
mysql_variables                                               Manage MySQL global variables
mysql_user                                                    Adds or removes a user from a MySQL database
proxysql_backend_servers                                      Adds or removes mysql hosts from proxysql admin interface
azure_rm_mysqlconfiguration                                   Manage Configuration instance
azure_rm_mysqlfirewallrule                                    Manage MySQL firewall rule instance
azure_rm_mysqlserver                                          Manage MySQL Server instance
mysql_replication                                             Manage MySQL replication
proxysql_mysql_users                                          Adds or removes mysql users from proxysql admin interface
azure_rm_mysqldatabase                                        Manage MySQL Database instance

mysql-user

[root@yusy-test yusy]# ansible-doc -s mysql_user
- name: Adds or removes a user from a MySQL database
  mysql_user:
      append_privs:          # Append the privileges defined by priv to the existing ones for this user instead of overwriting existing ones.
      ca_cert:               # The path to a Certificate Authority (CA) certificate. This option, if used, must specify the same certificate as used by the server.
      check_implicit_admin:   # Check if mysql allows login as root/nopassword before trying supplied credentials.
      client_cert:           # The path to a client public key certificate.
      client_key:            # The path to the client private key.
      config_file:           # Specify a config file from which user and password are to be read.
      connect_timeout:       # The connection timeout when connecting to the MySQL server.
      encrypted:             # Indicate that the 'password' field is a `mysql_native_password` hash.
      host:                  # The 'host' part of the MySQL username.
      host_all:              # Override the host option, making ansible apply changes to all hostnames for a given user. This option cannot be used when creating users.
      login_host:            # Host running the database.
      login_password:        # The password used to authenticate with.
      login_port:            # Port of the MySQL server. Requires `login_host' be defined as other than localhost if login_port is used.
      login_unix_socket:     # The path to a Unix domain socket for local connections.
      login_user:            # The username used to authenticate with.
      name:                  # (required) Name of the user (role) to add or remove.
      password:              # Set the user's password..
      priv:                  # MySQL privileges string in the format: `db.table:priv1,priv2'. Multiple privileges can be specified by separating each one using a forward slash:
                               `db.table:priv/db.table:priv'. The format is based on MySQL `GRANT' statement. Database and table names can be quoted, MySQL-style. If column
                               privileges are used, the `priv1,priv2' part must be exactly as returned by a `SHOW GRANT' statement. If not followed, the module will always
                               report changes. It includes grouping columns by permission (`SELECT(col1,col2') instead of `SELECT(col1',SELECT(col2))).
      sql_log_bin:           # Whether binary logging should be enabled or disabled for the connection.
      state:                 # Whether the user should exist. When `absent', removes the user.
      update_password:       # `always' will update passwords if they differ. `on_create' will only set the password for newly created users.

2.1.3 ansible命令详解
命令的具体格式如下:

ansible <host-pattern> [-f forks] [-m module_name] [-a args]

也可以通过ansible -h来查看帮助,常用的选项意义如下:

  • -a ,MODULE_ARGS   #模块的参数,如果执行默认COMMAND的模块,即是命令参数,如: “date”,“pwd”等等
  • -k,–ask-pass #ask for SSH password。登录密码,提示输入SSH密码而不是假设基于密钥的验证
    –ask-su-pass #ask for su password。su切换密码
  • -K,–ask-sudo-pass #ask for sudo password。提示密码使用sudo,sudo表示提权操作
  • –ask-vault-pass #ask for vault password。假设我们设定了加密的密码,则用该选项进行访问
  • -B SECONDS #后台运行超时时间
  • -C #模拟运行环境并进行预运行,可以进行查错测试
  • -c CONNECTION #连接类型使用
  • -f FORKS #并行任务数,默认为5
  • -i INVENTORY #指定主机清单的路径,默认为/etc/ansible/hosts
  • –list-hosts #查看有哪些主机组
  • -m MODULE_NAME #执行模块的名字,默认使用 command 模块,所以如果是只执行单一命令可以不用 -m参数
  • -o #压缩输出,尝试将所有结果在一行输出,一般针对收集工具使用
  • -S #用 su 命令
  • -R SU_USER #指定 su 的用户,默认为 root 用户
  • -s #用 sudo 命令
  • -U SUDO_USER #指定 sudo 到哪个用户,默认为 root 用户
  • -T TIMEOUT #指定 ssh 默认超时时间,默认为10s,也可在配置文件中修改
  • -u REMOTE_USER #远程用户,默认为 root 用户
  • -v #查看详细信息,同时支持-vvv,-vvvv可查看更详细信息

2.2 ansible常用模块

2.2.1 主机连通性测试
使用以下命令进行主机连通性测试

ansible web -m ping

2.2.2 command模块
这个模块可以直接在远程主机上执行命令,并将结果返回本主机,如:

ansible web -m command -a 'ss -ntl'
ansible web -m command -a 'ls -a /home/work'

command模块接受命令名称,后面是空格分隔的列表参数。给定的命令将在所有选定的节点上执行。它不会通过shell进行处理,比如$HOME和操作如"<",">","|",";","&" 工作(需要使用(shell)模块实现这些功能)。注意,该命令不支持| 管道命令。
该模块常用的几个命令为

chdir       # 在执行命令之前,先切换到该目录
executable # 切换shell来执行命令,需要使用命令的绝对路径
free_form   # 要执行的Linux指令,一般使用Ansible的-a参数代替。
creates  # 一个文件名,当这个文件存在,则该命令不执行,可以用来做判断
removes # 一个文件名,这个文件不存在,则该命令不执行

命令示例如下:

ansible web -m command -a 'chdir=/data/ ls'	#先切换到/data/ 目录,再执行“ls”命令
ansible web -m command -a 'creates=/data/aaa.jpg ls'	#如果/data/aaa.jpg存在,则不执行“ls”命令
ansible web -m command -a 'removes=/data/aaa.jpg cat /data/a'	#如果/data/aaa.jpg存在,则执行“cat /data/a”命令

2.2.3 shell模块
shell模块可以在远程主机上调用shell解释器运行命令,支持shell的各种功能,例如管道等。只要是shell命令,都可以通过这个模块在远程主机上运行。
如:

ansible web -m shell -a 'cat /etc/passwd |grep "keer"'

2.2.4 copy模块
这个模块用于将文件复制到远程主机,同时支持给定内容生成文件和修改权限等。
其相关选项如下:

src    #被复制到远程主机的本地文件。可以是绝对路径,也可以是相对路径。如果路径是一个目录,则会递归复制,用法类似于"rsync"
content   #用于替换"src",可以直接指定文件的值
dest    #必选项,将源文件复制到的远程主机的绝对路径
backup   #当文件内容发生改变后,在覆盖之前把源文件备份,备份文件包含时间信息
directory_mode    #递归设定目录的权限,默认为系统默认权限
force    #当目标主机包含该文件,但内容不同时,设为"yes",表示强制覆盖;设为"no",表示目标主机的目标位置不存在该文件才复制。默认为"yes"
others    #所有的 file 模块中的选项可以在这里使用

用法举例如下:

  • 复制文件
ansible web -m copy -a 'src=~/hello dest=/data/hello' 
  • 给定内容生成文件,并指定权限
ansible web -m copy -a 'content="I am keer\n" dest=/data/name mode=666'
  • 覆盖
ansible web -m copy -a 'content="I am keerya\n" backup=yes dest=/data/name mode=666'

2.2.5 file模块
该模块主要用于设置文件的属性,比如创建文件、创建链接文件、删除文件等。
下面是一些常见的命令:

force  #需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
group  #定义文件/目录的属组。后面可以加上mode:定义文件/目录的权限
owner  #定义文件/目录的属主。后面必须跟上path:定义文件/目录的路径
recurse  #递归设置文件的属性,只对目录有效,后面跟上src:被链接的源文件路径,只应用于state=link的情况
dest  #被链接到的路径,只应用于state=link的情况
state  #状态,有以下选项:
  • directory :如果目录不存在,就创建目录
  • file:即使文件不存在,也不会被创建
  • link:创建软连接
  • hard:创建硬链接
  • touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
  • absent:删除目录、文件或者取消链接文件
    用法举例如下:
  • 创建目录
ansible web -m file -a 'path=/data/app state=directory'
  • 创建链接文件
ansible web -m file -a 'path=/data/bbb.jpg src=aaa.jpg state=link'
  • 删除文件
ansible web -m file -a 'path=/data/bbb.jpg state=absent'

2.5.6 fetch 模块
该模块用于从远程某主机获取(复制)文件到本地。
有两个选项

  • dest:用来存放文件的目录
  • src:在远程拉取的文件,并且必须是一个file,不能是目录

举例如下:

ansible web -m fetch -a 'src=/data/hello dest=/data'  

文件保存的路径在我们设置的接收目录下的被管制主机ip目录下
2.5.7 cron模块
该模块适用于管理cron计划任务的。其使用的语法和crontab文件中的语法一致,同时,可以指定以下选项:

  • day= #日应该运行的工作( 1-31, *, */2, )
  • hour= # 小时 ( 0-23, *, */2, )
  • minute= #分钟( 0-59, *, */2, )
  • month= # 月( 1-12, *, /2, )
  • weekday= # 周 ( 0-6 for Sunday-Saturday, )
  • job= #指明运行的命令是什么
  • name= #定时任务描述
  • reboot # 任务在重启时运行,不建议使用,建议使用special_time
  • special_time #特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly(每周),daily(每天),hourly(每小时)
  • state #指定状态,present表示添加定时任务,也是默认设置,absent表示删除定时任务 user # 以哪个用户的身份执行

举例如下:

  • 添加计划任务
ansible web -m cron -a 'name="ntp update every 5 min" minute=*/5 job="/sbin/ntpdate 172.17.0.1 &> /dev/null"'
  • 查看计划任务
ansible web -m shell -a 'crontab -l'
  • 删除计划任务
ansible web -m cron -a 'name="ntp update every 5min"minute=*/5 jbo="/sbin/ntpdate 172.17.0.1 & >/dev/null" state=absent'

2.5.8 yum 模块
该模块主要用于软件的安装
其选项如下:

name=  #所安装的包的名称
state=  #present--->安装, latest--->安装最新的, absent---> 卸载软件。
update_cache  #强制更新yum的缓存
conf_file  #指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
disable_pgp_check  #是否禁止GPG checking,只用于presentor latest。
disablerepo  #临时禁止使用yum库。 只用于安装或更新时。
enablerepo  #临时使用的yum库。只用于安装或更新时。

示例:

ansible web -m yum -a 'name=htop state=present'

2.5.9 service模块
该模块用于服务程序的管理。
其主要选项如下:

arguments #命令行提供额外的参数
enabled #设置开机启动。
name= #服务名称
runlevel #开机启动的级别,一般不用指定。
sleep #在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。(定义在剧本中。)
state #有四种状态,分别为:started--->启动服务, stopped--->停止服务, restarted--->重启服务, reloaded--->重载配置
  • 开启服务并设置开机自启动
ansible web -m service -a 'name=nginx state=started enable=true'
  • 关闭服务
ansible web -m servuce -a 'name=nginx state=stopped'

2.5.10 user模块
该模块主要是用来管理用户账号。
其主要选项如下:

comment  # 用户的描述信息
createhome  # 是否创建家目录
force  # 在使用state=absent时, 行为与userdel –force一致.
group  # 指定基本组
groups  # 指定附加组,如果指定为(groups=)表示删除所有组
home  # 指定用户家目录
move_home  # 如果设置为home=时, 试图将用户主目录移动到指定的目录
name  # 指定用户名
non_unique  # 该选项允许改变非唯一的用户ID值
password  # 指定用户密码
remove  # 在使用state=absent时, 行为是与userdel –remove一致
shell  # 指定默认shell
state  # 设置帐号状态,不指定为创建,指定值为absent表示删除
system  # 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
uid  # 指定用户的uid

举例如下:

  • 添加一个用户并指定其UID
ansible web -m user -a 'name=yusy uid=11111'
  • 删除用户
ansible web -m user -a 'name=yusy state=absent'

2.5.11 group 模块
该模块主要用于添加或删除组。
常用的选项如下:

  • gid=  #设置组的GID号
  • name=  #指定组的名称
  • state=  #指定组的状态,默认为创建,设置值为absent为删除
  • system=  #设置值为yes,表示创建为系统组
    举例如下:
  • 创建组
ansible web -m group -a 'name=yusy gid=111'
  • 删除组
ansible web -m group -a 'name=yusy state=absent'

2.5.12 script 模块
该模块用于将本机的脚本在被管理端的机器上运行
该模块直接制定脚本的路径即可,具体使用方法如下:

  1. 写一个脚本,并给其加上执行权限
vim /tmp/df.sh
  1. 直接运行命令来实现在被管理端执行该脚本
ansible web -m script -a '/tmp/df.sh'

2.5.13 setup 模块
该模块主要用于收集信息,是通过调用facts组件来实现的。
facts组件是Ansible用于采集被管机器设备信息的一个功能,我们可以使用setup模块查机器的所有facts信息,可以使用filter来查看指定信息。整个facts信息被包装在一个JSON格式的数据结构中,ansible_facts是最上层的值。
facts就是变量,内建变量 。每个主机的各种信息,cpu颗数、内存大小等。会存在facts中的某个变量中。调用后返回很多对应主机的信息,在后面的操作中可以根据不同的信息来做不同的操作。如redhat系列用yum安装,而debian系列用apt来安装软件。

  • 查看信息
    使用命令获取到变量的值,如下:
ansible web -m setup -a 'filter="*mem*"'
  • 保存信息

setup模块还有一个很好用的功能就是可以保存所筛选的信息至主机上,同时,文件名为被管制的主机的IP,这样方便知道是哪台机器出的问题。
示例如下:

ansible web -m setup -a 'filter="*mem*"' --tree /tmp/facts

3. ansible-playbook

3.1 Playbook介绍

Playbook与ad-hoc相比,是一种完全不同的运用ansible的方式。类似于saltstack的state状态文件。ad-hoc无法持久使用,playbook可以持久使用。
Playbook是由一个或多个play组成的列表,play的主要功能在于将事先归并为一组的主机装扮成通过ansible中的task定义好的角色。从根本上来讲,所谓的task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联合起来按事先编排的机制完成某一任务。

3.2 Playbook核心元素

  • Hosts -执行的远程主机列表
  • Tasks -任务集
  • Varniables- 内置变量或自定义变量在playbook中调用
  • Templates -模板,即使用模板语法的文件,比如配置文件等
  • Handlersnotity-结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
  • tags-标签,指定某条任务执行,用于选择运行playbook中的部分代码。

3.3Playbook语法

ansible-playbook采用YAML语法编写,后缀可以使yaml,也可以是yml
示例:

---
 - hosts: control-node    # 将要执行任务的主机,已经在hosts文件中定义好了,可以是单个主机或主机组
  remote_user: root      # 在目标主机上执行任务时的用户身份
  vars:                  #定义变量
    - pkg: httpd         #变量
  tasks:                 #定义一个任务的开始
    - name: "install httpd package."   #定义任务的名称
      yum: name={
    
    {
    
     pkg }}  state=installed   #调用模块,具体要做的事情
    - name: "copy httpd configure file to remote host."
     copy: src=/root/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
     notify:              #定义执行一个动作(action)让handlers来引用执行,与handlers配合使用。当这个任务执行状态发生改变时,触发handlers执行.
      - restart httpd     #执行的动作,这里必须与handlers中的name定义内容一致
 - name: "boot httpd service."
     service: name=httpd state=started
  handlers:                # handlers与tasks是同一级别。处理器:task中notify定义的action出发执行相应的处理动作
    - name: restart httpd  #要与notify定义的内容相同
      service: name=httpd state=restarted   #触发要执行的动作

3.3.1 playbook语法有如下特性:

  • 在单一一个playbook文件中,可以用连续三个连字号(—)区分多个play。还可以选择连续三个点号(…)用来表示play的结尾,也可以省略。
  • 次行开始写Playbook的内容,但是一般要求写明该playbook的功能;
  • 使用#号注释代码。
  • 缩进必须统一,不能空格和tab混用
  • 缩进级别必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的;
  • YAML文件内容和Linux系统大小写判断方式保持一致,是区分大小写的,k/v的值均需大小写敏感。
  • K/V的值可同行写,也可换行写。同行使用 :分隔,换行写需要以 - 分隔;
  • V可以是字符串,也可以是一个列表。
  • 一个完整的代码块功能块最起码要包括两个元素 name:task。

3.3.2 执行playbook
第一次执行可以加-c选项,检查写的playbook是否正确

ansible-playbook -c yaml/httpd.yaml 

3.4 Playbook的运行方式

通过ansible-playbook命令运行
格式:ansible-playbook <filename.yml> … [options]
#ansible-playbook常用选项:

  • –check or -C #只检测可能会发生的改变,但不真正执行操作
  • –list-hosts #列出运行任务的主机
  • –list-tags #列出playbook文件中定义所有的tags
  • –list-tasks #列出playbook文件中定义的所以任务集
  • –limit #主机列表 只针对主机列表中的某个主机或者某个组执行
  • -f #指定并发数,默认为5个
  • -t #指定tags运行,运行某一个或者多个tags。(前提playbook中有定义tags)
  • -v #显示过程 -vv -vvv更详细

3.5 Playbook 中元素属性

3.5.1 主机与用户

在一个playbook开始时,最先定义的是要操作的主机和用户

---
- hosts: 192.168.1.31
  remote_user: root

除了上面的定义外,还可以在某一个tasks中定义要执行该任务的远程用户

tasks: 
  - name: run df -h
    remote_user: test
    shell: name=df -h

还可以定义使用速度授权用户执行该任务

tasks: 
  - name: run df -h
    sudo_user: test
    sudo: yes
    shell: name=df -h

3.5.2 tasks任务列表
每一个task必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很清楚的辨别是属于哪一个task的,如果没有定义name,action的值将会用作输出信息中标记特定的task。
每一个playbook中可以包含一个或者多个tasks任务列表,每一个tasks完成具体的一件事,(任务模块)比如创建一个用户或者安装一个软件等,在hosts中定义的主机或者主机组都将会执行这个被定义的tasks。

tasks:
  - name: create new file
    file: path=/tmp/test01.txt state=touch
  - name: create new user
    user: name=test001 state=present

3.5.3 Handlers与Notify
很多时候当一个配置发生改变,则需要重启服务,(比如httpd配置文件发生改变了),这时候就可以用到handlers和notify了。
当发生改动时,notify actions会在playbook的每一个task结束时被触发,而且及时有多个不同task通知改动的发生,notify actions 只会被触发一次。比如多个resources指出因为一个配置文件被改动,所以Apache需要重启,但是重新启动的操作只会被执行一次。

用于安装httpd并配置启动

---
- hosts: 192.168.1.31
  remote_user: root

  tasks:
  - name: install httpd
    yum: name=httpd state=installed
  - name: config httpd
    template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify:
      - restart httpd
  - name: start httpd
    service: name=httpd state=started

  handlers:
    - name: restart httpd
      service: name=httpd state=restarted
#这里只要对httpd.conf配置文件作出了修改,修改后需要重启生效,在tasks中定义了restart httpd这个action,然后在handlers中引用上面tasks中定义的notify。

3.6 playbook中变量的使用

3.6.1 yaml文件中定义变量
编写playbook时,直接在里面定义变量,然后直接引用,可以定义多个变量;注意:如果在执行playbook时,又通过-e参数指定变量的值,那么会以-e参数指定的为准。

---
- hosts: compute-node
  remote_user: root
  vars:
    pkg: httpd        # 定义变量
  tasks:
    - name: install httpd service
      yum: name={
    
    {
    
     pkg }} state=installed     # 引用变量

playbook中用vars关键字声明变量,变量定义-- 变量名:变量值
变量引用:{ {变量名}}

3.6.2 引用外部变量
在命令行使用 --extra-vars参数赋值变量
执行playbook的时候通过参数-e(或者–extra_vars)传入变量,这样传入的变量在整个playbook中都可以被调用,属于全局变量

[root@LOCALHOST ~]# ansible-playbook yaml/extra_vars.yaml --extra-vars "filename=temp.txt"
[root@ansible PlayBook]# ansible-playbook -e "pkg=httpd" variables.yml

  • hosts: control-node
    remote_user: root
    tasks:
    • name: create a file
      file:
      path: /tmp/{ { filename }} # 引用外部变量
      mode: 0644
      state: touch

–extra-vars “变量名=变量值”

3.6.3 资产清单(inverntory)中定义的变量
资产清单(/etc/ansible/hosts)

[root@LOCALHOST ~]# cat /etc/ansible/hosts
[load-node]
openstack-load1 
openstack-load2

[compute-node]
openstack-compute1 ansible_ssh_host=10.0.1.10 ansible_ssh_port=2002 ansible_ssh_user=stanley ansible_ssh_pass=etyfhzmweadf
openstack-compute2

[control-node]
openstack-control1 filename=control1.txt    # 主机变量
openstack-control2 filename=control2.txt

[openstack:children]
load-node
compute-node
control-node

[openstack:vars]
issue="Hello, World"    # 组变量

注意:组变量定义时,不要落下关键字vars,[组名:vars]。 在playbook中引用{ { 变量名 }}即可。

ansible内置了一些固定的主机变量名,在inventory中定义其值,如下:

  • ansible_ssh_host 将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置.
  • ansible_ssh_port ssh端口号.如果不是默认的端口号,通过此变量设置.
  • ansible_ssh_user 默认的 ssh 用户名
  • ansible_ssh_pass ssh 密码(这种方式并不安全,我们强烈建议使用 --ask-pass 或 SSH 密钥)
  • ansible_sudo_pass sudo 密码(这种方式并不安全,我们强烈建议使用 --ask-sudo-pass)
  • ansible_sudo_exe (new in version 1.8) sudo 命令路径(适用于1.8及以上版本)
  • ansible_connection 与主机的连接类型.比如:local, ssh 或者 paramiko. Ansible1.2 以前默认使用
  • paramiko.1.2 以后默认使用 ‘smart’,‘smart’ 方式会根据是否支持 ControlPersist, 来判断’ssh’ 方式是否可行.
  • ansible_ssh_private_key_file ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的情况.
  • ansible_shell_type 目标系统的shell类型.默认情况下,命令的执行使用 ‘sh’ 语法,可设置为 ‘csh’ 或 ‘fish’.
  • ansible_python_interpreter 目标主机的 python 路径.适用于的情况: 系统中有多个Python,
    或者命令路径不是"/usr/bin/python",比如 *BSD, 或者 /usr/bin/python.不是 2.X 版本的
    Python.我们不使用 “/usr/bin/env” 机制,因为这要求远程用户的路径设置正确,且要求 “python”
    可执行程序名不可为 python以外的名字(实际有可能名为python26).

3.6.4 直接使用facts变量
setup模块默认是获取主机信息的,有时候在playbook中需要用到,所以可以直接调用。

[root@LOCALHOST ~]# cat yaml/facts_vars.yaml
---
 - hosts: compute-node
  remote_user: root
  tasks:
    - name: write fqdn into fqdn.log
      shell: "echo {
    
    { ansible_fqdn }} {
    
    { ansible_eth1.ipv4.address }} > /tmp/fqdn.log"

上述代码中{ {ansible_fqdn}}就是直接引用的facts变量;
{ {ansible_eht1.ipv4.address}}引用的值就相当于下面这样:

{
    
         "ansible_eth1": {
    
    
       "ipv4": {
    
    
           "address":10.0.1.10,
       },    }, }

3.6.5 注册变量
在playbook中用register关键字定义一个变量,这个变量的值就是当前任务执行的输出结果。

[root@LOCALHOST ~]# cat yaml/reg_vars.yaml 
---
- hosts: load-node
  remote_user: root
  tasks:
    - name: show date
      shell: "/bin/date"
      register: date        # 注册一个变量
    - name: Record time log
      shell: "echo {
    
    { date.stdout }} > /tmp/date.log"

引用的注册变量要用{ {date.stdout}}表示标准输出

[root@openstack-load1 ~]# cat /tmp/date.log 
2018年 03月 29日 星期四 15:52:01 CST

如果直接{ { date }} 这样引用,则文件中写入的是如下内容

{
    
    stderr_lines: [], uchanged: True, uend: u2018-03-29 15:49:52.609894, failed: False, ustdout: u2018\u5e74 03\u6708 29\u65e5 \u661f\u671f\u56db 15:49:52 CST, ucmd: u/bin/date, urc: 0, ustart: u2018-03-29 15:49:52.602918, ustderr: u, udelta: u0:00:00.006976, stdout_lines: [u2018\u5e74 03\u6708 29\u65e5 \u661f\u671f\u56db 15:49:52 CST]}

3.6.6YAML文件中定义独立的变量
为了方便将所有的变量统一放在一个独立的变量YAML文件中,playbook文件直接引用文件调用变量即可。

# 定义存放变量的文件
[root@ansible PlayBook]# cat var.yml 
var1: vsftpd
var2: httpd

# 编写playbook
[root@ansible PlayBook]# cat variables.yml 
---
- hosts: all
  remote_user: root
  vars_files:    #引用变量文件
    - ./var.yml   #指定变量文件的path(这里可以是绝对路径,也可以是相对路径)

  tasks:
    - name: install package
      yum: name={
    
    {
    
     var1 }}   #引用变量
    - name: create file
      file: name=/tmp/{
    
    {
    
     var2 }}.log state=touch   #引用变量

执行playbook

[root@ansible PlayBook]# ansible-playbook  variables.yml

3.6.7 变量优先级
上述这些变量定义的方法,他们的优先级如下:

  • 命令行中定义的变量(即用-e或–extra-vars定义的变量);
  • 在Inventory中定义的连接变量(比如:ansible_ssh_user);
  • 大多数的其他变量(命令行转换、play中的变量、included的变量、role中的变量等);
  • 在Inventory中定义的其他变量;
  • Facts变量;
  • “Role”默认变量,这个是默认的值,很容易丧失优先权。

3.7 playbook中标签的使用

一个playbook文件中,执行时如果想执行某一个任务,那么可以给每个任务集进行打标签,这样在执行的时候可以通过-t选择指定标签执行,还可以通过–skip-tags选择除了某个标签外全部执行等。

编辑playbook
[root@ansible PlayBook]# cat httpd.yml 
---
- hosts: 192.168.1.31
  remote_user: root

  tasks:
    - name: install httpd
      yum: name=httpd state=installed
      tags: inhttpd

    - name: start httpd
      service: name=httpd state=started
      tags: sthttpd

    - name: restart httpd
      service: name=httpd state=restarted
      tags: 
        - rshttpd
        - rs_httpd

# 正常执行的结果
[root@ansible PlayBook]# ansible-playbook httpd.yml 

PLAY [192.168.1.31] **************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.1.31]

TASK [install httpd] *************************************************************************************************************************
ok: [192.168.1.31]

TASK [start httpd] ***************************************************************************************************************************
ok: [192.168.1.31]

TASK [restart httpd] *************************************************************************************************************************
changed: [192.168.1.31]

PLAY RECAP ***********************************************************************************************************************************
192.168.1.31               : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  • 通过-t选项指定tags进行执行
# 通过-t指定tags名称,多个tags用逗号隔开
[root@ansible PlayBook]# ansible-playbook -t rshttpd httpd.yml 

PLAY [192.168.1.31] **************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.1.31]

TASK [restart httpd] *************************************************************************************************************************
changed: [192.168.1.31]

PLAY RECAP ***********************************************************************************************************************************
192.168.1.31               : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  • 通过–skip-tags选项排除不执行的tags
 [root@ansible PlayBook]# ansible-playbook --skip-tags inhttpd httpd.yml 

PLAY [192.168.1.31] **************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.1.31]

TASK [start httpd] ***************************************************************************************************************************
ok: [192.168.1.31]

TASK [restart httpd] *************************************************************************************************************************
changed: [192.168.1.31]

PLAY RECAP ***********************************************************************************************************************************
192.168.1.31               : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

3.8 playboo的流程控制

3.8.1 when 条件判断
当关键字when后面的条件满足时(也就是通过运算得到的结果为true时),才会执行当前任务。
示例如下:

---
- hosts: load-node,img
  remote_user: root
  tasks:
  - name: "touch flag file"
    command: "touch /tmp/this_is_{
    
    { ansible_distribution }}_system" 
    when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == '6') or
          (ansible_distribution == "Debian" and ansible_distribution_major_version == '7')

上述代码中,ansible_distribution和ansible_distribution_major_version都是是Facts变量,分别表示Linux发行版和版本号

3.8.2 循环语句
playbook中的循环类型,如下表:
在这里插入图片描述

列表中前三个为常用的循环语句

  1. 标准循环 with_items
---
- name: when and with_items
  hosts: load-node
  remote_user: root
  gather_facts: false            
  tasks:
  - name: Create thress groups
    group: name=testgroup6 state=present
    ignore_errors: yes
    register: excu_result
  - name: Append excu_result to tmp.txt
    shell: "echo {
    
    { excu_result }} > /tmp/tmp.txt"
  - name: Create some users
    user: name={
    
    {
    
     item }} group=testgroup6 state=present
    when: excu_result|success
    with_items:
      - testuser1
      - testuser2
      - testuser3

释义:
gather_facts: false表示运行此playbook时不收集目标主机的系统信息。因为默认此项是开启的,每次运行playbook都会收集主机facts,这会影响playbook的运行速度。将gather_facts设为false即可关闭。
when:excu_result|success的意思为当变量excu_result执行结果为成功状态,则执行当前的任务。其中success为Ansible内部过滤器方法,返回True代表命令运行成功。还有excu_result|failed表示excu_result执行结果为失败状态;excu_result|skipped表示excu_result执行被跳过。
with_items的值还可以写成[testuser1, testuser2, testuser3]

  1. 编列字典 wth_dict

输出用户的姓名和电话:

---
 1. hosts: load-node
  remote_user: root
  tasks:
 2. name: print phone records
    debug: msg="User {
    
    { item.key }} is {
    
    { item.value.name }} ({
    
    { item.value.phone }})"
    with_dict: {
    
    'alice':{
    
    'name':'Alice Appleworth', 'phone':'13243252136'}, 'bob':{
    
    'name':'Bob Banarama', 'phone': '18766761211'}}

playbook中对字典的循环,与python中对字典循环类似,取值方法也一样

  1. 遍历目录文件with_fileglob
    遍历 /root /sh目录下的所有文件,并将其拷贝至目标主机
[root@LOCALHOST ~]# cat yaml/with_fileglob.yaml 
---
- hosts: DH-TEST
  remote_user: root
  gather_facts: false
  tasks:
  - name: create a directory
    file: path=/root/script state=directory
    ignore_errors: yes
    register: result
  - name: copy some scripts
    copy: src={
    
    {
    
     item }} dest=/root/script owner=root mode=600
    when: result|success
    with_fileglob:
      - /root/sh/*

with——fileglob匹配单个目录中的素有文件,非递归匹配模式

3.9 playbook异常处理

3.9.1 ignore_errors
在有些情况下,一些必需运行的命令或脚本会报一些错误,而这些错误并不一定真的说明有问题,但是经常会给接下来要运行的任务造成困扰,甚至直接导致playbook运行中断。
这时候我们可以在相关任务中添加ignore_errors:true来屏蔽当前任务的报错信息。ansible也将视该任务运行成功,不在报错,这样就不会对接下来要运行的任务造成额外困扰。但是要注意的是,我们不应孤独依赖ignore_errors,因为他会隐藏所有的报错信息,而应该把精力集中在寻找报错的原因上面,这样才能从根本上解决问题。
示例如下:

[root@LOCALHOST ~]# cat yaml/httpd.yaml 
---
- hosts: load-node
  remote_user: root
  vars:
    - pkg: httpd
  tasks:
    - name: "install httpd package."
      yum: name={
    
    {
    
     pkg }}  state=installed
    - name: "copy httpd configure file to remote host."
      copy: src=/root/config/httpd.conf dest=/etc/httpd/conf/httpd.conf
      notify: restart httpd
      ignore_errors: true         # 忽略错误
    - name: "start httpd service."
      tags:
        - start_httpd
      service: name=httpd state=started
  handlers:
    - name: restart httpd
      service: name=httpd state=restarted

3.9.2 failed_when
当满足一定的条件时,主动抛出错误

[root@LOCALHOST ~]# cat yaml/failed_when.yaml 
---
- hosts: DH-TEST
  remote_user: root
  gather_facts: false
  tasks:
  - name: get process
    shell: ps aux | wc -l 
    register: process_count
    failed_when: process_count > 3
  - name: touch a file
    file: path=/tmp/test3.txt state=touch owner=root mode=070

failed_when: process_count >3 当进程数大于3时主动抛出错误,后续任务就不会执行了。如果不满足条件,则不会抛出错误。

3.9.3 changed_when

[root@LOCALHOST ~]# cat yaml/changed_when.yaml 
---
- hosts: DH-TEST
  remote_user: root
  gather_facts: false
  tasks:
  - name: touch a file
    file: path=/tmp/changed_test state=touch

执行结果:
在这里插入图片描述如果想要关闭状态改变的提示,则可以添加changed_when: false,如下:

[root@LOCALHOST ~]# cat yaml/changed_when.yaml 
---
- hosts: DH-TEST
  remote_user: root
  gather_facts: false
  tasks:
  - name: touch a file
    file: path=/tmp/changed_testi2 state=touch
    changed_when: false       # 关闭状态改变提示

执行结果如下:
在这里插入图片描述

3.10 Roles

Roles是一种在大型Playbook中使用的剧本配置模式,它有着自己特定的结构。用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。
剧本roles设计思路:将公共任务、资源、变量等对象尽可能独立。
一个roles的案例如下所示:

site.yml            # 主入口文件
webservers.yml      # webserver类型服务所用的剧本
dbservers.yml       # 数据库类型的服务所用的剧本
files/              # 存放通用的将要被上传的文件
templates/          # 存放通用的模板文件
roles/              # roles目录名称是固定的
   common/          # 此目录下的各个组件是所有角色共用的
     tasks/         # 存放通用的任务文件
     handlers/      # 存放通用的处理器文件
     vars/          # 存放通用的变量文件 
     meta/          # 存放通用的角色依赖文件
   webservers/      # 存放webserver类型的服务的各个组件  
     files/         # 存放webserver角色需要的上传文件
     templates/     # 存放webserver角色需要的模板文件
     tasks/
     handlers/
     vars/
     meta/

而在playbook中,可以这样使用roles:

---
- hosts: webservers
  roles:
     - common
     - webservers

也可以向roles传递参数,例如:

---
 - hosts: webservers
  roles:
    - {
    
     role: some_role, when: "ansible_os_family == 'RedHat'"

3.10.1 创建role的步骤

  • 创建一roles命名的目录;
  • 在roles目录中分别创建以各角色命名命名的目录,如erbservers等;
  • 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用到的目录可以创建为空目录,也可以不创建。
  • 在roles目录的同级目录下创建一个yaml文件,如: site.yml,再次文件中调用各角色。

3.10.2 role内个目录中可用的文件

  • tasks目录:至少应该包含一个名为main.yml的文件,其定义了此角色的任务列表;此文件可以使用include包含其他的位于此目录中的task文件;
  • files目录:存放由copy会script等模块调用的文件;
  • templates目录:template模块会自动在此目录中寻找jinja2模板文件。
  • handlers目录:此目录中应当包含一个main.yml文件,用于定义此角色用到的各handler;在handler中使用include包含的其他的handler文件也应该位于此目录中;
  • vars目录:应当包含一个main.yml文件,用于定义此角色用到的变量;
  • meta目录:应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系;ansible1.3及其以后的版本才支持;
  • default目录:为当前角色设定默认变量时使用此目录;应当包含一个main.yml文件;

3.11 Ansible Galaxy

Ansible Galaxy是ansible官方Roles分享平台(galaxy.ansible.com),在Galaxy平台上所有人可以免费上传或下载Roles,在这里好的技巧、思想、架构得以积累和传播。

3.11.1 ansible-galaxy命令用法

[root@LOCALHOST tasks]# ansible-galaxy --help
Usage: ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] ...

Options:
  -h, --help            列出此帮助信息并退出
  -c, --ignore-certs    忽略SSL证书验证错误。
  -s API_SERVER, --server=API_SERVER  指定API目的服务器                      
  -v, --verbose         详情模式,(-vvv获取更多,-vvvv启用连接检测)
  --version             显示项目版本信息并退出
  • 搜索lamp相关的roles:
    命令如下:
ansible-galaxy search lamp
  • 安装一个搜索到的角色:
    命令如下:
ansible-galaxy install vivaserver.lamp
  • 按作者搜索roles:
ansible-galaxy search zabbix --author dj-wasabi

其中dj-wasabi是作者的用户名

3.11.2批量安装多个roles

# cat roles.txt
user1.role1,v1.0.0
user2.role2,v0.5
user2.role3 

安装

ansible-galaxy install -r roles.txt

参考
https://www.cnblogs.com/keerya/p/7987886.html
https://www.jianshu.com/p/171578692c94
https://www.cnblogs.com/yanjieli/p/10969299.html

猜你喜欢

转载自blog.csdn.net/xiguashixiaoyu/article/details/106442162