Ansible命令可以在一个或多个主机上自动执行单个任务
,临时命令既快速又简单,但是不可重用
例如:放假关闭公司内的所有机器,可以在ansible中执行快速的单行代码,无需编写playbook
Ansible的命令格式
ansible <host-pattern> [options]
# host-pattern:是目标主机的模式,可以是一个主机名、多个主机名、主机组名等。
# options:是可选的命令行选项,用于指定要执行的操作、远程登录用户名、清单文件位置、并行操作数量、sudo权限等。
选项 | 解释 |
---|---|
-m | 指定要执行的模块,例如ping、command、shell等。 |
-a | 指定要传递给模块的参数,例如命令行参数、文件路径等。 |
-u | 指定远程主机的用户名,默认为当前用户。 |
-f | 默认情况下,Ansible 仅同时使用五个进程。 指定并发执行任务的数量,它允许你同时在多个目标主机上并行执行任务,以提高执行效率 |
命令行默认使用的模块是command模块。
检查Ansible安装环境
检查所有的远程主机,是否以“csq”用户创建了Ansible管理主机可以访问的环境
[root@localhost ~]# ansible all -m ping -u csq
重新启动服务器
对名为test
的主机组执行一个命令/sbin/reboot
,并且同时最多有10个任务并发执行
[root@localhost ~]# ansible test -a '/sbin/reboot' -f 10
执行命令
在所有远程主机上,执行“/bin/echo hello”
[root@localhost ~]# ansible all -a "/bin/echo hello"
192.168.200.20 | CHANGED | rc=0 >>
hello
复制文件
复制文件/etc/hosts到远程主机组test,位置为“/tmp/hosts”
[root@localhost ~]# ansible test -m copy -a "src=/etc/hosts dest=/tmp/hosts"
安装包
在远程主机(组)tests上安装yum包
[root@localhost ~]# ansible test -m yum -a "name=httpd state=present"
启动服务
[root@localhost ~]# ansible test -m service -a "name=httpd state=started"
添加用户
[root@localhost ~]# ansible test -m user -a "name=foo password=<设置的密码>"
查看远程主机的全部系统信息
[root@localhost ~]# ansible all -m setup
ansible-config
命令用于查看和修改Ansible的配置文件,即ansible.cfg
。它提供了一种检查和修改Ansible配置选项的方便方式。
ansible-config
命令的一般语法如下:
ansible-config <subcommand> [options]
ansible-config
命令用于查看和修改Ansible的配置文件,即ansible.cfg
。它提供了一种检查和修改Ansible配置选项的方便方式。让我们详细解释一下这个命令。 ansible-config
命令的一般语法如下:
ansible-config <subcommand> [options]
选项:
list:
-c:配置文件的路径,默认为在优先级中找到的第一个文件
-t:过滤到特定的插件类型
view:
-c:同上
-t:同上
dump:
-c:同上
-t:同上
--only-changed:仅显示已更改的配置
init:
-c:同上
-t:同上
--disabled:在所有条目前面加上注释字符以禁用它们
list:列出并输出可用配置
ansible-config list
view:显示当前配置文件
ansible-config view
dump:显示当前设置,如果指定,则合并ansible.cfg
ansible-config dump
init:创建初始配置
ansible-config init
ansible-console
是Ansible的交互式命令行控制台工具,它提供了一个交互式环境,可以在其中执行Ansible模块、命令和Playbook
更多操作查看
man ansible-console
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-galaxy
命令是Ansible的一个用于管理和分享Ansible角色的工具。它提供了一组命令,用于搜索、安装、创建、删除和发布Ansible角色。
常用操作如下:
安装模块
ansible-galaxy collection install 模块
在网站上搜索模块https://galaxy.ansible.com/,如图输入关键字过滤即可,前提要注册一个账号
搜索Ansible角色:
ansible-galaxy search <角色名>
安装Ansible角色:
ansible-galaxy install <作者>.<角色>
安装具有特定版本的Ansible角色:
ansible-galaxy install <作者>.<角色>,<版本号>
创建新的Ansible角色:
ansible-galaxy init <角色名>
删除已安装的Ansible角色:
ansible-galaxy remove <作者>.<角色>
列出已安装的Ansible角色:
ansible-galaxy list
发布Ansible角色到Ansible Galaxy(角色仓库):
ansible-galaxy publish <角色路径>
ansible-galaxy
命令会默认从Ansible Galaxy(https://galaxy.ansible.com/)获取角色,以及本地的角色仓库。您还可以指定其他自定义的角色仓库。
ansible-inventory
是用于生成和管理Ansible的主机清单(inventory)。主机清单是一个包含了运行Ansible操作的目标主机信息的文件,可以是静态文件或动态生成的脚本。
ansible-playbook
命令是用于执行Ansible的Playbook。Playbook是一个包含任务和配置的文本文件,用于定义Ansible的自动化任务和工作流。
常用操作如下:
ansible-playbook --force-handlers
ansible-playbook --become-user <BECOME_USER>
ansible-playbook --step
ansible-playbook --syntax-check
ansible-pull
从远程代码仓库拉取Playbook并为本地主机执行它们
==更多操作查看:man ansible-pull
ansible-vault
用于处理和管理加密的Ansible变量文件。
为了避免重复地输入命令,Ansible可以使用脚本来管理主机。
在 Ansible 中,脚本通常是由 YAML 格式的 Playbook 组成
。Playbook 是一组有序的任务列表,每个任务由一个或多个模块组成。可以根据需要编写自定义模块,也可以使用 Ansible 内置的模块来完成任务。
ansible-playbook service.yaml
Playbook 包含了多个关键字,用于定义任务、变量、条件等。以下是 Ansible Playbook 中常见的关键字列表及其作用:
Ansible Playbook关键字官方文档
hosts
:主机IP或主机组名,或者关键字all
remote_user
:以某个用户身份执行
vars
:变量
tasks
:ansible的核心,定义顺序执行的动作(action),每个动作调用一个ansible模块
action语法:
模块: 模块参数=模块值
handers:Playbook的事件处理操作,有且仅有在被Action触发时才会执行。但多次触发只执行一次,并按照声明的顺序执行
下面是主机(组)test部署Apache的ansiblehttp.yaml文件,部署步骤如下:
(1)先安装firewalld模块
ansible-galaxy collection install ansible.posix
(2)安装Apache包,安装成功后,apache服务会被开启,并且设置开机自启
(3)修改默认的站点文件index.html,写入内容为
(4)设置防火墙开启http服务
[root@localhost ~]# vim ansiblehttp.yaml
- hosts: test
vars: # 变量
myname: csq
remote_user: root
tasks:
- name: install httpd # 安装httpd
yum: name=httpd state=present
notify:
- restart httpd
- name: modify index.html # 修改index.html
shell: echo "name:{{myname}}
" > /usr/share/httpd/noindex/index.html
- name: firewall open service httpd # 开放端口
firewalld: port=80/tcp state=enabled permanent=true
- name: reload firewalld # 重新加载防火墙
shell: firewall-cmd --reload
handlers:
- name: restart httpd
service: name=httpd state=restarted
执行结果详解
[root@localhost ~]# ansible-playbook ansiblehttp.yaml --syntax-check
playbook: ansiblehttp.yaml
[root@localhost ~]# ansible-playbook ansiblehttp.yaml
PLAY [test] ***************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************
ok: [192.168.200.20]
TASK [install httpd] ******************************************************************************************************************
changed: [192.168.200.20]
TASK [modify index.html] **************************************************************************************************************
changed: [192.168.200.20]
TASK [firewall open service httpd] ****************************************************************************************************
changed: [192.168.200.20]
TASK [reload firewalld] ***************************************************************************************************************
changed: [192.168.200.20]
RUNNING HANDLER [restart httpd] *******************************************************************************************************
changed: [192.168.200.20]
PLAY RECAP ****************************************************************************************************************************
192.168.200.20 : ok=6 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Play(剧本)
一个Play是一个包含主机、变量、任务和处理程序的最小执行单位。它定义了在一组主机上执行的操作,可以是安装软件包、配置文件、启动服务等等。
Playbook(剧本集)
一个Playbook是一个包含一个或多个Play的脚本或配置文件
例如:test安装mariadb,test2安装httpd
[root@localhost ~]# vim playandplaybook.yaml
- hosts: test
remote_user: root
tasks:
- name: install mariadb
yum: name=mariadb state=present
- hosts: test2
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
在 Ansible 中,模块指的是 Ansible 提供的用于管理和配置目标主机的工具,它们是 Ansible 发挥功能的基本组件。Ansible 模块是用 Python 编写的可重用的脚本或程序,通过调用远程主机上的 Python 解释器来实现与目标主机的交互。
在命令行中:
例如之前的案例:使用yum模块在远程主机test1上安装httpd包
[root@localhost ~]# ansible test1 -m yum -a "name=httpd state=present"
在Playbook脚本中,tasks中的每一个任务都是对模块的一次调用。在每个任务中:
# 例如上面写的脚本
- hosts: test
remote_user: root
tasks:
- name: install mariadb
yum: name=mariadb state=present
- hosts: test2
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
文件模块
系统模块
包管理模块
服务模块
用户模块
调试和测试类模块
Ansible的ping模块是用于测试远程主机的连通性和认证的模块,可以用来检查Ansible是否能够与远程主机建立连接,以及是否具有足够的权限执行后续任务
。在使用ansible时,ping模块是最常用的模块之一,也是最基本的模块之一。
具体来说,ping模块有以下特点和用法:
ping模块不需要在目标主机上安装任何额外的软件或工具,只需要远程主机具有SSH服务即可。
ping模块使用SSH协议连接远程主机,并执行指定的命令,然后返回结果。
ping模块的返回结果包括两个字段:ping和pong。如果ping字段为pong,则说明连接正常;否则,说明连接失败或认证失败
。
使用命令行来使用该模块
测试所有主机的连通性
[root@localhost ~]# ansible all -m 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模块不支持"&&“和”>>"