Ansible是一种自动化工具,可以使用命令来管理主机。以下是一些常见的Ansible命令:
ansible <host-pattern> [options]
# host-pattern:是目标主机的模式,可以是一个主机名、多个主机名、主机组名或者通配符等。
# options:是可选的命令行选项,用于指定要执行的操作、远程登录用户名、清单文件位置、并行操作数量、sudo权限等。
选项 | 解释 |
---|---|
-i | 指定Ansible主机清单文件的路径。,默认为/etc/ansible/hosts |
-m | 指定要执行的模块,例如ping、command、shell等。 |
-a | 指定要传递给模块的参数,例如命令行参数、文件路径等。 |
-u | 指定远程主机的用户名,默认为当前用户。 |
-k | 在连接到远程主机之前提示输入密码。 |
-K | 在连接到远程主机之前提示输入sudo密码。 |
-f | 指定并发执行任务的进程数。 |
-l | 指定某个远程主机 ,例如:-l 192.168.200.20 |
-C | 运行模拟模式,不实际执行任务 |
-e | 用于指定额外的变量 |
使用Ansible工具,在所有主机上执行命令echo hello
[root@localhost ~]# ansible all -a "echo hello"
192.168.200.30 | CHANGED | rc=0 >>
hello
192.168.200.20 | CHANGED | rc=0 >>
hello
使用Ansible工具,在所有主机上执行命令ls -al /home
[root@localhost ~]# ansible all -a "ls -al /home"
192.168.200.30 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x. 3 root root 17 5月 26 18:37 .
dr-xr-xr-x. 17 root root 224 4月 5 20:11 ..
drwx------. 2 foo foo 62 5月 26 18:37 foo
192.168.200.20 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x. 4 root root 28 5月 26 18:37 .
dr-xr-xr-x. 17 root root 224 4月 5 20:11 ..
drwx------. 2 csq csq 83 5月 26 18:57 csq
drwx------. 2 foo foo 83 5月 26 18:56 foo
ansible-doc命令用于查看Ansible模块的文档,可以了解模块的参数、用法和示例等信息。
选项 | 解释 |
---|---|
-l | 列出所有可用的模块 |
-s | 显示模块的详细文档 |
-j | 以JSON格式输出文档 |
列出所有可用的模块
[root@localhost ~]# ansible-doc -l
yum Manages packages with
copy Copy files to remote l...
ping Try to connect to host...
debug Print statements durin...
template Template a file out to...
file Manage files and file ...
service Manage services
command Execute commands on ta...
.......
......
.......
.......
列出copy模块的详细信息
[root@localhost ~]# ansible-doc -s copy
- name: Copy files to remote locations
copy:
attributes: # The attributes the resulting file or directory should
have. To get supported
flags look at the man page
for `chattr' on the target
system. This string should
contain the attributes in
the same order as the one
displayed by `lsattr'. The
`=' operator is assumed as
default, otherwise `+' or
`-' operators need to be
included in the string.
backup: # Create a backup file including the timestamp information
.......
.......
不加任何参数查看copy模块全部信息(非常详细,翻到后面有使用案例)
[root@localhost ~]# ansible-doc copy
为了避免重复地输入命令,Ansible可以使用脚本来管理主机。这样做的好处是,可以通过脚本自动化执行一些常见的管理操作,例如创建、删除、修改用户、安装软件包、配置系统等等。
在 Ansible 中,脚本通常是由 YAML 格式的 Playbook 组成
。Playbook 是一组有序的任务列表,每个任务由一个或多个模块组成。可以根据需要编写自定义模块,也可以使用 Ansible 内置的模块来完成任务。
ansible-playbook service.yaml
Ansible Playbook 包含了多个关键字,用于定义任务、变量、条件、循环等。以下是 Ansible Playbook 中常见的关键字列表及其作用:
以上是 Ansible Playbook 中常见的关键字,每个关键字都有自己的作用和用法。在编写 Playbook 时,可以根据实际需要选择和使用相应的关键字。
以下是一个使用内置模块管理主机的 Playbook 示例:
[root@localhost ~]# vim ansiblehttp.yaml
- name: install add start http # 脚本说明
hosts: test1 # 主机组为test1
tasks: # 定义任务
- name: install httpd # 第一个执行:安装 httpd
yum:
name: httpd
state: present
- name: start httpd # 第二个执行:开启httpd服务
service:
name: httpd
state: started
# 如果看不懂请参考下面的yum模块和service模块
执行结果详解
[root@localhost ~]# ansible-playbook ansiblehttp.yaml
PLAY [install add start http] ***********************************************************
# 表示这个 Playbook 的名称。
TASK [Gathering Facts] ******************************************************************
# 表示执行了一个任务,用于收集主机的基本信息。
ok: [192.168.200.20] # 表示任务在 192.168.200.20 主机上执行成功。
ok: [192.168.200.30] # 表示任务在 192.168.200.30 主机上执行成功。
TASK [install http] *********************************************************************
# 表示执行了一个任务,用于安装 http 服务。
changed: [192.168.200.20]
changed: [192.168.200.30]
TASK [start httpd] **********************************************************************
# 表示执行了一个任务,用于启动 httpd 服务。
changed: [192.168.200.20]
changed: [192.168.200.30]
PLAY RECAP ******************************************************************************
# 表示这个 Playbook 的执行结果摘要。
192.168.200.20 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.200.30 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
# ok=3:表示成功执行了 3 个任务。
# changed=2:表示对 2 个主机进行了修改。
# unreachable=0:表示没有无法连接的主机。
# failed=0:表示没有执行失败的任务。
# skipped=0:表示没有被跳过的任务。
# rescued=0:表示没有被救援的任务。
# ignored=0:表示没有被忽略的任务。
在Ansible中,模块(Module)是指执行某个具体任务的代码实现,为Ansible提供了执行任务的基础。Ansible模块可以实现各种各样的功能,如管理文件、安装软件包、管理用户、启动服务等等
。模块可以使用各种编程语言开发,如Python、PowerShell、Bash脚本等。
Ansible中的模块是按照任务的类型分类的,比如文件模块、系统模块、包管理模块、服务模块等等
。使用模块可以简化Ansible Playbooks的编写,提高了可读性和可维护性。
在命令行中:
例如之前的案例:使用yum模块在远程主机test1上安装httpd包
[root@localhost ~]# ansible test1 -m yum -a "name=httpd state=present"
在Playbook脚本中,tasks中的每一个任务都是对模块的一次调用。在每个任务中:
# 例如上面写的脚本
- name: install add start http
hosts: test1
tasks:
- name: install httpd
yum: # 模块的名字
name: httpd # 调用的参数
state: present # 调用的参数
- name: start httpd
service: # 模块的名字
name: httpd # 调用的参数
state: started # 调用的参数
文件模块
系统模块
包管理模块
服务模块
用户模块
调试和测试类模块
Ansible的ping模块是用于测试远程主机的连通性和认证的模块,可以用来检查Ansible是否能够与远程主机建立连接,以及是否具有足够的权限执行后续任务
。在使用ansible时,ping模块是最常用的模块之一,也是最基本的模块之一。
具体来说,ping模块有以下特点和用法:
ping模块不需要在目标主机上安装任何额外的软件或工具,只需要远程主机具有SSH服务即可。
ping模块使用SSH协议连接远程主机,并执行指定的命令,然后返回结果。
ping模块的返回结果包括两个字段:ping和pong。如果ping字段为pong,则说明连接正常;否则,说明连接失败或认证失败
。
使用命令行来使用该模块
测试所有主机的连通性
[root@localhost ~]# ansible all -m ping
192.168.200.20 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.200.30 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
该命令将对所有主机执行ping操作,并返回结果。可以看到所有主机都返回pong,则说明所有主机都可以正常连接;否则,说明某些主机连接失败。
将上面的命令转为Playbook脚本如下
- name: 测试远程主机连接
hosts: all
tasks:
- name: 测试远程主机连接
ping:
Ansible的debug模块用在命令中输出调试信息。它可以打印任何文本消息或变量的值
选项参数 | 选项解释 |
---|---|
msg | 参数用于输出文本消息。 |
var | 参数用于输出变量的值。 |
打印消息
[root@localhost ~]# ansible all -m debug -a "msg=hello,word"
192.168.200.20 | SUCCESS => {
"msg": "hello,word"
}
192.168.200.30 | SUCCESS => {
"msg": "hello,word"
}
将上面的内容转为Playbook脚本
- name: 打印字符串
hosts: all
tasks:
- name: 打印字符串
debug:
msg: "hello,word"
打印变量
[root@localhost ~]# ansible all -m debug -a "var=my_var" -e "my_var=hello,word"
192.168.200.20 | SUCCESS => {
"my_var": "hello,word"
}
192.168.200.30 | SUCCESS => {
"my_var": "hello,word"
}
将上面的内容转为Playbook脚本
- name: 打印变量
hosts: all
vars:
my_var: "hello,word"
tasks:
- name: 打印变量
debug:
var: my_var
copy模块用于在目标主机上复制文件,从控制主机复制到目标主机。
选项参数 | 选项解释 |
---|---|
src | 源文件路径(本地文件路径) |
dest | 目标文件路径 |
group | 指定目标文件的属组 |
owner | 指定目标文件的属主 |
mode | 指定目标文件的权限(可以是数字也可以是字符) |
backup | 是否备份目标文件 |
validate | 指定验证目标文件的命令或脚本 |
content | 要写入目标文件的内容,可以是字符串或者文件内容 |
设置文件权限
(注意你首先得要有源文件,还得有用户csq才行)
[root@localhost ~]# ansible server -m copy -a "src=/home/csq.txt dest=/tmp/csq.txt owner=csq group=csq mode=0644"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "5d6b664215ea1dafa080ea28a6f4ac2adfb6b320",
"dest": "/tmp/csq.txt",
"gid": 1000,
"group": "csq",
"mode": "0644",
"owner": "csq",
"path": "/tmp/csq.txt",
"size": 10,
"state": "file",
"uid": 1000
}
# 验证一下 可以自己看看
[root@localhost ~]# ansible server -a "ls -al /tmp/csq.txt"
192.168.124.3 | CHANGED | rc=0 >>
-rw-r--r-- 1 csq csq 10 5月 27 09:36 /tmp/csq.txt
将上面的内容转为Playbook为
- hosts: server
tasks:
- name: 设置文件权限
copy:
src: /home/csq.txt
dest: /tmp/csq.txt
owner: csq
group: csq
mode: 0644
备份节点上原来的文件
(backup 参数为yes的时候,如果发生了复制操作,那么先复制目标节点的源文件。如果两个文件相同时,就不会再复制操作,你可以去试试 changed 会显示 false )
[root@localhost ~]# ansible server -m copy -a "src=/etc/sudoers dest=/tmp backup=yes"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "e683ad5e5d8d7112d14924c11c98be7bf2ef4918",
"dest": "/tmp/sudoers",
"gid": 0,
"group": "root",
"md5sum": "1b134d95a4618029ff962a63b021e1ca",
"mode": "0644",
"owner": "root",
"size": 4328,
"src": "/root/.ansible/tmp/ansible-tmp-1685151783.5-76295-265861765397760/source",
"state": "file",
"uid": 0
}
# 测试
[root@localhost ~]# ansible server -a "ls -al /tmp/sudoers"
192.168.124.3 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 4328 5月 27 09:43 /tmp/sudoers
将上面的文件转为Playbook为:
- hosts: server
tasks:
- name: 文件备份
copy:
src: /etc/sudoers
dest: /tmp
backup: yes
复制后的验证操作
(validate 参数接需要验证的命令。一般需要验证复制后的文件,所以 %s 都可以指代复制后的文件。当copy模块中加入了validate参数后,不仅需要成功复制文件,还需要validate命令返回成功的状态,整个模块的执行状态才算成功
)
visudo -cf /etc/sudoers
# 含义是对指定的sudoers文件进行语法检查,以确保sudoers文件中的语法没有错误。
# -c 表示进行语法检查
# -f 选项指定sudoers文件的路径
[root@localhost ~]# ansible server -m copy -a "src=/etc/sudoers dest=/home/sudoers validate='visudo -cf %s'"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "e683ad5e5d8d7112d14924c11c98be7bf2ef4918",
"dest": "/home/sudoers",
"gid": 0,
"group": "root",
"md5sum": "1b134d95a4618029ff962a63b021e1ca",
"mode": "0644",
"owner": "root",
"size": 4328,
"src": "/root/.ansible/tmp/ansible-tmp-1685153548.95-13296-265956376109416/source",
"state": "file",
"uid": 0
}
将上面的例子转为Playbook为:
- hosts: server
tasks:
- name: 复制完成验证文件
copy:
src: /etc/sudoers
dest: /home/
validate: 'visudo -cf %s'
在文件里写入内容
- hosts: server
tasks:
- name: 输入内容
copy:
dest: /home/hello.sh
content: |
#!/bin/bash
echo "hello,word"
# 测试
[root@localhost ~]# ansible server -a "cat /home/hello.sh"
192.168.124.3 | CHANGED | rc=0 >>
#!/bin/bash
echo "hello,word"
我们先来看看template模块的参数有哪些
选项参数 | 选项解释 |
---|---|
src | 源文件路径(本地文件路径) |
dest | 目标文件路径 |
group | 指定目标文件的属组 |
owner | 指定目标文件的属主 |
mode | 指定目标文件的权限(可以是数字也可以是字符) |
backup | 是否备份目标文件 |
validate | 指定验证目标文件的命令或脚本 |
是不是很熟悉,我们可以看到template模块和copy模块几乎一模一样,那么copy模块和template模块有什么区别吗?
template模块和copy模块都可以用于将一个文件从控制节点复制到远程主机上,但它们的实现方式不同。
template模块是先将模板文件中的变量替换为具体的值,然后再将生成的目标文件复制到目标路径中。通俗的说,就是先写好一个模板,然后把模板里的变量替换为实际的值,最后生成一个新的文件。template模块适用于需要根据模板文件生成目标文件的情况。
copy模块则是直接将源文件复制到目标文件中。通俗的说,就是直接把一个文件从控制节点复制到远程主机上。copy模块适用于直接复制文件的情况。
比如安装Apache后,你需要给节点复制一个测试页面index.html。index.html 里面需要显示当前节点的主机名和IP,这时候就需要用到 template
在index.html中,需要指定想替换的是哪个部分,那么整个部分就用变量来标识。
(变量的表示法为:{{ }}
)
index.html 具体应该怎么写?既然是template,那么就加一个后缀来提高可读性,index.html.j2。
my host is {{localhost}} my ip is {{hostIP}}
# 这里博主不会html 所以粗略表示一下
我们设置了两个变量一个表示主机名,一个表示IP,Ansible会替我们搜索,可以直接在Playbook中使用,当然也可也直接在template中使用
[root@localhost ~]# ansible server -m template -a "src=index.html.j2 dest=/var/www/html/index.html" -e "localhost=centos hostIP=192.168.124.3 "
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "f0c7820ed16933325e5c41eb90505635d9595291",
"dest": "/var/www/html/index.html",
"gid": 0,
"group": "root",
"md5sum": "39a33c1a91930f432cc7bca71c8c047d",
"mode": "0644",
"owner": "root",
"size": 42,
"src": "/root/.ansible/tmp/ansible-tmp-1685169366.66-99925-15764606242534/source",
"state": "file",
"uid": 0
}
# 测试
[root@localhost ~]# ansible server -a "cat /var/www/html/index.html"
192.168.124.3 | CHANGED | rc=0 >>
my host is centos my ip is 192.168.124.3
转为Playbook为
- hosts: server
vars:
localhost: centos
hostIP: 192.168.124.3
tasks:
- name: 将带有变量的文件复制到远程主机
template:
src: index.html.j2
dest: /var/www/html/index.html
在Ansible中,file模块用于管理文件和目录,以下是file模块常用的参数及其详解:
选项参数 | 选项解释 |
---|---|
path | 指定要操作的文件路径,可以是绝对路径或相对路径。 |
state | 控制文件的状态,可选值包括[file、directory、hard、link、absent、touch],其中 file:确保路径指向一个普通文件,文件元数据和内容都可以设置。 directory:确保路径指向一个目录,权限和所有权都可以设置。 hard:确保硬链接的存在,可以指定原始文件和目标目录 link:确保符号链接存在,可以指定链接到的目标。 absent:确保路径不存在,被删除或无实际变化的文件不会报错。 touch:确保文件存在,如果不存在则创建之,如果存在则仅更改文件的时间戳。 |
owner | 指定文件所有者的用户名或用户ID。 |
group | 指定文件所属组的组名或组ID。 |
mode | 指定文件或目录的权限,可以使用数字形式或符号形式表示。 |
src | 用于创建符号链接或硬链接时指定原始文件的路径。。需要注意和copy模块的用法不一样 |
dest | 用于创建符号链接或硬链接时指定目标文件的路径。需要注意和copy模块的用法不一样 |
改变文件的权限
[root@localhost ~]# ansible server -m file -a "path=/etc/foo.conf owner=foo group=foo mode=0644"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 1002,
"group": "foo",
"mode": "0644",
"owner": "foo",
"path": "/etc/foo.conf",
"size": 0,
"state": "file",
"uid": 1002
}
# 测试
[root@localhost ~]# ansible server -a "ls -al /etc/foo.conf"
192.168.124.3 | CHANGED | rc=0 >>
-rw-r--r-- 1 foo foo 0 5月 27 16:30 /etc/foo.conf
将上面的例子转为Playbook
- hosts: server
tasks:
- name: 改变文件权限
file:
path: /etc/fooo.conf
owner: foo
group: foo
mode: 0644
创建文件的软链接
[root@localhost ~]# ansible server -m file -a "src=/home/n3 dest=/home/n4 owner=foo group=foo state=link"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/home/n4",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 8,
"src": "/home/n3",
"state": "link",
"uid": 0
}
# 测试
[root@localhost ~]# ansible server -a "ls -al /home/n3 /home/n4"
192.168.124.3 | CHANGED | rc=0 >>
-rw-r--r-- 1 foo foo 0 5月 27 18:00 /home/n3
lrwxrwxrwx 1 root root 8 5月 27 18:00 /home/n4 -> /home/n3
将上面的例子转为Playbook为
- hosts: server
tasks:
- name: 创建符号链接
file:
src: /home/n3
dest: /home/n4
owner: foo
group: foo
state: link
创建一个新文件
[root@localhost ~]# ansible server -m file -a "path=/home/zzzzz state=touch mode=0644"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/home/zzzzz",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
# 测试
[root@localhost ~]# ansible server -a "ls -al /home/zzzzz"
192.168.124.3 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 0 5月 27 18:05 /home/zzzzz
将上面的例子转为Playbook为
- hosts: server
tasks:
- name: 创建一个新文件
file:
path: /home/zzzzz
state: touch
mode: 0644
创建新的文件夹
[root@localhost ~]# ansible server -m file -a "path=/home/csq/zhwdir state=directory mode=755"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/home/csq/zhwdir",
"size": 6,
"state": "directory",
"uid": 0
}
# 测试
[root@localhost ~]# ansible server -a "ls /home/csq/"
192.168.124.3 | CHANGED | rc=0 >>
csq.txt
zhwdir
将上面的例子转为Playbook为
- hosts: server
tasks:
- name: 创建一个目录
file:
path: /home/csq/zhwdir
state: directory
mode: 0755
user模块是用于管理远程主机上面的用户账号。该模块具有的常用参数如下:
选项参数 | 选项解释 |
---|---|
append | 如果是yes,将用户添加到指定组中 |
name | 指定用户名,必需参数。 |
comment | 用户的注释。 |
uid | 用户ID。 |
group | 用户所属组。 |
groups | 用户所属的附加组。 |
home | 用户的主目录路径。 |
shell | 用户的默认shell程序路径。 |
password | 用户的密码(加密后的) |
generate_ssh_key | 如果设置为yes,Ansible会为用户生成SSH密钥。 |
ssh_key_bits | 生成SSH密钥时,指定密钥位数。 |
remove | 如果设置为yes,则删除用户 |
force | 是否强制删除用户 |
move_home | 是否移动用户的主目录 |
state | 用户的状态,可以是present(存在)、absent(不存在)或locked(被锁定)。 |
增加用户
[root@localhost ~]# ansible server -m user -a "name=zzh comment='zzh user' uid=1025 group=csq"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"comment": "zzh user",
"create_home": true,
"group": 1000,
"home": "/home/zzh",
"name": "zzh",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1025
}
# 测试
[root@localhost ~]# ansible server -a "tail -n 1 /etc/passwd"
192.168.124.3 | CHANGED | rc=0 >>
zzh:x:1025:1000:zzh user:/home/zzh:/bin/bash
将上面的例子转为Playbook为
- hosts: server
tasks:
- name: 创建用户
user:
name: zzh
uid: 1025
group: csq
comment: "zzh user"
创建账号添加属组和附加组
[root@localhost ~]# ansible server -m user -a "name=hehe shell=/bin/bash groups=csq,zhw append=yes"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1026,
"groups": "csq,zhw",
"home": "/home/hehe",
"name": "hehe",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1026
}
# 测试
[root@localhost ~]# ansible server -a "tail -n 5 /etc/group"
192.168.124.3 | CHANGED | rc=0 >>
csq:x:1000:csq,hehe
docker:x:981:
zhw:x:1001:hehe
foo:x:1002:
hehe:x:1026:
将上面的例子转为Playbook为
- hosts: server
tasks:
- name: 创建用户属组和附加组
user:
name: hehe
shell: /bin/bash
groups: csq,zhw
append: yes
删除用户
[root@localhost ~]# ansible server -m user -a "name=zzh state=absent remove=yes"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"force": false,
"name": "zzh",
"remove": true,
"state": "absent"
}
# 测试
[root@localhost ~]# ansible server -a "tail -n 4 /etc/passwd"
192.168.124.3 | CHANGED | rc=0 >>
csq:x:1000:1000:csq:/home/csq:/bin/bash
zhw:x:1001:1001::/home/zhw:/bin/bash
foo:x:1002:1002::/home/foo:/bin/bash
hehe:x:1026:1026::/home/hehe:/bin/bash
将上面的例子转为Playbook为
- hosts: server
tasks:
- name: 删除用户
user:
name: zzh
state: absent
remove: yes
修改账号的属性
[root@localhost ~]# ansible server -m user -a "name=foo generate_ssh_key=yes ssh_key_bits=3096 ssh_key_file=.ssh/id_rsa"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"append": false,
"changed": true,
"comment": "",
"group": 1002,
"home": "/home/foo",
"move_home": false,
"name": "foo",
"shell": "/bin/bash",
"ssh_fingerprint": "3096 SHA256:GmuS8A9pXdbbKBIlz82PvuCBPVAUBRu87Qv76ZJptAg ansible-generated on k8s-master-node1 (RSA)",
"ssh_key_file": "/home/foo/.ssh/id_rsa",
"ssh_public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABhADG9bNYn+ZpkjHro6aRh8/VEEJFVJFq60zeGAKVQgbEInnA+kswTpeyatWTGHehbQIhfU9ovuujq7HC/hgGRXFWEQooYBdb12+wk1REjDwM/JyZv+faHzghS0yBWdGaxEw3RCF99CC7c0WSRHK94fjH0bnZZvS4zSOPtm8lOuK0U101mi3fqYatqBdDAT3VC6FOyYyJ1WsmuQ2h8J3hh+LxNx4uoHBxIj1akqICm3vipq1ZT1XTYEQ3znhLOgNGeGdtJ8mUzFtnt5Zk4O+xcG8jpFgUvmXBom6rUxEIDSPgLMFHofsW3z8t72dt53dxnVZ4WFjnAo0eGehmxZJCu9/IKbEcu9HlswOUT5jD4NttKLO5AhQEPPWAKa8QsedSUTpaSMfLk3sM7pepTYaCwKnFYKv+GGi+b/n7idGP7h8XG1iq3Z9/iIh5TVW9WoQTcGO9LSlqA/wqodQhyhCnQPrB4JGuGyWDFI6Wo+9vjILTgV4YMfKOtf46LQJvBj6pvpamcqM= ansible-generated on k8s-master-node1",
"state": "present",
"uid": 1002
}
# 这个就不测试了,很直观就能看到
将上面的例子转为Playbook为
- hosts: server
tasks:
- name: 给用户创建一个3096位的密钥
user:
name: foo
generate_ssh_key: yes
ssh_key_bits: 3096
ssh_key_file: .ssh/id_rsa
管理CentOS和RedHat等Linux系统上的软件包
选项参数 | 选项解释 |
---|---|
name | 要操作的RPM包的名称,可以是单个包的名称或者一个包的列表。 |
state | 要执行的操作类型,可以是present (安装或更新)、absent (卸载)或latest (安装最新版本)。 |
enablerepo | 要启用的仓库的名称或ID |
disablerepo | 要禁用的仓库的名称或ID |
安装最新版本的包,如果版本旧,就更新到最新版本
[root@localhost ~]# ansible server -m yum -a "name=httpd state=latest"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"changes": {
"installed": [
"httpd"
],
"updated": []
},
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: mirrors.cloud.aliyuncs.com\n * extras: mirrors.cloud.aliyuncs.com\n * updates: mirrors.cloud.aliyuncs.com\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-98.el7.centos.7 will be installed\n--> Processing ...
........
........
........
# 安装成功
将上面的例子转为Playbook为
- hosts: server
tasks:
- name: 安装httpd,如果安装了就更新到最新版本
yum:
name: httpd
state: latest
安装指定版本的包
[root@localhost ~]# ansible server -m yum -a "name=httpd-2.4.6-98.el7.centos.7 state=present"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"changes": {
"installed": [
"httpd-2.4.6-98.el7.centos.7"
]
},
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\n * base: mirrors.aliyun.com\n * extras: mirrors.aliyun.com\n * updates: mirrors.aliyun.com\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-98.el7.centos.7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n httpd x86_64 2.4.6-98.el7.centos.7 updates 2.7 M\n\nTransaction Summary\n================================================================================\nInstall.....
........
........
........
# 安装成功
将上面的例子转为Playbook为
- hosts: server
tasks:
- name: 安装httpd指定版本
yum:
name: httpd-2.4.6-98.el7.centos.7
state: present
删除httpd包
[root@localhost ~]# ansible server -m yum -a "name=httpd state=absent"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"changes": {
"removed": [
"httpd"
]
},
"msg": "",
"rc": 0,
"results": [
"已加载插件:fastestmirror, langpacks\n正在解决依赖关系\n--> 正在检查事务\n---> 软件包 httpd.x86_64.0.2.4.6-98.el7.centos.7 将被 删除\n--> 解决依赖关系完成\n\n依赖关系解决\n\n================================================================================\n Package 架构 版本 源 大小\n================================================================================\n正在删除:.....
.......
.......
# 卸载成功
将上面的例子转为Playbook为
- hosts: server
tasks:
- name: 删除httpd包
yum:
name: httpd
state: absent
从指定的repo仓库中安装软件包
[root@localhost ~]# ansible server -m yum -a "name=httpd enablerepo=updates state=present"
192.168.124.3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"changes": {
"installed": [
"httpd"
]
},
"msg": "",
"rc": 0,
"results": [
......
.....
# 安装成功
将上面的例子转为Playbook为
- hosts: server
tasks:
- name: 在指定的repo仓库中下载httpd
yum:
name: httpd
enablerepo: updates
state: present
管理系统服务,如启动、停止、重启、重载等操作
选项参数 | 选项解释 |
---|---|
name | 要操作的系统服务的名称。 |
state | 要执行的操作类型,可以是started (启动)、stopped (停止)、restarted (重新启动)或reloaded (重新加载)。 |
enabled | 是否在系统启动时自动启动服务,默认是yes 。 |
arguments | 启动服务时传递的其他参数 |
sleep | 在执行操作之前等待的时间(秒) |
开启服务
[root@localhost ~]# ansible ailiyun -m service -a "name=httpd state=started"
192.168.100.10 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"name": "httpd",
"state": "started",
.....
.....
将上面的例子转为Playbook为
- hosts: ailiyun
tasks:
- name: 开启httpd服务
service:
name: httpd
state: started
关闭服务
[root@localhost ~]# ansible ailiyun -m service -a "name=httpd state=stopped"
192.168.100.10 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"name": "httpd",
"state": "stopped",
.....
....
将上面的例子转为Playbook为
- hosts: ailiyun
tasks:
- name: 关闭httpd服务
service:
name: httpd
state: stopped
重启服务
[root@localhost ~]# ansible ailiyun -m service -a "name=httpd state=restarted"
将上面的例子转为Playbook为
- hosts: ailiyun
tasks:
- name: 重启httpd服务
service:
name: httpd
state: restarted
设置开启启动服务
[root@localhost ~]# ansible ailiyun -m service -a "name=httpd enabled=yes"
192.168.100.10 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"enabled": true,
"name": "httpd",
.....
.....
将上面的例子转为Playbook为
- hosts: ailiyun
tasks:
- name: 开机自启httpd
service:
name: httpd
enabled: yes
重启 网络服务的 eth0
[root@localhost ~]# ansible ailiyun -m service -a "name=network state=restarted args=eth0"
将上面的例子转为Playbook为
- hosts: ailiyun
tasks:
- name: 重启网络服务并加一条参数
service:
name: httpd
state: restarted
args: eth0
Ansible的firewall模块用于配置Linux系统的防火墙规则,它可以根据指定的参数来添加、修改或删除防火墙规则。下面是firewall模块常用的参数及其详解:
选项参数 | 选项解释 |
---|---|
state | 规则状态,可以是enabled 、disabled 、present 、absent 中的一种。如果是 enabled ,则启用规则;如果是disabled ,则禁用规则;如果是present ,则添加规则;如果是absent ,则删除规则。 |
source | 指定防火墙规则源地址。 |
service | 指定防火墙规则服务。 |
port | 表示要匹配的端口号,可以指定一个或多个端口号。例如,port: 80 表示匹配80端口 |
zone | 用于指定要操作的防火墙区域。 trusted 允许所有数据包 home 拒绝流入的流量,除非与流出的流量相关,允许ssh、mdns、ippclient、amba-client、dhcpv6-client服务通过 internal 等同于home work 拒绝流入的流量,除非与流出的流量相关,允许ssh、ipp-client、dhcpv6-client服务通过 public 拒绝流入的流量,除非与流出的流量相关,允许ssh、dhcpv6-client服务通过 external 拒绝流入的流量,除非与流出的流量相关,允许ssh服务通过 dmz 拒绝流入的流量,除非与流出的流量相关,允许ssh服务通过 block 拒绝流入的流量,除非与流出的流量相关,非法流量采取拒绝操作 drop 拒绝流入的流量,除非与流出的流量相关,废了流量采取丢弃操作 |
interface | 用于指定要操作的网络接口。 |
port | 指定防火墙规则端口。 |
rich_rule | 指定防火墙规则的高级规则。 |
permanent | 是否永久生效,可选值为 yes 、no 。默认为 no |
masquerade | 是否开启防火墙的伪装模式 |
针对 test2 这台主机,添加一个名为 http 的服务到 public 区域,并设置该防火墙规则为永久生效状态
- hosts: test2
tasks:
- name: 为服务添加firewalld规则
firewalld:
service: http
permanent: true
state: enabled
针对 test2 这台主机,添加一个名为 http 的服务到 dmz 区域,并设置该防火墙规则为永久生效状态
- hosts: test2
tasks:
- name: 为服务添加firewalld规则
firewalld:
zone: dmz
service: http
permanent: true
state: enabled
添加端口号 8081 的防火墙规则,并设置规则为永久生效状态,同时将该规则设置为禁用状态
- hosts: test2
tasks:
- name: 为端口号添加firewalld规则
firewalld:
port: 8081/tcp
permanent: true
state: dsiabled
添加 UDP 协议的 161-162 端口范围的防火墙规则,并设置规则为永久生效状态,同时将该规则设置为启用状态
- hosts: test2
tasks:
- name: 为端口号添加firewalld规则
firewalld:
port: 161-162/udp
permanent: true
state: enabled
== test2 主机执行一个任务,该任务是添加一个复杂的防火墙规则,该规则允许允许 ftp 服务通过该防火墙,并限制每分钟只能匹配一次该规则,同时生成审计日志,并将该规则设置为永久生效状态,同时将该规则设置为启用状态==
- hosts: test2
tasks:
- name: 其他复杂的firewalld规则
firewalld:
rich_rule: 'rule service name="ftp" audit limit value="1/m" accept'
permanent: true
state: enabled
对 test2 主机执行一个任务,该任务是添加一个允许来自 192.168.200.0/24 网络的数据包通过 internal 区域的防火墙规则,并将该规则设置为启用状态和永久生效状态
- hosts: test2
tasks:
- name: 其他复杂的firewalld规则
firewalld:
source: 192.168.200.0/24
zone: internal
state: enabled
permanent: true
对 test2 主机执行一个任务,该任务是添加一个允许通过 ens33 网卡的数据包通过 trusted 区域的防火墙规则,并将该规则设置为启用状态和永久生效状态
- hosts: test2
tasks:
- name: 其他复杂的firewalld规则
firewalld:
zone: trusted
interface: ens33
permanent: true
state: enabled
对 test2 主机执行一个任务,该任务是添加一个允许 dmz 区域通过 NAT 网络地址转换的防火墙规则,并将该规则设置为启用状态和永久生效状态
- hosts: test2
tasks:
- name: 其他复杂的firewalld规则
firewalld:
masquerade: yes
state: enabled
permanent: true
zone: dmz
在远程主机上执行 shell 命令
选项参数 | 选项解释 |
---|---|
creates | 要检查的文件路径,如果文件存在,则不会执行命令。 |
chdir | 要执行命令的工作目录。 |
executable | 要执行的命令的路径 |
支持 【$home】【<】【>】【|】【;】【&】
支持$HOME
[root@localhost ~]# ansible test1 -m shell -a "echo 'my home is ${HOME}' > /tmp/test1"
192.168.200.30 | CHANGED | rc=0 >>
192.168.200.20 | CHANGED | rc=0 >>
# 测试
[root@localhost ~]# ansible test1 -m shell -a "cat /tmp/test1"
192.168.200.30 | CHANGED | rc=0 >>
my home is /root
192.168.200.20 | CHANGED | rc=0 >>
my home is /root
将上面的例子转为Playbook为
- hosts: test1
tasks:
- name: 变量输入
shell: echo "my home is ${HOME}" > /tmp/test1
支持 “&&”
[root@localhost ~]# ansible test1 -m shell -a "cd /home && pwd"
192.168.200.20 | CHANGED | rc=0 >>
/home
192.168.200.30 | CHANGED | rc=0 >>
/home
将上面的例子转为Playbook为
- hosts: test1
tasks:
- name: "&&"
shell: cd /home && pwd
调用脚本
[root@localhost ~]# ansible test1 -m shell -a "/root/hello.sh >> hello.log"
192.168.200.20 | CHANGED | rc=0 >>
192.168.200.30 | CHANGED | rc=0 >>
# 测试
[root@localhost ~]# ansible test1 -m shell -a "cat /root/hello.log"
192.168.200.30 | CHANGED | rc=0 >>
Hello World!
192.168.200.20 | CHANGED | rc=0 >>
Hello World!
将上面的例子转为Playbook为
- hosts: test1
tasks:
- name: 脚本执行输出结果调用到hello.log文件里
shell: /root/hello.sh >> hello.log
在执行命令前改变工作目录
[root@localhost ~]# ansible test1 -m shell -a "/root/hello.sh >> hello.log chdir=/home"
192.168.200.30 | CHANGED | rc=0 >>
192.168.200.20 | CHANGED | rc=0 >>
# 测试
[root@localhost ~]# ansible test1 -m shell -a "cat /home/hello.log"
192.168.200.20 | CHANGED | rc=0 >>
Hello World!
192.168.200.30 | CHANGED | rc=0 >>
Hello World!
将上面的例子转为Playbook为
- hosts: test1
tasks:
- name: 在执行脚本前改变工作目录
shell: /root/hello.sh >> hello.log
args:
chdir: /home
在执行命令前改变工作目录,并且仅在文件hello.log 不存在时执行命令
[root@localhost ~]# ansible test1 -m shell -a "/root/hello.sh >> hello.log chdir=/home creates=hello.log"
192.168.200.30 | SUCCESS | rc=0 >>
skipped, since hello.log exists
192.168.200.20 | SUCCESS | rc=0 >>
skipped, since hello.log exists
[root@localhost ~]# ansible test1 -m shell -a "/root/hello.sh >> hello.log chdir=/tmp creates=hello.log"
192.168.200.20 | CHANGED | rc=0 >>
192.168.200.30 | CHANGED | rc=0 >>
# 可以看到/home 目录下存在hello.log 因此他不会做出修改
将上面的例子转为Playbook为
- hosts: test1
tasks:
- name: 在执行脚本前改变工作目录,并且hello.log不存在时才执行命令
shell: /root/hello.sh >> hello.log
args:
chdir: /home
creates: hello.log
指定用bash运行命令
[root@localhost ~]# ansible test1 -m shell -a "cat < /tmp/*txt executable=/bin/bash"
192.168.200.30 | CHANGED | rc=0 >>
bbb
192.168.200.20 | CHANGED | rc=0 >>
aaa
将上面的例子转为Playbook为
- hosts: test1
tasks:
- name: 指定用bash运行命令
shell: /root/hello.sh >> hello.log
args:
executable: /bin/bash #要写绝对路径
在远程节点上执行命令
选项参数 | 选项解释 |
---|---|
chdir | 要执行命令的工作目录。 |
creates | 要检查的文件路径,如果文件存在,则不会执行命令。 |
与shell模块由相同之处
都可以调用单条命令
[root@localhost ~]# ansible test1 -m command -a "ls -al"
192.168.200.30 | CHANGED | rc=0 >>
总用量 32
dr-xr-x---. 4 root root 175 5月 29 16:13 .
dr-xr-xr-x. 17 root root 224 4月 5 20:11 ..
-rw-------. 1 root root 1698 4月 5 20:12 anaconda-ks.cfg
......
.....
192.168.200.20 | CHANGED | rc=0 >>
总用量 36
dr-xr-x---. 4 root root 196 5月 29 16:13 .
dr-xr-xr-x. 17 root root 235 5月 29 16:12 ..
-rw-------. 1 root root 1698 4月 5 20:12 anaconda-ks.cfg
.....
....
将上面的例子转为Playbook为
- hosts: test1
tasks:
- name: 查看当前路径下的所有内容和权限
command: ls -al
都可以执行命令前改变目录,并且某个文件不存在时再执行
[root@localhost ~]# ansible test1 -m command -a "/root/hello.sh chdir=/opt creates=hello.sh"
192.168.200.20 | CHANGED | rc=0 >>
Hello World!
192.168.200.30 | CHANGED | rc=0 >>
Hello World!
将上面的例子转为Playbook为
- hosts: test1
tasks:
- name: 在执行脚本前改变工作目录,并且hello.sh不存在时才执行命令
shell: /root/hello.sh
args:
chdir: /opt
creates: hello.sh
command模块和shell模块不同之处
command模块不支持"&&“和”>>"