ansible的使用

一、ansible入门

1、简介

	Ansible是一个自动化统一配置管理工具,自动化主要体现在Ansible集成了丰富模块以及功能组件,可以通过一个命令完成一系列的操作,进而能减少重复性的工作和维护成本,可以提高工作效率。


2、组成

1.连接插件connection plugins用于连接主机 用来连接被管理端
2.核心模块core modules连接主机实现操作, 它依赖于具体的模块来做具体的事情
3.自定义模块custom modules根据自己的需求编写具体的模块
4.插件plugins完成模块功能的补充
5.剧本playbookansible的配置文件,将多个任务定义在剧本中,由ansible自动执行
6.主机清单inventor定义ansible需要操作主机的范围
 
最重要的一点是 ansible是模块化的 它所有的操作都依赖于模块


3、执行流程

1.Ansible读取playbook剧本,剧本中会记录对哪些主机执行哪些任务。   #web 安装nginx
2.首先Ansible通过主机清单找到要执行的主机,然后调用具体的模块。    #web 是谁
3.其次Ansible会通过连接插件连接对应的主机并推送对应的任务列表。    #使用yum模块安装nginx
4.最后被管理的主机会将Ansible发送过来的任务解析为本地Shell命令执行。   #受控端执行yum install -y nginx

二、ansible的使用

1、环境准备

2、控制端安装

#1.安装epel源
[root@m01 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
 
#2.安装Ansible
[root@m01 ~]# yum install -y ansible

3、参数解释

# ansible <host-pattern> [options]
#不常用参数
--version   #ansible版本信息
-v          #显示详细信息
-i          #主机清单文件路径,默认是在/etc/ansible/hosts
-k          #提示输入ssh密码,而不使用基于ssh的密钥认证
-C          #模拟执行测试,但不会真的执行
-T          #执行命令的超时
 
#常用参数
-m          #使用的模块名称,默认使用command模块
-a          #使用的模块参数,模块的具体动作
--syntax-check      #验证语法
 
[root@m01 ~]# ansible --version
ansible 2.9.15
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]

4、配置文件

[root@m01 ~]# rpm -qc ansible
/etc/ansible/ansible.cfg
/etc/ansible/hosts


[root@m01 ~]# cat /etc/ansible/ansible.cfg 
#inventory      = /etc/ansible/hosts      #主机列表配置文件
#library        = /usr/share/my_modules/  #库文件存放目录
#remote_tmp     = ~/.ansible/tmp          #临时py文件存放在远程主机目录
#local_tmp      = ~/.ansible/tmp          #本机的临时执行目录
#forks          = 5                       #默认并发数
#sudo_user      = root                    #默认sudo用户
#ask_sudo_pass = True                     #每次执行是否询问sudo的ssh密码
#ask_pass      = True                     #每次执行是否询问ssh密码
#remote_port    = 22                      #远程主机端口
host_key_checking = False                 #跳过检查主机指纹
log_path = /var/log/ansible.log           #ansible日志
 
#普通用户提权操作
[privilege_escalation]
#become=True
#become_method=sudo
#become_user=root
#become_ask_pass=False 

5、主机清单配置

1)、基于密码的方式
1、单主机配置
#方式一: ip + 端口 + 用户名 + 用户密码
[root@m01 ~]# vim /etc/ansible/hosts 
[web01]
10.0.0.7 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
[web02]
10.0.0.8 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
 
#测试
[root@m01 ~]# ansible web01 -m ping
10.0.0.7 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}


#方式二: ip + 用户密码
[root@m01 ~]# vim /etc/ansible/hosts 
[web01]
10.0.0.7 ansible_ssh_pass='1'
[web02]
10.0.0.8 ansible_ssh_pass='1'
 
[root@m01 ~]# ansible web02 -m ping
10.0.0.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

#方式三: ip + 变量密码
[root@m01 ~]# vim /etc/ansible/hosts 
[web01]
10.0.0.7
[web02]
10.0.0.8 
 
[web01:vars]
ansible_ssh_pass='1'



2、多主机配置

[root@m01 ~]# vim /etc/ansible/hosts 
[web_group]
10.0.0.7 ansible_ssh_pass='1'
10.0.0.8 ansible_ssh_pass='1'
 
[root@m01 ~]# ansible 'web_group' -m ping
10.0.0.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
10.0.0.7 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
2)、基于秘钥的方式
1.生成密钥对
[root@m01 ~]# ssh-keygen
 
2.推送公钥
[root@m01 ~]# ssh-copy-id 10.0.0.7
[root@m01 ~]# ssh-copy-id 10.0.0.8

3、配置主机清单
[root@m01 ~]# vim /etc/ansible/hosts 
[web_group]
10.0.0.7
10.0.0.8


4、修改host配置主机清单
#配置主机清单
[root@m01 ~]# vim /etc/ansible/hosts 
[web_group]
web01
web02
 
