批量管理服务概述

ansible批量管理服务概述

1) 是基于python语言开发的自动化软件工具
2) 是基于SSH远程管理服务实现远程主机批量管理

ansible批量管理服务意义

1) 提高工作的效率
2) 提高工作准确度
3) 减少维护的成本
4) 减少重复性工作

ansible批量管理服务功能

1) 可以实现批量系统操作配置
2) 可以实现批量软件服务部署
3) 可以实现批量文件数据分发
4) 可以实现批量系统信息收集		--- 资产管理

ansible批量管理服务特点

1) 管理端不需要启动服务程序(no server)
2) 管理端不需要编写配置文件(/etc/ansible/ansible.cfg)
3) 受控端不需要安装软件程序(libselinux-python)
4) 受控端不需要启动服务程序(no agent)
5) 服务程序管理操作模块众多(module)
6) 利用剧本编写来实现自动化(playbook)

批量管理软件安装部署过程

前提 ansible 基于 ssh 服务进行

第一步: 下载 ansible

yum install -y ansible

第二步: 配置网站主机清单

/etc/ansible/hosts

方法一: 直接写入主机地址信息
vim /etc/ansible/hosts
	172.16.1.7
	172.16.1.8
ansible all -m ping

方式二: 基于密码方式进行配置
vim /etc/ansible/hosts
	172.16.1.7 ansible_user=root ansible_password=123456 ansible_port=52113
	172.16.1.8 ansible_user=root ansible_password=123456 ansible_port=52113
ansible all -m ping

方式三: 采用主机组方式配置
vim /etc/ansible/hosts
	[mysql]
	172.16.1.31 ansible_user=root ansible_password=654321 ansible_port=52113
	[web]
	172.16.1.7
	172.16.1.8
ansible mysql -m ping

扩展: 主机子组配置
vim /etc/ansible/hosts
	[fater:children]
	server
	client
	
	[server]
	172.16.1.31 ansible_user=root ansible_password=654321 ansible_port=52113
	
	[client]
	172.16.1.41
	172.16.1.7
	ansible fater -m ping

方式四: 采用匹配方式配置主机信息
vim /etc/ansible/hosts
	172.16.1.[10:20]

批量管理服务应用方法

批量管理命令语法结构

ansible 管理主机信息/主机组信息 -m 模块名称 -a "模块参数"

vim /etc/ansible/hosts
	[web]
	172.16.1.7
	172.16.1.8

第一个模块: command模块(默认)

作用说明: 命令模块
使用方法:
	ansible 管理主机信息/主机组信息 -a "命令"	---- 不识别特殊的符号

模块参数:
	chdir: 在执行批量管理命令时, 先进行目录切换
	ansible web  -m command -a "chdir=/tmp pwd"

	creates: 判断指定文件是否存在, 如果不存在, 就执行后面命令; 如果存在, 后面命令不再执行
	ansible web -m command -a "creates=/tmp/test.txt touch /tmp/test.txt"

第二个模块: shell模块(万能模块)

作用说明: 批量执行命令(和command模块区别 可以识别特殊符号)
使用方法: 
	ansible oldboy -a "cd /tmp ; touch test.txt"

模块参数:
	chdir: 在执行批量管理命令时, 先进行目录切换
	ansible web  -m command -a "chdir=/tmp pwd"

	creates: 判断指定文件是否存在, 如果不存在, 就执行后面命令; 如果存在, 后面命令不再执行
	ansible web -m shell -a "creates=/tmp/test.txt touch /tmp/test.txt"

第三个模块: script

作用说明: 批量执行脚本模块
使用方法: 
	ansible web -m script -a "/server/scripts/ansible_test2.sh"

第四个模块: copy

作用说明:
	1) 将管理主机数据批量分发到被管理主机上
	2) 将被管理主机数据进行备份

使用方法:
将数据进行批量分发:
ansible web -m copy -a "src=/etc/selinux/config  dest=/tmp"

将被管理主机数据做备份
ansible web -m copy -a "src=/tmp/test.txt  dest=/tmp/test.txt.bak  remote_src=yes"

模块参数:
	backup: 在批量传输文件, 进行覆盖之前, 对源文件进行备份
	ansible web -m copy -a "src=/tmp/test.txt  dest=/tmp/ backup=yes"

mode:  批量分发文件时, 修改文件权限信息
owner: 批量分发文件时, 修改文件属主信息
group: 批量分发文件时, 修改文件属组信息
ansible web -m copy -a "src=/tmp/test.txt dest=/tmp mode=600 owner=root group=root"

