ansible

Ansible-3 ansible Ad-Hoc

2020-01-14  本文已影响0人  Habit_1027

场景假设

资产在 /etc/ansible/Inventory目录下
[root@mpn-master Inventory]# ls
web111  web127  web99
[root@mpn-master Inventory]# cat web99
[web99]
10.3.134.99

管理节点:
10.3.134.72

被管理节点(资产):
10.3.134.99
10.3.134.111
10.3.134.127

我们在快速入门中执行的Ansible 命令,类似于我们的批处理命令。在Ansible 中统称为Ansible Ad-Hoc。
其命令语法格式如下:


```shell
ansible pattern [-i inventory] -m module -a argument
pattern, 资产选择器
-i , 指定资产的位置
-m , 指定本次Ansible ad-hoc 要执行的模块。可以类别成SHELL 中的命令。
-a , 模块的参数. 可以类比成SHELL 中的命令参数

Example
// 快速入门的实例

[root@mpn-master Inventory]# ansible all -i web99  -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf"

3.2 模块类型
Ansible 模块分三种类型: 核心模块(core module)、附加模块(extra module)及用户自定义模块(consume module)。
核心模块是由Ansible 的官方团队提供的。
附加模块是由各个社区提供的。例如: OPENSTACK 社区、DOCKER 社区等等。
当核心模块和附加模块都无法满足你的需求时,用户可以自定义模块。

默认情况下,在安装Ansible 的时候, 核心模块和附加模块都已经安装而无需用户干预。

3.3 联机帮助
Ansible 的核心模块和附加模块,数量有1000+ 。这样庞大的模块数量,对于任何一个接触Ansible 的人都不可能将其完全记住、掌握使用。 因此能够顺利使用Ansible 的帮助文档,对我们来说是很有必要的。Ansible 的帮助文档,由
它本身提供的命令 ansible-doc 实现。

常用帮助参数

// 列举出所有的核心模块和附加模块
# ansible-doc -l
// 查询某个模块的使用方法
# ansible-doc modulename
// 查询某个模块的使用方法,比较简洁的信息
# ansible-doc -s modulename

// Example
# ansible-doc yum
# ansible-doc -s yum
3.4 常用模块

command & shell 模块

两个模块都是在远程服务器上去执行命令。但command模块是ad-hoc的默认模块,在执行ad-hoc时,若不指定模块的名字则默认使用此模块.常用参数如下:
command & shell 
- chdir       在运行命令之前,切换到此目录。
- executable  更改用于执行命令的shell(bash,sh),需要是可执行文件的绝对路径。

Example

// ad-hoc 默认在不指定 -m 参数的时候, 使用了默认的command 模块
[root@mpn-master Inventory]# ansible all -i web111 -a "ls /root"
10.3.134.111 | CHANGED | rc=0 >>
anaconda-ks.cfg

[root@mpn-master Inventory]# ansible all -i web111 -m command -a "ls /root"
10.3.134.111 | CHANGED | rc=0 >>
anaconda-ks.cfg   //等同第一个命令
[root@mpn-master Inventory]# ansible all -i web111 -m shell -a "ls /root"
10.3.134.111 | CHANGED | rc=0 >>
anaconda-ks.cfg

两个模块功能类似的模块又存在的必要吗? 他们之间的差异在哪里?
shell   模块可以执行SHELL 的内置命令
command 模块无法执行SHELL 的内置命令
如何检测那些命令是shell 的 内置命令呢?
# type -a set        // set 为SHELL内置命令
set is a shell builtin
# type -a env        // env 非内置命令
env is /bin/env
env is /usr/bin/env

Example

[root@mpn-master Inventory]# ansible all -i localhost, -c local -a "set"
localhost | FAILED | rc=2 >>
[Errno 2] No such file or directory

[root@mpn-master Inventory]# ansible all -i localhost, -c local -m shell -a "set"
localhost | CHANGED | rc=0 >>
BASH=/bin/sh
BASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_EXECUTION_STRING=set
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.2.46(2)-release'
DIRSTACK=()
EUID=0
GROUPS=()
HISTCONTROL=ignoredups
HISTSIZE=1000
HOME=/root
HOSTNAME=mpn-master
HOSTTYPE=x86_64
IFS='   
...
...

script 模块

将管理节点上的脚本传递到远程服务器上进行执行,理论上此模块的执行完全不需要被管理服务器上有Python。

Example

// 管理节点上的一个脚本
[root@mpn-master ~]# cat /root/a.sh
#/bin/sh
ip a

[root@mpn-master ~]# ansible all -i 10.3.134.127, -m script -a "/root/a.sh"
10.3.134.127 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 10.3.134.127 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 10.3.134.127 closed."
    ], 
    "stdout": "1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1\r\n    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\r\n    inet 127.0.0.1/8 scope host lo\r\n       valid_lft forever preferred_lft forever\r\n    inet6 ::1/128 scope host \r\n       valid_lft forever preferred_lft forever\r\n2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000\r\n    link/ether 00:0c:29:40:eb:04 brd ff:ff:ff:ff:ff:ff\r\n    inet 10.3.134.127/24 brd 10.3.134.255 scope global ens32\r\n       valid_lft forever preferred_lft forever\r\n    inet6 fe80::3a71:8c5f:c51:d951/64 scope link \r\n       valid_lft forever preferred_lft forever\r\n", 
    "stdout_lines": [
        "1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1", 
        "    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00", 
        "    inet 127.0.0.1/8 scope host lo", 
        "       valid_lft forever preferred_lft forever", 
        "    inet6 ::1/128 scope host ", 
        "       valid_lft forever preferred_lft forever", 
        "2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000", 
        "    link/ether 00:0c:29:40:eb:04 brd ff:ff:ff:ff:ff:ff", 
        "    inet 10.3.134.127/24 brd 10.3.134.255 scope global ens32", 
        "       valid_lft forever preferred_lft forever", 
        "    inet6 fe80::3a71:8c5f:c51:d951/64 scope link ", 
        "       valid_lft forever preferred_lft forever"
    ]
}

copy 模块

copy 模块的主要用于管理节点和被管理节点之间的文件拷贝。经常使用到的参数如下:
- src    指定拷贝文件的源地址
- dest   指定拷贝文件的目标地址
- backup 拷贝文件前,若原始文件发生变化,则对目标文件进行备份
- woner  指定新拷贝文件的所有者
- group  指定新拷贝文件的所有组
- mode   指定新拷贝文件的权限

Example

Example

// copy 管理节点上的/tmp/a.conf 到被管理节点上
# ansible all -i inventory -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf"
// copy 前, 在被管理节点上对原文件进行备份
# ansible all -i inventory -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf backup=yes"
// copy 文件的同时对文件进行用户及用户组设置
# ansible all -i inventory -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf owner=nobody group=nobody"
// copy 文件的同时对文件进行权限设置
# ansible all -i inventory -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf mode=0755"

service 模块

管理远程节点上的服务。类似于Linux上的service命令。常用参数如下:
– enabled  是否开机启动 yes|no 
– name     必选项,服务名称 
– runlevel 运行级别 
– sleep    如果执行了restarted,在则stop和start之间沉睡几秒钟 
– state    对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)

注意:
使用 service 模块时, enabled 和 state 参数至少要指定一个。
使用 service 模块管理的服务,必须在系统中存在 /etc/init.d/XXX 对应的服务。
比如若管理Nginx 服务,则应该存在 /etc/init.d/nginx

Example

// 启动 Nginx 服务
# ansible all -i web111 -m service -a "name=nginx state=started"
// 关闭 Nginx 服务
# ansible all -i web111 -m service -a "name=nginx state=stopped"
// 重启 Nginx 服务
# ansible all -i web111 -m service -a "name=nginx state=restarted"
// 重新加载 Nginx 服务
# ansible all -i web111 -m service -a "name=nginx state=reloaded"
// 加 Nginx 服务设置开机自启动
# ansible all -i web111 -m service -a "name=nginx enabled=yes"

systemd 模块

管理远程节点上的 systemd 服务,就是由 systemd 所管理的服务。常用参数如下:
- daemon_reload  重新载入 systemd,扫描新的或有变动的单元
– enabled  是否开机启动 yes|no 
– name     必选项,服务名称 
– state    对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)

Example

// 重新加载 systemd
# ansible all -i web111 -m systemd -a "daemon_reload=yes"
// 启动 Mariadb 服务
# ansible all -i web111 -m systemd -a "name=mariadb state=started"
// 关闭 Mariadb 服务
# ansible all -i web111 -m systemd -a "name=mariadb state=stopped"
// 重启 Mariadb 服务
# ansible all -i web111 -m systemd -a "name=mariadb state=restarted"
// 重新加载 Mariadb 服务
# ansible all -i web111 -m systemd -a "name=mariadb state=reloaded"
// 将 Mariadb 服务设置开机自启动
# ansible all -i web111 -m systemd -a "name=mariadb enabled=yes"

yum 模块

等同于 Linux 上的YUM 命令, 对远程服务器上RPM包进行管理。常用参数如下:
- name    要安装的软件包名, 多个软件包以逗号(,) 隔开
- state   对当前指定的软件安装、拆卸操作(present installed latest absent removed)
          安装参数 present installed latest
          拆卸参数 absent removed

Example

// 安装一个软件包
# ansible all -i web111 -m yum -a "name=nginx state=present"
# ansible all -i web111 -m yum -a "name=nginx state=latest"
# ansible all -i web111 -m yum -a "name=nginx state=installed"
// 拆卸一个软件包
# ansible all -i web111 -m yum -a "name=nginx state=absent"
# ansible all -i web111 -m yum -a "name=nginx state=removed"
// 安装一个软件包组
# ansible all -i web111 -m yum -a "name='@Development tools' state=present"

group 模块

在被管理节点上,对组进行管理。 常用参数如下:
- name     组名称, 必须的
- system   是否为系统组, yes/no

Example

// 创建普通组 db_admin
# ansible all -i 10.3.134.127, -m group -a "name=db_admin"

user 模块

用于在被管理节点上对用户进行管理。常用参数如下:
- name  必须的参数, 指定用户名
- password    设置用户的密码,这里接受的是一个加密的值,因为会直接存到 shadow
- update_password  假如设置的密码不同于原密码,则会更新密码. 在 1.3 中被加入
- home        指定用户的家目录
- shell       设置用户的 shell
- uid         指定用户的 UID
- comment     用户的描述信息
- create_home 在创建用户时,是否创建其家目录。默认创建,假如不创建,设置为 no。2.5版本之前 
              使用 createhome
              
- group       设置用户的主组
- groups      将用户加入到多个组中,多个用逗号隔开,也可以是个列表
- system      设置为 yes 时,将会创建一个系统账号
- expires     设置用户的过期时间,值为时间戳,会转为为天数后,放在 shadow 的最后一个字段里
- generate_ssh_key  设置为 yes 将会为用户生成密钥,这不会覆盖原来的密钥
- ssh_key_type 指定用户的密钥类型, 默认 rsa, 具体的类型取决于被管理节点

- remove       当与 state=absent 一起使用,删除一个用户及其家目录,可选的值为: yes/no

Example

// 生成加密的密码
[root@mpn-master Inventory]# echo 123456 | openssl passwd -1 stdin
$1$7Uidt5cm$fLUQin9nBeGKzexHd.wPx/

[root@mpn-master Inventory]# ansible all -i 10.3.134.127, -m user -a "name=dingdang password=$1$7Uidt5cm$fLUQin9nBeGKzexHd.wPx"

10.3.134.127 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "append": false, 
    "changed": true, 
    "comment": "", 
    "group": 1000, 
    "home": "/home/dingdang", 
    "move_home": false, 
    "name": "dingdang", 
    "password": "NOT_LOGGING_PASSWORD", 
    "shell": "/sbin/nologin", 
    "state": "present", 
    "uid": 1000

// 创建一个用户 nginx, 指定其 shell 为 nologin
# ansible all -i web111 -m user  -a "name=nginx shell=/sbin/nologin"
// 创建用户 yangge, 并且为其创建密钥对,并且密钥类型为: ecdsa
# ansible all -i web111 -m user -a "name=yangge generate_ssh_key=yes ssh_key_type=ecdsa"

// 创建用 tom, 并且设置其有效期到 2019年8月16日, 加入到组 db_admin 中
# timestamp=$(date +%s -d 20180725)
// 或者
# timestamp=$(python -c 'import time;print(time.mktime(time.strptime("2019-08-16", "%Y-%m-%d")))')
# ansible all -i 10.3.134.111, -m user -a "name=tom expires=$timestamp"

// 修改已有用户 tom 在 31 天后过期
# ansible all -i 10.3.134.111, -m user -a "name=tom expires=$(echo $((86400 * 31))) groups=db_admin,"

date 命令说明

// 计算 3 小时之后是几点几分
# date +%T -d '3 hours'
// 任意日期的前 N 天,后 N 天的具体日期
# date +%F -d "20190910 1 day"
# date +%F -d "20190910 -1 day"

// 计算两个日期相差天数, 比如计算生日距离现在还有多少天
# d1=$(date +%s -d 20180728)
# d2=$(date +%s -d 20180726)
# echo $(((d1-d2)/86400))

file 模块

file 模块主要用于远程主机上的文件操作,经常使用的模块参数如下: 
- group  定义文件/目录的属组 
- mode   定义文件/目录的权限 
- owner  定义文件/目录的属主 
- path   必选项,定义文件/目录的路径 
- recurse  递归的设置文件的属性,只对目录有效 
- src    要被链接(软/硬)的源文件的路径,只应用于state=link的情况 
- dest   被链接到的路径,只应用于state=link的情况 
- state 
   directory  如果目录不存在,创建目录 
   file       文件不存在,则不会被创建,存在则返回文件的信息,常用于检查文件是否存在。 
   link       创建软链接 
   hard       创建硬链接 
   touch      如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间 
   absent     删除目录、文件或者取消链接文件

Example

// 创建一个文件
# ansible all -i 10.3.134.111,10.3.134.127 -m file -a "path=/tmp/foo.conf state=touch"
// 改变文件所有者及权限
# ansible all -i 10.3.134.111,10.3.134.127 -m file -a "path=/tmp/foo.conf owner=nobody group=nobody mode=0644"
// 创建一个软连接
# ansible all -i 10.3.134.111,10.3.134.127 -m file -a "src=/tmp/foo.conf dest=/tmp/link.conf state=link"
// 创建一个目录
# ansible all -i 10.3.134.111,10.3.134.127 -m file -a "path=/tmp/testdir state=directory"
// 取消一个连接
# ansible all -i 10.3.134.111,10.3.134.127 -m file -a "path=/tmp/link.conf state=absent"
// 删除一个文件
# ansible all -i 10.3.134.111,10.3.134.127 -m file -a "path=/tmp/foo.conf state=absent"

cron 模块

管理远程节点的CRON 服务。等同于Linux 中的CRON。 常用命令如下:
- name   指定一个cron job 的名字。一定要指定,便于日之后删除。
- minute 指定分钟,可以设置成(0-59, *, */2 等)格式。 默认是 * , 也就是每分钟。
- hour   指定小时,可以设置成(0-23, *, */2 等)格式。 默认是 * , 也就是每小时。
- day    指定天,  可以设置成(1-31, *, */2 等)格式。 默认是 * , 也就是每天。
- month  指定月份, 可以设置成(1-12, *, */2 等)格式。 默认是 * , 也就是每周。
- weekday 指定星期, 可以设置成(0-6 for Sunday-Saturday, * 等)格式。默认是 *,也就是每星期。
- job    指定要执行的内容,通常可以写个脚本,或者一段内容。
- state  指定这个job的状态,可以是新增(present)或者是删除(absent)。 默认为新增(present)

Example

// 新建一个 CRON JOB 任务
# ansible all -i 10.3.134.111,10.3.134.127 -m cron -a "name='create new job' minute='0' job='ls -alh > /dev/null'"
// 删除一个 CRON JOB 任务,删除时,一定要正确指定job 的name参数,以免误删除。
# ansible all -i 10.3.134.111,10.3.134.127 -m cron -a "name='create new job' state=absent" 

登录任何一台管理机验证cron

# crontab -l
#Ansible: create new job
0 * * * * ls -alh > /dev/null

debug模块

debug 模块主要用于PlayBook调试时使用,通常的作用是将一个变量的结果打印出来。常用参数如下:
- var 直接打印一个指定的变量值
- msg 打印一段可以格式化的字符串

Example

// 这里引入了变量,我们只需了解 debug 模板的使用即可。在学习变量、剧本时,我们会对它有更深刻的理解。
# ansible all -i 10.3.134.111,10.3.134.127 -m debug -a "var=role" -e "role=web"
# ansible all -i 10.3.134.111,10.3.134.127 -m debug -a "msg='role is {{role}} '" -e "role=web"

template 模块

template 模块使用了Jinjia2格式作为文件模版,可以进行文档内变量的替换。
         它的每次使用都会被ansible标记为”changed”状态。文件以 .j2 结尾
模块常用参数如下:
- backup 创建一个包含时间戳信息的备份文件,这样如果您以某种方式错误地破坏了原始文          件, 就可以将其恢复原状。yes/no
- force  默认值是yes,当内容与源不同时,它将替换远程文件。如果no,仅在目标不存在          时才传输文件。
- src    指定 Ansible 控制端的 文件路径
- dest   指定 Ansible 被控端的 文件路径
- owner  指定文件的属主
- group  指定文件的属组
- mode   指定文件的权限

- newline_sequence 指定新文件的换行符; \n,\r, 或 \r\n

内置变量
ansible_managed - 包含一个字符串,可用于描述模板名称,主机,模板文件的修改时间和所有者的uid
template_host - 包含模板机器的节点名称
template_uid - 所有者的uid
template_path - 模版路径
template_fullpath - 模版的绝对路径
template_run_date - 模版呈现的时间

Example

// 把本地的当前目录下的 jinja2 模板文件 foo.j2 传送到目标机器上,并指定属主为 shark, 属组 为 wheel, 权限为 0644
# ansible all -i 10.3.134.111,10.3.134.127 -m template -a "src=./foo.j2 dest=/tmp/foo.conf owner=shark group=wheel mode=0644"
// 上面的用法其实和 copy 模块一样,下面我们就来介绍 template 模块的强大之处
1. 建立一个 template 文件, 名为 hello_world.j2
# cat hello_world.j2
Hello {{var}} !

2. 执行命令,并且设置变量 var 的值为 world
# ansible all -i 10.3.134.111,10.3.134.127 -m template -a "src=hello_world.j2 dest=/tmp/hello_world.world" -e "var=world"

3. 在被控主机上验证
# cat /tmp/hello_world.world
Hello world !

所有模块列表 https://docs.ansible.com/ansible/latest/modules/list_of_all_modules.html

模块按照首字母排序

上一篇下一篇

猜你喜欢

热点阅读