自动化运维工具 Ansible 在部署大数据平台下的应用(上)

Ansible 命令行模式的使用

Ansible 执行自动化任务,分为以下两种执行模式:
(1)ad-hoc(单个模块),单条命令的批量执行,或者叫命令行模式;
(2)playbook,为面向对象的编程,可以把多个想要执行的任务放到一个 playbook 中,当然多个任务在事物逻辑上最好是有上下关联的,通过多个任务可以完成一个总体的目标。

命令行模式一般用于测试、临时应用等场景,而 playbook 方式,主用用于正式环境,通过编写 playbook 文件,可实现固定的、批量的对系统或服务进行配置以及维护工作。

本课时将从头讲 Ansible,使用时需要注意两个概念:管理机和远程主机。管理机是安装 Ansible 的机器,远程主机是 Ansible 批量操作的对象,可以是一个或一组主机。Ansible 通过管理机发出批量操作远程主机的指令,这些指令在每个远程主机上依次执行

(1)hosts 文件(以下 hosts 文件均指 /etc/ansible/hosts 文件)

该文件用来定义 Ansible 批量操作的主机列表,主机列表有多种书写方式,最简单的格式如下:

中括号中的名字代表组名,可以根据需求将庞大的主机分成具有标识的组。比如上面分了两个组 webservers 和 dbservers 组。

主机(hosts)部分可以使用域名、主机名、IP 地址表示;当然使用前两者时,需要主机能反解析到相应的 IP 地址,一般此类配置中多使用 IP 地址;未分组的机器需保留在 hosts 的顶部。

也可在 hosts 文件中,指定主机的范围,示例如下

[web]
www[01:50].ixdba.net
[db]
db[a:f].ixdba.ent

这个配置中,web 主机组的主机为 www01.ixdba.net、www02.ixdba.net、www03.ixdba.net 等以此类推,一直到 www50.ixdba.net。下面的 db 组中的 a:f 表示从 a 到 f 的字符。

在 hosts 文件中,还可以使用变量,变量分为主机变量和组变量两种类型,常用的变量如下表所示

(2)ansible.cfg 文件

此文件定义了 Ansible 主机的默认配置熟悉,比如默认是否需要输入密码、是否开启 sudo 认证、action_plugins 插件的位置、hosts 主机组的位置、是否开启 log 功能、默认端口、key 文件位置等。一般情况下这个文件无需修改,保存默认即可。

注意:host_key_checking 表示是否关闭第一次使用 Ansible 连接客户端时 yes/no 的连接确认提示,False 表示关闭,我们只需要去掉此选项的注释即可。这个问题其实是 SSH 连接的问题,因为 Linux 下的主机在第一次 SSH 连接到一个新的主机时,一般会需要 yes/no 的连接确认,这在自动化运维中是不需要的,因此需要禁止这种确认。在 Ansible 中通过设置 host_key_checking 为 False 就可以避免这种情况。

2. commands 模块

命令行下执行 ansible,基本格式如下

ansible 主机或组  -m 模块名 -a '模块参数'  ansible参数

其中:

主机或组,在 /etc/ansible/hosts 里进行指定;

模块名,可以通过 ansible-doc -l 查看目前安装的模块,默认不指定时,使用的是 command 模块;

模块参数,可以通过 “ansible-doc 模块名”查看具体用法

ansible 常用的参数如下表所示:

下面看几个使用 command 模块的例子

[root@docker ~]# ansible 192.168.0.80 -m command  -a 'pwd'
192.168.0.80 | CHANGED | rc=0 >>
/root
[root@docker ~]# ansible 192.168.0.80 -m command -a 'chdir=/tmp/ pwd'
192.168.0.80 | CHANGED | rc=0 >>
/tmp
[root@docker ~]# ansible 192.168.0.80  -m command  -a 'creates=/tmp/tmp.txt date'
192.168.0.80 | CHANGED | rc=0 >>
Mon Feb  1 12:44:47 CST 2021
[root@docker ~]# ansible 192.168.0.80  -m command  -a 'removes=/tmp/tmp.txt date'
192.168.0.80 | SUCCESS | rc=0 >>
skipped, since /tmp/tmp.txt does not exist
[root@docker ~]# ansible 192.168.0.80  -m command  -a 'ps -ef|grep sshd' 
192.168.0.80 | FAILED | rc=1 >>
error: unsupported SysV option