content: 在批量管理主机上, 创建新的文件, 并填写内容
ansible web -m copy -a "content='测试' dest=/tmp/test.txt"

第五个模块: file

模块说明:	
1) 修改已有文件属性信息 (权限 属主 属组)
	ansible web -m file -a "path=/test/test.txt mode=600 owner=root group=root"
	ansible web -m file -a "path=/test/ mode=600 owner=root group=root"

2) 用于创建新的数据信息/删除数据信息
	创建普通文件:
		ansible web -m file -a "path=/test/test100.txt state=touch
	
创建目录文件:
	ansible web -m file -a "path=/test/test01 state=directory"

创建链接文件: (软连接)
	ansible web -m file -a "src=/test/test100.txt path=/test/test_soft.txt  state=link" 

创建链接文件: (硬链接)
	ansible web -m file -a "src=/test/test100.txt path=/test/test_hard.txt  state=hard"

删除文件数据:
	ansible web -m file -a "path=/test/test100.txt state=absent" 
	ansible web -m file -a "path=/test/test_dir state=absent"

第六个模块: fetch

模块说明: 将被管理主机数据进行拉取
	ansible web -m fetch -a "src=/test/awk.txt dest=/tmp/"

第七个模块: yum

模块说明: 批量安装软件包(并行)
	ansible web -m yum -a "name=htop state=installed"
	ansible web -m yum -a "name=htop state=removed"

第八个模块: service == systemctl

模块说明:  管理服务运行状态
		ansible web -m service -a "name=crond state=stopped"
		ansible web -m service -a "name=crond state=started"
		ansible web -m service -a "name=crond state=restarted"
		ansible web -m service -a "name=crond state=restarted enabled=yes"
		确认服务已经被systemctl命令管理

第九个模块: cron

模块说明: 实现批量设置定时任务
模块参数:
	name	: 设置定时任务注释信息 (用于判断定时任务是否相同)
	minute	: 设置时间分钟信息  (0-59 * / -)
	hour	: 设置时间小时信息  (0-23 * / -)
	day		: 设置时间日期信息  (1-31 * / -)
	month	: 设置时间月份信息  (1-12 * / -)
	weekday	: 设置时间星期信息  (0-6  * / -)
	jobs	: 设置任务信息

模块实践:
	创建定时任务
		ansible web -m cron -a "name='exec shell scripts03'  minute=0 hour=2  job='/bin/sh /server/scripts/test.sh'"
	
	删除定时任务
		ansible web -m cron -a "name='exec shell scripts02' state=absent"
	
	注释定时任务: 
		ansible web -m cron -a "name='exec shell scripts' minute=0 hour=2 day=15 month=12 weekday=5 job='/bin/sh /server/scripts/test.sh' disabled=yes"
		ansible web -m cron -a "name='exec shell scripts' minute=0 hour=2 day=15 month=12 weekday=5 job='/bin/sh /server/scripts/test.sh' disabled=no"

扩展: 以普通用户身份设置定时任务
	ansible web -m cron -a "name='exec shell scripts' job='/bin/sh /server/scripts/test.sh' user=alex100"

正常设置定时任务:
	分 时 日 月 周   任务信息

第十个模块:user (useradd usermoduserdel) / group

模块说明: 批量创用户信息
模块参数:
	comment		--- 给添加用户设置注释信息   useradd -c
	create_home	--- 指定是否创建家目录       useradd -M
	group		--- 指定用户所属主要组信息   useradd -g
	groups		--- 指定用户所属附加组信息   useradd -G
	home		--- 指定用户家目录存放路径   useradd -b
	name		--- 指定创建用户名称
	password	--- 设置用户密码信息(必须是密文?)
	shell		--- 指定用户登录系统方式     useradd -s
	state		--- 可以删除用户信息(absent) userdel -r
	uid			--- 指定用户uid数值信息

创建新的用户:
	ansible web -m user -a "name=test10 uid=6666 group=test groups=test200 create_home=no shell=/sbin/nologin"

修改用户信息: usermod
	ansible web -m user -a "name=test10 uid=7777"

删除用户信息:
	ansible web  -m user -a "name=test20 state=absent"

