ansible批量管理服务工具
批量管理服务器的工具
无须部署agent,通过ssh进行管理
流行的自动化运维工具:https://github.con/ansible/ansible
三种批量管理工具
ansible (so easy) 500以下服务器
saltstack (比较复杂) 1000到4万服务器
puppet (超级复杂) 只有很老企业在用
jkenkins简介
可视化运维(主要用在可视化部署)
持续构建,可以和git,svn结合(存放开发代码的仓库)
可结合ssh实现可视化运维
可结合ansible实现可视化运维
Ansible服务器简单的综合安全管理策略
#禁止非root用户查看Ansible管理服务器端/etc/hosts文件
[root@ansible ~]# ll /etc/hosts
-rw-r--r--. 1 root root 180 9月 9 00:38 /etc/hosts
[root@ansible ~]# chmod 600 /etc/hosts
#禁止非root用户查看Ansible的主机清单配置文件
[root@ansible ~]# ll /etc/ansible/hosts
-rw-r--r-- 1 root root 87 9月 9 21:59 /etc/ansible/hosts
[root@ansible ~]# chmod 600 /etc/ansible/hosts
ansible查看帮助
/usr/local/python/bin/ansible-doc -l(查看总帮助)
/usr/local/python/bin/ansible-doc -s shell(查看shell模块的帮助)
/usr/local/python/bin/ansible-doc -s raw
安装ansible流程
如果Centos7版本
需要安装yun -y install net-toolsvim
关闭防火墙:systemctl stop firewalld 关闭防火墙开机启动:systemctl disable fierwalld
关闭selinux
7.5yum安装ansible
7.5yum仓库全可以用,本地的需要自己手动打开
yum -y install epel-release
yum -y install ansible (自动安装sshpass软件包)
安装支持包
yum -y install lrzsz vim net-tools gcc gcc-c++ ncurses ncurses-devel unzip zlib-devel zlib openssl-devel openssl libffi-devel
下载python源码包
(需要云yum)
wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz
源码编译Python3.5
tar xf Python-3.5.2.tgz -C /usr/src
cd /usr/src/Python-3.5.2
./configure --prefix=/usr/local/python
make && make install
ln -s /usr/local/python/bin/python3 /usr/bin/python3(制作软链接)
which python3(查看命令是否存在)
python3 -V(查询python版本)
静心等待ansible安装完毕后
ln -s /usr/local/python/bin/ansible /usr/local/bin(制作软链接)
which ansible(查看命令是否存在)
ansible --version(查看ansible版本)
ansible的简单配置
通过pip安装的ansible是没有配置文件的
mkdir -p /etc/ansible(默认没有,需要手动创建)
vim /etc/ansible/hosts(默认没有,需要手动创建)
ansible命令使用格式
ansible -i 主机或主机组 -m 指定模块 -a 命令 (-i指定配置文件,不写就默认路径下/etc/ansible/hosts,-m指定模块,-a发布命令)
command模块发布命令使用格式
(对方需要有python包,发布命令)
ansible nginx -m command -a 'hostname -I'
(分发模块内容格式,nginx是模块名,-a是条件,-m command是调用ansible里面的模块发布命令用)ansible client2 -m command -a 'hostname -I'
(分发单个主机格式,client2是主机名,-a是条件,-m command是调用ansible里面的模块发布命令用)ansible client1 -m command -a 'hostname -I'
(分发单个主机格式,client1是主机名,-a是条件,-m command是调用ansible里面的模块发布命令用)ansible client1:client2 -m command -a 'hostname -I'
(分发多个主机格式,client1:client2是主机名,-a是条件,-m command是调用ansible里面的模块发布命令用)ansible all -m command -a 'hostname -I'
(all是分发所有主机格式,-a是条件,-m command是调用ansible里面的模块发布命令用)
ping模块发布命令使用格式
(对方需要有python包)
ping模块检查服务器是否连接正常,ping模块不需要-a指定参数
ansible all -m ping (ansible的ping模块格式)
shell模块发布命令使用格式
(对方需要有python包)
shell模块支持管道符格式
ansible all -m shell -a 'echo test | grep t'shell模块支持重定向格式
ansible all -m shell -a "echo bb >> /tmp/testansible"shell模块支持awk格式
ansible all -m shell -a "cat /etc/passwd | awk -F":" '{print $1}'" (如果遇到特殊符号需要加入转义)
raw模块使用格式仅通过ssh实现
(不依赖python包)
copy模块注意事项
yum -y install libselinux-python(传送失败的话说明对方没有这个支持包)
copy模块拷贝文件目录使用格式
ansible all -m copy -a 'src=/root/xin dest=/tmp'
(src源文件,dest目标位置,对方没有目录模块自动创建)
ansible all -m copy -a 'src=/root/xin dest=/tmp backup=yes'
(src源文件,dest目标位置,backup=yes覆盖同时是否备份源文件)
ansible all -m copy -a 'src=/root/xin dest=/tmp owner=nobody group=nobody mode=0600'
(owner=属主是谁,group=属组是谁,mode=它权限)
script模块批量运行脚本使用格式
ansible all -m script -a "/service/scripts/auto_nginx.sh" (6版本必须/bin/sh运行脚本,7版本直接绝对路径启动脚本即可)
cron定时任务模块
Ansible中的cron模块用于定义任务计划。主要包括两种状态(state)
#添加定时任务计划,在所有被管理的主机里每十分钟输出hello字符串,定时任务描述为test cron job
[root@ansible ~]# ansible all -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job"'
Web02 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"test cron job"
]
}
Web01 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"test cron job"
]
}
[root@ansible ~]# ansible all -m shell -a 'crontab -l'
Web01 | SUCCESS | rc=0 >>
#Ansible: test cron job
*/10 * * * * /bin/echo hello
Web02 | SUCCESS | rc=0 >>
#Ansible: test cron job
*/10 * * * * /bin/echo hello
#删除描述为test cron job的定时任务
[root@ansible ~]# ansible all -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job" state=absent'
Web02 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
Web01 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
[root@ansible ~]# ansible all -m shell -a 'crontab -l'
Web02 | SUCCESS | rc=0 >>
Web01 | SUCCESS | rc=0 >>
#给Web01服务器上的普通用户yunjisuan添加一个定时任务
[root@ansible ~]# ansible Web01 -m shell -a 'id yunjisuan'
Web01 | SUCCESS | rc=0 >>
uid=1000(yunjisuan) gid=1000(yunjisuan) 组=1000(yunjisuan)
[root@ansible ~]# ansible Web01 -m cron -a 'minute="*/10" job="/bin/echo hello" name="yunjisuan cron job" user="yunjisuan"'
Web01 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"yunjisuan cron job"
]
}
[root@ansible ~]# ansible Web01 -m shell -a 'crontab -u yunjisuan -l'
Web01 | SUCCESS | rc=0 >>
#Ansible: yunjisuan cron job
*/10 * * * * /bin/echo hello
[root@ansible ~]# ansible Web01 -m cron -a 'minute="*/10" job="/bin/echo hello" name="yunjisuan cron job" user="yunjisuan" state="absent"'
Web01 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
[root@ansible ~]# ansible Web01 -m shell -a 'crontab -u yunjisuan -l'
Web01 | SUCCESS | rc=0 >>
yum模块批量安装软件包
利用yum模块安装软件包,虽然能被shell模块替代,但是用yum模块更显专业一些
user模块批量创建用户
用户管理模块。管理用户账号
#在Web02上创建一个普通用户yunjisuan,并设置用户的密码为123123
[root@ansible ~]# ansible Web02 -m user -a 'name=yunjisuan comment="welcom to yunjisuan" uid=1066 groups=wheel password=123123 shell=/bin/bash home=/home/yunjisuan'
Web02 | SUCCESS => {
"changed": true,
"comment": "welcom to yunjisuan",
"create_home": true,
"group": 1066,
"groups": "wheel",
"home": "/home/yunjisuan",
"name": "yunjisuan",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1066
}
[root@ansible ~]# ansible Web02 -m shell -a 'tail -1 /etc/passwd'
Web02 | SUCCESS | rc=0 >>
yunjisuan:x:1066:1066:welcom to yunjisuan:/home/yunjisuan:/bin/bash
[root@ansible ~]# ansible Web02 -m shell -a 'tail -1 /etc/shadow'
Web02 | SUCCESS | rc=0 >>
yunjisuan:123123:17783:0:99999:7::: #密码居然是明文!!!
利用ansible的user模块状态用户时要注意在password参数的后边添加密文,否则不能登陆用户
通过Python的pip程序安装passlib即可为密码加密
#安装Python2的pip工具,并通过pip工具安装Python的加密模块来给密码加密
[root@ansible ~]# yum -y install epel-release
[root@ansible ~]# yum -y install python2-pip
[root@ansible ~]# pip install passlib
#生成密文密码
[root@ansible ~]# python -c "from passlib.hash import sha512_crypt;import getpass;print sha512_crypt.encrypt(getpass.getpass())"
Password: #输入你想要加密的密码
$6$rounds=656000$Tw15COd8DLh/VS94$Mcmz/8CcjBKiEl0mYHcOQQCxEA5mz66EcGH2qXVk6o.Sm7FsRS.DsDVy6ET8iI6jDa045I94slZqWFwyYnRSW1 #加密后的密码
#删除之前创建的yunjisuan用户,并删除它的家目录
[root@ansible ~]# ansible Web02 -m user -a 'name=yunjisuan state=absent remove=true'
Web02 | SUCCESS => {
"changed": true,
"force": false,
"name": "yunjisuan",
"remove": true,
"state": "absent"
}
#继续在Web02上创建yunjisuan用户
[root@ansible ~]# ansible Web02 -m user -a 'name=yunjisuan comment="welcom to yunjisuan" uid=1066 groups=wheel password=$6$rounds=656000$Tw15COd8DLh/VS94$Mcmz/8CcjBKiEl0mYHcOQQCxEA5mz66EcGH2qXVk6o.Sm7FsRS.DsDVy6ET8iI6jDa045I94slZqWFwyYnRSW1 shell=/bin/bash' home=/home/yunjisuan'
[root@ansible ~]# ansible Web02 -m shell -a 'tail -1 /etc/shadow'
Web02 | SUCCESS | rc=0 >>
yunjisuan:$6$rounds=656000$Tw15COd8DLh/VS94$Mcmz/8CcjBKiEl0mYHcOQQCxEA5mz66EcGH2qXVk6o.Sm7FsRS.DsDVy6ET8iI6jDa045I94slZqWFwyYnRSW1:17783:0:99999:7::: #终于密文了
setup模块批量查看服务的所有属性
Ansible中使用setup模块收集,查看被管理主机的facts(facts是Ansible采集被管理主机设备信息的一个功能)。每个被管理主机在接收并运行管理命令之前,都会将自己的相关信息(操作系统版本,IP地址等)发送给控制主机
#查看远程主机的facts信息
[root@ansible ~]# ansible Web01 -m setup | head
Web01 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.200.184"
],
"ansible_all_ipv6_addresses": [
"fe80::20c:29ff:fe77:16ad"
],
"ansible_apparmor": {
"status": "disabled"
ansible-playbook的初步使用
(playbook可以把ansible的模块进行组合)
ln -s /usr/local/python/bin/ansible-playbook /usr/local/bin (优先制作软链接)
shell模块支持很多模式,copy模块分发文件或目录,register模块输出命令运行结果,nginx_conf配置下发并检测,vars自定义变量,setupvars内置变量,filevars可变配置文件
vim test_shell[copy,register,nginx_conf,vars,setupvars,filevars].yaml (执行模板)
ansible-playbook test_shell[copy,register,nginx_conf,vars,setupvars,filevars].yaml (执行配置文件)
我们可以使用ansible all -m setup | less (查看ansible内置变量)
vim if.j2 (下发配置文件模板样式)
下发配置文件里面使用判断语法
vim /tmp/if.j2
{% if PORT %} #if PORT存在
ip=0.0.0.0:{{ PORT }}
{% else %} #否则的话
ip=0.0.0.0:80
{% endif %} #结尾
vim test_ifvars.yaml
---
- hosts: all
gather_facts: True #开启系统内置变量
vars:
- PORT: 90 #自定义变量
tasks:
- name: jinja2 if test
template: src=/tmp/if.j2 dest=/root/test
ansible-playbook test_ifvars.yaml (下达分发命令)
如果我们将变量PORT值为空的话,就会进入else否则的80端口
---
- hosts: all
gather_facts: True
vars:
- PORT: #置空
tasks:
- name: jinja2 if test
template: src=/tmp/if.j2 dest=/root/test
Playbook下发可变配置文件
---
- hosts: all
gather_facts: True #开启系统变量
vars:
- myname: "yunjisuan" #自定义变量
tasks:
- name: template test
template: src=/tmp/test dest=/root/test #使用template下发可变配置文件
配置文件如果使用copy模块去下发的话,那配置都是一样的;
如果下发的配置文件里有可变的配置,需要用到template模块。
playbook使用register输出命令运行结果
---
- hosts: all
tasks:
- name: test register
shell: echo "welcome to yunjisuan"
register: print_result #将之前命令的输出结果保存在变量print_result里
- debug: var=print_result #将变量的值作为debug输出出来。
我们在用playbook进行ansible模块操作的时候,并没有命令的执行结果输出,默认被隐藏了
我们可以通过register模块追加输出命令的执行结果
playbook的自定义变量和内置变量
---
- hosts: all
vars: #定义变量
- name: "yunjisuan" #第一个name变量
age: "3" #第二个age变量
tasks:
- name: "{{ name }}" #{{}}两对大括号引用变量,变量名两头空格
shell: echo "myname {{ name }},myage {{ age }}"
register: var_result
- debug: var=var_result
特别提示:
引用变量需要在双引号中引用。
在使用自定义变量时,我们要特别注意不要和系统的内置保留变量同名,容易引发问题。
Found variable using reserved name: name #name是一个保留的内置变量,我们在自定义时不能用,会有警告
---
- hosts: all
gather_facts: True #使用ansible内置变量
tasks:
- name: setup var
shell: echo "ip {{ ansible_all_ipv4_addresses[0] }} cpu {{ ansible_processor_count }}" >> /tmp/test
- name: setup var2
shell: echo "time {{ ansible_date_time["date"] }}" >> /tmp/test
register: var_result
- debug: var=var_result
#python取变量方法
a = [1,3,5] --> a [0]=1 #这样取值就不会带[]
a = {"sl":123123,"sl1"123321} --> a[sl]=123123 #这样取值就不会带[]
playbook的简单shell模块的使用
--- #开头三个小-开头
- hosts: webB
tasks:
- name: test
shell: echo "welcome to yunjisaun" >> /tmp/username
- name: test2
shell: echo "welcome to yunjisuan" >> /tmp/username
模板说明:
--- #开头必须有三个小-,顶格写
- hosts: #正文配置代码的第一级,必须有两个空格(-占一个空格位)
- host: webB #webB是host参数的值,值和hosts:之间要有一个空格
tasks: #tasks:表示接下来要执行的具体任务
- name: #相对于tasks再多缩进两个格(-占一个空格位),表示属于tasks的下一级
- name: test #test只是要执行的具体命令的名字可以随便写。name:后还是有一个空格要注意
shell: #表示调用shell模块执行命令相对于tasks仍旧要多缩进两个空格
shell: echo "xxx" >> xxx #shell:后边还是要有个空格,需要注意。
playbook的简单copy模块的使用
---
- hosts: all
tasks:
- name: test copy
copy: src=/tmp/copy_test dest=/tmp/
模板说明:
--- #开头必须有三个小-,顶格写
- hosts: #正文配置代码的第一级,必须有两个空格(-占一个空格位)
tasks: #tasks:表示接下来要执行的具体任务
- name: test #test只是要执行的具体命令的名字可以随便写。name:后还是有一个空格要注意
copy: src=/tmp/copy_test dest=/tmp/ #把源文件拷贝到对方的位置
Playbook的notify通知和下发nginx配置
vim nginx.j2
worker_processes {{ ansible_processor_count }}; #可变的参数
#实战下发可执行动作的可变的nginx配置文件
---------------------------------------------------------------------------
vim test_nginxvars.yaml
---
- hosts: all
gather_facts: True #开启系统内置变量
tasks:
- name: nginx conf
template: src=/tmp/nginx.j2 dest=/usr/local/nginx/conf/nginx.conf
notify:
- reload nginx #下发通知给handlers模块执行名字叫做reload nginx的动作
handlers: #定义动作
- name: reload nginx #动作的名字
shell: /usr/local/nginx/sbin/nginx -s reload
ansible-playbook test_nginxvars.yaml (执行分发命令)
nginx配置下发并检测
---
- hosts: all
tasks:
- name: copy nginx.conf
copy: src=/tmp/nginx.conf dest=/usr/local/nginx/conf/ backup=yes
- name:
shell: /usr/local/nginx/sbin/nginx -t
register: nginx_result
- debug: var=nginx_result
ansible的script模块批量运行脚本
#操作示例-->远程批量分发并自动部署nginx
#所有被管理端需要挂载光盘,并创建本地yum配置文件
auto_nginx.sh #自动安装nginx脚本
fenfa.sh #批量分发脚本
nginx-1.10.2.tar.gz #nginx源码包
#!/bin/sh
#nginx install shell scripts
test -d /media/cdrom || mkdir -p /media/cdrom
mount /dev/sr0 /media/cdrom &>/dev/null
yum -y install gcc gcc-c++ make pcre pcre-devel zlib zlib-devel openssl openssl-devel &>/dev/null
test -d /service/scripts || exit 3
cd /service/scripts/
tar xf nginx-1.10.2.tar.gz -C /usr/src/
cd /usr/src/nginx-1.10.2/
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module &>/dev/null
make &>/dev/null
make install &>/dev/null
exit 0
#源码包和安装脚本的批量分发脚本
#!/bin/sh
#批量分发脚本
Group=$1
ansible $Group -m copy -a "src=/service/scripts/ dest=/service/scripts/"
ansible $Group -m script -a "/service/scripts/auto_nginx.sh"
ansible批量管理企业案例
4.1 ansible all -m copy -a 'src=/root/xin.sh dest=/root'
4.2 ansible all -m user -a 'name=yunjisuan shell=/sbin/nologin createhome=no'
4.3 ansible all -m shell -a 'echo "123123" | pass --stdin root'
4.4 ansible all -m user -a 'name=benet password=321321 shell=/bin/bash'
4.5 ansible all -m cron -a 'job="/bin/echo xin > /tmp/sl" name="test cron job"'
4.6 ansible all -m shell -a 'vmstat'