Ansible四个命令模块
1.组成
command、shell、raw
2.特点
应尽量避免
使用这三个模块
来执行命令,因为其他模块大部分都是幂等性
的,可以自动进行更改跟踪。幂等性
:输入相同,输出相同,无论多少次执行
。比如说确认接口,如果传入订单号,返回确认ok
,如果已经确认过了
,再次调用确认接口,返回如果还是确认ok
,那么这个接口
就是满足幂等性
command、shell、raw不具备幂等性
3.区别
3.1command、shell
模块
- 相同点:要求受管主机上安装
python
- 不同点:
command
可以在受管主机上执行Linux命令
,但是不支持环境变量和操作符(例如'|' '<' '>' '&'
),shell模块
需要调用/bin/sh
指令执行
3.2raw
模块
- 不需要受管主机安装
python
,直接使用远程shell
运行命令,通常用于无法安装python的系统(例如:网络设备等)
4.command
模块
4.1参数表
名称 | 必选 | 备注 |
---|---|---|
chdir | no(不是必选参数) | 运行command命令前先cd到这个目录 |
creates | no | 如果这个参数对应的文件存在,就不运行command |
free_form | yes | 需要执行的脚本(没有真正的参数为free_form) |
executable | no | 改变用来执行命令的shell,是可执行文件的绝对路径 |
removes | no | 如果这个参数对应的文件不存在,就不运行command,与creates参数作用相反 |
stdin | no | 2.4后的新增,将命令的stdin设置为指定的值 |
4.2free_form
参数
必须参数
,指定需要远程执行的命令。
free_form 参数与其他参数(如果想要使用一个参数,那么则需要为这个参数赋值,也就是name=value模式)并不相同。
- 如:需要在
远程主机
上执行ls
命令时,错误
写法:free_form=ls
,因为并没有任何参数
的名字是free_form
,若要在远程主机中执行ls
命令时,直接
写成ls
即可。因为command
模块的作用是执行命令
,所以任何一个可以在远程主机上执行的命令
都可以被称为free_form
- 例:
[root@server ~]# ansible-inventory --graph #分组查看
@all:
|--@ungrouped:
| |--node1.example.com
| |--node2.example.com
[root@server ~]# ansible all -m command -a "ls /root" #查看目录
node2.example.com | CHANGED | rc=0 >>
公共
模板
视频
图片
文档
下载
音乐
桌面
anaconda-ks.cfg
node1.example.com | CHANGED | rc=0 >>
公共
模板
视频
图片
文档
下载
音乐
桌面
anaconda-ks.cfg
frp_0.56.0_linux_amd64
frp_0.56.0_linux_amd64.tar.gz
mysql-8.0.37-linux-glibc2.17-x86_64.tar.xz
[root@server ~]# ansible all -m command -a "cd /"
node2.example.com | CHANGED | rc=0 >>
node1.example.com | CHANGED | rc=0 >>
[root@server ~]# ansible all -m command -a "pwd"
node2.example.com | CHANGED | rc=0 >>
/root
node1.example.com | CHANGED | rc=0 >>
/root
[root@server ~]# ansible all -m command -a "touch file.ansible"
node1.example.com | CHANGED | rc=0 >>
node2.example.com | CHANGED | rc=0 >>
[root@node1 ~]# ls
公共 文档 模板 下载 anaconda-ks.cfg file.ansible
[root@node2 ~]# ls
公共 模板 视频 anaconda-ks.cfg file.ansible
[root@server ~]# ansible all -m command -a "ls /root creates=file.ansible" #当文件file.ansible存在则就不执行前面的命令
node1.example.com | SUCCESS | rc=0 >>
skipped, since file.ansible existsDid not run command since 'file.ansible' exists
node2.example.com | SUCCESS | rc=0 >>
skipped, since file.ansible existsDid not run command since 'file.ansible' exists
[root@server ~]# ansible all -m command -a "ls /root removes=file.ansible" #当文件file.ansible不存在则就不执行前面的命令
node2.example.com | CHANGED | rc=0 >>
公共
模板
视频
图片
文档
下载
音乐
桌面
anaconda-ks.cfg
file.ansible
node1.example.com | CHANGED | rc=0 >>
公共
模板
视频
图片
文档
下载
音乐
桌面
anaconda-ks.cfg
file.ansible
frp_0.56.0_linux_amd64
frp_0.56.0_linux_amd64.tar.gz
mysql-8.0.37-linux-glibc2.17-x86_64.tar.xz
#无法使用管道符和输入输出重定向
[root@server ~]# ansible all -m command -a "echo 'hello world' > file.ansible"
node1.example.com | CHANGED | rc=0 >>
hello world > file.ansible
node2.example.com | CHANGED | rc=0 >>
hello world > file.ansible
[root@server ~]# ansible all -m command -a "cat file.ansible"
node2.example.com | CHANGED | rc=0 >>
node1.example.com | CHANGED | rc=0 >>
[root@server ~]# ansible all -m command -a "ls /root | grep file.ansible"
node2.example.com | FAILED | rc=2 >>
file.ansible
/root:
公共
模板
视频
图片
文档
下载
音乐
桌面
anaconda-ks.cfg
file.ansiblels: 无法访问 '|': 没有那个文件或目录
ls: 无法访问 'grep': 没有那个文件或目录non-zero return code
node1.example.com | FAILED | rc=2 >>
file.ansible
/root:
公共
模板
视频
图片
文档
下载
音乐
桌面
anaconda-ks.cfg
file.ansible
frp_0.56.0_linux_amd64
frp_0.56.0_linux_amd64.tar.gz
mysql-8.0.37-linux-glibc2.17-x86_64.tar.xzls: 无法访问 '|': 没有那个文件或目录
ls: 无法访问 'grep': 没有那个文件或目录non-zero return code
5.shell
模块
5.1作用
-
- 让
远程主机
在shell进程
下执行命令
,从而支持shell的特性
,如管道等
,参数
与command模块
几乎相同,但在执行命令的时候调用
的是/bin/sh
- 让
5.2例如
[root@server ~]# ansible all -m shell -a "tree chdir=/root"
node2.example.com | CHANGED | rc=0 >>
.
├── 公共
├── 模板
├── 视频
├── 图片
├── 文档
├── 下载
├── 音乐
├── 桌面
├── anaconda-ks.cfg
└── file.ansible
8 directories, 2 files
node1.example.com | CHANGED | rc=0 >>
.
├── 公共
├── 模板
├── 视频
├── 图片
├── 文档
├── 下载
├── 音乐
├── 桌面
├── anaconda-ks.cfg
├── file.ansible
├── frp_0.56.0_linux_amd64
│ ├── frpc
│ ├── frpc.toml
│ └── LICENSE
├── frp_0.56.0_linux_amd64.tar.gz
└── mysql-8.0.37-linux-glibc2.17-x86_64.tar.xz
9 directories, 7 files
[root@server ~]# ansible node1.example.com -m shell -a "echo 'hello world' > file.ansible"
node1.example.com | CHANGED | rc=0 >>
[root@server ~]# ansible node1.example.com -m shell -a "cat /root/file.ansible"
node1.example.com | CHANGED | rc=0 >>
hello world
6.script
模块
script
与shell
类似,都可以执行脚本区别
:script
执行的脚本在ansible管理机
上,而shell
执行的脚本必须先放到目标节点
上去,才能执行shell
执行可以使用环境变量
,bash
等,但是script
只是执行.sh
脚本,不能带bash
6.1示例
- 在
server
端写一个t2.sh
的脚本
[root@server ~]# vim t2.sh
#!/bin/bash
echo "hello world"
[root@server ~]# ansible all -m script -a "t2.sh"
node2.example.com | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to node2.example.com closed.\r\n",
"stderr_lines": [
"Shared connection to node2.example.com closed."
],
"stdout": "hello world\r\n",
"stdout_lines": [
"hello world"
]
}
node1.example.com | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to node1.example.com closed.\r\n",
"stderr_lines": [
"Shared connection to node1.example.com closed."
],
"stdout": "hello world\r\n",
"stdout_lines": [
"hello world"
]
}
- 在目标节点上
[root@node1 ~]# vim t2.sh
#!/bin/bash
echo "hello world"
[root@node2 ~]# vim t2.sh
#!/bin/bash
echo "hello world"
[root@server ~]# ansible all -m shell -a "bash t2.sh"
node2.example.com | CHANGED | rc=0 >>
hello world
node1.example.com | CHANGED | rc=0 >>
hello world
7.raw
模块
raw
模块主要用于执行一些低级
的命令,一般适用于下列两种场景
第一种
:在较老的(python2.4和之前的版本
)主机上执行命令第二种
:对任何
没有安装python
的设备(如路由器
)- 注意:在任何
其他情况
下,使用shell
或command
模块更为合适
7.1参数
名称 | 必选 | 备注 |
---|---|---|
executable | no(可以不选) | 改变用来执行命令的shell,是可执行文件的绝对路径 |
free_form | yes | 需要执行的脚本(没有真正的参数为free_form) |
7.2示例
[root@server ~]# ansible all -m raw -a "pwd"
node1.example.com | CHANGED | rc=0 >>
/root
Shared connection to node1.example.com closed.
node2.example.com | CHANGED | rc=0 >>
/root
Shared connection to node2.example.com closed.
[root@server ~]# ansible all -m raw -a "echo 'hello world'"
node1.example.com | CHANGED | rc=0 >>
hello world
Shared connection to node1.example.com closed.
node2.example.com | CHANGED | rc=0 >>
hello world
Shared connection to node2.example.com closed.
文件操作模块
1.file
模块
作用:实现对文件的基本操作
,如:创建
目录或文件,删除
目录或文件,修改文件权限
等
1.1参数
path
:必须参数
,用于指定
要操作的文件
或目录
,在之前版本的ansible
中,使用dest参数
或者name参数
指定要操作的文件或目录
,为了兼容之前的版本
,使用dest
或name
也可以state:
格式
:path=“路径” state= touch | directory | link | hard | absent
此参数
使用灵活,如:在远程主机
中创建一个目录
,则使用path参数
指定对应的目录路径
,假设在远程主机上创建/testdir/a/b
目录,则设置路径:path=/testdir/a/b
,但ansible
无法从/testdir/a/b
这个路径看出b
是一个文件
还是一个目录
,所以需要通过state
参数进行说明
参数 | 值 | 含义 |
---|---|---|
state= | absent | 删除 远程机器上的指定文件 或目录 |
state= | directory | 创建 一个空目录 |
state= | file | 查看 指定目录 是否存在 |
state= | touch | 创建 一个空文件 |
state= | hard/link | 创建 链接文件 |
-
src
:当state
设置为link
或者hard
时,表示创建一个软链
或硬链
,则必须通过指明src参数
即可指定链接源
-
force
: 当state=link
的时,使用force=yes
参数表示强制
创建链接文件
,该文件
分为三种情况
:- 当要创建的
链接文件
指向的源文件
并不存在
时,使用此参数,可以先强制
创建出链接文件
- 当
存储目录
中已经存在
与链接文件
同名的文件
时,会将同名文件
覆盖为链接文件
,相当于删除同名文件
,创建链接文件
- 当你要创建
链接文件
的目录
中已经存在
与链接文件
同名的文件,并且链接文件指向的源文件
也不存在,这时会强制替换
同名文件为链接文件
- 当要创建的
-
owner
:用于指定被操作文件的属主信息
,属主
对应的用户
必须在远程主机中存在
,否则会报错
-
group
:用于指定
被操作文件的属组
,属组
对应的组
必须在远程主机
中存在,否则会报错
-
mode
:用于指定
被操作文件
的权限
,如:- 要将
文件权限
设置为: “rw-r-x---
”,则可以使用mode=650
进行设置,或者使用mode=0650
- 要设置
特殊权限
,如:为二进制文件
设置suid
,则可以使用mode=4700
- 要将
-
recurse
:当要操作的文件
为目录
时,recurse
设置为yes
可以递归
的修改
目录中文件的属性
和权限
1.2示例
- 在所有
远程主机
上创建一个名为data
的目录,如果存在
则不做操作
[root@server ~]# ansible all -m file -a "path=/root/data state=directory"
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/root/data",
"size": 6,
"state": "directory",
"uid": 0
}
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/root/data",
"size": 6,
"state": "directory",
"uid": 0
}
[root@server ~]# ansible all -m command -a "ls chdir=/root"
node1.example.com | CHANGED | rc=0 >>
公共
模板
视频
图片
文档
下载
音乐
桌面
anaconda-ks.cfg
data
file.ansible
frp_0.56.0_linux_amd64
frp_0.56.0_linux_amd64.tar.gz
mysql-8.0.37-linux-glibc2.17-x86_64.tar.xz
t2.sh
node2.example.com | CHANGED | rc=0 >>
公共
模板
视频
图片
文档
下载
音乐
桌面
anaconda-ks.cfg
data
file.ansible
t2.sh
- 在
node1
主机上创建一个名为testfile1
的文件,如果testfile1
文件已经存在,则会更新
文件的时间戳
,与touch
命令的作用相同
[root@server ~]# ansible node1.example.com -m file -a "path=/root/data/testfile1 state=touch"
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/root/data/testfile1",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
[root@server ~]# ansible node1.example.com -m command -a "ls chdir=/root/data"
node1.example.com | CHANGED | rc=0 >>
file1
testfile1
- 在
node1
上为testfile1
文件创建软链接
文件,软链接
名为linkfile1
[root@server ~]# ansible node1.example.com -m file -a "path=/root/data/linkfile1 state=link src=/root/data/testfile1"
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/root/data/linkfile1",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 20,
"src": "/root/data/testfile1",
"state": "link",
"uid": 0
}
[root@server ~]# ansible node1.example.com -m command -a "ls chdir=/root/data"
node1.example.com | CHANGED | rc=0 >>
file1
linkfile1
testfile1
- 在
node1
上为testfile1
文件创建硬链接
文件,硬链接
名为hardfile1
(类似于复制
)
[root@server ~]# ansible node1.example.com -m file -a "path=/root/data/hardfile1 state=hard src=/root/data/testfile1"
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/root/data/hardfile1",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"src": "/root/data/testfile1",
"state": "hard",
"uid": 0
}
[root@server ~]# ansible node1.example.com -m command -a "ls /root/data"
node1.example.com | CHANGED | rc=0 >>
file1
hardfile1
linkfile1
testfile1
- 在创建
链接
文件时,如果源文件
不存在,或者链接文件与其他文件同名
时,强制覆盖同名文件
或者创建链接文件
,参考上述force
参数的解释
[root@server ~]# ansible node1.example.com -m file -a "path=/root/data/linkfile3 state=link src=/root/data/123 force=yes" #注意:123文件不存在
[WARNING]: Cannot set fs attributes on a non-existent symlink target. follow should be
set to False to avoid this.
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/root/data/linkfile3",
"src": "/root/data/123"
}
[root@server ~]# ansible node1.example.com -m command -a "ls chdir=/root/data"
node1.example.com | CHANGED | rc=0 >>
file1
hardfile1
linkfile1
linkfile3
testfile1
- 删除
node1
上的/root/data
目录
[root@server ~]# ansible node1.example.com -m file -a "path=/root/data state=absent"
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"path": "/root/data",
"state": "absent"
}
[root@server ~]# ansible node1.example.com -m command -a "ls chdir=/root"
node1.example.com | CHANGED | rc=0 >>
公共
模板
视频
图片
文档
下载
音乐
桌面
anaconda-ks.cfg
file.ansible
frp_0.56.0_linux_amd64
frp_0.56.0_linux_amd64.tar.gz
mysql-8.0.37-linux-glibc2.17-x86_64.tar.xz
t2.sh
- 创建
文件
或目录
的时候指定属主
,或者修改远程主机
上的文件或目录的属主
[root@server ~]# ansible all -m file -a "path=/root/testfile1 state=touch owner=redhat" #新建文件并指定为属主为redhat,组默认为root
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/root/testfile1",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "redhat",
"size": 0,
"state": "file",
"uid": 1000
}
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/root/testfile1",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "redhat",
"size": 0,
"state": "file",
"uid": 1000
}
[root@server ~]# ansible all -m file -a "path=/root/testfile2 state=touch" #新建文件,默认为root
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/root/testfile2",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/root/testfile2",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
#修改属主和组
[root@server ~]# ansible all -m file -a "path=/root/testfile2 state=touch owner=redhat group=redhat"
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/root/testfile2",
"gid": 1000,
"group": "redhat",
"mode": "0644",
"owner": "redhat",
"size": 0,
"state": "file",
"uid": 1000
}
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/root/testfile2",
"gid": 1000,
"group": "redhat",
"mode": "0644",
"owner": "redhat",
"size": 0,
"state": "file",
"uid": 1000
}
- 创建
文件或目录
的时候指定权限
,或者修改远程主机
上的文件或目录的权限
[root@server ~]# ansible all -m file -a "path=/root/testfile1 state=touch mode=777"
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/root/testfile1",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "redhat",
"size": 0,
"state": "file",
"uid": 1000
}
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/root/testfile1",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "redhat",
"size": 0,
"state": "file",
"uid": 1000
}
递归
方式将目录中的文件
的属主属组
都设置为redhat
[root@server ~]# ansible all -m file -a "path=/data/test/demo state=directory owner=redhat group=redhat recurse=yes"
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"gid": 1000,
"group": "redhat",
"mode": "0755",
"owner": "redhat",
"path": "/data/test/demo",
"size": 6,
"state": "directory",
"uid": 1000
}
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"gid": 1000,
"group": "redhat",
"mode": "0755",
"owner": "redhat",
"path": "/data/test/demo",
"size": 6,
"state": "directory",
"uid": 1000
}
[root@node1 ~]# ll /data/test
总用量 0
drwxr-xr-x 2 redhat redhat 6 7月 7 22:15 demo
[root@node2 ~]# ll /data/test/
总用量 0
drwxr-xr-x 2 redhat redhat 6 7月 7 22:15 demo
2.copy模块
作用:拷贝文件
,将ansible
主机上的文件
拷贝到远程受控
主机中
2.1参数
参数 | 默认值 | 含义 |
---|---|---|
src | 用于指定需要copy 的文件或目录 | |
backup | no,yes | 当远程主机的目标路径中已存在同名文件 ,并且与ansible 主机中的文件内容不同 时,是否对远程主机的文件 进行备份 ,设为yes 时,会先备份远程主机中的文件 ,然后再拷贝 到远程主机 |
content | 当不使用src 指定拷贝的文件时,可以使用content 直接指定文件内容,src 与content 两个参数必有其一,否则会报错 | |
dest | 用于指定文件将被拷贝到远程主机的哪个目录中 ,dest 为必须参数 | |
group | 指定文件 拷贝到远程主机后的属组 ,但是远程主机上 必须有对应的组 ,否则会报错 | |
owner | 指定文件拷贝 到远程主机后的属主 ,但是远程主机上 必须有对应的用户 ,否则会报错 | |
mode | 错文指定 文件拷贝到远程主机 后的权限 ,如果你想将权限设置为"rw-r--r-- ",则可以使用mode=0644 表示,如果你想要在user 对应的权限位上添加执行权限 ,则可以使用mode=u+x 表示 | |
force | no,yes | 当远程主机 的目标路径中已经存在同名文件 ,并且与ansible 主机中的文件内容 不同时,是否强制覆盖 ,默认值为yes ,表示覆盖 ;如果设置为no ,则不会 执行覆盖拷贝 操作,远程主机中的文件保持不变 |
2.2案例
- 将
ansible
主机中/testdir/copytest
文件复制到远程主机的/opt
目录下
[root@server ~]# mkdir /testdir
[root@server ~]# ls /
afs boot etc lib media opt root sbin sys tmp var
bin dev home lib64 mnt proc run srv testdir usr
[root@server ~]# cd /testdir
[root@server testdir]# touch copytest
[root@server testdir]# ls
copytest
[root@server testdir]# cd ~
[root@server ~]# ansible all -m copy -a "src=/testdir/copytest dest=/opt/" #将copytest文件拷贝到/opt目录下
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/opt/copytest",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1720450453.919859-36867-174194189918470/source",
"state": "file",
"uid": 0
}
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/opt/copytest",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1720450453.9200246-36868-113441556515108/source",
"state": "file",
"uid": 0
}
[root@node1 ~]# ls /opt
copytest
[root@node2 ~]# ls /opt
copytest
- 将
ansible
主机中/testdir/copytest
文件修改后
复制到远程主机
的/opt
目录中时,若已存在设置force=no/yes
参数,查看文件是否覆盖
[root@server ~]# echo "hello world" > /testdir/copytest
[root@server ~]# cat /testdir/copytest
hello world
[root@server ~]# ansible all -m copy -a "src=/testdir/copytest dest=/opt force=no" #不会覆盖
node2.example.com | SUCCESS => {
"changed": false,
"dest": "/opt",
"src": "/testdir/copytest"
}
node1.example.com | SUCCESS => {
"changed": false,
"dest": "/opt",
"src": "/testdir/copytest"
}
[root@node1 ~]# cat /opt/copytest
[root@node1 ~]#
[root@node2 ~]# cat /opt/copytest
[root@node2 ~]#
[root@server ~]# ansible all -m copy -a "src=/testdir/copytest dest=/opt/ force=yes" #强制覆盖
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "22596363b3de40b06f981fb85d82312e8c0ed511",
"dest": "/opt/copytest",
"gid": 0,
"group": "root",
"md5sum": "6f5902ac237024bdd0c176cb93063dc4",
"mode": "0644",
"owner": "root",
"size": 12,
"src": "/root/.ansible/tmp/ansible-tmp-1720451177.648205-37031-177158159212978/source",
"state": "file",
"uid": 0
}
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "22596363b3de40b06f981fb85d82312e8c0ed511",
"dest": "/opt/copytest",
"gid": 0,
"group": "root",
"md5sum": "6f5902ac237024bdd0c176cb93063dc4",
"mode": "0644",
"owner": "root",
"size": 12,
"src": "/root/.ansible/tmp/ansible-tmp-1720451177.5918782-37030-264028233882428/source",
"state": "file",
"uid": 0
}
[root@node1 ~]# cat /opt/copytest
hello world
[root@node1 ~]#
[root@node2 ~]# cat /opt/copytest
hello world
[root@node2 ~]#
- 创建
文件编辑内容
:在远程主机的/opt/
目录下生成文件test
,test
文件中有两行文本
,第一行
文本为aaa
,第二行
为bbb
,注意:当使用content
指定文件内容时,dest
参数对应的值必须是一个文本文件
,而不能是一个路径
[root@server ~]# ansible all -m copy -a "content='aaa\nbbb\n' dest=/opt/test"
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "90c206af0bfefa95541d3e724efe1dbc1ed3877f",
"dest": "/opt/test",
"gid": 0,
"group": "root",
"md5sum": "8b652b8c79f357694a04bd793f533c96",
"mode": "0644",
"owner": "root",
"size": 8,
"src": "/root/.ansible/tmp/ansible-tmp-1720453015.187645-37277-130863076749400/source",
"state": "file",
"uid": 0
}
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "90c206af0bfefa95541d3e724efe1dbc1ed3877f",
"dest": "/opt/test",
"gid": 0,
"group": "root",
"md5sum": "8b652b8c79f357694a04bd793f533c96",
"mode": "0644",
"owner": "root",
"size": 8,
"src": "/root/.ansible/tmp/ansible-tmp-1720453015.2046587-37278-148094787612008/source",
"state": "file",
"uid": 0
}
[root@node1 ~]# cat /opt/test
aaa
bbb
[root@node2 ~]# cat /opt/test
aaa
bbb
- 将
ansible
主机中/testdir/copytest
文件复制到远程主机的/opt/
目录中时,若文件同名
但内容不同
则会将远程主机
中的原文件
重命名并备份
,然后再进行拷贝操作
[root@server ~]# ansible all -m copy -a "src=/testdir/copytest dest=/opt backup=yes"
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"backup_file": "/opt/copytest.41315.2024-07-09@00:10:06~",
"changed": true,
"checksum": "64d86bcd5fab0b28323fff9b11570b16138b478f",
"dest": "/opt/copytest",
"gid": 0,
"group": "root",
"md5sum": "e8d4d99f8564d6ae406d93fff6f76c36",
"mode": "0644",
"owner": "root",
"size": 18,
"src": "/root/.ansible/tmp/ansible-tmp-1720455002.0885086-37578-97928856130482/source",
"state": "file",
"uid": 0
}
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"backup_file": "/opt/copytest.43874.2024-07-09@00:10:06~",
"changed": true,
"checksum": "64d86bcd5fab0b28323fff9b11570b16138b478f",
"dest": "/opt/copytest",
"gid": 0,
"group": "root",
"md5sum": "e8d4d99f8564d6ae406d93fff6f76c36",
"mode": "0644",
"owner": "root",
"size": 18,
"src": "/root/.ansible/tmp/ansible-tmp-1720455002.1215124-37577-266110372847425/source",
"state": "file",
"uid": 0
}
[root@node1 ~]# ls /opt
copytest copytest.43874.2024-07-09@00:10:06~ test
[root@node1 ~]# cat /opt/copytest.43874.2024-07-09@00\:10\:06~ #原文件
hello world
[root@node1 ~]# cat /opt/copytest #新文件
hello world
world
[root@node2 ~]# ls /opt
copytest copytest.41315.2024-07-09@00:10:06~ test
[root@node2 ~]# cat /opt/copytest.41315.2024-07-09@00\:10\:06~ #原文件
hello world
[root@node2 ~]# cat /opt/copytest #新文件
hello world
world
拷贝文件
并指定文件属主,属组,权限
,注意:远程主机
上必须存在对应的用户和组
[root@server ~]# ansible all -m copy -a "src=/etc/hosts dest=/mnt owner=redhat group=redhat mode=777"
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "a789c3a6db6b03f0dda3e6c68dc18be4fa2d2c4d",
"dest": "/mnt/hosts",
"gid": 1000,
"group": "redhat",
"md5sum": "6cb2596bad547548ca8bf0652abb0545",
"mode": "0777",
"owner": "redhat",
"size": 146,
"src": "/root/.ansible/tmp/ansible-tmp-1720455574.7210171-37681-271891804338772/source",
"state": "file",
"uid": 1000
}
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "a789c3a6db6b03f0dda3e6c68dc18be4fa2d2c4d",
"dest": "/mnt/hosts",
"gid": 1000,
"group": "redhat",
"md5sum": "6cb2596bad547548ca8bf0652abb0545",
"mode": "0777",
"owner": "redhat",
"size": 146,
"src": "/root/.ansible/tmp/ansible-tmp-1720455574.597354-37680-251426597887287/source",
"state": "file",
"uid": 1000
}
[root@node1 ~]# ll /mnt
总用量 4
-rwxrwxrwx 1 redhat redhat 146 7月 9 00:19 hosts
[root@node2 ~]# ll /mnt
总用量 4
-rwxrwxrwx 1 redhat redhat 146 7月 9 00:19 hosts
- 拷贝文件时,指定
文件的权限
[root@server ~]# ansible all -m copy -a "src=/testdir/copytest dest=/opt mode=0755"
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "64d86bcd5fab0b28323fff9b11570b16138b478f",
"dest": "/opt/copytest",
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/opt/copytest",
"size": 18,
"state": "file",
"uid": 0
}
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"checksum": "64d86bcd5fab0b28323fff9b11570b16138b478f",
"dest": "/opt/copytest",
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/opt/copytest",
"size": 18,
"state": "file",
"uid": 0
}
[root@node1 ~]# ll /opt
总用量 12
-rwxr-xr-x 1 root root 18 7月 9 00:10 copytest
-rw-r--r-- 1 root root 12 7月 8 23:06 copytest.43874.2024-07-09@00:10:06~
-rw-r--r-- 1 root root 8 7月 8 23:36 test
[root@node2 ~]# ll /opt
总用量 12
-rwxr-xr-x 1 root root 18 7月 9 00:10 copytest
-rw-r--r-- 1 root root 12 7月 8 23:06 copytest.41315.2024-07-09@00:10:06~
-rw-r--r-- 1 root root 8 7月 8 23:36 test
3.fetch
模块
作用:拉取
远程主机的文件
,并以主机IP地址
或主机名
为目录
,并保留
了原来
的目录
结构
3.1参数
src
:源地址
dest
:目标地址
flat=yes
:不按照src
的目录来创建目录
3.2案例
- 从
远程节点
上拷贝文件到控制节点
[root@server ~]# ansible node1.example.com -m fetch -a "src=/etc/hosts dest=/opt" #不加flat=yes会将/etc/hosts整个目录结构拉取到/opt目录下
node1.example.com | CHANGED => {
"changed": true,
"checksum": "df4bc9f1931e1a407f339b577ddaef0bd89733fd",
"dest": "/opt/node1.example.com/etc/hosts",
"md5sum": "7f573883c475ca74c1284c99fe60ee4a",
"remote_checksum": "df4bc9f1931e1a407f339b577ddaef0bd89733fd",
"remote_md5sum": null
}
[root@server ~]# ls /opt
node1.example.com
[root@server ~]# ls /opt/node1.example.com/
etc
[root@server ~]# ls /opt/node1.example.com/etc
hosts
[root@server ~]# ansible node2.example.com -m fetch -a "src=/etc/hosts dest=/opt" #不加flat=yes会将/etc/hosts整个目录结构拉取到/opt目录下
node2.example.com | CHANGED => {
"changed": true,
"checksum": "795568e0dc150ac64e6c6fe2fca644129f318cfb",
"dest": "/opt/node2.example.com/etc/hosts",
"md5sum": "2879c33c5c52e6d2623211864c832d84",
"remote_checksum": "795568e0dc150ac64e6c6fe2fca644129f318cfb",
"remote_md5sum": null
}
[root@server ~]# ls /opt
node1.example.com node2.example.com
[root@server ~]# ls /opt/node2.example.com/
etc
[root@server ~]# ls /opt/node2.example.com/etc
hosts
- 不采用默认的文件级结构
[root@server ~]# ansible node1.example.com -m fetch -a "src=/etc/hosts dest=/opt/hosts flat=yes" #加上flat=yes会将/etc/hosts中的hosts文件拉取到/opt目录下并命名为hosts
node1.example.com | CHANGED => {
"changed": true,
"checksum": "df4bc9f1931e1a407f339b577ddaef0bd89733fd",
"dest": "/opt/hosts",
"md5sum": "7f573883c475ca74c1284c99fe60ee4a",
"remote_checksum": "df4bc9f1931e1a407f339b577ddaef0bd89733fd",
"remote_md5sum": null
}
[root@server ~]# ls /opt
hosts node1.example.com node2.example.com
[root@server ~]# cat /opt/hosts
127.0.0.1 node1.example.com
192.168.80.129 server.example.com
192.168.80.130 node1.example.com
192.168.80.131 node2.example.com
[root@server ~]# ansible node1.example.com -m fetch -a "src=/etc/hosts dest=/opt/host flat=yes" #加上flat=yes会将/etc/hosts中的hosts文件拉取到/opt目录下并命名为host
node1.example.com | CHANGED => {
"changed": true,
"checksum": "df4bc9f1931e1a407f339b577ddaef0bd89733fd",
"dest": "/opt/host",
"md5sum": "7f573883c475ca74c1284c99fe60ee4a",
"remote_checksum": "df4bc9f1931e1a407f339b577ddaef0bd89733fd",
"remote_md5sum": null
}
[root@server ~]# ls /opt
host hosts node1.example.com node2.example.com
[root@server ~]# cat /opt/host
127.0.0.1 node1.example.com
192.168.80.129 server.example.com
192.168.80.130 node1.example.com
192.168.80.131 node2.example.com
软件包管理
1.yum/dnf
模块
作用:使用yum
包管理器安装
,升级
,降级
,删除
和列出包和组
1.1参数
-
name
:必须参数
,用于指定需要管理的软件包
,比如nginx
-
state
:用于指定软件包
的状态
安装
:present
或installed
或latest
(安装yum
中最新
的版本)删除
:absent
或removed
-
disable_gpg_check
:用于禁用对rpm
包的公钥gpg
验证disable_gpg_check=no
,为默认值,表示启用
disable_gpg_check=yes
,表示禁用
,即不验证包直接安装注意
:在对应的yum源
没有开启gpg
验证的情况下,需要将此参数的值设置为yes
,否则会报错
而无法进行安装
-
enablerepo
:临时启用
的yum
源。若想要从A源
中安装软件,但不确定A源
是否启用,则可设置为yes
-
disablerepo
:临时禁用
的yum
源。某些场景下需要此参数,如:多个yum
源中同时存在需要安装的软件包时,可以临时禁用某个源,此时安装软件包时则不会从对应的源中选择安装包,enablerepo
和disablerepo
可以同时使用 -
download_only
:yes \ no
,默认no
,只下载,不安装
-
list
:等价于yum list
1.2案例
- 注意:需要删除之前的
repo
文件
[root@server ~]# ansible all -m command -a "ls /etc/yum.repos.d" #查看
node2.example.com | CHANGED | rc=0 >>
redhat.repo
RHELserver.repo
node1.example.com | CHANGED | rc=0 >>
redhat.repo
RHELserver.repo
[root@server ~]# ansible all -m command -a "rm -f /etc/yum.repos.d/redhat_dvd.repo" #都删除
node1.example.com | CHANGED | rc=0 >>
node2.example.com | CHANGED | rc=0 >>
[root@server ~]# ansible all -m command -a "yum clean all" #删除缓存
node2.example.com | CHANGED | rc=0 >>
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
24 文件已删除
node1.example.com | CHANGED | rc=0 >>
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
24 文件已删除
[root@server ~]# ansible all -m command -a "yum makecache" #重新缓存
node2.example.com | CHANGED | rc=0 >>
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
appstream 751 kB/s | 20 MB 00:27
basestream 715 kB/s | 8.2 MB 00:11
上次元数据过期检查:0:00:03 前,执行于 2024年07月10日 星期三 00时14分17秒。
元数据缓存已建立。
node1.example.com | CHANGED | rc=0 >>
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
appstream 757 kB/s | 20 MB 00:26
basestream 680 kB/s | 8.2 MB 00:12
上次元数据过期检查:0:00:03 前,执行于 2024年07月10日 星期三 00时14分18秒。
元数据缓存已建立。
- 安装
[root@server ~]# ansible all -m yum -a "name=httpd disable_gpg_check=yes"
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: mod_http2-2.0.26-2.el9.x86_64",
"Installed: apr-util-1.6.1-23.el9.x86_64",
"Installed: httpd-tools-2.4.57-8.el9.x86_64",
"Installed: apr-util-bdb-1.6.1-23.el9.x86_64",
"Installed: httpd-2.4.57-8.el9.x86_64",
"Installed: mod_lua-2.4.57-8.el9.x86_64",
"Installed: httpd-core-2.4.57-8.el9.x86_64",
"Installed: apr-util-openssl-1.6.1-23.el9.x86_64",
"Installed: centos-logos-httpd-90.8-1.el9.noarch",
"Installed: apr-1.7.0-12.el9.x86_64",
"Installed: httpd-filesystem-2.4.57-8.el9.noarch"
]
}
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: httpd-filesystem-2.4.57-8.el9.noarch",
"Installed: mod_http2-2.0.26-2.el9.x86_64",
"Installed: apr-util-1.6.1-23.el9.x86_64",
"Installed: httpd-tools-2.4.57-8.el9.x86_64",
"Installed: apr-util-bdb-1.6.1-23.el9.x86_64",
"Installed: httpd-2.4.57-8.el9.x86_64",
"Installed: mod_lua-2.4.57-8.el9.x86_64",
"Installed: httpd-core-2.4.57-8.el9.x86_64",
"Installed: apr-util-openssl-1.6.1-23.el9.x86_64",
"Installed: centos-logos-httpd-90.8-1.el9.noarch",
"Installed: apr-1.7.0-12.el9.x86_64"
]
}
[root@server ~]# ansible all -m yum -a "name=ftp state=present"
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: ftp-0.17-89.el9.x86_64"
]
}
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: ftp-0.17-89.el9.x86_64"
]
}
[root@server ~]# ansible all -m dnf -a "name=bind"
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: bind-license-32:9.16.23-15.el9.noarch",
"Installed: bind-32:9.16.23-15.el9.x86_64",
"Installed: python3-bind-32:9.16.23-15.el9.noarch",
"Installed: bind-utils-32:9.16.23-15.el9.x86_64",
"Installed: bind-dnssec-doc-32:9.16.23-15.el9.noarch",
"Installed: bind-dnssec-utils-32:9.16.23-15.el9.x86_64",
"Installed: python3-ply-3.11-14.el9.noarch",
"Installed: bind-libs-32:9.16.23-15.el9.x86_64",
"Removed: bind-libs-32:9.16.23-5.el9_1.x86_64",
"Removed: bind-license-32:9.16.23-5.el9_1.noarch",
"Removed: bind-utils-32:9.16.23-5.el9_1.x86_64"
]
}
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: bind-license-32:9.16.23-15.el9.noarch",
"Installed: bind-32:9.16.23-15.el9.x86_64",
"Installed: python3-bind-32:9.16.23-15.el9.noarch",
"Installed: bind-utils-32:9.16.23-15.el9.x86_64",
"Installed: bind-dnssec-doc-32:9.16.23-15.el9.noarch",
"Installed: bind-dnssec-utils-32:9.16.23-15.el9.x86_64",
"Installed: python3-ply-3.11-14.el9.noarch",
"Installed: bind-libs-32:9.16.23-15.el9.x86_64",
"Removed: bind-libs-32:9.16.23-5.el9_1.x86_64",
"Removed: bind-license-32:9.16.23-5.el9_1.noarch",
"Removed: bind-utils-32:9.16.23-5.el9_1.x86_64"
]
}
[root@node1 ~]# yum list httpd
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:0:00:50 前,执行于 2024年07月10日 星期三 00时28分44秒。
已安装的软件包
httpd.x86_64 2.4.57-8.el9 @app
[root@node1 ~]# yum list ftp
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:0:00:58 前,执行于 2024年07月10日 星期三 00时28分44秒。
已安装的软件包
ftp.x86_64 0.17-89.el9 @app
[root@node1 ~]# yum list bind
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:0:01:07 前,执行于 2024年07月10日 星期三 00时28分44秒。
已安装的软件包
bind.x86_64 32:9.16.23-15.el9 @app
[root@node2 ~]# yum list httpd
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:0:03:48 前,执行于 2024年07月10日 星期三 00时26分11秒。
已安装的软件包
httpd.x86_64 2.4.57-8.el9 @app
[root@node2 ~]# yum list ftp
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:0:03:59 前,执行于 2024年07月10日 星期三 00时26分11秒。
已安装的软件包
ftp.x86_64 0.17-89.el9 @app
[root@node2 ~]# yum list bind
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:0:04:05 前,执行于 2024年07月10日 星期三 00时26分11秒。
已安装的软件包
bind.x86_64 32:9.16.23-15.el9 @app
- 删除
[root@server ~]# ansible all -m yum -a "name=bind,ftp state=removed"
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Removed: bind-32:9.16.23-15.el9.x86_64",
"Removed: ftp-0.17-89.el9.x86_64"
]
}
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Removed: bind-32:9.16.23-15.el9.x86_64",
"Removed: ftp-0.17-89.el9.x86_64"
]
}
[root@node1 ~]# yum list bind
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:0:03:55 前,执行于 2024年07月10日 星期三 00时28分44秒。
可安装的软件包
bind.x86_64 32:9.16.23-15.el9 app
[root@node1 ~]# yum list ftp
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:0:04:08 前,执行于 2024年07月10日 星期三 00时28分44秒。
可安装的软件包
ftp.x86_64 0.17-89.el9 app
[root@node2 ~]# yum list bind
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:0:06:51 前,执行于 2024年07月10日 星期三 00时26分11秒。
可安装的软件包
bind.x86_64 32:9.16.23-15.el9 app
[root@node2 ~]# yum list ftp
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:0:06:56 前,执行于 2024年07月10日 星期三 00时26分11秒。
可安装的软件包
ftp.x86_64 0.17-89.el9 app
- 安装
telnet
时,确定多个源中都有telnet
,但是不想从local源
中安装,则临时禁用local源
[root@server ~]# ansible all -m yum -a "name=telnet disable_gpg_check=yes disablerepo=local"
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: telnet-1:0.17-85.el9.x86_64"
]
}
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Installed: telnet-1:0.17-85.el9.x86_64"
]
}
[root@node1 ~]# yum list telnet
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:0:07:02 前,执行于 2024年07月10日 星期三 00时28分44秒。
已安装的软件包
telnet.x86_64 1:0.17-85.el9 @app
[root@node2 ~]# yum list telnet
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。
上次元数据过期检查:0:09:45 前,执行于 2024年07月10日 星期三 00时26分11秒。
已安装的软件包
telnet.x86_64 1:0.17-85.el9 @app
2.service / systemd
模块
作用:服务程序的管理
2.1参数
参数 | 作用 |
---|---|
name | 操作的服务名称 |
state | 服务状态(started 、stopped 、restarted 、reloaded ) |
enabled | yes 、no 设置开机自启动 |
arguments | 给命令提供一些选项 |
runlevel | 运行等级 |
sleep | 设置停止时间 |
2.2案例
[root@node1 ~]# systemctl status httpd
○ httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: di>
Active: inactive (dead)
Docs: man:httpd.service(8)
[root@node2 ~]# systemctl status httpd
○ httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: di>
Active: inactive (dead)
Docs: man:httpd.service(8)
[root@server ~]# ansible all -m systemd -a "name=httpd state=started enabled=yes"
[root@node1 ~]# systemctl status httpd
○ httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: di>
Active: inactive (dead)
Docs: man:httpd.service(8)
[root@node1 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: dis>
Active: active (running) since Wed 2024-07-10 00:43:05 CST; 1min 5s ago
Docs: man:httpd.service(8)
Main PID: 49549 (httpd)
Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes served/>
Tasks: 177 (limit: 11985)
Memory: 21.9M
CPU: 278ms
CGroup: /system.slice/httpd.service
├─49549 /usr/sbin/httpd -DFOREGROUND
├─49550 /usr/sbin/httpd -DFOREGROUND
├─49551 /usr/sbin/httpd -DFOREGROUND
├─49552 /usr/sbin/httpd -DFOREGROUND
└─49553 /usr/sbin/httpd -DFOREGROUND
7月 10 00:43:05 node1.example.com systemd[1]: Starting The Apache HTTP Server...
7月 10 00:43:05 node1.example.com systemd[1]: Started The Apache HTTP Server.
7月 10 00:43:05 node1.example.com httpd[49549]: Server configured, listening on: port 80
[root@node2 ~]# systemctl status httpd
○ httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: di>
Active: inactive (dead)
Docs: man:httpd.service(8)
[root@node2 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: dis>
Active: active (running) since Wed 2024-07-10 00:43:05 CST; 1min 10s ago
Docs: man:httpd.service(8)
Main PID: 46449 (httpd)
Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes served/>
Tasks: 177 (limit: 11985)
Memory: 23.9M
CPU: 256ms
CGroup: /system.slice/httpd.service
├─46449 /usr/sbin/httpd -DFOREGROUND
├─46450 /usr/sbin/httpd -DFOREGROUND
├─46451 /usr/sbin/httpd -DFOREGROUND
├─46452 /usr/sbin/httpd -DFOREGROUND
└─46453 /usr/sbin/httpd -DFOREGROUND
7月 10 00:43:05 node2.example.com systemd[1]: Starting The Apache HTTP Server...
7月 10 00:43:05 node2.example.com httpd[46449]: Server configured, listening on: port 80
7月 10 00:43:05 node2.example.com systemd[1]: Started The Apache HTTP Server.
压缩
和解压
unarchive
模块
作用:解包解压缩
参数
-
copy
:默认为copy=yes
copy=yes
:将ansible
主机上的压缩包
传到远程主机
后解压缩
至特定目录
copy=no
:不是ansible
主机
-
remote_src
:和copy
功能一样且互斥remote_src=yes
:在远程主机
remote_src=no
:文件在ansible
主机上
-
src
:源路径
,可以是ansible
主机上的路径,也可以是远程主机
上的路径,如果是远程主机上
的路径,则需要设置copy=no
-
dest
:远程主机
上的目标路径
-
mode
:设置解压缩后
的文件权限
-
exec
:列出需要排除
的目录和文件
-
owner
:设置解压的属主
-
group
:设置解压的属组
-
creates
:在创建一个文件之前
,先判断文件
是否存在
,如果存在
则跳过
前面的东西,如果不存在
则执行前面的动作
案例
- 从
本地
解压到远程主机
#server端本地打包,建立实验环境
[root@server ~]# tar -zcvf testroot.tar.gz /root
[root@server ~]# ansible all -m unarchive -a "src=/root/testroot.tar.gz dest=/tmp"
node1.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/tmp",
"extract_results": {
"cmd": [
"/usr/bin/gtar",
"--extract",
"-C",
"/tmp",
"-z",
"-f",
"/root/.ansible/tmp/ansible-tmp-1720544626.3687835-38954-141351106846735/source"
],
"err": "",
"out": "",
"rc": 0
},
"gid": 0,
"group": "root",
"handler": "TgzArchive",
"mode": "01777",
"owner": "root",
"size": 4096,
"src": "/root/.ansible/tmp/ansible-tmp-1720544626.3687835-38954-141351106846735/source",
"state": "directory",
"uid": 0
}
node2.example.com | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"dest": "/tmp",
"extract_results": {
"cmd": [
"/usr/bin/gtar",
"--extract",
"-C",
"/tmp",
"-z",
"-f",
"/root/.ansible/tmp/ansible-tmp-1720544626.3665028-38955-9843957645180/source"
],
"err": "",
"out": "",
"rc": 0
},
"gid": 0,
"group": "root",
"handler": "TgzArchive",
"mode": "01777",
"owner": "root",
"size": 4096,
"src": "/root/.ansible/tmp/ansible-tmp-1720544626.3665028-38955-9843957645180/source",
"state": "directory",
"uid": 0
}
[root@node1 ~]# ls /tmp/root/
公共 视频 文档 音乐 anaconda-ks.cfg t2.sh
模板 图片 下载 桌面 inv testroot.tar.gz
[root@node2 ~]# ls /tmp/root/
公共 视频 文档 音乐 anaconda-ks.cfg t2.sh
模板 图片 下载 桌面 inv testroot.tar.gz
- 从
远程主机
解压到远程主机
制定目录
# 建立实验环境,将上例压缩包copy到远程主机
[root@node2 ~]# ansible all -m copy -a "src=/root/testroot.tar.gz dest=/mnt"
[root@node2 ~]# ansible all -m unarchive -a 'src=/mnt/testroot.tar.gz dest=/usr copy=no mode=0777'
- 从网络下载解压缩
[root@node2 ~]# ansible all -m unarchive -a 'src=http://nginx.org/download/nginx-1.22.0.zip dest=/root copy=no' # 下载Nginx解压到远程主机
[root@node2 ~]# ansible all -m command -a "ls /root"