#配置hosts
[root@m01 ~]# vim /etc/hosts
10.0.0.7 web01
10.0.0.8 web02
 
#测试
[root@m01 ~]# ansible 'web_group' -m ping
web02 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
web01 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

6、定义整合组

1)、定义
[root@m01 ~]# vim /etc/ansible/hosts 
[web_group]
web01
web02
[nfs_server]
nfs ansible_ssh_pass='1'
[rsync_server]
backup ansible_ssh_pass='1'
[db_server]
db01 ansible_ssh_pass='1'
#定义整合组,下面包含多个组
[www:children]
web_group
nfs_server
rsync_server
 
#配置hosts
[root@m01 ~]# vim /etc/hosts
10.0.0.7 web01
10.0.0.8 web02
10.0.0.31 nfs
10.0.0.41 backup
10.0.0.51 db01
2)、查看
[root@m01 ~]# ansible www --list-host
  hosts (4):
    web01
    web02
    nfs
    backup

7、测试

#单主机
[root@m01 ~]# ansible 'web01' -m ping
 
#所有主机
[root@m01 ~]# ansible '*' -m ping
 
#所有主机
[root@m01 ~]# ansible 'all' -m ping
 
#主机组
[root@m01 ~]# ansible 'web_group' -m ping
 
#整合组
[root@m01 ~]# ansible 'www' -m ping

三、ansible ad-hoc

1、简介

ad-hoc简而言之就是"临时命令",执行完即结束,并不会保存

[root@m01 ~]# ansible web01 -m command -a 'df -h'
web01 | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3        18G  1.6G   17G   9% /
devtmpfs        476M     0  476M   0% /dev
tmpfs           487M     0  487M   0% /dev/shm
tmpfs           487M  7.7M  479M   2% /run
tmpfs           487M     0  487M   0% /sys/fs/cgroup
/dev/sda1      1014M  127M  888M  13% /boot
tmpfs            98M     0   98M   0% /run/user/0
 
[root@m01 ~]# ansible web_group -m command -a 'free -m'
web01 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:            972         128         481           7         362         658
Swap:          1023           0        1023
web02 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:            972         111         551           7         309         691
Swap:          1023           0        1023



绿色: 代表被管理端主机没有被修改
黄色: 代表被管理端主机发现变更
红色: 代表出现了故障,注意查看提示

2、ad-hoc常用模块

command             # 执行shell命令(不支持管道等特殊字符)
shell               # 执行shell命令
scripts             # 执行shell脚本
yum_repository      # 配置yum仓库
yum                 # 安装软件
copy                # 变更配置文件
file                # 建立目录或文件
service             # 启动与停止服务
systemd             # 启动与停止服务
mount               # 挂载设备
cron                # 定时任务
get_url             #下载软件
firewalld           #防火墙
selinux             #selinux
setup               #获取主机信息

注意:查看帮助
#1.查看所有模块
[root@m01 ~]# ansible-doc -l
 
#2.查看指定模块的用法
[root@m01 ~]# ansible-doc yum
 
#3.查看模块参数
[root@m01 ~]# ansible-doc -s yum

3、命令模块

1、command
#默认模块,远程执行命令
[root@m01 ~]# ansible web01 -m command -a 'free -m'
web01 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:            972         128         479           7         364         658
Swap:          1023           0        1023
 
