ansible自动化运维

Ansible概述

Ansible是一个配置管理系统configuration management system

python 语言是运维人员必须会的语言

ansible 是一个基于python 开发的自动化运维工具

其功能实现基于ssh远程连接服务

ansible 可以实现批量系统配置,批量软件部署,批量文件拷贝,批量运行命令等功能

除了ansible之外,还有saltstack 等批量管理软件

Ansible能做什么

ansible可以帮助我们完成一些批量任务,或者完成一些需要经常重复的工作。
比如:同时在100台服务器上安装nginx服务,并在安装后启动服务。
比如:将某个文件一次性拷贝到100台服务器上。
比如:每当有新服务器加入工作环境时,你都要为新服务器部署某个服务,也就是说你需要经常重复的完成相同的工作。
这些场景中我们都可以使用到ansible。

 ansible批量管理服务意义
    01. 提高工作的效率
    02. 提高工作准确度
    03. 减少维护的成本
    04. 减少重复性工作
  

ansible批量管理服务功能
    01. 可以实现批量系统操作配置
    02. 可以实现批量软件服务部署
    03. 可以实现批量文件数据分发
    04. 可以实现批量系统信息收集

 Ansible软件特点

1.ansible不需要单独安装客户端,SSH相当于ansible客户端。
2.ansible不需要启动任何服务,仅需安装对应工具即可。
3.ansible依赖大量的python模块来实现批量管理。
4.ansible配置文件/etc/ansible/ansible.cfg


 Ansible基础架构

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

最重要的一点是 ansible是模块化的 它所有的操作都依赖于模块

不需要单独安装客户端(no agents),基于系统自带的sshd服务,sshd就相当于ansible的客户端

不需要服务端(no sever)

需要依靠大量的模块实现批量管理

配置文件 /etc/ansible/ansible.cfg (前期不用配置)

     

   ansible自动化运维实例
        

            
1. ansible 安装

安装tree命令---便于查看ansible工作目录
[root@localhost ~]# yum -y install tree


上传ansible相关软件,创建本地yum仓库
[root@localhost ~]# mv  ansiblerepo/ /usr/src/

[root@localhost ~]# du -sh /usr/src/ansiblerepo/
 

[root@localhost ~]# vim /etc/yum.repos.d/local.repo 

[local]
name=centos7.4
baseurl=file:///usr/src/ansiblerepo
enabled=1
gpgcheck=0


[root@localhost ~]# yum clean all

安装ansible
[root@localhost ~]# yum -y install ansible

查看ansible版本
[root@localhost ~]# ansible --version

ansible 2.3.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.5 (default, Aug  4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]

2.为了便于管理远程主机,配置ssh信任  

[root@localhost ~]# ssh-keygen -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): ##公钥和私钥默认保存位置
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): ##可设置验证密码,默认
Enter same passphrase again:  ##默认
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:Jws2KHO5W171BF6gKDN9Oudo0D2VKmYNRJKxKbQfsmA [email protected]
The key's randomart image is:
+---[RSA 2048]----+
|  . o+o   .      |
| . ..* . . o     |
|.E+ B + o + .    |
|.. = O * + o     |
|  + * @ S + .    |
|   + * O * o     |
|    . + +   .    |
|     = .         |
|    . .          |
+----[SHA256]-----+

传输私钥到远程主机
[root@localhost ~]# ssh-copy-id [email protected]

根据提示输入:
yes

输入:root密码

[root@localhost ~]# ssh-copy-id [email protected]


验证:无须输入密码即可远程登录
[root@localhost ~]# ssh 192.168.10.2

查看ip是否是远程主机
[root@localhost ~]# ip a

[root@localhost ~]# exit


[root@localhost ~]# ssh 192.168.10.3

[root@localhost ~]# ip a

[root@localhost ~]# exit


            ----ansilble基础管理------
    yum install -y ansible     --- 需要依赖epel的yum源
    /etc/ansible/ansible.cfg   --- ansible服务配置文件
       /etc/ansible/hosts         --- 主机清单文件   定义可以管理的主机信息
       /etc/ansible/roles         --- 角色目录???
    
            
1. Ansible清单管理/etc/ansible/hosts

inventory文件通常用于定义要管理主机的认证信息, 例如ssh登录用户名、密码以及key相关信息。