Usage:
 ps [options]

 Try 'ps --help <simple|list|output|threads|misc|all>'
  or 'ps --help <s|l|o|t|m|a>'
 for additional help text.

For more details see ps(1).non-zero return code
[root@docker ~]# 

上面的例子是对主机 192.168.0.80 进行的操作,在实际应用中需要替换为主机组。另外,还用到了 command 模块的几个选项:

creates,后跟一个文件名,当远程主机上存在这个文件时,该命令不执行,否则执行;

chdir,在执行指令之前,先切换到该指定的目录;

removes,后跟一个文件名,当该文件存在时,该选项执行,否则不执行。

注意:commands 模块的执行,在远程主机上,需有 Python 环境的支持。该模块通过在 -a 参数后面跟上要在远程机器上执行的命令即可完成远程操作,不过命令里如果带有特殊字符(“<”、“>”、“|”、“&”等),则执行不成功,也就是 commands 模块不支持这些特殊字符。上面最后那个例子无法执行成功就是这个原因。

3. shell 模块

shell 模块的功能和用法与 command 模块一样,不过 shell 模块执行命令的时候使用的是 /bin/sh,该模块可以执行任何命令。看下面个例子

[root@docker ~]# ansible 192.168.0.80  -m shell  -a 'ps -ef|grep sshd' 
192.168.0.80 | CHANGED | rc=0 >>
root       1279      1  0 11:55 ?        00:00:00 /usr/sbin/sshd -D
root       1798   1279  0 11:55 ?        00:00:00 sshd: root@pts/0
root       3884   1908 32 12:47 pts/0    00:00:00 /usr/bin/python2 /usr/bin/ansible 192.168.0.80 -m shell -a ps -ef|grep sshd
root       3892   3884 14 12:47 pts/0    00:00:00 /usr/bin/python2 /usr/bin/ansible 192.168.0.80 -m shell -a ps -ef|grep sshd
root       3895   1279 12 12:47 ?        00:00:00 sshd: root@pts/2
root       3979   3974  0 12:47 pts/2    00:00:00 /bin/sh -c ps -ef|grep sshd
root       3981   3979  0 12:47 pts/2    00:00:00 grep sshd
[root@docker ~]# 

官方文档表示 command 用起来更安全,更有可预知性,但从我使用角度来说,并没发现有多大差别。

 4.raw 模块和 script 模块

raw 模块功能与 command 和 shell 模块类似,shell 能够完成的操作,raw 也都能完成。不同的是,raw 模块不需要远程主机上的 Python 环境。

Ansible 要执行自动化操作,需在管理机上安装 Ansible,客户机上安装 Python,如果客户机上没有安装,那么 command、shell 模块将无法工作,但 raw 可以正常工作。因此,若有的机器没有装 Python,或者装的版本在 2.4 以下,就可以使用 raw 模块来装 Python、python-simplejson 等。

若有些机器根本安装不了 Python 的话(如交换机、路由器等),那么,直接用 raw 模块是最好的选择。下面看个例子:

[root@docker ~]# ansible 192.168.0.80 -m raw -a "ps -ef|grep sshd|awk '{print \$2}'" 
192.168.0.80 | CHANGED | rc=0 >>
1279
1798
4137
4145
4147
4148
4158
4171
Shared connection to 192.168.0.80 closed.

[root@docker ~]#

script 模块是将管理端的 shell 脚本拷贝到被管理的远程主机上执行,其原理是先将 shell 复制到远程主机,再在远程主机上执行。此模块的执行,不需要远程主机上的 Python 环境。看下面这个例子:

[root@docker mnt]# cat westos.sh 
#!/bin/bash
echo $HOSTNAME
[root@docker mnt]# ansible 192.168.0.38 -m script -a '/mnt/westos.sh'
192.168.0.38 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.0.38 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.0.38 closed."
    ], 
    "stdout": "zabbix\r\n", 
    "stdout_lines": [
        "zabbix"
    ]
}

