Linux操作文档——Ansible自动化运维


一、Ansible 概述

1、特点

Ansible基于Python开发,运维工程师对其二次幵发相对较容易。
Ansibled丰富的内置模块,基本可以满足一切需求。
管理模式非常简单,一条命令可以影响上千台机器。
无客户端模式,底层通过SSH通信。 
Ansible 发布后,也陆续被 AWS、Google Cloud Platform, Microsoft Azures Cisco、HP、VMwarev Twitter等大公司接纳并投入使用。

2、Ansible工具集

Ansible Playbooks:任务脚本,编排定义Ansible任务集的配置文件,由Ansible按序依次执行, 通常是JSON格式的丫ML文件。
Inventory:Ansible 管理主机清单。
Modules:AnSlble:执行命令功能模块,多数为内置的核心模块,也可以自定义。
Plugins:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用。
API:供第三方程序调用的应用程序编程接口。
Ansible:组合Inventorys API、Modules、Plugins可以理解为是Ansible 命令工具,其为核心执行工具。

二、Ansible 安装

[root@ansible ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo              //下载epel源
[root@ansible ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo              //下载linux镜像源
[root@ansible ~]# yum -y install ansible
[root@ansible ~]# ansible --version              //验证安装结果
ansible 2.9.10
  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, Nov  6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]
[root@ansible ~]# 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:
01:ff:ae:b3:11:57:a3:b0:fa:a2:82:7c:a8:f0:90:df root@ansible
The key's randomart image is:
+--[ RSA 2048]----+
|      .          |
|       o         |
|        +   o    |
|         = o .   |
|        S +      |
| .     . +       |
|=..   . . .      |
|o*.o  ...o       |
|o +.E. .+o       |
+-----------------+
[root@ansible ~]# ssh-copy-id [email protected]               //复制公钥到远端192.168.1.20
[root@ansible ~]# ssh-copy-id [email protected]               //复制公钥到远端192.168.1.30
[root@ansible ~]# ssh-copy-id [email protected]               //复制公钥到远端192.168.1.40
[root@ansible ~]# ssh 192.168.1.20
Last login: Sat Jul 11 19:19:40 2020
[root@web ~]# exit               //退出192.168.1.20 shell环境
登出
Connection to 192.168.1.20 closed.
[root@ansible ~]# ssh 192.168.1.30               //可以免密码登录192.168.1.20
Last login: Mon Jun  1 14:14:02 2020
[root@nfs ~]# exit               //退出192.168.1.30 shell环境
登出
Connection to 192.168.1.30 closed.

SSH密码认证

[root@ansible ~]# vim /etc/ansible/hosts               //编写hosts文件
[web]
192.168.1.20 ansbile_ssh_user=root ansible_ssh_pass='123456' ansible_ssh_port=22
192.168.1.20 ansbile_ssh_user=root ansible_ssh_pass='123456' ansible_ssh_port=22
[root@ansible ~]# vim /etc/ansible/ansible.cfg
#host_key_checking = False        将#号去掉,可以sh第一次连接的时候不提示输入yes

三、Ansible 配置

[root@ansible ~]# vim /etc/ansible/hosts               //编写hosts文件
[web]
192.168.1.20
[nfs]
192.168.1.30
[rsync]
192.168.1.40
[mail]
zs1.kgc.cn
zs[2:5].kgc.cn               //[2:5]表示2~5之间的所有数字,即表示zs2.kgc.cn,zs3.kgc.cn······的所有主机
[test01]
www.admin.cn:222               //通过222端口管理设备
[benet:children]
web
nfs
rsync
[root@ansible ~]# ansible -i /etc/ansible/hosts web -m ping               //查看主机信息
192.168.1.20 | SUCCESS => {
    
    
    "ansible_facts": {
    
    
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"

针对特定的服务器操作

[root@ansible ~]# ansible web -m command -a "systemctl status httpd" --limit "192.168.1.20"               //只对web组中192.168.1.20主机操作。通过--limit参数限定主机的变更
[root@ansible ~]# ansible 192.168.1.20 -m command -a "systemctl status httpd"              //只对192.168.1.20主机操作。通过ip限定主机的变更
[root@ansible ~]# ansible 192.168.1.* -m command -a "systemctl status httpd"               //只对192.168.1.*  网段主机操作。通过通配符限定主机的变更

四、Ansible 命令

1、ansible

参数 说明
-v (–verbose) 输出详细的执行过程信息,可以得到执行过程所有信息
-i PATH (–inventory=PATH) 指定 inventory 信息,默认为/etc/ansibIe/hosts
-f NUM (-forks=NUM) 并发线程数,默认为5个线程
–private-key=PRIVATE_KEY_FILE 指定密钥文件
-m NAME,–module-name=NAME 指定执行使用的模块
-M DIRECTORY (–module-path=DIRECTORY) 指定模块存放路径,默认为/usr/share/ansibIe
-a ARGUMENTS (–args=ARGUMENTS) 指定模块参数
-u USERNAME (–user=USERNAME) 指定远程主机以USERNAME运行命令
-I subset (–limit=SUBSET) 限制运行主机
–list-hosts 列出符合条件的主机列表,不执行任何命令
[root@ansible ~]# ansible all -f 5 -m ping               //检查所有主机是否存活
192.168.1.20 | SUCCESS => {
    
    
    "ansible_facts": {
    
    
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.1.30 | SUCCESS => {
    
    
    "ansible_facts": {
    
    
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.1.40 | SUCCESS => {
    
    
    "ansible_facts": {
    
    
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
[root@ansible ~]# ansible web --list               //列出web组所有的主机列表
  hosts (1):
    192.168.1.20
[root@ansible ~]# ansible web -m command -a "df -hT"               //批量显示web组中的磁盘使用空间
192.168.1.20 | CHANGED | rc=0 >>
文件系统            类型      容量  已用  可用 已用% 挂载点
/dev/mapper/cl-root xfs        50G  4.4G   46G    9% /
devtmpfs            devtmpfs  1.4G     0  1.4G    0% /dev
tmpfs               tmpfs     1.4G  144K  1.4G    1% /dev/shm
tmpfs               tmpfs     1.4G  9.0M  1.4G    1% /run
tmpfs               tmpfs     1.4G     0  1.4G    0% /sys/fs/cgroup
/dev/sda1           xfs      1014M  173M  842M   18% /boot
/dev/mapper/cl-home xfs        46G   36M   46G    1% /home
tmpfs               tmpfs     280M   16K  280M    1% /run/user/0

2、Ansible-doc

[root@ansible ~]# ansible-doc -l               //列出支持的模块
fortios_router_community_list                                 Configure com...
azure_rm_devtestlab_info                                      Get Azure Dev...
ecs_taskdefinition                                            register a ta...
avi_alertscriptconfig                                         Module for se...
tower_receive                                                 Receive asset...
netapp_e_iscsi_target                                         NetApp E-Seri...
azure_rm_acs                                                  Manage an Azu...
fortios_log_syslogd2_filter                                   Filters for r...
......
[root@ansible ~]# ansible-doc ping               //查询ping模块的说明信息
> PING    (/usr/lib/python2.7/site-packages/ansible/modules/system/ping.py)

        A trivial test module, this module always returns `pong' on
        successful contact. It does not make sense in playbooks, but
        it is useful from `/usr/bin/ansible' to verify the ability to
        login and that a usable Python is configured. This is NOT ICMP
        ping, this is just a trivial test module that requires Python
        on the remote-node. For Windows targets, use the [win_ping]
        module instead. For Network targets, use the [net_ping] module
        instead.
......

3、Ansible-playbook

Ansible-playbook命令后跟yml格式的playbook文件,playbook文件存放了要执行的任务代码
例:ansible-playbook playbook.yml(指定playbook.yml的绝对路径)

4、Ansible-console

交互操作远程主机,通过cd命令切换主机或分组,列出当前的设备

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

root@all (9)[f:5]$ cd web
root@web (1)[f:5]$ list
192.168.1.20
root@web (1)[f:5]$ cd nfs
root@nfs (1)[f:5]$ list
192.168.1.30

五、Ansible 模块

1、command 模块

参数 说明
chdir 在远程主机上运行命令前要提前进入的目录
creates 在命令运行时创建一个文件,如果文件已存在,则不会执行创建任务
removes 命令运行时移除一个文件,如果文件不存在,则不会执行移除任务
executeble 指明运行命令的shell程序
[root@ansible ~]# ansible all -m command -a "chdir=/home ls ./"               //在所有主机上运行* ./"命令,运行前切换到/home目录
192.168.1.40 | CHANGED | rc=0 >>
lisi
192.168.1.30 | CHANGED | rc=0 >>
user1
192.168.1.20 | CHANGED | rc=0 >>
lisi
[root@ansible ~]# ansible web -m command -a "hostname"               //查看主机名称
192.168.1.20 | CHANGED | rc=0 >>
web
[root@ansible ~]# ansible web -m command -a "useradd zhangsan"               //创建zhangsan用户
192.168.1.20 | CHANGED | rc=0 >>

2、shell 模块

[root@ansible ~]# ansible web -m shell -a 'echo "hello">> /tmp/hello.txt'               //在远程主机执行命令在/tmp目录下创建内容为hello的hello.txt文件
192.168.1.20 | CHANGED | rc=0 >>
[root@ansible ~]# ssh 192.168.1.20 cat /tmp/hello.txt
hello
[root@ansible ~]# ansible web -m shell -a "echo 123 | passwd --stdin zhangsan"               //更改用户zhangsan的密码
192.168.1.20 | CHANGED | rc=0 >>
更改用户 zhangsan 的密码 。
passwd:所有的身份验证令牌已经成功更新。

或者

[root@ansible ~]# vim /etc/ansible/shell.yml
- name: 将命令结果输出到指定文件
  shell: somescript.sh >> somelog.txt
- name: 切换目录执行命令
  shell:
    cmd: ls -l | grep log
    chdir: somedir/
- name: 编写脚本
  shell: |
      if [ 0 -eq 0 ]; then
         echo yes > /tmp/result
      else
         echo no > /tmp/result
      fi
  args:
    executable: /bin/bash

3、copy模块

参数 说明
dest 指出复制文件的目标目录位置,使用绝对路径。如果源是目录,则目标也要是目录,如果目标文件已存在,会覆盖原有内容
src 指出源文件的路径,可以使用相对路径和绝对路径,支持直接指定目录。如果源是目录,则目标也要是目录
mode 指出复制时,目标文件的权限,可选
owner 指出复制时,目标文件的属主,可选
group 指出复制时,目标文件的属组,可选
content 指出复制到目标主机上的内容,不能与src一起使用,相当于复制content指明的数据到目标文件中
[root@ansible ~]# ansible benet -m copy -a "src=/etc/hosts  dest=/etc/hosts backup=yes"               //将本机hosts文件复制到所有主机

例如在ansible上远程配置rsync服务

[root@ansible ~]# mkdir /etc/ansible/conf               //修改rsync配置文件,并传到rsync服务器
[root@ansible ~]# cd /etc/ansible/conf
[root@ansible conf]# cp /etc/rsyncd.conf ./
[root@ansible conf]# vim rsyncd.conf 
uid = nobody
gid = nobody
port 873
address = 192.168.1.40
hosts allow = 192.168.1.0/24
max connections = 4
pid file = /var/run/rsyncd.pid
timeout = 900
dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
[backup]
		path = /backup
		read only = no
		auth users = rsync_backup
		secrets file = /etc/rsync.password 
[root@ansible conf]# ansible 192.168.1.40 -m copy -a "src=rsyncd.conf  dest=/etc/rsyncd.conf backup=yes"
[root@ansible conf]# ansible rsync -m shell -a "rsync --daemon"               //启动rsync服务
[root@ansible conf]# ansible rsync -m file -a "path=/backup owner=root group=root recurse=yes mode=777"               //创建目录,并赋权,更改属主属组
[root@ansible ~]# ansible rsync -m copy -a "content='rsync_backup:1' dest=/etc/rsync.password owner=root group=root mode=600"               //配置rsync服务器的密码文件
[root@ansible ~]# ansible rsync -m shell -a "ls -l /etc/rsync.password"
192.168.1.40 | CHANGED | rc=0 >>
-rw------- 1 root root 14 712 10:06 /etc/rsync.password
[root@ansible ~]# ansible rsync -m shell -a "cat /etc/rsync.password"
192.168.1.40 | CHANGED | rc=0 >>
rsync_backup:1
[root@ansible ~]# ansible benet -m copy -a "content='1' dest=/etc/server.pass owner=root group=root mode=600"               //配置所有服务器的rsync连接密码文件
[root@ansible ~]# ansible web -m shell -a "rsync -avz --password-file=/etc/server.pass /etc/httpd/conf/httpd.conf rsync_backup@rsync::backup"               //备份WEB的httpd.conf配置文件
192.168.1.20 | CHANGED | rc=0 >>
sending incremental file list
httpd.conf

sent 4602 bytes  received 27 bytes  9258.00 bytes/sec
total size is 11753  speedup is 2.54

或者

[root@ansible ~]# vim /etc/ansible/copy.yml
- name: 拷贝文件
  copy:
    src: /srv/myfiles/foo.conf
    dest: /etc/foo.conf
    owner: foo
    group: foo
    mode: u=rw,g=r,o=r
    # mode: u+rw,g-wx,o-rwx
    # mode: '0644'
    backup: yes

4、hostname模块

[root@ansible ~]# ansible 192.168.1.30 -m hostname -a "name=demo"               //将192.168.1.30主机名改为demo
[root@ansible ~]# ssh 192.168.1.30
Last login: Sun Jul 12 11:10:53 2020 from 192.168.1.10
[root@demo ~]# hostname
demo

5、yum模块

参数 说明
name 程序包的名称,可以带上版本号。若不指明版本,则默认为最新版本
state=present latest
disablerepo 在用yum安装时,临时禁用某个仓库的ID
enablerepo 在用yum安装时,临时启用某个仓库的ID
confjile yum运行时的配置文件,而不是使用默认的配置文件
diable_gpg_check=yes no
[root@ansible ~]# ansible web -m yum -a "name=httpd state=installed"               //在web主机安装httpd服务
[root@ansible ~]# ssh 192.168.1.20 rpm -qa | grep httpd
httpd-2.4.6-93.el7.centos.x86_64
httpd-tools-2.4.6-93.el7.centos.x86_64

或者

[root@ansible ~]# ansible webservers -m yum -a "name=http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.16.1-1.el7.ngx.x86_64.rpm state=present"
[root@ansible ~]# ansible webservers -m systemd -a "name=http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.16.1-1.el7.ngx.x86_64.rpm state=restarted enabled=yes"
[root@ansible ~]# vim /etc/ansible/yum.yml
- name: 安装最新版apache
  yum:
    name: httpd
    state: latest
- name: 安装列表中所有包
  yum:
    name:
      - nginx
      - postgresql
      - postgresql-server
    state: present
- name: 卸载apache包
  yum:
    name: httpd
    state: absent 
- name: 更新所有包
  yum:
    name: '*'
    state: latest
- name: 安装nginx来自远程repo
  yum:
    name: http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
    # name: /usr/local/src/nginx-release-centos-7-0.el7.ngx.noarch.rpm
    state: present

6、service 模块

参数 说明
name 被管理的服务名称
state=started stopped
enabled=yes no
run level 如果设定了enabled开机自启动,则要定义在哪些运行目标下自动启动
[root@ansible ~]# ansible web -m service -a "name=httpd state=stopped enabled=yes"               //启动httpd服务,并设置为开机启动

或者

[root@ansible ~]# vim /etc/ansible/service.yml
- name: 服务管理
  service:
    name: httpd
    state: started
    #state: stopped
    #state: restarted
    #state: reloaded
- name: 设置开机启动
  service:
    name: httpd
    enabled: yes

7、user模块

参数 说明 参数 说明
name 必选参数,账号名称 state=present absent
system=yes/no 是否为系统账号 uid 用户UID
group 用户的基本组 groups 用户的附加组
shell 默认使用的shell home 用户的家目录
move_home=yes/no 如果设置的家目录已经存在,是否将已存在的家目录进行移动 password 用户的密码,建议使用加密后的字符串
comment 用户的注释信息 remove=yes/no 当state=absent时,是否要删除用户的家目录
[root@ansible ~]# ansible all -m user -a "name=www"               //在所有清单主机上创建用户www,gid 666
[root@ansible ~]# ansible web -m shell -a "echo 123 | passwd --stdin www"               //更改web主机用户www的密码
192.168.1.20 | CHANGED | rc=0 >>
更改用户 www 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@ansible ~]# ansible web -m user -a 'name=user1 system=yes uid=501 group=root groups=sshd shell=/sbin/nologin home=/home/user1 password=user1 comment="test user"'
[root@ansible ~]# ssh 192.168.1.20 tail -1 /etc/passwd
user1:x:501:0:test user:/home/user1:/sbin/nologin
[root@ansible ~]# ansible web -m user -a "name=user1 remove=yes state=absent"              //删除user1用户
[root@ansible ~]# ssh 192.168.1.20 tail -1 /etc/passwd
www:x:1002:1002::/home/www:/bin/bash

8、group模块

[root@ansible ~]# ansible all -m group -a "name=www gid=666"               //在所有清单主机上创建组www,gid 666
[root@ansible ~]# ansible all -m group -a "name=www gid=666 state=absent"               //在所有清单主机删除组www

9、file模块

[root@ansible ~]# ansible rsync -m file -a "path=/backup owner=root group=root recurse=yes mode=777"               //创建目录,并赋权,更改属主属组
[root@ansible ~]# ansible rsync -m file -a "path=/test.txt owner=root group=root state=touch  mode=777"               //创建文件

或者

[root@ansible ~]# vim /etc/ansible/file.yml
- name: 创建目录
  file:
    path: /etc/some_directory
    state: directory
    mode: '0755'
- name: 删除文件
  file:
    path: /etc/foo.txt
    state: absent
- name: 递归删除目录
  file:
    path: /etc/foo
    state: absent

present,latest:表示安装
absent:表示卸载

10、mount模块

[root@ansible ~]# ansible nfs -m file -a "path=/nfs owner=root group=root recurse=yes mode=777"
[root@ansible ~]# vim exports
/nfs 192.168.1.0/24(rw,sync,no_root_squash)
[root@ansible ~]# ansible nfs -m copy -a "src=exports dest=/etc/exports"
[root@ansible ~]# ansible nfs -m service -a "name=nfs state=restarted"
[root@ansible ~]# ansible nfs -m service -a "name=rpcbind state=restarted"
[root@ansible ~]# ansible web -m mount -a "src=192.168.1.30:/nfs path=/var/www/html fstype=nfs state=mounted"

11、unarchive模块

- name: 解压
  unarchive: 
    src=test.tar.gz 
    dest=/tmp

12、debug模块

执行过程中打印语句。

- debug:
    msg: System {
    
    {
    
     inventory_hostname }} has uuid {
    
    {
    
     ansible_product_uuid }}

- name: 显示主机已知的所有变量
  debug:
    var: hostvars[inventory_hostname]
    verbosity: 4

六、playbook配置文件

1、执行配置文件

参数 说明
hosts 任务的目标主机,多个主机用冒号分隔,一般调用/etc/ansible/hosts中的分组信息
remote_user 远程主机上,运行此任务的身份默认为root
tasks 任务,即定义的具体任务,由模块定义的操作列表
handlers 触发器,只是在特定的条件下才会触发的任务
roles 角色,将hosts剥离出去,由tasks、handlers等所组成的一种特定的结构集合
因为需要缩进两个字符,默认的tab键是四个字符,所以要使用tab键,需要修改.vimrc
[root@ansible ~]# vim /root/.vimrc
set tabstop=2

注意:各个要素务必对齐,冒号和横杠后面要有空格

[root@ansible ~]# vim /etc/ansible/hosts                   //修改 hosts 文件
[web1]
192.168.1.30
[web2]
192.168.1.40
[root@ansible ~]# vim /etc/ansible/a.yml                   //创建a.yml文件
#针对web1(192.168.1.30)的操作
  - hosts: web1
	#远端执行用户身份为root
    remote_user: root
    #任务列表
    tasks:
    	#任务名称
        - name: adduser
          #执行user模块,创建用户
          user: name=user2 state=present
          #创建tag标签
          tags :
          #tag标签为aaa
          - aaa
        #任务名称
        - name: addgroup
          #执行group模块,创建组
          group: name=root system=yes
          #创建tag标签
          tags :
          #tag标签为bbb
          - bbb
  #针对web2(192.168.1.40)的操作
  - hosts: web2 
    #远端执行用户身份为root
    remote_user: root
    #任务列表
    tasks:
    	#任务名称
        - name: copy file to web
       	  #执行copy模块,复制文件
          copy: src=/etc/passwd dest=/home
          #创建tag标签
          tags:
          	#tag标签为ccc
             - ccc

ansible-playbook命令用法:

ansible-playbook  [option]    /PATH/TO/PLAYBOOK. yaml
参数 说明
–syntax-check 检测yaml文件的语法
-C(–check) 预测试,不会改变目标主机的任何设置
–list-hosts 列出yaml文件影响的主机列表
–list-tasks 列出yaml文件的任务列表
–list-tags 列出yaml文件中的标签
-t TAGS (–tags=TAGS) 表示只执行指定标签的任务
–skip-tags=SKIP_TAGS 表示除了指定标签的任务,执行其他任务
–start-at-task=START_AT 从指定的任务开始往下运行
[root@ansible ~]# ansible-playbook --syntax-check /etc/ansible/a.yml               //语法检查

playbook: /etc/ansible/a.yml
[root@ansible ~]# ansible-playbook -C /etc/ansible/a.yml               //预测试
[root@ansible ~]# 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.1.30

  play #2 (web2): web2	TAGS: []
    pattern: [u'web2']
    hosts (1):
      192.168.1.40
[root@ansible ~]# 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@ansible ~]# 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@ansible ~]# ansible-playbook /etc/ansible/a.yml               //执行任务
[root@ansible ~]# ssh 192.168.1.30 tail -1 /etc/passwd
user2:x:1002:1002::/home/user2:/bin/bash
[root@ansible ~]# ssh 192.168.1.40 tail -1 /etc/passwd
www:x:1001:1001::/home/www:/bin/bash
[root@ansible ~]# ssh 192.168.1.40 ls -l /home/passwd
-rw-r--r-- 1 root root 2232 713 17:36 /home/passwd

2、触发器

正常情况下 httpd 监听 80 端口

[root@ansible ~]# ssh 192.168.1.30 netstat -lnpt | grep 80                //正常情况下 httpd监听80端口
tcp6       0      0 :::80                   :::*                    LISTEN      64665/httpd              
[root@ansible ~]# vim /etc/ansible/httpd.yml               //创建 httpd.yml 配置文件
  - hosts: web1
    remote_user: root
    tasks:
    	#修改端口
        - name: change port
          command: sed -i 's/Listen\ 80/Listen\ 8080/g' /etc/httpd/conf/httpd.conf
          #配置触发条件
          notify:
          		#完成该任务后调用名为"restart httpd server"的触发器
                - restart httpd server
    #配置触发器
    handlers:
  		  #指定触发器名字
        - name: restart httpd server
          #触发任务为重启 httpd 服务
          service: name=httpd state=restarted
[root@ansible ~]# ansible-playbook /etc/ansible/httpd.yml                //执行 yml 文件
[root@ansible ~]# ssh 192.168.1.30 netstat -lnpt | grep 8080               //远端主机已经运行8080端口
tcp6       0      0 :::8080                 :::*                    LISTEN      66255/httpd         

3、角色

[root@ansible ~]# mkdir -p /etc/ansible/roles/mariadb/{files,tasks,handlers}                //创建角色目录
[root@ansible ~]# cd /etc/ansible/roles/mariadb/tasks/                //进入mariadb角色文件夹的tasks
[root@ansible tasks]# vim main.yml                //编写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.bak"
  - name: provide a new config file
    #src可以不指定路径,自动到角色目录下的files文件夹去找
    copy: src=my.cnf dest=/etc/my.cnf
  - name: reload mariadb
    shell: systemctl restart mariadb
  - name: create database testdb
    shell: mysql -u root -e "create database testdb;grant all on testdb.* to 'test'@'192.168.1.%' identified by 'test123';flush privileges;"
    notify:
    - restart mariadb
[root@ansible tasks]# cd ../handlers/                //进入rnariadb角色文件夹的handlers
[root@ansible handlers]# vim main.yml                //编写main.yml文件
  - name: restart mariadb
    service: name=mariadb state=restarted
[root@ansible handlers]# cp /etc/my.cnf /etc/ansible/roles/mariadb/files/                //提前准备my.cnf配置文件,准备复制到被管理主机
[root@ansible handlers]# cd ../../..
[root@ansible ansible]# vim mariadb.yml
  - hosts: web1
    remote_user: root
    roles:
    - mariadb
[root@ansible ~]# ansible-playbook /etc/ansible/mariadb.yml                 
[root@mysql ~]# mysql -u test -p -h 192.168.1.30               //查看远端主机
Enter password:                //无密码
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 5
Server version: 5.5.65-MariaDB MariaDB Server

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

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

MariaDB [(none)]> 

4、playbook配置web-nfs-rsync架构环境

[root@ansible ~]# yum -y install httpd
[root@ansible ~]# cp /etc/httpd/conf/httpd.conf ./               //复制httpd配置文件
[root@ansible ~]# vim httpd.conf              //按需求修改配置文件
[root@ansible ~]# mkdir -p /etc/ansible/ansible_playbook/{conf,file,scripts,tools}               //创建ansible目录
[root@ansible ~]# vim /etc/ansible/hosts               //创建ansible清单
[web]
192.168.1.20
[nfs]
192.168.1.30
[rsync]
192.168.1.40
[root@ansible ~]# vim /etc/ansible/ansible_playbook/base.yaml               //基础环境部署
- hosts: all
  tasks:
    - name: clear repos.d
      file: path=/etc/yum.repos.d/ state=absent

    - name: create repos.d
      file: path=/etc/yum.repos.d/ state=directory

    - name: install base repo
      get_url: url=http://mirrors.aliyun.com/repo/Centos-7.repo dest=/etc/yum.repos.d/CentOS-Base.repo

    - name: install epel repo
      get_url: url=http://mirrors.aliyun.com/repo/epel-7.repo dest=/etc/yum.repos.d/epel.repo

    - name: install rsync nfs-utils
      yum: name=rsync,nfs-utils state=installed

    - name: create group www
      group: name=www gid=666

    - name: create user www
      user: name=www uid=666 create_home=no shell=/sbin/nologin

    - name: create rsync client password
	  copy: content='1' dest=/etc/rsync.pass mode=600

    - name: create scripts directory
      file: path=/server/scripts/ recurse=yes state=directory

    - name: push scripts
      copy: src=./scripts/rsync_backup.sh dest=/server/scripts

    - name: crontab
      cron: name="backup scripts" hour=01 minute=00 job="/usr/bin/bash /server/scripts/rsync_backup.sh &> /dev/null"
[root@ansible ~]# vim /etc/ansible/ansible_playbook/rsync.yaml               //rsync配置
- hosts: rsync
  tasks:
  
    - name: install rsync
      yum: name=rsync,mailx state=installed

    - name: config rsync
      copy: src=/etc/ansible/ansible_playbook/conf/rsyncd.conf dest=/etc/rsyncd.conf
      notify: restart rsync

    - name: create rsync local user
      copy: content='rsync_backup:1' dest=/etc/rsync.password mode=600

    - name: create data
      file: path=/data state=directory recurse=yes owner=www group=www mode=755

    - name: create backup
      file: path=/backup state=directory recurse=yes owner=www group=www mode=755

    - name: start rsync
      service: name=rsyncd state=started enabled=yes

    - name: push check scripts
      copy: src=./scripts/rsync_check.sh dest=/server/scripts/

    - name: crond check scripts
      cron: name="check scripts" hour=05 minute=00 job="/usr/bin/bash /server/scripts/rsync_check.sh &> /dev/null"

  handlers:
    - name: restart rsync
      service: name=rsyncd state=restarted
[root@ansible ~]# vim /etc/ansible/ansible_playbook/nfs.yaml               //nfs部署
- hosts: nfs

  tasks:
    - name: install nfs
      yum: name=nfs-utils state=installed

    - name: config nfs
      copy: src=./conf/exports dest=/etc/exports

    - name: create data
      file: path=/data state=directory recurse=yes owner=www group=www mode=755

    - name: start nfs
      service: name=nfs-server state=started enabled=yes

  handlers:
    - name: restart nfs
      service: name=nfs-server state=restarted
[root@ansible ~]# cd /etc/ansible/ansible_playbook/scripts/
[root@ansible scripts]# vim rsync_backup.sh
#!/usr/bin/bash
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

#1.定义变量
Host=$(hostname)
Addr=$(ifconfig ens33|awk 'NR==2{print $2}')
Date=$(date +%F)
Dest=${Host}_${Addr}_${Date}
Path=/backup

#2.创建备份目录
[ -d $Path/$Dest ] || mkdir -p $Path/$Dest

#3.备份对应的文件
cd / && \
[ -f $Path/$Dest/system.tar.gz ] || tar czf $Path/$Dest/system.tar.gz etc/fstab etc/rsyncd.conf && \
[ -f $Path/$Dest/log.tar.gz ] || tar czf $Path/$Dest/log.tar.gz  var/log/messages var/log/secure && \

#4.携带md5验证信息
[ -f $Path/$Dest/flag ] || md5sum $Path/$Dest/*.tar.gz >$Path/$Dest/flag_${Date}

#4.推送本地数据至备份服务器
export RSYNC_PASSWORD=1
rsync -avz $Path/ rsync_backup@rsync1::backup

#5.本地保留最近7天的数据
find $Path/ -type d -mtime +7|xargs rm -rf
[root@ansible scripts]# vim rsync_check.sh
#!/usr/bin/bash

#1.定义全局的变量
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

#2.定义局部变量
Path=/backup
Date=$(date +%F)

#3.查看flag文件,将校验的结果保存至result_时间
find $Path/*_${Date} -type f -name "flag$Date"  >$Path/result_${Date}

#4.将校验的结果发送邮件给管理员
mail -s "Rsync Backup $Date" 1793594335@qq.com <$Path/result_${Date}

#5.删除超过7天的校验结果文件, 删除超过180天的备份数据文件
find $Path/ -type f -name "result*" -mtime +7|xargs rm -f
find $Path/ -type d -mtime +180|xargs rm -rf
[root@ansible scripts]# cd
[root@ansible ~]# wget https://files.cnblogs.com/files/hypj/sersync2.5.4_64bit_binary_stable_final.tar.gz
[root@ansible ~]# tar zxf sersync2.5.4_64bit_binary_stable_final.tar.gz -C /etc/ansible/ansible_playbook/
[root@ansible ~]# cd /etc/ansible/ansible_playbook/
[root@ansible ansible_playbook]# mv GNU-Linux-x86/ tools/sersync
[root@ansible ansible_playbook]# cd tools/sersync/
[root@ansible sersync]# vim confxml.xml 
    <sersync>
	<localpath watch="/data">
	    <remote ip="192.168.1.104" name="data"/>
	    <!--<remote ip="192.168.8.39" name="tongbu"/>-->
	    <!--<remote ip="192.168.8.40" name="tongbu"/>-->
	</localpath>
[root@ansible sersync]# cd
[root@ansible ~]# vim /etc/ansible/ansible_playbook/sersync.yaml               //sersync部署
- hosts: nfs

  tasks:
    - name: scp sersync
      copy: src=./tools/sersync/ dest=/usr/local/sersync owner=www group=www mode=755

    - name: start sersync
      shell: pgrep sersync;
              [ $? -eq 0 ] || /usr/local/sersync/sersync2 -dro /usr/local/sersync/confxml.xml
[root@ansible ~]# cp httpd.conf /etc/ansible/ansible_playbook/conf
[root@ansible ~]# vim /etc/ansible/ansible_playbook/web.yaml               //web部署
- hosts: web

  tasks:
    - name: mount nfs
      mount: src=nfs1:/data path=/data fstype=nfs state=mounted
    - name: install httpd
      yum: name=httpd state=installed

    - name: config httpd
      copy: src=./conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
      notify: restart httpd

    - name: start httpd
      service: name=httpd state=started enabled=yes

  handlers:
    - name: restart httpd
      service: name=httpd state=restarted
[root@ansible ~]# cd /etc/ansible/ansible_playbook/conf/
[root@ansible conf]# vim rsyncd.conf
uid = nobody
gid = nobody
port 873
address = 192.168.1.40
hosts allow = 192.168.1.0/24
max connections = 4
pid file = /var/run/rsyncd.pid
timeout = 900
dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
[backup]
		path = /backup
		read only = no
		auth users = rsync_backup
		secrets file = /etc/rsync.password
[root@ansible conf]# vim exports
/data 192.168.1.0/24(rw,sync,all_squash)
[root@ansible conf]# cd ../
[root@ansible ansible_playbook]# vim main.yaml
- import_playbook: base.yaml
- import_playbook: rsync.yaml
- import_playbook: nfs.yaml
- import_playbook: sersync.yaml
- import_playbook: web.yaml
[root@ansible ansible_playbook]# ansible-playbook main.yaml 

猜你喜欢

转载自blog.csdn.net/g950904/article/details/104709771