主机

1.支持主机名通配以及正则表达式,例如web[1:3].oldboy.com
2.支持基于非标准的ssh端口,例如web1.oldboy.com:6666
3.支持指定变量,可对个别主机的特殊配置,如登陆用户,密码等

主机组

1.支持嵌套组,例如[game:children],那么在game模块下面的组都会被game所包含
2.支持指定变量,例如[game:vars]在下面指定变量

[root@localhost ~]# vim /etc/ansible/hosts

[web]   ## 主机组
192.168.10.2
192.168.10.3

[test01]
www.bdqn.cn:222   ##通过端口222管理设备

[mail]
ly01.mail.cn

[ly]
ly[2:5].test.com  ##正则表达式:表示4台主机ly2,ly3,ly4,ly5..

验证:可以对组或组中成员进行远程操作
--limit 限制为组中成员

只对web组中192.168.10.2主机进行命令操作
[root@localhost ~]# ansible web -m command -a "ip a" --limit "192.168.10.2"

192.168.10.2 | SUCCESS | rc=0 >>
……………………


通过指定主机来远程操作
[root@localhost ~]# ansible 192.168.10.3 -m command -a "ip a"

192.168.10.3 | SUCCESS | rc=0 >>

通过通配符来指定多个主机远程操作
[root@localhost ~]# ansible 192.168.10.* -m command -a "firewall-cmd --state"

192.168.10.2 | FAILED | rc=252 >>
not running

192.168.10.3 | FAILED | rc=252 >>
not running


------------------------------------------
Ansible注意事项->提示颜色信息说明

黄色:对远程节点进行相应修改
绿色:对远程节点不进行相应修改,或者只是对远程节点信息进行查看
红色:操作执行命令有异常
紫色:表示对命令执行发出警告信息(可能存在的问题,给你一下建议)

-----------------------------------------------------

2.ansible命令
ansible应用场景:多用于临时的、无规律的任务操作
--非固化需求
--临时一次性操作
--二次开发接口调用

检查清单中所有主机是否存活
-f  并发线程数为5
-m   调用ping模块(并不是ping命令)

[root@localhost ~]# ansible all -f 5 -m ping

## success---表示成功; => {} 表示返回结果
## changed false 表示没有对主机进行更改
##pong ---ping模块返回结果

192.168.10.3 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.10.2 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}


列出web组主机列表
[root@localhost ~]# ansible web --list
  hosts (2):
    192.168.10.2
    192.168.10.3

批量显示web组磁盘使用情况    
[root@localhost ~]# ansible web -m command -a "df -hT"


3.ansible-doc  可用来查询模块文档的说明,类似于man

列出所有模块信息
[root@localhost ~]# ansible-doc -l

查询ping模块的说明信息
[root@localhost ~]# ansible-doc ping


4.ansible-console 交互式工具。类似于cmd或shell

[root@localhost ~]# ansible-console
Welcome to the ansible console.
Type help or ? to list commands.

root@all (8)[f:5]$ cd web  ##通过cd命令切换主机或分组
root@web (2)[f:5]$ list    ##列出当前设备
192.168.10.2
192.168.10.3
root@web (2)[f:5]$ 


     --------------ansible常用模块------

Shell功能全面但是执行率低
command不支持:逻辑运算符、条件判断符号、重定向命令或者是管道命令


1.command模块---远程执行命令     
chdir---在远程主机运行命令前,要提前进入的目录
creates---创建文件(如文件已存在,则不执行)
removes--移除文件(如文件不存在,则不执行)
executable--更改shell环境(并且执行命令时要使用绝对路径)


在web组主机上运行命令,运行前切换到/root目录
[root@localhost ~]# ansible web -m command -a "chdir=/root  ls ./"

192.168.10.3 | SUCCESS | rc=0 >>
anaconda-ks.cfg
:wq

192.168.10.2 | SUCCESS | rc=0 >>
anaconda-ks.cfg
:wq


2.shell模块---相当于调用远程主机的shell进程,在该shell下打开一个子shell运行命令

[root@localhost ~]# ansible web -m shell -a 'echo "hello ly" >> /tmp/hello.txt'
192.168.10.3 | SUCCESS | rc=0 >>


192.168.10.2 | SUCCESS | rc=0 >>

