自动化运维之ansible

ansible 基于python开发,实现了批量操作系统配置,批量程序部署,批量运行命令等功能

可以实现:自动化部署APP 管理配置项 持续交付  云服务管理

选择配置管理软件要考虑的问题

活跃度(社区)     学习成本     使用成本    编码语言     性能    使用是否广泛 

优点:

只需要ssh和python,无客户端 ,容易,门槛低

ansible功能强大,模块丰富,社区活跃

基于python开发,做二次开发更容易

特性:

模块化设计,调用特定的模块完成特定任务

基于python语言实现   paramiko   PyYAML(半结构化语言)   Jinja2

扫描二维码关注公众号,回复: 5940309 查看本文章

模块支持JSON等标准输出格式,可以采用任何编程语言重写

部署简单,易于使用,支持多层部署和异构IT环境

支持自定义模块,palybook,主从模式工作

部署ansible

依赖关系python2.6或2.7

模块:paramiko  PyYAML  Jinja2   httplib2   six

对于被托管主机(ansible默认通过ssh协议管理机器,被管理主机要开启ssh服务,如果节点开启了SELinux。需要安装libselinux-python)

可以基于源码运行

源码安装

pip  需要配置扩展软件包源extras

git   

yum -y install epel-release

yum -y install git python2-pip

pip安装依赖模块

pip install paramiko PyYAML Jinja2  httplib2  six

ansible源码下载

git clone git://github.com/ansible/ansible.git

yum install python-setuptools python-devel

python setup.py build

python setup.py install

pip方式安装

pip install ansible

yum安装

添加ansible到自定义软件源

[root@guo ansible]# ls
ansible-2.4.2.0-2.el7.noarch.rpm         python-paramiko-2.1.1-4.el7.noarch.rpm
python2-jmespath-0.9.0-3.el7.noarch.rpm  python-passlib-1.6.5-2.el7.noarch.rpm
python-httplib2-0.9.2-1.el7.noarch.rpm   sshpass-1.06-2.el7.x86_64.rpm
[root@guo ansible]# createrepo --update  .

安装ansible

虚拟机:2cpu  2G内存,大于20G硬盘  ip 192.168.1.10   ansible

[root@ansible ~]# vim /etc/yum.repos.d/local.repo 
[server]
name=server
baseurl=ftp://192.168.1.254/CentOS7.4
gpgcheck=0
enabled=1

[ansible]
name=ansible
baseurl=ftp://192.168.1.254/ansible
gpgcheck=0
enabled=1
[root@ansible ~]# yum -y install ansible

验证

[root@ansible ~]# ansible  --version
ansible 2.4.2.0
  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, Aug  4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]

管理主机

主机定义与分组

ansible配置文件查找顺序

检测ANSIBLE_CONFIG变量--- 当前目录下的./ansible.cfg文件 ---再次检查当前用户家目录下~/ansible.cfg 文件 ---最后检查/etc/ansible/ansible.cfg文件

ansible.cfg配置文件/etc/ansible/ansible.cfg

inventory 定义托管主机地址配置文件

先编辑/etc/ansible/hosts文件,写入远程主机的地址

 [root@ansible ~]# vim /etc/ansible/ansible.cfg 

 14 #inventory      = /etc/ansible/hosts         //去掉注释,定义管理的主机位置
...
 61 #host_key_checking = False                    //去掉注释

分组/etc/ansible/hosts

[root@ansible ~]# vim /etc/ansible/hosts 
[web]
web[1:10]

[databases]
db1
db2

[other]
cache

查看组和主机(可以单独链接主机,链接组,可以链接组,主机   all所有组主机)

[root@ansible ~]# ansible  web --list-hosts
  hosts (2):
    web1
    web2
[root@ansible ~]# ansible  web,cache --list-hosts
  hosts (3):
    web1
    web2
    cache

实验环境,部署虚拟机

192.168.1.11  web1  , 192.168.1.12  web2  ,  192.168.1.21  db1 ,  192.168.1.22  db1  , 192.168.133   cache

[root@ansible ~]# vim /etc/hosts
192.168.1.11 web1
192.168.1.12 web2
192.168.1.21 db1
192.168.1.22 db2
192.168.1.33 cache

ping主机

[root@ansible ~]# ansible cache -m ping -k      //交互式输入密码
SSH password: 
cache | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

inventory参数

ansible_ssh_pass ssh密码(这种方式并不安全,我们强烈建议使用--ask-pass或SSH密钥)

ansible_sudo_pass   sudo密码(建议使用--ask-sudo-pass)

ansible_sudo_exe(new  in  version  1.8)   sudo命令路径(适用于1.8及以上版本)

ansible_connection  与主机的链接类型 如:local, ssh或paramiko, 1.2以前使用paramiko  1.2使用smart  它会根据是否支持ControlPersist来判断 'ssh'方式是否可行

ansible_ssh_private_key_file ssh   ssh使用的私钥文件,适用于有多个密钥,而你不想使用SSH代理的情况

