ansible 自动化运维工具


一 安装:yum 安装或者 编译安装

#CentOS 的EPEL源的rpm包安装 [root@centos ~]#yum install ansible #ubuntu 安装 [root@ubuntu ~]#apt -y install ansible 编译安装 yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto wget https://releases.ansible.com/ansible/ansible-1.5.4.tar.gz tar xf ansible-1.5.4.tar.gz cd ansible-1.5.4 python setup.py build python setup.py install mkdir /etc/ansible cp -r examples/* /etc/ansible   二、配置文件 主配置文件: /etc/ansible/ansible.cfg   基本不需要动

 host_key_checking=False 放开注释,那么在使用ansible 的时候就不需要输入yes no 了

主机清单    : /etc/ansible/hosts  里面添加需要管理的机器  三、基于key 验证 主机清单    : /etc/ansible/hosts  配置说明 ansible_ssh_host #将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置. ansible_ssh_port #ssh端口号.如果不是默认的端口号,通过此变量设置.这种可以使用 ip:端口 192.168.1.100:2222 ansible_ssh_user #默认的 ssh 用户名 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. Ansible 1.2 以前默 认使用 paramiko.1.2 以后默认使用 'smart','smart' 方式会根据是否支持 ControlPersist, 来 判断'ssh' 方式是否可行. ansible_ssh_private_key_file #ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的 情况. ansible_shell_type #目标系统的shell类型.默认情况下,命令的执行使用 'sh' 语法,可设置为 'csh' 或 'fish'. ansible_python_interpreter #目标主机的 python 路径.适用于的情况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",比如 \*BSD, 或者 /usr/bin/python 不是 2.X 版本的 Python.之所以不使用 "/usr/bin/env" 机制,因为这要求远程用户的路径设置正确,且要求 "python" 可执行程序名不可为 python以外的名字(实际有可能名为python26).与 ansible_python_interpreter 的工作方式相同,可设定如 ruby 或 perl 的路径....   范例 ntp.magedu.com [webservers] www1.magedu.com:2222 www2.magedu.com [dbservers] db1.magedu.com db2.magedu.com db3.magedu.com #或者 db[1:3].magedu.com 范例2 [webservers] www[1:100].example.com [dbservers] db-[a:f].example.com [appservers] 10.0.0.[1:100] #定义testsrvs组中包括两个其它分组,实现组嵌套 [testsrvs:children] webservers dbservers 范例3 [test] 10.0.0.8  ansible_connection=local   #指定本地连接,无需ssh配置 #ansible_connection=ssh 需要StrictHostKeyChecking no 10.0.0.7  ansible_connection=ssh  ansible_ssh_port=2222  ansible_ssh_user=wang ansible_ssh_password=magedu   10.0.0.6  ansible_connection=ssh  ansible_ssh_user=root ansible_ssh_password=123456   #执行ansible命令时显示别名,如web01 [websrvs] web01 ansible_ssh_host=10.0.0.101 web02 ansible_ssh_host=10.0.0.102 [websrvs:vars] ansible_ssh_password=magedu some_host         ansible_ssh_port=2222     ansible_ssh_user=manager aws_host          ansible_ssh_private_key_file=/home/example/.ssh/aws.pem freebsd_host      ansible_python_interpreter=/usr/local/bin/python ruby_module_host  ansible_ruby_interpreter=/usr/bin/ruby.1.9.3   三、基于key 验证

 直接用,是报红的

如果不配置基于key 验证,那么需要用到参数 -k  ,需要输入密码

常用ansible 功能模块:

command

功能:在远程主机执行命令,此为默认模块,可忽略 -m 选项 可以在 /etc/ansible/ansible.cfg 中修改。 注意:此命令不支持 $VARNAME < > | ; & 等,可能用shell模块实现 注意:此模块不具有幂等性常用参数

chdir参数:此参数的作用就是指定一个目录,在执行对应的命令之前,会先进入到chdir参数指定的目录中。

creates参数:看到creates,你可能会从字面上理解这个参数,但是使用这个参数并不会帮助我们创建文件,它的作用是当指定的文件存在时,就不执行对应命令,比如:如果/testdir/test文件存在,就不执行我们指定的命令。

removes参数:与creates参数的作用正好相反,,此参数并不会帮助我们删除文件它的作用是==当指定的文件不存在时,就不执行对应命令,==比如:如果/testdir/tests文件不存在,就不执行我们指定的命令