如何设置密码:
	ansible oldboy -m user -a 'name=oldbaby11 password=$6$oldboy$MVd3DevkLcimrBLdMICrBY8HF82Wtau5cI8D2w4Zs6P1cCfMTcnnyAmmJc7mQaE9zuHxk8JFTRgYMGv9uKW7j1'

扩展说明: 如何给密码明文信息加密

方法一:
ansible all -i localhost, -m debug -a "msg={{ '123456' | password_hash('sha512', '用户名称') }}"

方法二:
yum install -y python-pip
优化pip源 --> https://developer.aliyun.com/mirror/pypi?spm=a2c6h.13651102.0.0.53322f70kU73Ag
pip install passlib
python -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.using(rounds=5000).hash(getpass.getpass()))"

第十一模块: unarchive

模块说明: 解压压缩包
模块参数:
	ansible web -m unarchive -a "src=/test/foo.tgz dest=/test/"   将本地压缩数据解压被管理主机上
	ansible web -m unarchive -a "src=/test/foo.tgz dest=/test/ remote_src=yes"
	ansible web -m unarchive -a "src=/test/sersync-master.zip dest=/test/"

批量管理服务剧本编写

利用剧本可以实现自动化部署服务功能
备份服务部署过程:
	服务端: 下载软件程序 --- 编写配置文件 --- 创建虚拟用户 --- 创建密码文件(600) --- 创建备份目录(属主属组) --- 开启服务
	客户端: 下载软件程序 --- 创建密码文件(600)

剧本编写规范

两部分内容:    角色信息  角色任务

具体编写规范:  pyyaml语法结构

满足三个要求:
1) 满足信息缩进规范:  以两个空格作为一个缩进关系  
	一级信息
	  二级信息
	     三级信息
	  二级信息
	一级信息
2) 满足信息字典规范: 在使用冒号时后面需要跟上空格, 冒号结尾不需要有空格
3) 满足信息列表规范: 短横线加空格构成列表信息
	- 一级信息: 开发课程体系
	- 一级信息: 运维课程体系 
	- 一级信息: 网络课程体系

利用剧本批量安装软件:
- hosts: web
  remote_user: root
  tasks:
    yum: name=htop state=installed

剧本执行操作:
	ansible-playbook /etc/ansible/ansible_playbook/test01.yaml

剧本语法检查:
	ansible-playbook --syntax-check /etc/ansible/ansible_playbook/rsync_auto.yaml
	ansible-playbook -C /etc/ansible/ansible_playbook/rsync_auto.yaml               模拟执行剧本 类似彩排过程

补充: ansible颜色信息说明
绿色信息: 没有对远程主机做任何修改 查看操作
黄色信息: 对远程主机做数据修改调整
红色信息: 远程管理出现错误
紫色信息: 警告提示信息
蓝色信息: 命令和剧本执行过程信息
	
编写备份服务剧本:
第一个历程: 修改hosts文件
[rsync_server]
172.16.1.41

[rsync_client]
172.16.1.31 ansible_user=root ansible_password=654321 ansible_port=22
172.16.1.7

第二个历程: 编写剧本信息

- hosts: rsync_server
gather_facts: no 
tasks:
  #- name: install software
  #  yum: name=rsync state=installed
  - name: edit rsync conf file
    copy: src=/etc/ansible/ansible_playbook/rsyncd.conf dest=/etc/
  - name: create user
    user: name=rsync create_home=no shell=/sbin/nologin
  - name: create password file
    copy: content='rsync_backup:oldboy123' dest=/etc/rsync.password mode=600
  - name: create backup dir
    file: path=/backup state=directory owner=rsync group=rsync
  - name: boot rsyncd server
    service: name=rsyncd state=started enabled=yes

- hosts: rsync_client
gather_facts: no
tasks:
  #- name: install software
  #  yum: name=rsync state=installed
  - name: create password
    copy: content='oldboy123' dest=/etc/rsync.password mode=600

执行ansible命令出错排查思路

1) 查看被管理主机数据信息
2) 利用远程方式进行操作
3) 确认远程连接是否异常
4) 远程连接后在本地主机上操作测试

剧本编写特殊方法

1) 剧本编写变量设置方法

需求: 进行网站服务数据迁移  站点目录
web01	/html/www		web01_new	/var/html 
		/html/shouji	web02_new	/opt/html 
		/html/diannao	web03_new	/usr/html

模拟练习环境
tree data/
   data/
     ├── shouji
     │?? └── index.html
     └── www
         └── index.html
   
