ansible:提高效率的工具,实现自动化运维

自动化:系统自动化(PXE+KS/PXE+COBBLER)
程序自动化(Ansible/Saltstack/Puppet)
代码自动化(Jenkins)

程序自动化工具分为两类:

(1)C/S架构:Saltstack /Puppet

(2)无客户端模式:Ansible(主控端/被控端)

区别:

Ansible:基于python开发,使用ssh协议,没有客户端,200-300台,适用于中小型应用环境,一个系统控制多台主机,有两个角色:主控端和被控端

Saltstack :基于python开发,支持统一管理,比较轻量级 支持管理500台服务器,python编写,需要部署agent,主控端通过安装在被控端的代理来对被控端进行操作

Puppet:Ruby语言编写,重型程序,适合大型环境,谷歌公司在用,软件过于复杂,国内一般不到1000+

Ansible特性

  • 模块化:调用特定的模块,完成特定的任务,约3000模块,每个模块功能不同
  • 有paramiko(基于ssh开发,主要做远程控制)PyYAML(可以实现剧本)Jinja2(模板语言),这三个模块是Ansible的核心
  • 支持自定义模块(python)
  • 安全,基于openssh
  • 支持playbook编排任务(PyYAML)
  • 幂等性:一个任务执行一遍和n变效果一样,不会因为重复执行而带来意外情况(如:复制文件时,执行两次会报是否覆盖,而使用Ansible可以避免这种情况,后面copy模块会讲到)

部署Ansible环境

实验环境:四台linux服务器

​ 192.168.1.1(用作Ansible服务器)

​ 192.168.1.4(被控端)

​ 192.168.1.5(被控端)

​ 192.168.1.6(被控端)

实验目的:使用控制端来控制3个被控端工作

实验步骤:

控制端部署

在控制端(192.168.1.1)安装epel-release和Ansible(使用网络yum)

epel-release:Extra Packages for Enterprise Linux(企业版linux扩展包)

# 创建yum缓存,加快yum安装速度
[root@localhost ~]# yum makecache fast
# epel是一个系统扩展yum源
[root@localhost ~]# yum -y install epel-release
[root@localhost ~]# yum -y install ansible

设置控制端免密登录被控端

通过ssh密钥对实现

[root@localhost ~]# ssh-keygen                # 生成私钥和公钥,一直回车即可
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:
SHA256:2puXlUxjnsxKrVhnGbNahVhbZLJrMr9q/8B9uDr144Y root@localhost
The key's randomart image is:
+---[RSA 2048]----+
|            ..o  |
|            .+.  |
|           o.+   |
|          . O..  |
|        S oOoX   |
|       o  o*/... |
|      . .+ X+.+..|
|        .oB .E =.|
|        oo.o++=..|
+----[SHA256]-----+

# 默认生成在当前用户的.ssh/目录下
[root@localhost ~]# ls /root/.ssh
id_rsa  id_rsa.pub