范例:打开 151  152 机器上 etc 目录下 的centos-release 文件
[root@node01 ~]# ansible webservers -m command -a 'chdir=/etc cat centos-release'
10.0.0.152 | CHANGED | rc=0 >>
CentOS Linux release 7.9.2009 (Core)
10.0.0.151 | CHANGED | rc=0 >>
CentOS Linux release 7.9.2009 (Core)

[root@node01 ~]# ansible webservers -m command -a 'chdir=/etc creates=/data/f1.txt cat centos-release'
10.0.0.151 | SUCCESS | rc=0 >>
skipped, since /data/f1.txt exists
10.0.0.152 | CHANGED | rc=0 >>
CentOS Linux release 7.9.2009 (Core)
[root@node01 ~]# ansible webservers -m command -a 'chdir=/etc removes=/data/f1.txt cat centos-release'
10.0.0.152 | SUCCESS | rc=0 >>
skipped, since /data/f1.txt does not exist
10.0.0.151 | CHANGED | rc=0 >>
CentOS Linux release 7.9.2009 (Core)
[root@node01 ~]#

shell模块是ansible里面比较常用的模块。顾名思义,shell模块用于执行shell命令。我们利用ansible批量在多台机器上执行shell命令,该模块非常的简单粗暴。 对于ansible很多模块,都可以用shell替代达到相对应的效果。

虽然shell模块看起来非常万能,但存在着许多风险。例如:shell注入风险,非幂等性(即统一命令多次执行的结果可能是不一样的)

说明:

chdir:在哪个目录下执行shell命令,相当于执行shell命令前先cd到对应目录

creates:如果存在某文件,就不执行shell

removes:如果不存在某文件,就不执行shell;与creates左右相反(有点绕)

executable:修改并指定shell解释器来执行命

free_form:指的就是具体的shell命令,实际上是一个不存在的选项

范例1:查看当前主目录
#-m shell表示使用shell模块
#-a 表示传递shell模块的相关参数
#-i 指定了inventory文件
#local是inventory文件里面定义好的节点



[root@node01 ~]# ansible -i /etc/ansible/hosts local -m shell -a 'pwd'
10.0.0.150 | CHANGED | rc=0 >>
/root
 
范例2:查看远程主机的主机名 注意双引号和单引号的区别,双引号查出来的是自己的,单引号查出来的是远程主机的
[root@node01 ~]# ansible webservers -m shell -a "echo $HOSTNAME"
10.0.0.151 | CHANGED | rc=0 >>
node01
10.0.0.152 | CHANGED | rc=0 >>
node01
[root@node01 ~]# ansible webservers -m shell -a 'echo $HOSTNAME'
10.0.0.152 | CHANGED | rc=0 >>
node03
10.0.0.151 | CHANGED | rc=0 >>
node02
[root@node01 ~]# 

Script 模块

功能:在远程主机上运行ansible服务器上的脚本(无需执行权限) 注意:此模块不具有幂等性
范例
ansible websrvs -m script -a /data/test.sh

copy 模块用于将本地或远程机器上的文件拷贝到远程主机

名称 必选 默认值 可选值 备注
backup no no yes/no 在覆盖之前将原文件备份,备份文件包含时间信息
src no     将本地路径复制到远程服务器; 可以是绝对路径或相对的。如果是一个目录,它将被递归地复制。如果路径以/结尾,则只有该目录下内容被复制到目的地,如果没有使用/来结尾,则包含目录在内的整个内容全部复制
dest yes     目标绝对路径。如果src是一个目录,dest也必须是一个目录。如果dest是不存在的路径,并且如果dest以/结尾或者src是目录,则dest被创建。如果srcdest是文件,如果dest的父目录不存在,任务将失败
owner no     设置文件/目录的所属用户,将被馈送到chown
group no     设置文件/目录的所属组,将被馈送到chown
content no     当用content代替src参数的时候,可以把文档的内容设置到特定的值
follow no no yes/no 是否遵循目的机器中的文件系统链接
froce no no yes/no 当内容不同于源时,将替换远程文件。设置为no,则只有在目标不存在的情况下才会传输文件
local_follow no yes yes/no 是否遵循本地机器中的文件系统链接
mode no     设置文件权限,模式实际上是八进制数字(如0644),少了前面的零可能会有意想不到的结果。从版本1.8开始,可以将模式指定为符号模式(例如u+rwx或u=rw,g=r,o=r)
范例:
#如目标存在,默认覆盖,此处指定先备份
ansible websrvs -m copy -a "src=/root/test1.sh dest=/tmp/test2.sh  owner=wang mode=600 backup=yes"
#指定内容,直接生成目标文件    
ansible websrvs -m copy -a "content='test line1\ntest line2\n' dest=/tmp/test.txt"
#复制/etc目录自身,注意/etc/后面没有/
ansible websrvs -m copy -a "src=/etc dest=/backup"
#复制/etc/下的文件,不包括/etc/目录自身,注意/etc/后面有/
ansible websrvs -m copy -a "src=/etc/ dest=/backup
Fetch 模块 功能:从远程主机提取文件至ansible的主控端,copy相反,目前不支持目录
范例;
ansible websrvs -m fetch -a 'src=/root/test.sh dest=/data/scripts'
注意 这里的src 就是远程主机的目录 dest 代表是 ansible 主控端的主机
  Get_url 模块 功能: 用于将文件从http、https或ftp下载到被管理机节点上 常用参数如下