ansible_shell_type  目标系统的shell类型,默认情况下,命令的执行使用"sh"语法,可设置为‘csh’或‘fish’

ansible_python_interpreter   目标主机的python路径,适用情况:系统中多个python,或者命令路径不是"/usr/bin/python"

[root@ansible ~]# vim /etc/ansible/hosts 
[other]
cache  ansible_ssh_pass="123456"
[root@ansible ~]# ansible cache -m ping
cache | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

分组定义共性和应用分组

[root@ansible ansible]# vim hosts
[web]
web1
web2
[web:vars]                //web组:变量(vars不改),web组的多台机器共用一个用户名和密码
ansible_ssh_user="root"
ansible_ssh_pass="123456"

自定义配置文件

[root@ansible ~]# mkdir test
[root@ansible ~]# ls
bin  test
[root@ansible ~]# cd test
[root@ansible test]# vim ansible.cfg 
[defaults]
inventory   =  hosts
host_key_checking = False
[root@ansible test]# vim hosts
[app1]
web1
db1

[app2]
web2
db2

[other]
cache       
[root@ansible test]# ansible  app1,app2  --list      //从当前目录读取数据
  hosts (4):
    web1
    db1
    web2
    db2

动态主机

ansible inventory  包含静态inventory(在文件/etc/ansible/hosts中的主机和组和动态的inventory (通过外部脚本获取主机列表,按照要求格式返回给ansible命令)

json 

注意事项:主机部分必须是列表格式

hostdata行,其中的“hosts”部分可以省略,但使用时必须为"hosts"

批量执行

ansible命令 ansible <host-pattern>   [options]

host-pattern    主机或者定义的分组
-M 指定模块路径 -m 使用模块,默认command模块 -a or --args 模块参数 -i  inventory 文件路径或可执行脚本
-k 使用交互式登陆密码 -e 定义变量 -v  详细信息,-vvvv开启debug模式
[root@ansible test]# ansible all -m command -a 'uptime' -k     //查看所有机器负载
SSH password: 
web2 | SUCCESS | rc=0 >>
 14:10:14 up  3:26,  2 users,  load average: 0.00, 0.01, 0.05

db2 | SUCCESS | rc=0 >>
 14:10:15 up  3:25,  2 users,  load average: 0.00, 0.01, 0.05

web1 | SUCCESS | rc=0 >>
 14:10:15 up  3:26,  3 users,  load average: 0.00, 0.01, 0.05

db1 | SUCCESS | rc=0 >>
 14:10:15 up  3:25,  2 users,  load average: 0.00, 0.01, 0.05

cache | SUCCESS | rc=0 >>
 14:10:15 up  3:25,  2 users,  load average: 0.00, 0.01, 0.05

给多台主机公钥和私钥

[root@ansible ansible]# cd /root/.ssh/
[root@ansible .ssh]# ssh-keygen  -t rsa -b 1024  -N ''
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
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:hWw1IEou73hE8hbIRNdlKFSv41uwBxqvEn2LssYrejI root@ansible
The key's randomart image is:
+---[RSA 1024]----+
| .o.+ooo+.o      |
| o =..o= o .     |
|  = =.  = .      |
|   * . o .       |
|   .* = S        |
|  .=.=.=         |
| ...+o+.o        |
|E *....+         |
|o*o=. .          |
+----[SHA256]-----+
[root@ansible ansible]# ansible all -m authorized_key  -a  "user=root exclusive=true manage_dir=true  key='$(< /root/.ssh/id_rsa.pub)'"  -k -v
Using /etc/ansible/ansible.cfg as config file
SSH password: 
web2 | SUCCESS => {
    "changed": true, 
...
[root@ansible ansible]# ansible all -m ping 
web1 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

ansible-doc和ping模块

ansible-doc 模块的手册相当于shell的man

[root@ansible ansible]# ansible-doc -l     //列出所有模块
[root@ansible ansible]# ansible-doc 模块名     //查看帮助

ping模块没有参数 测试网络联通性

command模块 默认模块,远程执行命令

ansible  host-pattern      -m  command  -a ‘[args]’

注意事项:该模块通过-a跟上要执行的命令可以直接执行,有“<”,">","|","&"等字符则不能成功

                    该模块不启动shell直接在ssh进程中执行,所有用到shell的命令执行都会失败 ,如:

[root@ansible ansible]# ansible all -m command  -a 'ps aux | grep ssh'
cache | FAILED | rc=1 >>
...
[root@ansible ansible]# ansible all -m command  -a 'set'
db2 | FAILED | rc=2 >>
[Errno 2] 没有那个文件或目录
...

shell | raw 模块

shell模块   基本和command一样,不过,它是通过/bin/sh执行命令,可以执行bash的任意命令

raw模块     用法和shell一样,也可以执行任意命令,不过它没有chdir  creates  removes参数

[root@ansible ansible]# ansible all -m shell  -a 'set'
db1 | SUCCESS | rc=0 >>
BASH=/bin/sh

在web1,db2上创建用户张三,默认密码为abc 第一次登录需要修改密码

[root@ansible ansible]# ansible web1,db2 -m shell  -a 'useradd zhangsan'
[root@ansible ansible]# ansible web1,db2 -m shell  -a 'echo abc | passwd --stdin  zhangsan'
[root@ansible ansible]# ansible web1,db2 -m shell  -a 'chage -d0 zhangsan'

 script模块  可以执行脚本 不限于shell脚本

在web1和web2上创建用户lisi ,设置默认密码为123  要求 lisi不能和张三同时出现

[root@ansible ansible]# vim lisi.sh
#!/bin/bash
id 'zhangsan'
if [ $? -gt 0 ];then
  useradd lisi
  echo 123 | passwd --stdin lisi
fi
[root@ansible ansible]# ansible web1,web2 -m script -a 'lisi.sh'
wb1| SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to db2 closed.\r\n", 
    "stdout": "uid=1000(zhangsan) gid=1000(zhangsan) 组=1000(zhangsan)\r\n", 
    "stdout_lines": [
        "uid=1000(zhangsan) gid=1000(zhangsan) 组=1000(zhangsan)"
    ]
}
wb2 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to db1 closed.\r\n", 
    "stdout": "id: zhangsan: no such user\r\n更改用户 lisi 的密码 。\r\npasswd:所有的身份验证令牌已经成功更新。\r\n", 
    "stdout_lines": [
        "id: zhangsan: no such user", 
        "更改用户 lisi 的密码 。", 
        "passwd:所有的身份验证令牌已经成功更新。"
    ]
}

