Ansible常用模块

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参数表

名称必选备注
chdirno(不是必选参数)运行command命令前先cd到这个目录
createsno如果这个参数对应的文件存在,就不运行command
free_formyes需要执行的脚本(没有真正的参数为free_form)
executableno改变用来执行命令的shell,是可执行文件的绝对路径
removesno如果这个参数对应的文件不存在,就不运行command,与creates参数作用相反
stdinno2.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模块

  • scriptshell 类似,都可以执行脚本
  • 区别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的设备(如路由器
  • 注意:在任何其他情况下,使用shellcommand模块更为合适

7.1参数

名称必选备注
executableno(可以不选)改变用来执行命令的shell,是可执行文件的绝对路径
free_formyes需要执行的脚本(没有真正的参数为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参数指定要操作的文件或目录,为了兼容之前的版本,使用destname也可以
  • 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  77 22:15 demo



[root@node2 ~]# ll /data/test/
总用量 0
drwxr-xr-x 2 redhat redhat 6  77 22:15 demo

2.copy模块

作用:拷贝文件,将ansible主机上的文件拷贝到远程受控主机中

2.1参数

参数默认值含义
src用于指定需要copy文件或目录
backupno,yes当远程主机的目标路径中已存在同名文件,并且与ansible主机中的文件内容不同时,是否对远程主机的文件进行备份,设为yes时,会先备份远程主机中的文件,然后再拷贝远程主机
content当不使用src指定拷贝的文件时,可以使用content直接指定文件内容,srccontent两个参数必有其一,否则会报错
dest用于指定文件将被拷贝到远程主机的哪个目录中dest必须参数
group指定文件拷贝到远程主机后的属组,但是远程主机上必须有对应的组,否则会报错
owner指定文件拷贝到远程主机后的属主,但是远程主机上必须有对应的用户,否则会报错
mode错文指定文件拷贝到远程主机后的权限,如果你想将权限设置为"rw-r--r--",则可以使用mode=0644表示,如果你想要在user对应的权限位上添加执行权限,则可以使用mode=u+x表示
forceno,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/目录下生成文件testtest文件中有两行文本第一行文本为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  79 00:19 hosts



[root@node2 ~]# ll /mnt
总用量 4
-rwxrwxrwx  1 redhat redhat 146  79 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  79 00:10 copytest
-rw-r--r-- 1 root root 12  78 23:06 copytest.43874.2024-07-09@00:10:06~
-rw-r--r-- 1 root root  8  78 23:36 test



[root@node2 ~]# ll /opt
总用量 12
-rwxr-xr-x 1 root root 18  79 00:10 copytest
-rw-r--r-- 1 root root 12  78 23:06 copytest.41315.2024-07-09@00:10:06~
-rw-r--r-- 1 root root  8  78 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:用于指定软件包状态

    • 安装presentinstalledlatest(安装yum最新的版本)
    • 删除absentremoved
  • disable_gpg_check:用于禁用对rpm包的公钥gpg验证

    • disable_gpg_check=no,为默认值,表示启用
    • disable_gpg_check=yes,表示禁用,即不验证包直接安装
    • 注意:在对应的yum源没有开启 gpg 验证的情况下,需要将此参数的值设置为 yes,否则会报错无法进行安装
  • enablerepo临时启用yum源。若想要从A源中安装软件,但不确定A源是否启用,则可设置为 yes

  • disablerepo临时禁用yum源。某些场景下需要此参数,如:多个yum源中同时存在需要安装的软件包时,可以临时禁用某个源,此时安装软件包时则不会从对应的源中选择安装包,enablerepodisablerepo 可以同时使用

  • download_onlyyes \ 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服务状态(startedstoppedrestartedreloaded
enabledyesno 设置开机自启动
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

710 00:43:05 node2.example.com systemd[1]: Starting The Apache HTTP Server...
710 00:43:05 node2.example.com httpd[46449]: Server configured, listening on: port 80
710 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"
  • 37
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

^~^前行者~~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值