#不支持特殊字符
[root@m01 ~]# ansible web01 -m command -a "ifconfig eth0 | awk 'NR==2 {print \$2}'"
web01 | FAILED | rc=1 >>
|: Unknown host
ifconfig: `--help' gives usage information.non-zero return code



2、shell
[root@m01 ~]# ansible web01 -m shell -a 'free -m'
web01 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:            972         128         479           7         364         658
Swap:          1023           0        1023
 
#支持特殊字符
[root@m01 ~]# ansible web01 -m shell -a "ifconfig eth0 | awk 'NR==2 {print \$2}'"
web01 | CHANGED | rc=0 >>
10.0.0.7

4、文件管理模块

1、copy
[root@m01 ~]# ansible-doc copy
EXAMPLES:
- name: Copy file with owner and permissions
  copy:
    src: /srv/myfiles/foo.conf
    dest: /etc/foo.conf
    owner: foo
    group: foo
    mode: '0644'
    backup: yes
    content: '# This file was moved to /etc/other.conf'
    follow: yes
 
src         #文件的源地址
dest        #目标地址或文件
owner       #文da件属主
group       #文件属组
mode        #文件的权限
backup      #替换的文件是否备份
content     #直接将内容写入文件
follow      #处理软连接


例子:
#推送文件并备份
[root@m01 ~]# ansible web_group -m copy -a 'src=/root/index.html dest=/root/ owner=adm group=adm backup=yes'
注意:buckup参数不是用来回滚的,需要回滚的话要备份原来m01上推送的文件
 
#直接将内容写入文件
[root@m01 ~]# ansible web_group -m copy -a 'content="rsync_backup:123456" dest=/tmp/rsync.password mode=600'


2、file模块
[root@m01 ~]# ansible-doc file
EXAMPLES:
- name: Change file ownership, group and permissions
  file:
    src: /file/to/link/to
    path: /etc/foo.conf
    owner: foo
    group: foo
    mode: '0644'
    state: link
    recurse: yes
 
path        #创建的文件或目录的地址
owner       #文件或目录的属主
group       #文件或目录的属组
mode        #文件或目录的权限
state
    link        #创建软链接
        src     #源文件
        dest    #软链接的名字
    touch       #创建文件
    directory   #创建目录
    absent      #删除,目录,文件,软链接
recurse     #递归授权


例子:#单纯的创建目录
[root@m01 ~]# ansible web01 -m file -a 'path=/code state=directory'
相当于在远程机器上执行:mkdir /code
 
#创建目录并授权
[root@m01 ~]# ansible web01 -m file -a 'path=/code state=directory owner=nginx group=nginx'
相当于在远程机器上执行:mkdir /code && chown nginx.nginx /code
 
#递归创建目录,不需要加任何参数
[root@m01 ~]# ansible web01 -m file -a 'path=/code/wordpress/wp-content/pic state=directory'
 
#递归授权目录
[root@m01 ~]# ansible web01 -m file -a 'path=/code/ state=directory owner=nginx group=nginx recurse=yes'
 
#注意:
    1.当创建的目录不存在时,递归创建会递归授权
    2.当创建的目录已经存在,递归授权只授权最后一层目录下的内容
 
#创建文件
[root@m01 ~]# ansible web01 -m file -a 'path=/tmp/1.txt state=touch'
 
#创建文件并授权
[root@m01 ~]# ansible web01 -m file -a 'path=/tmp/1.txt state=touch owner=nginx group=nginx'
 
#创建软链接
[root@m01 ~]# ansible web01 -m file -a 'src=/tmp/1.txt dest=/tmp/1.ln state=link'


3、get_url 模块
[root@m01 ~]# ansible-doc get_url
EXAMPLES:
- name: Download foo.conf
  get_url:
    url: http://example.com/path/file.conf
    dest: /etc/foo.conf
    mode: '0440'
    checksum: sha256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
 
url         #文件下载地址
dest        #文件存放路径
mode        #文件下载后授权
checksum    #验证文件
    sha256  #加密方式

例子:#下载网站上的文件
[root@m01 ~]# ansible web01 -m get_url -a 'url=http://10.0.0.7/1.txt dest=/tmp'
 
#下载时验证文件
[root@m01 ~]# ansible web01 -m get_url -a 'url=http://10.0.0.7/1.txt dest=/tmp checksum=md5:d8e8fca2dc0f896fd7cb4cb0031ba249'

5、服务管理模块

1、server
[root@m01 ~]# ansible-doc service
EXAMPLES:
- name: Start service httpd, if not started
  service:
    name: httpd
    state: started
 
name: nginx         #服务名字
state:
    started         #启动服务
    stopped         #停止服务
    restarted       #重启服务
    reloaded        #重载服务
enabled: yes        #开机自启


2、systemd
[root@m01 ~]# ansible-doc systemd
EXAMPLES:
- name: Make sure a service is running
  systemd:
    state: started
    name: httpd
 
name: nginx         #服务名字
state:
    started         #启动服务
    stopped         #停止服务
    restarted       #重启服务
    reloaded        #重载服务
enabled: yes        #开机自启

5、用户管理模块

1、group
[root@m01 ~]# ansible-doc group
EXAMPLES:
- name: Ensure group "somegroup" exists
  group:
    name: somegroup         #组名字
    state: 
        present             #创建组
        absent              #删除组
    gid: 666                #指定组id

例子:
#创建用户组
[root@m01 ~]# ansible web01 -m group -a 'name=www gid=666 state=present'
 
#修改用户组
[root@m01 ~]# ansible web01 -m group -a 'name=www gid=666 state=absent'


2、user
[root@m01 ~]# ansible-doc user
EXAMPLES:
- name: Add the user 'johnd' with a specific uid and a primary group of 'admin'
  user:
    name: johnd
    comment: John Doe
    uid: 1040
    group: admin
    shell: /bin/bash
    state: absent
    remove: yes
    create_home: false
 
name        #用户名字
comment     #用户备注
uid         #用户id
group       #用户所在的组名字
shell
    /bin/bash   #用户可以登录
    /sbin/nologin   #用户不需要登录
state
    absent      #删除用户
    present     #创建用户
remove          #移除家目录
create_home     #是否创建家目录
    true        #创建家目录
    false       #不创建家目录

例子:
#创建用户,不需要登录,有家目录
[root@m01 ~]# ansible web01 -m user -a 'name=www uid=666 group=www shell=/sbin/nologin create_home=true'
 
#删除用户并移除家目录
[root@m01 ~]# ansible web01 -m user -a 'name=www state=absent remove=yes'
 
#注意:
    1.当组的名字与用户名字相同时,删除用户,组也会被删除
    2.当组的名字与用户名字相同时,而组下面还有其他用户,则删除用户时不会删除同名组

6、其他模块

1、cron定时任务模块
[root@m01 ~]# ansible-doc cron
EXAMPLES:
- name: Ensure a job that runs at 2 and 5 exists. Creates an entry like "0 5,2 * * ls -alh > /dev/null"
  cron:
    name: "check dirs"
    minute: "0"
    hour: "5,2"
    day: "*"
    month: "*"
    weekday: "*"
    job: "ls -alh > /dev/null"
    state: absent
    disabled: yes
 
name        #定时任务的备注
minute      #分钟
hour        #小时
day         #日
month       #月
weekday     #周
job         #指定的定时任务内容
state
    present #新建定时任务
    absent  #删除定时任务
disabled
    yes     #注释定时任务
    no      #取消注释


例子:
#添加定时任务,每五分钟执行一次时间同步(只配置分钟,其他不配置默认是 * )
[root@m01 ~]# ansible web01 -m cron -a 'name="测试ansible配置定时任务" minute=*/5 job="ntpdate time1.aliyun.com"'
#查看配置
[root@web01 html]# crontab -l
#Ansible: 测试ansible配置定时任务
*/5 * * * * ntpdate time1.aliyun.com
 
#注释定时任务
[root@m01 ~]# ansible web01 -m cron -a 'name="测试ansible配置定时任务" minute=*/5 job="ntpdate time1.aliyun.com" disabled=yes'
 
#删除定时任务
[root@m01 ~]# ansible web01 -m cron -a 'name="测试ansible配置定时任务" minute=*/5 job="ntpdate time1.aliyun.com" state=absent'
 
#注意:
    1.定时任务添加,是通过名字来区分是否一样的,如果不加name参数,则会添加重复的定时任务
    2.定时任务注释是通过 name 参数来注释的,所以一定要加 name 参数
    3.定时任务删除是通过 name 参数来删除的,所以一定要加 name 参数

2、mount模块
# 安装NFS
    1.安装nfs
    [root@m01 ~]# ansible nfs_server -m yum -a 'name=nfs-utils state=present'

    2.配置nfs
    [root@m01 ~]# ansible nfs_server -m copy -a 'content="/data 172.16.1.0/24(rw,sync,all_squash)" dest=/etc/exports'

    3.创建目录
    [root@m01 ~]# ansible nfs_server -m file -a 'path=/data state=directory owner=nfsnobody group=nfsnobody'

    4.启动服务
    [root@m01 ~]# ansible nfs_server -m systemd -a 'name=nfs state=started'


# 挂在模块的语法
[root@m01 ~]# ansible-doc mount
EXAMPLES:
- name: Mount DVD read-only
  mount:
    path: /mnt/dvd
    src: /dev/sr0
    fstype: iso9660
    opts: ro,noauto
    state: present
 
path        #本机准备挂载的目录
src         #远端挂载点
fstype      #指定挂载类型
opts        #挂载参数(/etc/fstab中的内容)
state
    present     #配置开机挂载,将配置写入自动挂载文件,并没有直接挂载
    unmounted   #取消挂载,但是没有删除自动挂载配置
    #常用配置
    mounted     #配置开机挂载,并且直接挂载上
    absent      #取消挂载,并且删除自动挂载配置

例子:
#配置开机挂载,将配置写入自动挂载文件,并没有直接挂载
[root@m01 ~]# ansible web01 -m mount -a 'path=/data src=172.16.1.31:/data fstype=nfs opts=defaults state=present'
 
#配置开机挂载,并且直接挂载上
[root@m01 ~]# ansible web01 -m mount -a 'path=/data src=172.16.1.31:/data fstype=nfs opts=defaults state=mounted'
 
#取消挂载,但是没有删除自动挂载配置
[root@m01 ~]# ansible web01 -m mount -a 'path=/data src=172.16.1.31:/data fstype=nfs opts=defaults state=unmounted'
 
#取消挂载,并且删除自动挂载配置
[root@m01 ~]# ansible web01 -m mount -a 'path=/data src=172.16.1.31:/data fstype=nfs opts=defaults state=absent


3、selinux模块
- name: Disable SELinux
  selinux:
    state: disabled
 
#关闭selinux
[root@m01 ~]# ansible web02 -m selinux -a 'state=disabled'
web02 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "configfile": "/etc/selinux/config", 
    "msg": "", 
    "policy": "targeted", 
    "reboot_required": false, 
    "state": "disabled"
}


4、firewalld模块
[root@m01 ~]# ansible-doc firewalld
EXAMPLES:
- firewalld:
    service: https          #指定服务
    permanent:              #是否永久生效
        yes                 #永久生效
        no                  #临时生效
    state: 
        enabled             #允许通过
    port: 
        8081/tcp            #指定端口
    zone: dmz               #指定区域
    rich_rule: rule service name="ftp" audit limit value="1/m" accept       #配置富规则
    source: 192.0.2.0/24     #指定网段
    interface: eth2         #帮定网卡
    masquerade: yes         #开启IP伪装

例子:
#允许访问http服务,永久生效
[root@m01 ~]# ansible web01 -m firewalld -a 'service=http permanent=yes state=enabled'
[root@m01 ~]# ansible web01 -m firewalld -a 'service=http state=enabled'
 
#允许访问80端口,临时生效
[root@m01 ~]# ansible web01 -m firewalld -a 'port=80/tcp state=enabled'
 
#配置允许10.0.0.0网段访问22端口
[root@m01 ~]# ansible web01 -m firewalld -a 'rich_rule="rule family=ipv4 source address=10.0.0.0/24 port port=22 protocol=tcp accept" state=enabled'
 
#配置网段白名单
[root@m01 ~]# ansible web01 -m firewalld -a 'source=10.0.0.0/24 zone=trusted state=enabled permanent=yes'
[root@m01 ~]# ansible web01 -m firewalld -a 'source=10.0.0.0/24 zone=trusted state=enabled permanent=no'


4、unachive模块
[root@m01 ~]# ansible-doc unarchive
EXAMPLES:
- name: Extract foo.tgz into /var/lib/foo
  unarchive:
    src: foo.tgz
    dest: /var/lib/foo
    remote_src: no          #默认是no
 
src         #包的路径
dest        #解压后的目标路径
remote_src
    yes     #包在受控端服务器上
    no      #包在控制端服务器上

例子:
#解压包到受控端,包在控制端上
[root@m01 ~]# ansible web01 -m unarchive -a 'src=/root/php.tar.gz dest=/tmp'
:
#在受控端解压包,包在受控端
[root@m01 ~]# ansible web01 -m unarchive -a 'src=/tmp/php.tar.gz dest=/tmp remote_src=yes'


5、archive压缩模块
[root@m01 ~]# ansible-doc archive
EXAMPLES:
- name: Compress directory /path/to/foo/ into /path/to/foo.tgz
  archive:
    path: /path/to/foo              #要打包的内容
    dest: /path/to/foo.tgz          #打好的包与存放位置
    format:gz                     #打包的类型 bz2, gz, tar, xz, zip
 
#打包实例
[root@m01 ~]# ansible web01 -m archive -a 'path=/tmp dest=/opt/php.tar.gz'

四、ansible主机学习模块

1、setup模块

#1.获取web01主机所有信息
[root@m01 ~]# ansible web01 -m setup
 
#2.获取主机IP
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_default_ipv4'
 
#3.获取主机名
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_fqdn'
web01 | SUCCESS => {
    "ansible_facts": {
        "ansible_fqdn": "www.baidu.com", 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
 
#4.获取内存信息
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_memory_mb'
web01 | SUCCESS => {
    "ansible_facts": {
        "ansible_memory_mb": {
            "nocache": {
                "free": 720, 
                "used": 252
            }, 
            "real": {
                "free": 276, 
                "total": 972, 
                "used": 696
            }, 
            "swap": {
                "cached": 0, 
                "free": 1023, 
                "total": 1023, 
                "used": 0
            }
        }, 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
 
#5.常用参数
ansible_all_ipv4_addresses:仅显示ipv4的信息。
ansible_devices:仅显示磁盘设备信息。
ansible_distribution:显示是什么系统,例:centos,suse等。
ansible_distribution_major_version:显示是系统主版本。
ansible_distribution_version:仅显示系统版本。
ansible_machine:显示系统类型,例:32位,还是64位。
ansible_eth0:仅显示eth0的信息。
ansible_hostname:仅显示主机名(不准确)
ansible_fqdn:仅显示主机名。
ansible_kernel:仅显示内核版本。
ansible_lvm:显示lvm相关信息。
ansible_memtotal_mb:显示系统总内存。
ansible_memfree_mb:显示可用系统内存。
ansible_memory_mb:详细显示内存情况。
ansible_swaptotal_mb:显示总的swap内存。
ansible_swapfree_mb:显示swap内存的可用内存。
ansible_mounts:显示系统磁盘挂载情况。
ansible_processor:显示cpu个数(具体显示每个cpu的型号)。
ansible_processor_vcpus:显示cpu个数(只显示总的个数)。

五、ansible剧本playbook

1、简介

[root@m01 ~]# vim touch.yml 
#定义要执行动作的主机或主机组
- hosts: web_group
  #定义操作的用户
  remote_user: root
  #定义变量
  vars:
    #变量:变量的值
    file_name: lhd
  #指定主机的动作
  tasks:
    #动作的注释
    - name: Touch New File
      #使用shell模块执行动作
      shell: touch /tmp/{{ file_name }}
 
#模拟执行
[root@m01 ~]# ansible-playbook -C touch.yml
#验证语法
[root@m01 ~]# ansible-playbook --syntax-check touch.yml
#注意:只能验证语法,验证不了逻辑

2、变量

1.通过命令行进行变量定义
2.在play文件中进行变量定义
3.通过Inventory主机清单中进行变量定义
4.通过vars_file定义变量
5.通过hosts_vars和group_vars定义变量
 
#变量的优先级
如果在定义变量时,变量冲突了
在上述的三个地方分别设置了:
    1.命令行中:age=11
    2.play文件中:age=12
    3.Inventory中:age=13
    那么,最终的age结果一定是 11
    变量的读取优先级:命令行 > playbook文件 > Inventory文件
 
#变量设置:命名时,应该由字母,数字,下划线组成,必须由字母开头


方式一:在模块下方定义
[root@m01 project]# vim yum.yml
- hosts: db01
  tasks:
    - name: Installed http Server
      yum:
        name: "{{ packages }}"
      vars:
        packages:
          - httpd
          - httpd-tools
 
#问题:
    1.如果将变量设置到模块下,那么其他的name是不识别的

方式二:在hosts下定义
[root@m01 project]# vim yum.yml
- hosts: db01
  vars:
    packages:
      - httpd
      - httpd-tools
  tasks:
    - name: Installed http Server
      yum:
        name: "{{ packages }}"
 
    - name: Mkdir Dir
      file:
        path: /tmp/{{ packages }}
        state: directory
 
#问题:
    1.创建目录时可能会出现格式转换问题
    2.如果将变量设置到hosts下,那么其他的hosts是不识别的


# 刚才我们学到在playbook中使用vars定义变量,有一个缺陷,就是其他的playbook无法使用该变量。所以我们可以采取第二种定义变量的方式,在vars_file中定义变量。


[root@m01 project]# mkdir vars
[root@m01 project]# cd vars/
[root@m01 vars]# vim vars.yml 
packages: httpd
dbs: mariadb-server


# 调用变量
[root@m01 project]# vim yum.yml 
- hosts: db01
  vars_files: /project/vars/vars.yml
  tasks:
    - name: Installed http Server
      yum:
        name: "{{ packages }}"
 
- hosts: db01
  vars_files: /project/vars/vars.yml
  tasks:
    - name: Installed http Server
      yum:
        name: "{{ dbs }}"


#通过inventory主机清单中进行变量定义
[root@m01 project]# vim /etc/ansible/hosts 
... ...
[db_server]
db01 ansible_ssh_pass='1'
 
[db_server:vars]
web=suibianshezhideneirong

调用变量:
[root@m01 project]# vim yum.yml 
- hosts: db_server
  tasks:
    - name: Touch File
      file:
        path: /tmp/{{ web }}
        state: touch
 
#注意:
    1.主机清单中定义变量,只要hosts配置的是主机清单中设置变量的组,可以直接使用变量
    2.如果hosts配置的不是主机清单中设置变量的组,变量不可识别

    3.主机组定义的变量优先级高于整合组定义的变量
    4.主机定义的变量优先级高于主机组定义的变量


# 命令行定义变量
[root@m01 project]# ansible-playbook test.yml -e "file=command" -e "file2=command2"


# 直接使用内置变量
#使用内置变量创建目录,目录格式为 主机名_IP_时间
[root@m01 project]# vim test.yml 
- hosts: web_group
  tasks:
    - name: Touch File
      file:
        path: /backup/{{ ansible_fqdn }}_{{ ansible_eth1.ipv4.address }}_{{ ansible_date_time.date }}
        state: directory

六、流程控制

1、实例

[root@m01 project]# vim startserver.yml
- hosts: web_group
  tasks:
    - name: Start CentOS 6 Server
      shell: "/etc/init.d/httpd start"
      when:
        - ansible_distribution == "CentOS"
        - ansible_distribution_major_version == "6"
 
    - name: Start CentOS 7 Server
      shell: "systemctl start httpd"
      when:
        - ansible_distribution == "CentOS"
        - ansible_distribution_major_version == "7"


[root@m01 project]# vim startserver.yml
- hosts: web_group
  tasks:
    - name: Start CentOS 6 Server
      shell: "/etc/init.d/httpd start"
      when: (ansible_distribution == "CentOS") and (ansible_distribution_major_version == "6")
 
    - name: Start CentOS 7 Server
      shell: "systemctl start httpd"
      when: (ansible_distribution == "CentOS") and (ansible_distribution_major_version == "7")


- hosts: web_group
  tasks:
    - name: Check Httpd Server
      command: systemctl is-active httpd
      ignore_errors: yes
      register: check_httpd
 
    - name: debug outprint
      debug: var=check_httpd
 
    - name: Httpd Restart
      service:
        name: httpd
        state: restarted
      when: check_httpd.rc == 0

七、循环语句

1、实例

#错误写法
[root@m01 project]# vim start.yml
- hosts: web_group
  tasks:
    - name: Start Server
      systemd:
        name: "{{ package }}"
        state: started
      vars:
        package:
          - redis
          - httpd
 
#正确写法
[root@m01 project]# vim start.yml
- hosts: web_group
  tasks:
    - name: Start Server
      systemd:
        name: "{{ item }}"
        state: started
      with_items:
        - redis
        - httpd


[root@m01 project]# cat user.yml 
- hosts: lb01
  tasks:
    - name: Create Some Group
      group:
        name: "{{ item.name }}"
        gid: "{{ item.gid }}"
        state: present
      with_items:
        - { name: "lhd", gid: "777" }
        - { name: "test", gid: "888" }
        - { name: "egon", gid: "999" }
 
    - name: Create Some User
      user:
        name: "{{ item.name }}"
        uid: "{{ item.uid }}"
        group: "{{ item.group }}"
        shell: "{{ item.shell }}"
        create_home: "{{ item.create_home }}"
      with_items:
        - { name: "lhd", uid: "777", group: "lhd", shell: "/sbin/nologin", create_home: "false" }
        - { name: "test", uid: "888", group: "test", shell: "/bin/bash", create_home: "false" }
        - { name: "egon", uid: "999", group: "egon", shell: "/bin/bash", create_home: "true" }

八、playbook handle触发器

1、实例

	handler用来执行某些条件下的任务,比如当配置文件发生变化的时候,通过notify触发handler去重启服务。
在saltstack中也有类似的触发器,写法相对Ansible简单,只需要watch,配置文件即可。

[root@m01 project]# cat nginx.yml 
- hosts: nginx
  tasks:
    - name: Config Nginx Server
      copy:
        src: /etc/nginx/nginx.conf
        dest: /etc/nginx/
      notify: restart_nginx
 
    - name: Start Nginx Server
      systemd:
        name: nginx
        state: started
 
  handlers:
    - name: restart_nginx
      systemd:
        name: nginx
        state: restarted


1.无论多少个task通知了相同的handlers,handlers仅会在所有tasks结束后运行一次。
 
2.Handlers只有在其所在的任务被执行时,才会被运行;如果一个任务中定义了notify调用Handlers,但是由于条件判断等原因,该任务未被执行,那么Handlers同样不会被执行。
 
3.Handlers只会在每一个play的末尾运行一次;如果想在一个playbook中间运行Handlers,则需要使用meta模块来实现。例如: -meta: flush_handlers。
 
4.如果一个play在运行到调用Handlers的语句之前失败了,那么这个Handlers将不会被执行。我们可以使用meta模块的--force-handlers选项来强制执行Handlers,即使Handlers所在的play中途运行失败也能执行。
 
5.不能使用handlers替代tasks


九、playbook任务标签

1、对一个任务打一个标签

- hosts: nginx
    - name: Config Nginx Server
      copy:
        src: /etc/nginx/nginx.conf
        dest: /etc/nginx/
      notify: restart_nginx
      tags: reconf_nginx

2、对一个任务打多个标签

- hosts: nginx
    - name: Config Nginx Server
      copy:
        src: /etc/nginx/nginx.conf
        dest: /etc/nginx/
      notify: restart_nginx
      tags: 
        - reconf_nginx
        - reconfig_nginx

3、对多个任务打一个标签

- hosts: nginx
    - name: Config Nginx Server
      copy:
        src: /etc/nginx/nginx.conf
        dest: /etc/nginx/
      notify: restart_nginx
      tags: reconf_nginx
 
    - name: Config Nginx wordpress
      copy:
        src: /project/conf/linux.wp.com.conf
        dest: /etc/nginx/conf.d/
      notify: reload_nginx
      when: (ansible_fqdn == "web01") or (ansible_fqdn == "web02")
      tags: reconf_nginx

4、使用标签的方式

1、查看标签
[root@m01 project]# ansible-playbook wp.yml --list-tags
 
playbook: wp.yml
 
  play #1 (nginx): nginx    TAGS: []
      TASK TAGS: [reconf_nginx, reconfig_nginx]

2、执行制定标签的内容
[root@m01 project]# ansible-playbook wp.yml -t reconfig_nginx
[root@m01 project]# ansible-playbook wp.yml -t reconf_nginx,reconfig_nginx
[root@m01 project]# ansible-playbook wp.yml --skip-tags reconfig_nginx    # 跳过标签内容

十、playbook的复用

1、实例

[root@m01 project]# cat play1.yml 
- name: Install Nginx Server
  yum:
    name: nginx
    state: present
 
[root@m01 project]# cat play2.yml 
- name: Config Nginx Server
  copy:
    src: /etc/nginx/nginx.conf
    dest: /etc/nginx/


[root@m01 project]# vim main.yml
- hosts: web_group
  tasks:
    - include_tasks: /project/play1.yml
    - include_tasks: /project/play2.yml


[root@m01 project]# cat main.yml 
- import_playbook: ./base.yml
- import_playbook: ./nginx.yml
- import_playbook: ./php.yml
- import_playbook: ./wordpress.yml
- import_playbook: ./mariadb.yml

十一、playbook忽略错误

1、使用

- hosts: web_group
  tasks:
    - name: Check Httpd Server
      #使用命令检查服务启动状态时,如果服务没有启动则会得到错误结果,剧本会停止运行
      command: systemctl is-active httpd
      #配置忽略错误可以继续执行剧本
      ignore_errors: yes
      register: check_httpd
 
    - name: debug outprint
      debug: 
        msg: "{{ check_httpd }}"
 
    - name: Httpd Restart
      service:
        name: httpd
        state: restarted
      when: check_httpd.rc == 0


# 强制执行handle的内容
[root@m01 ~]# cat handler.yml 
- hosts: web_group
  vars:
    - http_port: 8080
  force_handlers: yes
  tasks:
    - name: config httpd server
      template:
        src: ./httpd.j2
        dest: /etc/httpd/conf
      notify: 
        - Restart Httpd Server
        - Restart PHP Server
 
    - name: Install Http Server
      yum:
        name: htttpd
        state: present
 
    - name: start httpd server
      service:
        name:httpd
        state: started
        enabled: yes
 
  handlers:
    - name: Restart Httpd Server
      systemd:
        name: httpd
        state: restarted
 
    - name: Restart PHP Server
      systemd:
        name: php-fpm
        state: restarted

十二、ansible role

1、简介

	roles不管是Ansible还是saltstack,我在写一键部署的时候,都不可能把所有的步骤全部写入到一个'剧本'文件当中,我们肯定需要把不同的工作模块,拆分开来,解耦,那么说到解耦,我们就需要用到roles官方推荐,因为roles的目录结构层次更加清晰。
 
	例如:我们之前推荐大家写一个base.yml里面写所有基础优化的项目,其实把所有东西摞进去也是很鸡肋的,不如我们把这些功能全部拆分开,谁需要使用,就调用即可。
 
	建议:每个roles最好只使用一个tasks这样方便我们去调用,能够很好的做到解耦。(SOA)

2、目录介绍

production                # inventory file for production servers
staging                   # inventory file for staging environment
 
group_vars/
   group1.yml             # here we assign variables to particular groups
   group2.yml
host_vars/
   hostname1.yml          # here we assign variables to particular systems
   hostname2.yml
 
library/                  # if any custom modules, put them here (optional)
module_utils/             # if any custom module_utils to support modules, put them here (optional)
filter_plugins/           # if any custom filter plugins, put them here (optional)
 
site.yml                  # master playbook
webservers.yml            # playbook for webserver tier
dbservers.yml             # playbook for dbserver tier
 
roles/
    common/               # this hierarchy represents a "role"
        tasks/            #
            main.yml      #  <-- tasks file can include smaller files if warranted
        handlers/         #
            main.yml      #  <-- handlers file
        templates/        #  <-- files for use with the template resource
            ntp.conf.j2   #  <------- templates end in .j2
        files/            #
            bar.txt       #  <-- files for use with the copy resource
            foo.sh        #  <-- script files for use with the script resource
        vars/             #
            main.yml      #  <-- variables associated with this role
        defaults/         #
            main.yml      #  <-- default lower priority variables for this role
        meta/             #
            main.yml      #  <-- role dependencies
        library/          # roles can also include custom modules
        module_utils/     # roles can also include custom module_utils
        lookup_plugins/   # or other types of plugins, like lookup in this case
 
    webtier/              # same kind of structure as "common" was above, done for the webtier role
    monitoring/           # ""
    fooapp/               # ""

3、创建语法

[root@m01 roles]# ansible-galaxy init nginx
- Role nginx was created successfully
 
[root@m01 roles]# tree nginx
nginx                   #项目目录名称
├── defaults            #默认的变量(优先级很低)
│   └── main.yml
├── files               #存放文件,使用copy模块时自动获取
├── handlers            #存放触发器的配置
│   └── main.yml
├── meta                #依赖的服务,执行该项目时先执行其他的项目
│   └── main.yml
├── README.md
├── tasks               #默认执行的playbook
│   └── main.yml
├── templates           #存放jinja2模板,使用template模块时自动获取
├── tests
│   ├── inventory
│   └── test.yml
└── vars                #存放变量
    └── main.yml

4、role的依赖关系

	`roles`允许你再使用roles时自动引入其他的roles。role依赖关系存储在roles目录中meta/main.yml文件中。
 
	例如:推送wordpress并解压,前提条件,必须要安装nginx和php,把服务跑起来,才能运行wordpress的页面,此时我们就可以在wordpress的roles中定义依赖nginx和php的roles

[root@m01 roles]# vim /etc/ansible/roles/wordpress/meta/main.yml
dependencies:
  - { role: nginx }
  - { role: php }
 
如果编写了meta目录下的main.yml文件,那么Ansible会自动先执行meta目录中main.yml文件中的dependencies文件,如上所示,就会先执行nginx和php的安装。

  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值