脚本/mnt/westos.sh 在管理端本机上,script 模块执行的时候将脚本传送到远程的 192.168.0.38 主机中,然后执行这个脚本

file 模块、copy 模块与 synchronize 模块

file 模块功能强大,主要用于远程主机上的文件或目录操作,该模块包含如下选项:

下面来看几个使用示例

(1)创建一个不存在的目录,并进行递归授权:

[root@docker mnt]# ansible 192.168.0.80 -m file -a "path=/mnt/abc123 state=directory"
192.168.0.80 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/mnt/abc123", 
    "secontext": "unconfined_u:object_r:mnt_t:s0", 
    "size": 6, 
    "state": "directory", 
    "uid": 0
}
[root@docker mnt]# ll
total 7
drwxr-xr-x. 2 root root  6 Feb  1 15:34 abc123
drwxr-xr-x. 2 root root  6 Dec 11 16:08 hgfs
-rw-r--r--. 1 root root 11 Feb  1 12:55 install.sh
-rw-r--r--. 1 root root 27 Feb  1 15:27 westos.sh
[root@docker mnt]# ansible 192.168.0.80 -m file -a "path=/mnt/abc123 owner=nobody  group=nobody  mode=0644 recurse=yes"
192.168.0.80 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "gid": 99, 
    "group": "nobody", 
    "mode": "0644", 
    "owner": "nobody", 
    "path": "/mnt/abc123", 
    "secontext": "unconfined_u:object_r:mnt_t:s0", 
    "size": 6, 
    "state": "directory", 
    "uid": 99
}
[root@docker mnt]# ll
total 8
drw-r--r--. 2 nobody nobody  6 Feb  1 15:34 abc123
drw-r--r--. 2 sshd   sshd    6 Feb  1 15:33 ansibletemp
drwxr-xr-x. 2 root   root    6 Dec 11 16:08 hgfs
-rw-r--r--. 1 root   root   11 Feb  1 12:55 install.sh
-rw-r--r--. 1 root   root   27 Feb  1 15:27 westos.sh
[root@docker mnt]# ansible 192.168.0.80 -m file -a "path=/mnt/ansibletemp  owner=sshd  group=sshd mode=0644 state=directory "
192.168.0.80 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "gid": 74, 
    "group": "sshd", 
    "mode": "0644", 
    "owner": "sshd", 
    "path": "/mnt/ansibletemp", 
    "secontext": "unconfined_u:object_r:mnt_t:s0", 
    "size": 6, 
    "state": "directory", 
    "uid": 74
}
[root@docker mnt]# ll
total 8
drw-r--r--. 2 nobody nobody  6 Feb  1 15:34 abc123
drw-r--r--. 2 sshd   sshd    6 Feb  1 15:33 ansibletemp
drwxr-xr-x. 2 root   root    6 Dec 11 16:08 hgfs
-rw-r--r--. 1 root   root   11 Feb  1 12:55 install.sh
-rw-r--r--. 1 root   root   27 Feb  1 15:27 westos.sh
[root@docker mnt]# 

(2)创建一个文件(如果不存在),并进行授权:

[root@docker mnt]# ansible 192.168.0.80 -m file -a "path=/mnt/syncfile.txt mode=0444"
192.168.0.80 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0444", 
    "owner": "root", 
    "path": "/mnt/syncfile.txt", 
    "secontext": "unconfined_u:object_r:mnt_t:s0", 
    "size": 7, 
    "state": "file", 
    "uid": 0
}
[root@docker mnt]# ll
total 12
drw-r--r--. 2 nobody nobody  6 Feb  1 15:34 abc123
drw-r--r--. 2 sshd   sshd    6 Feb  1 15:33 ansibletemp
drwxr-xr-x. 2 root   root    6 Dec 11 16:08 hgfs
-rw-r--r--. 1 root   root   11 Feb  1 12:55 install.sh
-r--r--r--. 1 root   root    7 Feb  1 15:41 syncfile.txt
-rw-r--r--. 1 root   root   27 Feb  1 15:27 westos.sh
[root@docker mnt]# 

(3)创建一个软连接(将 /etc/ssh/sshd_config 软连接到 /mnt/sshd_config):