编写剧本实现迁移:
- hosts: web
    tasks:
   - name: 迁移数据信息
     copy: src=www     dest=/var/html/ owner=xxx mode=xxx 
	 copy: src=shouji  dest=/var/html/ xxx 
	 copy: src=diannao dest=/var/html/ 
  
剧本变量设置方法
   1) 在剧本中设置变量
 - hosts: web 
    vars:
	  dir_info: /opt/html 
	tasks:
	  - name: create dir 
	    file: path={{ dir_info }} state=directory
	  - name: move data
	    copy: src=/data/www     dest={{ dir_info }}  owner=oldboy
		copy: src=/data/shouji/ dest={{ dir_info }}  owner=oldboy

PS: 在同步传输目录信息时, 目录后面不要添加/

2) 在执行命令中设置变量
-e EXTRA_VARS, --extra-vars EXTRA_VARS   :  用于指定剧本中变量信息
ansible-playbook -e dir_info=/var/html  test_变量功能剧本.yaml

3) 在主机清单中设置变量
	[web]
	172.16.1.41 
	172.16.1.31 ansible_user=root ansible_password=654321 ansible_port=22
	172.16.1.7
	[web:vars]
	dir_info=/var/html

三个变量功能同时设置: 哪个变量设置更优先
	1) 剧本中设置变量: dir_info: /var/html	②
	2) 命令中设置变量: dir_info=/opt/html		①
	3) 清单中设置变量: dir_info=/usr/html		③

2) 掌握剧本信息输出方法

需求: 批量启动服务程序 并进行验证
   - hosts: web
     tasks:
       - name: boot server
         service: name=rsyncd state=started
       - name: check rsync status
         shell: netstat -lntup|grep 873
         register: port_info
       - name: output check info
         debug: msg={{ port_info.stdout_lines }}

3) 掌握剧本编写判断功能

需求: 管理3台主机 安装软件程序 httpd
	A windows主机
	B centos 主机
	C debian 主机

   setup  --- 收集主机信息模块
常见需要关注收集信息:
	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_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个数(只显示总的个数)。
  
判断剧本编写:
   简单判断语句信息
   - hosts: web
     tasks:
       - name: mkdir dir
         file: path=/oldboy/oldboy_test state=directory
         when: ansible_hostname == "nfs01"
   
   多个判断条件	   
   - hosts: web
     tasks:
       - name: mkdir dir
         file: path=/oldboy/oldboy_test state=directory
         when: (ansible_default_ipv4.address == "10.0.0.7") or/and (ansible_hostname == "nfs01")
		 
   判断排除功能:	 
   - hosts: web
     tasks:
       - name: mkdir dir
         file: path=/oldboy/oldboy_test state=directory
         when: (ansible_default_ipv4.address != "10.0.0.7") or (ansible_hostname == "nfs01")

4) 掌握剧本编写循环功能

循环方式一: 简单循环方法
   需求: 在主机上部署安装多个软件  nfs-utils rpcbind
 	- hosts: web
       tasks:
         - name: install software
           service: name={{ item }} state=started
           loop:
             - rpcbind
             - nfs-utils
  循环方式二: 多个变量信息进行循环
  需求: 在多个主机上创建目录信息
  A B C  /test_A_dir  mode=600 
  A B C  /test_B_dir  mode=601
  A B C  /test_C_dir  mode=602
  
     - hosts: web
       tasks:
         - name: install software
           service: name={{ item }} state=started
           loop:
             - rpcbind
             - nfs-utils
         - name: mkdir dir
           file: path={{ item.dir }} mode={{ item.mode }} state=directory
           loop:
             - {dir: '/test_A_dir', mode: '600'} 
             - {dir: '/test_B_dir', mode: '601'}
             - {dir: '/test_C_dir', mode: '602'}
 
      需求: 每天主机上 创建三个用户 
            oldboy666 uid 666  不能创建家目录 
            oldboy667 uid 667  可以创建家目录  不能登录系统
            oldboy668 uid 668  可以创建家目录  可以登录系统			  
      - hosts: web
  tasks:
    - name: create user 
	  user: name={{ item.info }}  uid={{ item.id }}  create_home={{ item.home }}  shell={{ item.login }} 
	  loop:
	    - {info: 'oldboy666', id: '666', home: 'no', login: '/bin/bash'}
		- {info: 'oldboy667', id: '667', home: 'yes', login: '/sbin/nologin'}
		- {info: 'oldboy668', id: '668', home: 'yes', login: '/bin/bash'}