copy模块  复制文件到远程主机

src 复制远程主机的文件到本地,绝对和相对均可,路径为目录时会递归复制。如果路径以/结尾,只复制目录里的内容,若不是/结尾,则复制包含目录在内的所有内容
dest 远程主机的绝对路径,如源文件是一个目录,那该路径必须是目录
backup 覆盖前先备份原文件,备份文件包含时间信息
force 若目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,设为no,则只有当目标主机的目标位置不存在该文件时才复制。默认为yes
[root@ansible ansible]# vim /etc/resolv.conf     //将nameserver值改为114.114.114.114
[root@ansible ansible]# ansible all -m copy  -a 'src=/etc/resolv.conf  dest=/etc/resolv.conf'
[root@ansible ansible]# ansible all -m shell -a  'cat /etc/resolv.conf'
web1 | SUCCESS | rc=0 >>
; generated by /usr/sbin/dhclient-script
nameserver 114.114.114.114
search localdomain

...

lineinfile | replace模块

类似于sed的一种行编辑替换模块

path目的文件(要修改的文件)

regexp 正则表达式(匹配要修改的地方)

line 替换后的结果(最终修改后的样子)  (replace模块--replace替换指定的字符 最终修改后的样子)

[root@ansible ansible]# ansible db1,db2 -m lineinfile -a 'path="/etc/my.cnf" regexp="^binlog_format" line="binlog_format = mixed"
> '
db2 | SUCCESS => {
    "backup": "", 
    "changed": true, 
    "msg": "line replaced"
}
db1 | SUCCESS => {
    "backup": "", 
    "changed": true, 
    "msg": "line replaced"
}
[root@ansible ansible]# ansible db1,db2 -m replace -a 'path="/etc/my.cnf" regexp="mixed" replace="statement"'
db2 | SUCCESS => {
    "changed": true, 
    "msg": "1 replacements made"
}
db1 | SUCCESS => {
    "changed": true, 
    "msg": "1 replacements made"
}

yum模块 使用yum包管理器来管理软件包

name  要进行操作的软件包(一个或多个)名字,也可传递一个url或一个本地的rpm包的路径

state    状态(present,absent,latest,installed,removed)

enablerepo  启用某个源

disablerepo  不启用某个源

service模块 管理服务

name       服务的名称,必选项

state        动作 started,stopped,restarted,reloaded

enabled  是否开机启动 yes|no

sleep       执行restarted 会在stop和start 之间沉睡几秒钟

案例:给所有web服务器安装apache  修改端口8080 设置开机自启动,设置默认主页为 hello world

[root@ansible ansible]# ansible  web  -m  yum  -a 'name="httpd"'
[root@ansible ansible]# ansible web  -m copy  -a 'src="index.html"  dest="/var/www/html/"' 
[root@ansible ansible]# ansible  web  -m  lineinfile  -a 'path="/etc/httpd/conf/httpd.conf" regexp="^Listen "   line="Listen 8080"'  
[root@ansible ansible]# ansible web -m service -a 'name="httpd" state=started enabled="yes"'

setup模块

获取主机信息,playbooks里经常会用的另一个参数gather_facts与该模块相关,setup模块经常用的是filter参数

filter过滤所需信息

猜你喜欢

转载自blog.csdn.net/weixin_43800781/article/details/86548849