[root@docker ~]# ansible 192.168.0.80 -m file -a "src=/etc/ssh/sshd_config dest=/mnt/sshd_config  owner=sshd state=link"
192.168.0.80 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "dest": "/mnt/sshd_config", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:mnt_t:s0", 
    "size": 20, 
    "src": "/etc/ssh/sshd_config", 
    "state": "link", 
    "uid": 0
}
[root@docker ~]# cd /mnt
[root@docker mnt]# ll
total 12
drw-r--r--. 2 nobody nobody  6 Feb  1 15:34 abc123
drw-r--r--. 2 sshd   sshd    6 Feb  1 15:33 ansibletemp
drwxr-xr-x. 2 root   root    6 Dec 11 16:08 hgfs
-rw-r--r--. 1 root   root   11 Feb  1 12:55 install.sh
lrwxrwxrwx. 1 root   root   20 Feb  1 15:50 sshd_config -> /etc/ssh/sshd_config
-r--r--r--. 1 root   root    7 Feb  1 15:41 syncfile.txt
-rw-r--r--. 1 root   root   27 Feb  1 15:27 westos.sh

(4)删除一个压缩文件:

[root@docker tmp]# ls -l backup.tar.gz 
-rw-r--r--. 1 root root 10240 Feb  1 16:22 backup.tar.gz
[root@docker tmp]# ansible 192.168.0.80 -m file -a "path=/tmp/backup.tar.gz  state=absent"
192.168.0.80 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "path": "/tmp/backup.tar.gz", 
    "state": "absent"
}
[root@docker tmp]# ls -l backup.tar.gz 
ls: cannot access backup.tar.gz: No such file or directory
[root@docker tmp]# 

(5)创建一个文件:

[root@docker mnt]# ansible 192.168.0.80 -m file -a "path=/mnt/ansibletemp state=touch"
192.168.0.80 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "dest": "/mnt/ansibletemp", 
    "gid": 74, 
    "group": "sshd", 
    "mode": "0644", 
    "owner": "sshd", 
    "secontext": "unconfined_u:object_r:mnt_t:s0", 
    "size": 6, 
    "state": "directory", 
    "uid": 74
}
[root@docker mnt]# 

接着继续来看 copy 模块,此模块用来复制文件到远程主机,copy 模块包含的选项如下表所示

(1)拷贝文件并进行权限设置

[root@docker mnt]# ansible 192.168.0.80 -m copy -a 'src=/etc/sudoers dest=/mnt/sudoers owner=root group=root mode=440 backup=yes'
192.168.0.80 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "e683ad5e5d8d7112d14924c11c98be7bf2ef4918", 
    "dest": "/mnt/sudoers", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "1b134d95a4618029ff962a63b021e1ca", 
    "mode": "0440", 
    "owner": "root", 
    "secontext": "system_u:object_r:mnt_t:s0", 
    "size": 4328, 
    "src": "/root/.ansible/tmp/ansible-tmp-1612167952.14-9699-10783327897062/source", 
    "state": "file", 
    "uid": 0
}
[root@docker mnt]# ls
abc123  ansibletemp  hgfs  install.sh  sshd_config  sudoers  syncfile.txt  westos.sh
[root@docker mnt]# 

copy 默认会对存在的备份文件进行覆盖,通过 backup=yes 参数可以在覆盖前,对之前的文件进行自动备份。

(2)拷贝文件之后进行验证

这里用了 validate 参数,表示在复制之前验证要拷贝的文件是否正确。如果验证通过则复制到远程主机上,%s 是一个文件路径的占位符,在文件被复制到远程主机之前,它会被替换为 src 后面的文件。

[root@docker mnt]# ansible 192.168.0.80 -m copy -a "src=/etc/sudoers dest=/mnt/sudoers  validate='visudo -cf  %s'"
192.168.0.80 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "checksum": "e683ad5e5d8d7112d14924c11c98be7bf2ef4918", 
    "dest": "/mnt/sudoers", 
    "gid": 0, 
    "group": "root", 
    "mode": "0440", 
    "owner": "root", 
    "path": "/mnt/sudoers", 
    "secontext": "system_u:object_r:mnt_t:s0", 
    "size": 4328, 
    "state": "file", 
    "uid": 0
}