# 将生成的公钥文件发送到指定的控制端,需要用到root密码
[root@localhost ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.1.4
[root@localhost ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.1.5
[root@localhost ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.1.6
# 此时在1.4的被控端的用户目录下的.ssh目录下会生成一个authorized_keys文件
[root@localhost ~]# ls /root/.ssh
authorized_keys
# 在控制端使用ssh登录到1.4,发现不使用密码即可
[root@localhost ~]# ssh root@192.168.1.4

配置Ansible的配置文件

ansible.cfg Ansible主配置文件

hosts 被控端的主机清单

roles 角色

修改主机清单:将被控端写入

在使用ansible操作时,可以通过分组名对,组中所有主机进行相同操作

格式为:

[分组名]
被控端ip1
被控端ip2
...

例:

# 在文件末尾添加,如果有DNS,直接写域名也可以
[root@localhost ~]# vim /etc/ansible/hosts 
添加:
[dbserver]
192.168.1.4            # 被控端

[webserver]
192.168.1.5            # 被控端
192.168.1.6            # 被控端

Ansible简单操作

ansible --version            # 查看ansible版本
ansible-doc -l        # 查看ansible支持模块
ansible-doc -s 模块名        # 关于模块的帮助信息
如:ansible-doc -s ping
ansible-doc -h       # 帮助信息

-------关于模块操作的语法-------
ansible 操作对象 -m 模块名 -a '模块参数'
    -a:在某些模块中可以省略
ansible 操作对象 -m 模块名 -a '模块参数' --limit x.x.x.x
    --limit:可以指定操作对象中的某个ip来执行该模块

常用模块

ping模块:

检测各主机之间的连接状况

如:

[root@localhost ~]# ansible all -m ping

command模块:

主要用于执行简单的shell命令:单个命令

如:ls、cat等类似简单命令,不带有管道符类似操作的使用shell模块

例:

[root@localhost ~]# ansible dbserver -m command -a 'ls /root'
# 配置主机清单时dbserver中,只写入了1.4,所以结果只有1.4主机运行ls /root
192.168.1.4 | CHANGED | rc=0 >>
anaconda-ks.cfg
initial-setup-ks.cfg
公共
模板
视频
图片
文档
下载
音乐
桌面

shell模块

执行linux复杂命令

[root@localhost ~]# ansible dbserver -m shell -a 'ls /root/ | wc -l'
192.168.1.4 | CHANGED | rc=0 >>
10

args

如果在编译安装包时,需要进入目录进行配置,使用以下

- shell: ./configure && make && make install
  args:
    chdir: 解压包路径

cron模块

执行计划任务,用于为被控制端设置自动化任务

# 设置任务
[root@localhost ~]# ansible dbserver -m cron -a 'minute="*/2" job="date >> /tmp/date.txt" name="show date" state=present'
state=persent:一般表示新增
# 删除任务,只需要指定name即可
[root@localhost ~]# ansible dbserver -m cron -a ' name="show date" state=absent'
state=absent:一般表示移除,可以用来删除计划任务
# cron的其他关键字参考
[root@localhost ~]# ansible-doc -s cron

user模块

常用操作

useradd 用户名        # 创建普通用户
passwd 用户名        # 设置用户密码
useradd -M -s /sbin/nologin 用户名        # 创建的用户没有家目录,不能登录
useradd -u 用户id -g gid 用户名   # 创建用户时指定uid和gid
userdel -r 用户            # 连同用户家目录一起删除用户

以上操作通过ansible来完成

ansible 操作对象 -m user -a 'name=用户名 state=present'    # 创建用户
# openssl passwd "123.com"用来获取加密后的密码
ansible 操作对象 -m user -a 'name=用户名 password="加密密码" state=present'   # 创建用户并设置密码
ansible 操作对象 -m shell -a 'echo "123.com" | passwd --stdin 用户名'   # 设置用户密码
# 创建无家目录,不能登录的用户
ansible 操作对象 -m user -a 'name=用户名 create_home=no shell=/sbin/nologin state=present'  
# 创建用户是指定uid和基本组
ansible 操作对象 -m user -a 'name=用户名 uid=id号 group=组名 state=present'
# 连同用户家目录一同删除
ansible 操作对象 -m user -a 'name=用户名 remove=yes state=absent'

group模块

添加组
ansible 操作对象 -m group -a 'name=组名 system=yes state=present gid=ID号'
system=yes:是否是公共组
删除组
ansible 操作对象 -m group -a 'name=组名 state=absent'

copy模块

1、从主控端复制文件到被控端(类似scp)

ansible all -m copy -a 'src=主控端文件路径 dest=被控端保存路径'
# 在被控端查看是否复制文件成功
ansible all -m shell -a 'ls 被控端保存文件路径'

2、主控端控制被控端复制和粘贴被控端的文件

ansible 操作对象 -m copy -a 'src=被控端源文件路径 dest=被控端目标位置 remote_src=yes'
# 验证ansible的幂等性,remote_src=yes,当发现同文件名时,不执行此命令
ansible 操作对象 -m copy -a 'src=被控端源文件路径 dest=被控端目标位置 remote_src=yes backup=yes'
# 修改被控端/root/resolv.conf的内容,使其可以发生文件覆盖,此时在加上backup进行文件覆盖前的备份

file模块

1、修改文件属性(owner(属主) group(属组) mode(权限) 对应linux命令 chown chmod

# 改变属主属组
ansible 操作对象 -m file -a 'path=被控端都存在的要修改属主属组的文件路径 owner=被控端都存在的用户 group=被控端都存在的组 recurse=yes'
# recurse=yes:表示递归设置属主属组
# 修改文件权限
ansible 操作对象 -m file -a 'path=被控端存在的文件路径 mode=7777 recurse=yes'
# 使用mnnn样式的四位8进制数表示,recurse=yes:对当前目录中的所有内容递归权限

2、软链接、硬链接

# 软链接
ansible 操作对象 -m file -a 'src=被控端源文件 dest=软链接文件路径 state=link'

# 硬链接
ansible 操作对象 -m file -a 'src=被控端源文件 dest=硬链接文件路径 state=hard'

3、创建文件和目录

# 创建文件
ansible 操作对象 -m file -a 'path=文件路径及文件名 state=touch'
# 创建目录
ansible 操作对象 -m file -a 'path=目录路径及目录名 state=directory'
# 删除文件或者目录
ansible 操作对象 -m file -a 'path=被控端删除文件或目录路径 state=absent'

yum模块

主控端控制被控端,使其使用yum安装rpm包

前提:被控端的yum可用

安装rpm某包
ansible 操作对象 -m yum -a 'name=包名,包名1... state=installed/present
# 默认不写state是installed/present
卸载rpm包
ansible 操作对象 -m yum -a 'name=包名,包名1... state=removed/absent

service模块

操控被控端开启、关闭、重启、重载(视具体服务而定)

notice:service可用管理rpm包安装的服务,源码安装的服务建议使用shell模块直接打命令

服务状态:started/stopped/restarted/reloaded

ansible 操作对象 -m service -a 'name=服务名 state=服务状态'

hostname模块

修改主机名操作

hostname 主机名 临时

hostnamectl set-hostname 主机名 永久

vim /etc/hosts 修改配置文件

ansible 操作对象 -m hostname -a 'name=主机名'

script模块

用于将主控端的脚本在被控端执行,shell脚本和python脚本

写一个简单创建用户的脚本

#!/bin/bash
for i in {1..10}
    do
        useradd user$i
        echo '123.com' | passwd --stdin user$i
    done

添加脚本可执行权限

chmod +x users.sh

使用script模块执行脚本

# 执行脚本
ansible 操作对象 -m script -a '脚本文件在主控端的路径'
# 验证
ansible 操作对象 -m shell -a 'tail /etc/passwd'

setup模块

用于获取被控端的ansible变量值,主要用于模板剧本中,可以利用变量,实现对被控端的快速配置和差异化配置

ansible变量:用于记录所有主控端和被控端的连接信息

ansible dbserver -m setup 查看所有的变量值

常用选项:ansible 操作对象 -m setup -a 'filter="*变量关键字*"' filter用于筛选变量

如:

# 关于cpu的变量
ansible dbserver -m setup -a 'filter="*cpu*"'

fetch模块

拿取被控端文件

# 存放时,会将每台被控端创建一个ip目录
ansible 操作对象 -m fetch -a 'src=被控端文件路径 dest=主控端存放路径'

replace模块

可以实现对文件内容的切换

# 替换文件中所有匹配的字符
ansible dbserver -m replace -a 'path=被控端文件路径 regexp='匹配要替换的字符' replace='替换后的字符''
# 替换指定行

template模块

主要用于主控端使用模板配置被控端配置文件的场景

需要用到模板文件,文件必须以.j2结尾

以web应用apache为例

主控端和被控端都通过yum模块按照了httpd,在主控端更改配置文件,并重命名.j2结尾

ansible webserver -m template -a 'src=.j2文件路径 dest=被控端主配置文件路径'
如:
ansible webserver -m template -a 'src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf'

也可以在主控端配置文件中引用变量,在主机清单文件中修改

[root@localhost ~]# vim /etc/ansible/hosts
[webserver]
192.168.1.5 http_port=88
192.168.1.6 http_port=90

修改.j2文件

[root@localhost ~]# vim httpd.conf.j2 
# {{http_port}} 引用变量
ServerName www.example.com {{http_port}}

.j2文件传送

ansible webserver -m template -a 'src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf'

这个时候查看被控端的配置文件中,发现1.5的端口为88,16的端口为90

unarchive模块

将主控端的压缩文件,解压后放在被控端

在主控端有一个nginx安装包,执行以下操作直接解压到被控端

ansible 操作对象 -m unarchive -a 'src=主控端安装包路径 dest=解压后的被控端存放路径'

lineinfile模块

修改配置文件时,修改指定行的内容,或者添加到指定行前和指定行后

可以实现在文件加入内容

命令参数说明:

参数 含义
path 指定要操作的文件对象
regexp 匹配条件
insertbefore 在指定行前插入
insertafter 在指定行后插入
line 要写入的文件内容
state present(添加)absent(删除)

insertbefore和insertafter的特殊值

BOF:begin of file(文件起始位置)
EOF:end of file (文件结束位置)

使用insertbefore和insertafter,还有regexp时,需要指定state,其他不需要

在文件开头插入内容

ansible 操作对象 -m lineinfile -a 'path=文件路径 insertbefore=BOF line="插入的内容"'
如:
ansible dbserver -m lineinfile -a 'path=/root/nginx.conf insertbefore=BOF line="# nihao a"'
# 在nginx.conf文件开头添"# nihao a"

在文件结束插入内容

ansible 操作对象 -m lineinfile -a 'path=文件路径 insertbefore=EOF line="插入的内容"'
如:
ansible dbserver -m lineinfile -a 'path=/root/nginx.conf insertbefore=EOF line="# nihao a"'
# 在nginx.conf文件的末尾添加# nihao a

在文件指定位置加入内容

ansible 操作对象 -m lineinfile -a 'path=文件路径 insertbefore="指定位置的内容" line="插入的内容" state=present
如:
ansible dbserver -m lineinfile -a 'path=/root/nginx.conf insertbefore="  server {" line="root html" state=present'
# 在nginx.conf的server {的上一行添加root html

删除文件中的指定内容

ansible 操作对象 -m lineinfile -a 'path=文件路径 regexp="要删除的内容" line="插入的内容" state=absent
如:
ansible dbserver -m lineinfile -a 'path=/root/nginx.conf regexp=" server {" state=absent'
# 删除nginx.conf的server { 这一行

ansible中文权威指南

评论




正在载入...
PoweredHexo
HostedAliyun
DNSAliyun
ThemeVolantis
UV
PV
BY-NC-SA 4.0