验证:
[root@localhost ~]# ssh 192.168.10.2 cat /tmp/hello.txt
hello ly
[root@localhost ~]# ssh 192.168.10.3  cat /tmp/hello.txt
hello ly

3.copy模块---在远程主机执行复制操作文件。 
– src:要复制到远程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用”/”来结尾,则只复制目录里的内容,如果没有使用”/”来结尾,则包含目录在内的整个内容全部复制,类似于rsync。 
– content:用于替代”src”,可以直接设定指定文件的值 
– dest:必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录 
– directory_mode:递归的设定目录的权限,默认为系统默认权限 
– force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes 
– others:所有的file模块里的选项都可以在这里使用

mode--文件权限

owner--属主

group--属组

[root@localhost ~]# ansible web -m copy -a "src=/etc/hosts dest=/tmp/ mode=777 owner=zgq group=root"

192.168.10.2 | SUCCESS => {
    "changed": true, 
    "checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa", 
    "dest": "/tmp/hosts", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "54fb6627dbaa37721048e4549db3224d", 
    "mode": "0777", 
    "owner": "zgq", 
    "size": 158, 
    "src": "/root/.ansible/tmp/ansible-tmp-1539955677.69-89456685777900/source", 
    "state": "file", 
    "uid": 99
}
192.168.10.3 | SUCCESS => {
    "changed": true, 
    "checksum": "7335999eb54c15c67566186bdfc46f64e0d5a1aa", 
    "dest": "/tmp/hosts", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "54fb6627dbaa37721048e4549db3224d", 
    "mode": "0777", 
    "owner": "zgq", 
    "size": 158, 
    "src": "/root/.ansible/tmp/ansible-tmp-1539955677.68-109392164568090/source", 
    "state": "file", 
    "uid": 99
}

验证:
[root@localhost ~]# ssh 192.168.10.2 ls -l /tmp/hosts

-rwxrwxrwx 1 zgq root 158 10月 19 21:27 /tmp/hosts

[root@localhost ~]# ssh 192.168.10.3 ls -l /tmp/hosts

-rwxrwxrwx 1 zgq root 158 10月 19 21:27 /tmp/hosts

4.hostname模块--设置远程主机的主机名

更改远程主机名为ly
[root@localhost ~]# ansible 192.168.10.2 -m hostname -a "name=ly"
192.168.10.2 | SUCCESS => {
    "ansible_facts": {
        "ansible_domain": "", 
        "ansible_fqdn": "ly", 
        "ansible_hostname": "ly", 
        "ansible_nodename": "ly"
    }, 
    "changed": true, 
    "name": "ly"
}

验证:
[root@localhost ~]# ssh 192.168.10.2
Last login: Fri Oct 19 21:29:44 2018 from 192.168.10.1
[root@ly ~]# hostname
ly
[root@ly ~]# cat /etc/hostname
ly
[root@ly ~]# exit
登出
Connection to 192.168.10.2 closed.


5.yum模块---调用远程主机的yum程序进行管理

Ansible yum模块主要用于软件的安装、升级、卸载,支持rpm软件包的管理 
yum模块使用详解:

conf_file:设置远程yum执行时所依赖的yum配置文件
disable_gpg_check:安装软件包之前是否检查gpg key
name:需要安装的软件名称,支持软件组安装
update_cache:安装软件之前更新缓存
enablerepo:指定repo源名称
skip_broken:跳过异常软件节点
state:软件包状态,包括installed、present、latest、absent、removed present, installed是指安裝套件,而latest指安裝最新的套件,也就是使用 yum mirror 上最新的版本。
absent, removed 没有什么区别
--------------------- 

查看远程主机是否安装httpd服务
[root@localhost ~]# ssh 192.168.10.3 rpm -q httpd
未安装软件包 httpd 

调用yum模块安装httpd服务
[root@localhost ~]# ansible 192.168.10.3 -m yum -a "name=httpd state=present"
192.168.10.3 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
    
    
验证:查看远程主机是否安装httpd服务    
[root@localhost ~]# ssh 192.168.10.3 rpm -q httpd
httpd-2.4.6-67.el7.centos.x86_64


6.service模块---管理远程主机服务
name---服务名
state=started/stopped/restarted  动作为启动、停止、重启
enabled=no/yes  是否设置为开机启动
runlevel :如果定义了开机启动,则设置运行级别