(3)拷贝目录并进行递归设定目录的权限

[root@docker mnt]# ansible 192.168.0.80 -m copy -a 'src=/etc/yum dest=/mnt/ owner=hadoop group=hadoop  directory_mode=644' 
192.168.0.80 | CHANGED => {
    "changed": true, 
    "dest": "/mnt/", 
    "src": "/etc/yum"
}
[root@docker mnt]# ansible 192.168.0.80 -m copy -a 'src=/etc/yum/ dest=/mnt/bak owner=hadoop group=hadoop directory_mode=644'
192.168.0.80 | CHANGED => {
    "changed": true, 
    "dest": "/mnt/bak/", 
    "src": "/etc/yum/"
}
[root@docker mnt]# 

上面这两个命令执行是有区别的,第一个是拷贝管理机的 /etc/yum 目录到远程主机的 /mnt 目录下;第二个命令是拷贝管理机 /etc/yum 目录下的所有文件或子目录到远程主机的 /mnt/bak 目录下。

copy 模块拷贝小文件还可以,如果拷贝大文件或者目录的话,速度很慢,不建议使用。此时推荐使用synchronize 模块,此模块通过调用 rsync 进行文件或目录同步,同步速度很快,还指出增量同步,该模块常用的选项如下表所示:

下面看几个例子。

(1)同步本地的 /mnt/install.sh  到远程主机

[root@docker mnt]# ansible 192.168.0.38 -m synchronize -a 'src=/mnt/install.sh  dest=/tmp'
192.168.0.38 | CHANGED => {
    "changed": true, 
    "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh=/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null --out-format=<<CHANGED>>%i %n%L /mnt/install.sh 192.168.0.38:/tmp", 
    "msg": "<f+++++++++ install.sh\n", 
    "rc": 0, 
    "stdout_lines": [
        "<f+++++++++ install.sh"
    ]
}
[root@docker mnt]#

(2)将远程主机192.168.0.38 上 /mnt/a 文件拷贝到本地的 /tmp 目录下。

[root@docker mnt]# ansible 192.168.0.38 -m synchronize -a 'mode=pull src=/mnt/a  dest=/tmp'
192.168.0.38 | CHANGED => {
    "changed": true, 
    "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh=/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null --out-format=<<CHANGED>>%i %n%L 192.168.0.38:/mnt/a /tmp", 
    "msg": ">f+++++++++ a\n", 
    "rc": 0, 
    "stdout_lines": [
        ">f+++++++++ a"
    ]
}
[root@docker mnt]# ls -l /tmp/a
-rw-r--r--. 1 root root 5 Feb  1 16:51 /tmp/a
[root@docker mnt]# 

cron 模块、yum 模块与 service 模块

cron 模块用于管理计划任务,常用选项含义如下表所示

下面是几个示例。

(1)系统重启时执行 /data/bootservice.sh 脚本。

ansible 192.168.0.38 -m cron -a 'name="job for reboot" special_time=reboot  job="/data/bootservice.sh" '

此命令执行后,会在 192.168.0.88  的 crontab 中写入“@reboot /data/bootservice.sh”,通过“crontab -l ”可以查看到。

(2)表示在每周六的 1:20 分执行"yum -y update"操作。

ansible 192.168.0.38  -m cron -a 'name="yum autoupdate" weekday="6" minute=20 hour=1 user="root" job="yum -y update"'

 (3)表示在每周六的 1:30 分以 root 用户执行 "/home/dokcer/backup.sh" 脚本。

ansible 192.168.0.38  -m cron -a  'backup="True" name="autobackup" weekday="6" minute=30  hour=1 user="root" job="/home/dokcer/backup.sh"'

(4)会在 /etc/cron.d 创建一个 check_http_for_ansible 文件,表示每天的 12:30 分通过 root 用户执行 /home/docker/check_http.sh 脚本。 

ansible 192.168.0.38  -m cron -a  'name="checkhttp" minute=30 hour=12 user="root" job="/home/docker/check_http.sh" cron_file="check_http_for_ansible" '

(5)删除一个计划任务。