常用参数如下:
url: 下载文件的URL,支持HTTP,HTTPS或FTP协议
dest: 下载到目标路径(绝对路径),如果目标是一个目录,就用服务器上面文件的名称,如果目标设置了名
称就用目标设置的名称
owner:指定属主
group:指定属组
mode:指定权限
force: 如果yes,dest不是目录,将每次下载文件,如果内容改变,替换文件。如果否,则只有在目标不存
在时才会下载该文件
checksum: 对目标文件在下载后计算摘要,以确保其完整性
           示例: checksum="sha256:D98291AC[...]B6DC7B97",
               checksum="sha256:http://example.com/path/sha256sum.txt"
url_username: 用于HTTP基本认证的用户名。 对于允许空密码的站点,此参数可以不使用
`url_password'
url_password: 用于HTTP基本认证的密码。 如果未指定`url_username'参数,则不会使用
`url_password'参数
validate_certs:如果“no”,SSL证书将不会被验证。 适用于自签名证书在私有网站上使用
timeout: URL请求的超时时间,秒为单位

范例:下载nginx 
[root@ansible ~]#ansible websrvs -m get_url -a 'url=http://nginx.org/download/nginx-1.18.0.tar.gz dest=/usr/local/src/nginx.tar.gz checksum="md5:b2d33d24d89b8b1f87ff5d251aa27eb8"'
  File 模块 功能:设置文件属性,创建软链接等
#创建空文件
ansible all -m file  -a 'path=/data/test.txt state=touch'  #创建 all 是只hosts 里面的所有IP
ansible all -m file  -a 'path=/data/test.txt state=absent' #删除 

ansible all -m file -a "path=/root/test.sh owner=wang mode=755"  #指定所有者并给权限
#创建目录
ansible all -m file  -a 'path=/data/testdir state=directory'
#递归修改目录属性,但不递归至子目录
ansible all -m file -a "path=/data/mysql state=directory owner=mysql 
group=mysql"
#递归修改目录及子目录的属性
ansible all -m file -a "path=/data/mysql state=directory owner=mysql group=mysql recurse=yes"


#创建软链接
ansible all -m file -a 'src=/data/testfile path|dest|name=/data/testfile-link 
state=link'
stat 模块 功能:检查文件或文件系统的状态 注意:对于Windows目标,请改用win_stat模块
选项
path:文件/对象的完整路径(必须)
常用返回值的判断
exists: 判断是否存在 isuid: 调用用户的ID与所有者ID是否匹配
范例:
[root@node01 ~]# ansible webservers -m stat -a 'path=/data/f1.txt'
10.0.0.151 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "stat": {
        "atime": 1647163799.815982, 
        "attr_flags": "", 
        "attributes": [], 
        "block_size": 4096, 
        "blocks": 0, 
        "charset": "binary", 
        "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
        "ctime": 1647163799.8239825, 
        "dev": 64770, 
        "device_type": 0, 
        "executable": false, 
        "exists": true, 
        "gid": 0, 
        "gr_name": "root", 
        "inode": 68, 
        "isblk": false, 
        "ischr": false, 
        "isdir": false, 
        "isfifo": false, 
        "isgid": false, 
        "islnk": false, 
        "isreg": true, 
        "issock": false, 
        "isuid": false, 
        "mimetype": "inode/x-empty", 
        "mode": "0644", 
        "mtime": 1647163799.075982, 
        "nlink": 1, 
        "path": "/data/f1.txt", 
        "pw_name": "root", 
        "readable": true, 
        "rgrp": true, 
        "roth": true, 
        "rusr": true, 
        "size": 0, 
        "uid": 0, 
        "version": "18446744072962527632", 
        "wgrp": false, 
        "woth": false, 
        "writeable": true, 
        "wusr": true, 
        "xgrp": false, 
        "xoth": false, 
        "xusr": false
    }
}
10.0.0.152 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "stat": {
        "atime": 1647163799.80998, 
        "attr_flags": "", 
        "attributes": [], 
        "block_size": 4096, 
        "blocks": 0, 
        "charset": "binary", 
        "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
        "ctime": 1647163799.8189805, 
        "dev": 64770, 
        "device_type": 0, 
        "executable": false, 
        "exists": true, 
        "gid": 0, 
        "gr_name": "root", 
        "inode": 68, 
        "isblk": false, 
        "ischr": false, 
        "isdir": false, 
        "isfifo": false, 
        "isgid": false, 
        "islnk": false, 
        "isreg": true, 
        "issock": false, 
        "isuid": false, 
        "mimetype": "inode/x-empty", 
        "mode": "0644", 
        "mtime": 1647163799.06798, 
        "nlink": 1, 
        "path": "/data/f1.txt", 
        "pw_name": "root", 
        "readable": true, 
        "rgrp": true, 
        "roth": true, 
        "rusr": true, 
        "size": 0, 
        "uid": 0, 
        "version": "723331210", 
        "wgrp": false, 
        "woth": false, 
        "writeable": true, 
        "wusr": true, 
        "xgrp": false, 
        "xoth": false, 
        "xusr": false
    }
}
[root@node01 ~]# 
unarchive 模块 功能:解包解压缩 实现有两种用法: 1、将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes,此为默认值,可省略 2、将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no
帮助语法

- name: Unarchive a file that is already on the remote machine
  unarchive:
    src: /tmp/foo.zip            #要解压的包
    dest: /usr/local/bin        #解压到目标位置
    remote_src: 
        yes                        #要解压的包在受控端
        no                        #要解压的包在控制端
常见参数
copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,如果设置为copy=no,
会在远程主机上寻找src源文件
remote_src:和copy功能一样且互斥,yes表示在远程主机,不在ansible主机,no表示文件在ansible
主机上
src:源路径,可以是ansible主机上的路径,也可以是远程主机(被管理端或者第三方主机)上的路径,如果
是远程主机上的路径,则需要设置copy=no
dest:远程主机上的目标路径
mode:设置解压缩后的文件权限
范例:解压foo.tgz 到受控端,文件在ansible 主机上,解压后的目标文件在受控端的 car/lib/foo 文件夹下
ansible all -m unarchive -a 'src=/data/foo.tgz dest=/var/lib/foo owner=wang 
group=bin'
#解压foo.tgz 到受控端,文件在受控机的 tmp目录下,解压后的目标文件在受控端的 car/lib/foo 文件夹下
ansible all -m unarchive -a 'src=/tmp/foo.zip dest=/data copy=no mode=0777' 
#解压foo.tgz 到受控端,文件在受控机的 tmp目录下,解压后的目标文件在受控端的 car/lib/foo 文件夹下
ansible all -m unarchive -a 'src=https://example.com/example.zip dest=/data copy=no' 

#解压foo.tgz 到受控端,文件在ansible 主机上,解压后的目标文件在受控端的 car/lib/foo 文件夹下
ansible websrvs -m unarchive -a 'src=https://releases.ansible.com/ansible/ansible-2.1.6.0-0.1.rc1.tar.gz dest=/data/   owner=root remote_src=yes' 
#解压foo.tgz 到受控端,文件在受控机的 tmp目录下,解压后的目标文件在受控端的 car/lib/foo 文件夹下
ansible websrvs -m unarchive -a 'src=http://nginx.org/download/nginx- 1.18.0.tar.gz dest=/usr/local/src/ copy=no'
Archive 模块 功能:打包压缩保存在被管理节点
帮助语法

EXAMPLES:
- name: Compress directory /path/to/foo/ into /path/to/foo.tgz
  archive:
    path: /path/to/foo            #要压缩的文件或目录
    dest: /path/to/foo.tgz        #压缩后的文件
    format:bz2, gz, tar, xz, zip    #指定打包的类型
范例

ansible websrvs -m archive  -a 'path=/var/log/ dest=/data/log.tar.bz2 format=bz2 owner=wang mode=0600'
Hostname 模块 功能:管理主机名
范例:

ansible node1 -m hostname -a "name=websrv"
ansible 10.0.0.18 -m hostname -a 'name=node18.magedu.com'
Cron 模块 功能:计划任务 支持时间:minute,hour,day,month,weekday
范例
#先创建备份数据库脚本
[root@centos8 ~]#cat /root/mysql_backup.sh 
#!/bin/bash
mysqldump -A -F --single-transaction --master-data=2 -q -uroot |gzip > 
/data/mysql_`date +%F_%T`.sql.gz


#创建任务
ansible 10.0.0.8 -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" 
job=/root/mysql_backup.sh'
ansible websrvs   -m cron -a "minute=*/5 job='/usr/sbin/ntpdate ntp.aliyun.com 
&>/dev/null' name=Synctime"
#禁用计划任务
ansible websrvs   -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1 
&>/dev/null' name=Synctime disabled=yes"
#启用计划任务
ansible websrvs   -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1 
&>/dev/null' name=Synctime disabled=no
#删除任务
ansible websrvs -m cron -a "name='backup mysql' state=absent"
ansible websrvs -m cron -a 'state=absent name=Synctime'
Yum 和 Apt 模块 功能: yum 管理软件包,只支持RHEL,CentOS,fedora,不支持Ubuntu其它版本 apt 模块管理 Ubuntu
范例
ansible websrvs -m yum -a 'name=httpd state=present'  #安装
ansible websrvs -m yum -a 'name=nginx state=present enablerepo=epel'  #启用epel源
进行安装
ansible websrvs -m yum -a 'name=* state=lastest exclude=kernel*,foo*' #升级除
kernel和foo开头以外的所有包
ansible websrvs -m yum -a 'name=httpd state=absent'   #删除
Service 模块 管理服务
范例

示例一、启动httpd服务
# ansible 192.168.85.251 -m service -a "name=httpd state=started" -i hosts 
示例二、重载httpd服务
# ansible 192.168.85.251 -m service -a "name=httpd state=reloaded" -i hosts
示例三、重启Httpd服务
ansible 192.168.85.251 -m service -a "name=httpd state=restarted" -i hosts
示例四、停止httpd服务
ansible 192.168.85.251 -m service -a "name=httpd state=stopped" -i hosts
示例五、 启动httpd服务,并加入开机自启
ansible 192.168.85.251 -m service -a "name=httpd state=started enabled=yes" -i hosts
User 模块 管理用户
范例

#创建用户 comment 是描述
ansible all -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root'

ansible all -m user -a 'name=nginx comment=nginx uid=88 group=nginx 
groups="root,daemon" shell=/sbin/nologin system=yes create_home=no 
home=/data/nginx non_unique=yes'
#remove=yes表示删除用户及家目录等数据,默认remove=no
ansible all -m user -a 'name=nginx state=absent remove=yes'
#生成123456加密的密码
ansible localhost -m debug -a "msg={{ '123456'| 
password_hash('sha512','salt')}}"
localhost | SUCCESS => {
    "msg": "$6$salt$MktMKPZJ6t59GfxcJU20DwcwQzfMvOlHFVZiOVD71w."
}#用上面创建的密码创建用户
ansible websrvs -m user -a 'name=test 
password="$6$salt$MktMKPZJ6t59GfxcJU20DwcwQzfMvOlHFVZiOVD71w."'
#创建用户test,并生成4096bit的私钥
ansible websrvs -m user -a 'name=test generate_ssh_key=yes ssh_key_bits=4096 
ssh_key_file=.ssh/id_rsa'
Group 模块 管理组
范例

#创建组
ansible websrvs -m group  -a 'name=nginx gid=88 system=yes'
#删除组
ansible websrvs -m group  -a 'name=nginx state=absent'
  Setup 模块 功能: setup 模块来收集主机的系统信息,这些 facts 信息可以直接以变量的形式使用,但是如果主机 较多,会影响执行速度 可以使用 gather_facts: no 来禁止 Ansible 收集 facts 信息  
范例
ansible all -m setup
ansible all -m setup -a "filter=ansible_nodename"
ansible all -m setup -a "filter=ansible_hostname"
ansible all -m setup -a "filter=ansible_domain"
ansible all -m setup -a "filter=ansible_memtotal_mb"
ansible all -m setup -a "filter=ansible_memory_mb"
ansible all -m setup -a "filter=ansible_memfree_mb"
ansible all -m setup -a "filter=ansible_os_family"
ansible all -m setup -a "filter=ansible_distribution_major_version"
ansible all -m setup -a "filter=ansible_distribution_version"
ansible all -m setup -a "filter=ansible_processor_vcpus"
ansible all -m setup -a "filter=ansible_all_ipv4_addresses"
ansible all -m setup -a "filter=ansible_architecture"
ansible all -m setup -a "filter=ansible_uptime_seconds"
ansible all -m setup -a "filter=ansible_processor*"
ansible all -m setup -a 'filter=ansible_env'
 

相关