查看httpd是否运行
[root@localhost ~]# ssh 192.168.10.3 systemctl status httpd

● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: man:httpd(8)
           man:apachectl(8)

启动httpd服务,并设置为开机运行           
[root@localhost ~]# ansible 192.168.10.3 -m service -a "name=httpd state=started enabled=yes"

192.168.10.3 | SUCCESS => {
    "changed": true, 
    "enabled": true, 
    "name": "httpd", 
    "state": "started", 

验证:
[root@localhost ~]# ssh 192.168.10.3 systemctl status httpd

[root@localhost ~]# ssh 192.168.10.3 netstat -anpt |grep httpd
tcp6       0      0 :::80                   :::*                    LISTEN      1871/httpd          

7.user模块---管理远程主机用户账户
Ansible user模块主要用于操作系统用户、组、权限、密码等操作 
user模块使用详解:

system:默认创建为普通用户,为yes则创建系统用户
append:添加一个新的组
comment:添加描述信息
createhome:给用户创建家目录
force:强制删除用户
group:创建用户主组
groups:将用户加入组或者附属组添加
home:指定用户的家目录
move_home=yes/no 如果设置的家目录已存在,是否将已存在的家目录进行移动
name:表示状态,是否create、remove、modify
password:指定用户的密码,为加密密码
remove:删除用户
shell:设置用户的shell登录环境
uid:设置用户ID
update_password:修改用户密码
state:用户状态,默认为present,表示新建用户
--------------------- 

[root@localhost ~]# ansible web -m user -a 'name=user1 system=yes uid=501 group=root groups=sshd shell=/sbin/nologin home=/user1 password=123 comment="test user"'


192.168.10.2 | SUCCESS => {
    "changed": true, 
    "comment": "test user", 
    "createhome": true, 
    "group": 0, 
    "groups": "sshd", 
    "home": "/user1", 
    "name": "user1", 
    "password": "NOT_LOGGING_PASSWORD", 
    "shell": "/sbin/nologin", 
    "state": "present", 
    "system": true, 
    "uid": 501
}
192.168.10.3 | SUCCESS => {
    "changed": true, 
    "comment": "test user", 
    "createhome": true, 
    "group": 0, 
    "groups": "sshd", 
    "home": "/user1", 
    "name": "user1", 
    "password": "NOT_LOGGING_PASSWORD", 
    "shell": "/sbin/nologin", 
    "state": "present", 
    "system": true, 
    "uid": 501
}

验证:
[root@localhost ~]# ssh 192.168.10.2 tail -1 /etc/passwd
user1:x:501:0:test user:/user1:/sbin/nologin
[root@localhost ~]# ssh 192.168.10.3 tail -1 /etc/passwd
user1:x:501:0:test user:/user1:/sbin/nologin

删除用户
[root@localhost ~]# ansible web -m user -a "name=user1 remove=yes state=absent"


192.168.10.3 | SUCCESS => {
    "changed": true, 
    "force": false, 
    "name": "user1", 
    "remove": true, 
    "state": "absent", 
    "stderr": "userdel: user1 邮件池 (/var/spool/mail/user1) 未找到\n", 
    "stderr_lines": [
        "userdel: user1 邮件池 (/var/spool/mail/user1) 未找到"
    ]
}
192.168.10.2 | SUCCESS => {
    "changed": true, 
    "force": false, 
    "name": "user1", 
    "remove": true, 
    "state": "absent", 
    "stderr": "userdel: user1 邮件池 (/var/spool/mail/user1) 未找到\n", 
    "stderr_lines": [
        "userdel: user1 邮件池 (/var/spool/mail/user1) 未找到"
    ]
}

验证:
[root@localhost ~]# ssh 192.168.10.2 tail -1 /etc/passwd
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
[root@localhost ~]# ssh 192.168.10.3 tail -1 /etc/passwd
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
    
        -----playbook配置文件(剧本)--------

我们完成一个任务,例如安装部署一个httpd服务,我们需要多个模块(一个模块也可以称之为task)提供功能来完成。而playbook就是组织多个task的容器,他的实质就是一个文件,有着特定的组织格式,它采用的语法格式是YAML(Yet Another Markup Language)。YAML语法能够简单的表示散列表,字典等数据结构。

playbook是由一个或多个模块组成的,使用多个不同的模块,完成一件事情。
编写剧本-脚本(playbook)---针对重复性的操作
    
playbook基础组件

Hosts:运行执行任务(task)的目标主机
remote_user:在远程主机上执行任务的用户
tasks:任务列表
handlers:任务,与tasks不同的是只有在接受到通知时才会被触发
templates:使用模板语言的文本文件,使用jinja2语法。
variables:变量,变量替换{{ variable_name }}
整个playbook是以task为中心,表明要执行的任务。hosts和remote_user表明在哪些远程主机以何种身份执行。其他组件让其能够更加灵活。    

roles:角色。将hosts剥离出去。由tasks、handlers等所组成的一种特定的结构集合

Usage: ansible-playbook playbook.yml
相对于ansible,增加了下列选项:
--flush-cache # 清除fact缓存
--syntax-check # 语法检查
--force-handlers # 如果任务失败,也要运行handlers
--list-tags # 列出所有可用的标签
--list-tasks # 列出将要执行的所有任务
--skip-tags=SKIP_TAGS # 跳过运行标记此标签的任务
--start-at-task=START_AT_TASK # 在此任务处开始运行
--step 一步一步:在运行之前确认每个任务
-t TAGS, --tags=TAGS 只运行标记此标签的任务

YAML有以下基本规则: 
1、大小写敏感 
2、使用缩进表示层级关系 
3、禁止使用tab缩进,只能使用空格键 
4、缩进长度没有限制,只要元素对齐就表示这些元素属于一个层级。 
5、使用#表示注释 
6、字符串可以不用引号标注

7.'-'表示项
8。 ’:‘ 分隔键和值
9.整个文件以‘---’开始,以'...’结束

    
更改清单服务    
[root@localhost ~]# vim /etc/ansible/hosts 
[web1]
192.168.10.2

[web2]
192.168.10.3

[root@localhost ~]# ls /etc/ansible/
ansible.cfg  hosts  roles

创建a.yml文件
[root@localhost ~]# vim /etc/ansible/a.yml
---

- hosts: web1
  remote_user: root
  tasks:
        - name: adduser
          user: name=user2 state=present
          tags:
                - aaa


        - name: addgroup
          group: name=test    system=yes
          tags:
                - bbb


- hosts: web2
  remote_user: root
  tasks:
        - name: copy file to web
          copy: src=/etc/passwd dest=/home
          tags:
                - ccc

...            

---------------------------------
注释:

---  ##以此开头

- hosts: web1      ##针对web1 192.168.10.2操作         
  remote_user: root  ##远端执行用户
  tasks:             ##任务列表
        - name: adduser   ##任务名称
          user: name=user2 state=present  ##user模块,创建用户
          tags:  ##创建tag标签
                - aaa   ##标签名称


        - name: addgroup
          group: name=root system=yes ##执行group模块,创建组
          tags:
                - bbb


- hosts: web2
  remote_user: root
  tasks:
        - name: copy file to web
          copy: src=/etc/passwd dest=/home ##执行copy模块,复制文件到home目录
          tags:
                - ccc

...            ##以此结尾


##进行语法检查                
[root@localhost ~]# ansible-playbook --syntax-check /etc/ansible/a.yml

playbook: /etc/ansible/a.yml  ##没有报错提示

预测试,并不真正执行命令
[root@localhost ~]# ansible-playbook -C /etc/ansible/a.yml

执行web1
PLAY [web1] ********************************************************************

采集信息
TASK [Gathering Facts] *********************************************************
ok: [192.168.10.2]

添加用户
TASK [adduser] *****************************************************************
changed: [192.168.10.2]

添加组
TASK [addgroup] ****************************************************************
ok: [192.168.10.2]

PLAY [web2] ********************************************************************

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

复制文件
TASK [copy file to web] ********************************************************
changed: [192.168.10.3]

信息反馈
PLAY RECAP *********************************************************************
192.168.10.2               : ok=3    changed=1    unreachable=0    failed=0   
192.168.10.3               : ok=2    changed=1    unreachable=0    failed=0   

列出该剧本执行主机
[root@localhost ~]# ansible-playbook --list-hosts /etc/ansible/a.yml 

playbook: /etc/ansible/a.yml

  play #1 (web1): web1    TAGS: []
    pattern: [u'web1']
    hosts (1):
      192.168.10.2

  play #2 (web2): web2    TAGS: []
    pattern: [u'web2']
    hosts (1):
      192.168.10.3


任务列表      
[root@localhost ~]# ansible-playbook --list-tasks  /etc/ansible/a.yml 

playbook: /etc/ansible/a.yml

  play #1 (web1): web1    TAGS: []
    tasks:
      adduser    TAGS: [aaa]
      addgroup    TAGS: [bbb]

  play #2 (web2): web2    TAGS: []
    tasks:
      copy file to web    TAGS: [ccc]
      
标签列表      
[root@localhost ~]# ansible-playbook --list-tags  /etc/ansible/a.yml 

playbook: /etc/ansible/a.yml

  play #1 (web1): web1    TAGS: []
      TASK TAGS: [aaa, bbb]

  play #2 (web2): web2    TAGS: []
      TASK TAGS: [ccc]
      
执行任务操作      
[root@localhost ~]# ansible-playbook   /etc/ansible/a.yml 

PLAY [web1] ********************************************************************

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

TASK [adduser] *****************************************************************
changed: [192.168.10.2]

TASK [addgroup] ****************************************************************
ok: [192.168.10.2]

PLAY [web2] ********************************************************************

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

TASK [copy file to web] ********************************************************
changed: [192.168.10.3]

PLAY RECAP *********************************************************************
192.168.10.2               : ok=3    changed=1    unreachable=0    failed=0   
192.168.10.3               : ok=2    changed=1    unreachable=0    failed=0   


验证:
[root@localhost ~]# ssh 192.168.10.2 tail -1 /etc/passwd
user2:x:1000:1000::/home/user2:/bin/bash

[root@localhost ~]# ssh 192.168.10.3 tail -1 /etc/passwd

apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

[root@localhost ~]# ssh 192.168.10.3 ls /home
passwd

2.触发器操作。当tasks任务执行成功后,触发器执行操作


启动远程主机的httpd服务
[root@localhost ~]# ssh 192.168.10.2 netstat -anpt | grep 80

[root@localhost ~]# ssh 192.168.10.2 systemctl start  httpd

[root@localhost ~]# ssh 192.168.10.2 netstat -anpt | grep 80

tcp6       0      0 :::80                   :::*                    LISTEN      16748/httpd         


创建触发器
[root@localhost ~]# vim /etc/ansible/httpd.yml
---

- hosts: web1
  remote_user: root
  tasks:
        - name: change port
        ##调用command模块,编辑httpd文件,更改侦听端口为8080
          command: sed -i 's/Listen\ 80/Listen \ 8080/g' /etc/httpd/conf/httpd.conf  


          ##配置触发条件,触发名称与下列的触发器名称对应
          notify:
                - restart httpd server
                
##配置触发器                
  handlers:
        ##触发器名称
        - name: restart httpd server
        ##调用服务模块,重启httpd服务
          service: name=httpd state=restarted

          
...

语法检查
[root@localhost ~]# ansible-playbook --syntax-check /etc/ansible/httpd.yml 

playbook: /etc/ansible/httpd.yml

预测试
[root@localhost ~]# ansible-playbook -C  /etc/ansible/httpd.yml 

执行命令
[root@localhost ~]# ansible-playbook   /etc/ansible/httpd.yml 

验证:
[root@localhost ~]# ssh 192.168.10.2 netstat -lnupt | grep httpd
tcp6       0      0 :::8080         


        --------playbook实例--安装数据库-----

ROLES 角色

         对于以上所有的方式有个弊端就是无法实现复用假设在同时部署Web、db、ha 时或不同服务器组合不同的应用就需要写多个yml文件。很难实现灵活的调用。。

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

1、目录层级结构

    roles每个角色中,以特定的层级目录进行组织

           Mysql/  角色

                   Files/     #存放有copy或script模块等调用的文件;’

                   Tepmlates/    #template模块查找所需要模板文件目录;

                   Tasks/           #定义任务;至少应该包含一个名为main.yml的文件;其他的文件需要在此文件中通过

    include进行包含。

                   Handlers/      #定义触发器;至少应该包含一个名为main.yml的文件;其他的文件需要在此文件中通过

    include进行包含。

                   Vars/              #定义变量;至少应该包含一个名为main.yml的文件;其他的文件需要在此文件中通过

    include进行包含。

                  Meta/             #定义变量;至少应该包含一个名为main.yml的文件;定义当前角色的特殊设定及其依赖

    关系;其他的文件需要在此文件中通过include进行包含。

                   Default/         #设定默认变量时使用此目录中的main.yml文件。


                   
创建角色目录        
[root@localhost ~]# mkdir -pv /etc/ansible/roles/mariadb/{files,tasks,handlers}

mkdir: 已创建目录 "/etc/ansible/roles/mariadb"
mkdir: 已创建目录 "/etc/ansible/roles/mariadb/files"
mkdir: 已创建目录 "/etc/ansible/roles/mariadb/tasks"
mkdir: 已创建目录 "/etc/ansible/roles/mariadb/handlers"

定义tasks任务的主文件
[root@localhost ~]# vim /etc/ansible/roles/mariadb/tasks/main.yml

- name: install mariadb
  yum: name=mariadb-server state=present

- name: move config file
  shell: "[ -e /etc/my.cnf ] && mv /etc/my.cnf /etc/my.cnf.ba
k"

- name: provide a new config file
  copy: src=my.cnf dest=/etc/my.cnf

- name: start mariadb
  shell: systemctl start mariadb

- name: create database testdb
  shell: mysql -u root -e "create database testdb;grant all o
n testdb.* to 'ly'@'192.168.10.%' identified by '123';flush p
rivileges;"
  notify:
        - restart mariadb

定义触发器的主文件        
[root@localhost ~]# vim /etc/ansible/roles/mariadb/handlers/main.yml
        
        
- name: restart mariadb
  service: name=mariadb state=restarted

复制文件到files目录--便于copy模块或scripts模块调用  
[root@localhost ~]# cp /etc/my.cnf /etc/ansible/roles/mariadb/files/


创建角色主文件
[root@localhost ~]# vim /etc/ansible/mariadb.yml

- hosts: web1
  remote_user: root
  roles:
  - maridb

  
预测试  
[root@localhost ~]# ansible-playbook -C /etc/ansible/mariadb.yml 


执行角色任务
[root@localhost ~]# ansible-playbook  /etc/ansible/mariadb.yml 

PLAY [web1] ********************************************************************

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

TASK [mariadb : install mariadb] ***********************************************
ok: [192.168.10.2]

TASK [mariadb : move config file] **********************************************
changed: [192.168.10.2]

TASK [mariadb : provide a new config file] *************************************
changed: [192.168.10.2]

TASK [mariadb : reload  mariadb] ***********************************************
changed: [192.168.10.2]

TASK [mariadb : create database testdb] ****************************************
changed: [192.168.10.2]

RUNNING HANDLER [mariadb : restart mariadb] ************************************
changed: [192.168.10.2]

PLAY RECAP *********************************************************************
192.168.10.2               : ok=7    changed=5    unreachable=0    failed=0   

ansible

验证:登录远程主机 192.168.10.2
查看mariadb是否安装、启动、是否有测试数据库testdb
[root@ly ~]# mysql -u root 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 5
Server version: 5.5.56-MariaDB MariaDB Server

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| testdb             |
+--------------------+
5 rows in set (0.00 sec)


MariaDB [(none)]> show grants for 'ly'@'192.168.10.%';

+--------------------------------------------------------------------------------------------------------------+
| Grants for [email protected].%                                                                                   |
+--------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'ly'@'192.168.10.%' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' |
| GRANT ALL PRIVILEGES ON `testdb`.* TO 'ly'@'192.168.10.%'                                                    |
+--------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

===============================================
        ansible 命令常用选项
        
Ad-Hoc,即 单条命令,指需要快速执行并且不需要保存的命令。默认不指定模块时,使用的是command模块。
复制代码
Usage: ansible [options]
命令选项
-a # 模块的参数。
-B # 异步运行时,多长时间超时。
-P    #如果使用-B,则设置轮询间隔。
-C # 只是测试一下会改变什么内容,不会真正去执行;相反,试图预测一些可能发生的变化。
-D # 当更改文件和模板时,显示这些文件得差异,比--check效果好。
-f # 指定定要使用的并行进程数,默认为5个。
-i # 指定主机清单文件或逗号分隔的主机,默认为/etc/ansible/hosts。
-l # 进一步限制所选主机/组模式,只执行-l 后的主机和组。 也可以这样使用 -l @retry_hosts.txt
-m   # 要执行的模块,默认为command。
-M   # 要执行的模块的路径。
-o   # 压缩输出,摘要输出.尝试一切都在一行上输出。
-v, --verbose # 输出执行的详细信息,使用-vvv获得更多,-vvvv 启用连接调试
--version # 显示程序版本号
-e --extra-vars=EXTRA_VARS # 添加附加变量,比如key=value,yaml,json格式。
--list-hosts # 输出将要操作的主机列表,不会执行操作
--output=OUTPUT_FILE # 加密或解密输出文件名 用于标准输出。
--tree=TREE # 将日志内容保存在该目录中,文件名以执行主机名命名。
--syntax-check # 对playbook进行语法检查,且不执行playbook。
--ask-vault-pass # vault 密码。
--vault-password-file=VAULT_PASSWORD_FILE vault密码文件
--new-vault-password-file=NEW_VAULT_PASSWORD_FILE 新vault密钥文件。
 
 
连接选项:
-k --ask-pass # 要求用户输入请求连接密码
-u --user=REMOTE_USER # 连接远程用户
-c --connection=CONNECTION # 连接类型,默认smart,支持local ssh 和 paramiko
-T --timeout=TIMEOUT # 指定默认超时时间,默认是10S
--ssh-common-args=SSH_COMMON_ARGS # 指定要传递给sftp / scp / ssh的常见参数 (例如 ProxyCommand)
--sftp-extra-args=SFTP_EXTRA_ARGS # 指定要传递给sftp,例如-f -l
--scp-extra-args=SCP_EXTRA_ARGS # 指定要传递给scp,例如 -l
--ssh-extra-args=SSH_EXTRA_ARGS # 指定要传递给ssh,例如 -R
--private-key=PRIVATE_KEY_FILE, --key-file=PRIVATE_KEY_FILE 私钥路径,使用这个文件来验证连接
 
 
特权升级选项:
-s --sudo # 使用sudo (nopasswd)运行操作, 不推荐使用
-U --sudo-user=SUDO_USER # sudo 用户,默认为root, 不推荐使用
-S --su # 使用su运行操作 不推荐使用
-R --su-user=SU_USER # su 用户,默认为root,不推荐使用
-b --become # 运行操作
--become-method=BECOME_METHOD # 权限升级方法使用 ,默认为sudo,有效选择:sudo,su,pbrun,pfexec,runas,doas,dzdo
--become-user=BECOME_USER # 使用哪个用户运行,默认为root
--ask-sudo-pass # sudo密码,不推荐使用
--ask-su-pass # su密码,不推荐使用
-K --ask-become-pass # 权限提升密码
复制代码
 

 
 
ansible-doc

用于查看模块信息
复制代码
Usage: ansible [options]

选项
-h --help # 显示此帮助信息
-l --list # 列出可用的模块
-s --snippet # 显示playbook制定模块的用法
-v --verbose # 详细模式(-vvv表示更多,-vvvv表示启用连接调试)
--version # 显示程序版本号
-M --module-path=MODULE_PATH # 指定模块库的路径


示例:
ansible-doc -l
ansible-doc shell
ansible-doc -s shell
复制代码
 
 
ansible-playbook

对于需反复执行的、较为复杂的任务,我们可以通过定义 Playbook 来搞定。它允许使用变量、条件、循环、以及模板,也能通过角色及包含指令来重用既有内容。
复制代码
Usage: ansible-playbook playbook.yml
相对于ansible,增加了下列选项:
--flush-cache # 清除fact缓存
--syntax-check # 语法检查
--force-handlers # 如果任务失败,也要运行handlers
--list-tags # 列出所有可用的标签
--list-tasks # 列出将要执行的所有任务
--skip-tags=SKIP_TAGS # 跳过运行标记此标签的任务
--start-at-task=START_AT_TASK # 在此任务处开始运行
--step 一步一步:在运行之前确认每个任务
-t TAGS, --tags=TAGS 只运行标记此标签的任务

你可能感兴趣的:(运维,自动化,服务器)