ansible 192.168.0.38  -m cron  -a  'name="yum  update" state=absent'

再看看 yum 模块的使用,此模块用来通过 yum 包管理器来管理软件包,常用选项以及含义如下表所示:

下面是几个示例。

(1)通过 yum 安装 Redis。

ansible 192.168.0.80 -m yum -a "name=redis state=installed"

(2)通过 yum 卸载 Redis。

ansible 192.168.0.80 -m yum -a "name=redis state=removed"

(3)通过 yum 安装 Redis 最新版本,并设置 yum 源。

ansible 192.168.0.80 -m yum -a "name=redis state=latest enablerepo=epel"

(4)通过指定地址的方式安装 bash

ansible 192.168.0.80 -m yum -a "name=http://mirrors.aliyun.com/centos/7.4.1708/os/x86_64/Packages/bash-4.2.46-28.el7.x86_64.rpm"  state=present'

service 模块,此模块用于管理远程主机上的服务,该模块包含如下选项

下面是几个使用示例。

(1)启动 httpd 服务。

ansible 192.168.0.80  -m service -a "name=httpd  state=started"

(2)设置 httpd 服务开机自启。

ansible 192.168.0.80  -m service -a "name=httpd  enabled=yes"

setup 模块获取 Ansible facts 信息

Ansible facts 是远程主机上的系统信息,主要包含 IP 地址、操作系统版本、网络设备、Mac 地址、内存、磁盘、硬件等信息,这些信息根据远程主机的信息来作为执行条件操作的场景,非常有用。比如,我们可以根据远程主机的操作系统版本,选择安装不同版本的软件包,或者收集远程主机上每个主机的主机名、IP 地址等信息。

那么如何获取 Ansible facts 信息呢,其实,Ansible 提供了一个 setup 模块来收集远程主机的系统信息,这些 facts 信息可以直接以变量的形式使用

下面是两个使用的例子。
(1)查看主机内存信息。

 ansible 192.168.0.80 -m setup -a 'filter=ansible_*_mb'

(2)查看接口为 eth0-2 的网卡信息。

ansible 192.168.0.80 -m setup -a 'filter=ansible_em[1-2]'


在后面 ansible-playbook 内容中会讲到的 playbooks 脚本中,经常会用到一个参数 gather_facts,其与该模块相关。gather_facts 默认值为 yes,也就是说,在使用 Ansible 对远程主机执行任何一个 playbook 之前,总会先通过 setup 模块获取 facts,并将信息暂存在内存中,直到该 playbook 执行结束为止。

user 模块与 group 模块

user 模块请求的是 useradd、userdel、usermod 三个指令;group 模块请求的是 groupadd、groupdel、groupmod 三个指令,常用的选项如下表所示

下面看几个使用例子。
(1)创建一个用户 usertest1。

ansible 192.168.0.80 -m user -a "name=usertest1"

(2)创建用户 usertest2,并设置附加组。

ansible 192.168.0.80 -m user -a "name=usertest2 groups=admins,developers"

(3)删除用户 usertest1 的同时,删除用户根目录。

ansible 192.168.0.80 -m user -a "name=usertest1 state=absent remove=yes"

(4)批量修改用户密码。

echo "linux123www" | openssl passwd -1 -salt $(< /dev/urandom tr -dc '[:alnum:]' | head -c 32)  -stdin
$1$YrkIHfuu$wzin4k5BFljuCbus5TlC..
ansible 192.168.0.80 -m user -a 'name=usertest2 password="$1$YrkIHfuu$wzin4k5BFljuCbus5TlC.." '

其中:
-1 表示采用的是 MD5 加密算法;
-salt 指定 salt 值,在使用加密算法进行加密时,即使密码一样,由于 salt 不一样,所以计算出来的 hash 值也不一样,除非密码一样,salt 值也一样,计算出来的 hash 值才一样;
“< /dev/urandom tr -dc '[:alnum:]' | head -c 32”产生一个随机的 salt;
passwd 的值不能是明文,passwd 关键字后面应该是密文,密文会被保存在 /etc/shadow 文件中。

猜你喜欢

转载自blog.csdn.net/yanghuadong_1992/article/details/113506723