ansible 自动化
作者:雪豹
归档:学习笔记
2018/09/24
备注:
基础知识
安装环境
服务部署
总结
扩展
第1章 自动化运维工具介绍
系统级别:PXE,Cobbler
提示:PXE 主要使用:dhcp、tftp
系统配置文件:
puppet,saltstack
1.1 运维工具分类:
有agent:puppet,func,saltstack
无agent:ansible
1.2 ansible 介绍
Ansible 简单的说是一个配置管理系统(configuration management system)。你只需要可以使用 ssh 访问你的服务器或设备就行。它也不同于其他工具,因为它使用推送的方式,而不是像 puppet 等 那样使用拉取安装agent的方式。你可以将代码部署到任意数量的服务器上!
1.3 Ansible特性
模块化:调用特定的模块,完成特定任务
有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块
支持自定义模块
基于Python语言实现
部署简单,基于python和SSH(默认已安装),agentless
安全,基于OpenSSH
支持playbook编排任务
幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
无需代理不依赖PKI(无需ssl)
可使用任何编程语言写模块
YAML格式,编排任务,支持丰富的数据结构
较强大的多层解决方案
提示:使用ssh 协议中可以使用:1、基于密钥做免密登录2、使用在inventory 文件中指定账号和密码。
1.4 ansible 架构
1.5 ansible 工作原理
1.6 Ansible主要组成部分功能说明
Ansible:Ansible核心程序。
Host Inventory (因温特瑞) 库存:记录由Ansible管理的主机信息,包括端口、密码、ip等。
Playbooks: (铺累books) play (铺累) 游戏”剧本”YAML格式文件,多个任务定义在一个文件中,定义主机需要调用哪些模块来完成的功能。
Core (酷儿) 核心 Modules(毛tu思) 模块:核心模块,主要操作是通过调用核心模块来完成管理任务。
Custom (看思淡木) 习俗 Modules:自定义模块,完成核心模块无法完成的功能,支持多种语言。
Connection(看乃个深) 连接 Plugins (朴陋跟思 )插件:连接插件,Ansible和Host通信使用
ansible任务执行
ansible任务执行模式
Ansible系统由控制主机对被管节点的操作方式可分为两类,即adhoc和playbook:
ad-hoc模式使用单个模块,支持批量执行单条命令。 ad-hoc 命令是一种可以快速输入的命令,而且不需要保存起来的命令。就相当于bash中的一句话shell。
playbook模式是Ansible主要管理方式,也是Ansible功能强大的关键所在。playbook通过多个task集合完成一类功能,如Web服务的安装部署、数据库服务器的批量备份等。可以简单地把playbook理解为通过组合多条ad-hoc操作作的配置文件。
ansible执行流程
简单理解就是Ansible在运行时,首先读取ansible.cfg中的配置,根据规则获取Inventory中的管理主机列表,并行的在这些主机中执行配置的任务,最后等待执行返回的结果
PLAYBOOKS:
任务剧本(任务集),编排定义Ansible任务集的配置文件,由Ansible顺序依次执行,通常是JSON格式的YML文件
INVENTORY:
Ansible管理主机的清单/etc/anaible/hosts
MODULES:
Ansible执行命令的功能模块,多数为内置的核心模块,也可自定义,ansible-doc –l 可查看模块
PLUGINS:
模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用
API:
供第三方程序调用的应用程序编程接口
ANSIBLE:
组合INVENTORY、 API、 MODULES、PLUGINS的绿框,可以理解为是ansible命令工具,其为核心执行工具
注意事项
执行ansible的主机一般称为主控端,中控,master或堡垒机
主控端Python版本需要2.6或以上
被控端Python版本小于2.4需要安装python-simplejson
被控端如开启SELinux需要安装libselinux-python
windows不能做为主控端
第2章 安装ansible 方法
rpm 安装
2.1 si吃的、eyum 安装
系统环境:centos 7 阿里云yum 源 (如果没有需要下载epel源)
[root@test2 ~]# yum list |grep ansible
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
ansible.noarch 2.3.2.0-2.el7 extras
ansible-doc.noarch 2.3.2.0-2.el7 extras
# 安装
[root@test2 ~]# yum install -y ansible
# 安装后发现 依赖好多python 模块
2.1.1 查看详细配置路径
[root@test2 ~]# rpm -ql ansible|head -20
/etc/ansible
/etc/ansible/ansible.cfg # ansible配置文件
/etc/ansible/hosts # invertory (定义端口 用户)
/etc/ansible/roles
/usr/bin/ansible
/usr/bin/ansible-2
/usr/bin/ansible-2.7
/usr/bin/ansible-config
/usr/bin/ansible-connection
/usr/bin/ansible-console
/usr/bin/ansible-console-2
/usr/bin/ansible-console-2.7
/usr/bin/ansible-doc
/usr/bin/ansible-doc-2
/usr/bin/ansible-doc-2.7
/usr/bin/ansible-galaxy
/usr/bin/ansible-galaxy-2
/usr/bin/ansible-galaxy-2.7
/usr/bin/ansible-inventory
/usr/bin/ansible-playbook
2.2 测试环境准备:
主备三台虚拟机
172.16.1.8
172.16.1.9 做ansible 管理机器
172.16.1.10
2.2.1 登录172.16.1.9 ansible 管理机器
[root@test2 ~]# cd /etc/ansible/
[root@test2 ansible]# ll
total 24
-rw-r--r-- 1 root root 19179 Jan 30 2018 ansible.cfg
-rw-r--r-- 1 root root 1016 Jan 30 2018 hosts
drwxr-xr-x 2 root root 6 Jan 30 2018 roles
# 备份
[root@test2 ansible]# cp hosts hosts.bak
[root@test2 ansible]# ll
total 28
-rw-r--r-- 1 root root 19179 Jan 30 2018 ansible.cfg
-rw-r--r-- 1 root root 1016 Jan 30 2018 hosts
-rw-r--r-- 1 root root 1016 Sep 24 15:23 hosts.bak
drwxr-xr-x 2 root root 6 Jan 30 2018 roles
查看hosts
[root@test2 ansible]# cat hosts
[webserver]
172.16.1.8
[dbserver]
172.16.1.10
2.2.2 hosts配置讲解
# 提示 在hosts 需要写你需要 管理的ansible 的集群,里面有几种写法
2.2.2.1 方法一
## [webservers] #定义的名字
## alpha.example.org # ansible 支持域名,需要有dns 服务器或者 本地hosts 解析
## beta.example.org
## 192.168.1.100 #支持直接写IP
## 192.168.1.110
2.2.2.2 方法二
## www[001:006].example.com # 如果集群主机名称有规律可以用正则写
第3章 使用普通用户分发
准备三台主机
172.16.1.8
172.16.1.9
172.16.1.10
三台主机均创建账号
[root@test1 ~]# useradd adeploy
[root@test1 ~]# echo '123456' |passwd --stdin adeploy
Changing password for user adeploy.
passwd: all authentication tokens updated successfully.
三台电脑都配置sudo 权限
[root@test1 ~]# sed -i '$a\adeploy ALL=(ALL) NOPASSWD: ALL' /etc/sudoers
在ansible 管理机配置公私钥文件
[root@test1 ~]# su - adeploy
[adeploy@test1 ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/adeploy/.ssh/id_rsa):
Created directory '/home/adeploy/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/adeploy/.ssh/id_rsa.
Your public key has been saved in /home/adeploy/.ssh/id_rsa.pub.
The key fingerprint is:
b9:50:99:df:b7:87:9a:50:50:27:ae:f0:0c:54:58:72 adeploy@test1
The key's randomart image is:
+--[ RSA 2048]----+
| o+E o . |
| ..= o o |
| * . . |
| . B + |
| . S = o . |
| . . . . o |
| . . o .|
| . o . |
| o |
分发
[adeploy@test1 ~]$ ssh-copy-id -i 172.16.1.9
3.1 做ssh 免密(先要在管理机)
# 在管理机器 做ssh 免密
[root@test2 ansible]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
3d:e0:49:99:9f:65:66:85:50:6d:0c:f3:31:bb:ac:ca root@test2
The key's randomart image is:
+--[ RSA 2048]----+
| .o+=+ |
| o .+++ |
| = =.o |
| o = * . . |
| S = o |
| . . |
| . |
| . . |
| E |
+-----------------+
[root@test2 ansible]# ssh-copy-id 172.16.1.8
The authenticity of host '172.16.1.8 (172.16.1.8)' can't be established.
ECDSA key fingerprint is d3:32:a8:ba:af:aa:a2:02:f6:71:32:4a:42:6c:3e:4a.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@172.16.1.8's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '172.16.1.8'"
and check to make sure that only the key(s) you wanted were added.
[root@test2 ansible]# ssh-copy-id 172.16.1.10
The authenticity of host '172.16.1.10 (172.16.1.10)' can't be established.
ECDSA key fingerprint is d3:32:a8:ba:af:aa:a2:02:f6:71:32:4a:42:6c:3e:4a.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@172.16.1.10's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '172.16.1.10'"
and check to make sure that only the key(s) you wanted were added.
以下用root用户操作
修改ansible管理机/etc/ansible/ansible.cfg文件
private_key_file = /home/adeploy/.ssh/id_rsa #提示其中adeploy 根据自己用户家目录
修改ansible相关目录的属主(之前是root)
[root@test1 ~]# chown -R adeploy.adeploy /etc/ansible/
[root@test1 ~]# chown -R adeploy.adeploy /usr/share/ansible/
切换到 adeploy 用户
[root@test1 ~]# su - adeploy
Last login: Sun Mar 8 01:44:16 CST 2020 on pts/0
[adeploy@test1 ~]$ cat /etc/ansible/hosts
增加两条测试
[web1]
172.16.1.9
[web2]
172.16.1.10
[adeploy@cg-controller2 playbook]$ cat test.yml
- hosts: all
remote_user: adeploy
become: yes
become_user: root
become_method: sudo
tasks:
- name: test
shell: grep tbj /etc/sudoers
register: result2
- name: Show debug info
debug: var=result2 verbosity=0
become: yes #是否允许身份切换
become_method: su #切换用户身份的方式,有sudo、su、pbrun等方式,默认为sudo
become_user: root #切换指定的用户
3.2 ansible 命令讲解
3.2.1 ansible 命令一查看帮助
[root@test2 ansible]# man ansible-doc
3.2.2 ansible-doc -l 查看支持模块
[root@test2 ansible]# ansible-doc -l
3.2.3 比如查看yum 详细支持
[root@test2 ansible]# ansible-doc -s yum
3.2.4 ansible 基本用法
基本使用语法: -f forks: 启动的并发线程数
-m module_name: 要使用的模块
-a :args; 模块持有的参数。
常见模块:
3.2.5 第一个模块 command 命令(默认模块)
[root@test2 ansible]# ansible 172.16.1.8 -m command -a 'date'
172.16.1.8 | SUCCESS | rc=0 >>
Mon Sep 24 15:49:32 CST 2018
# 提示:dbserver 识别名在ansible 配置文件写的
[root@test2 ansible]# ansible dbserver -m command -a 'date'
172.16.1.10 | SUCCESS | rc=0 >>
Mon Sep 24 15:50:50 CST 2018
# all 全部执行
[root@test2 ansible]# ansible all -m command -a 'date'
172.16.1.10 | SUCCESS | rc=0 >>
Mon Sep 24 15:51:47 CST 2018
172.16.1.8 | SUCCESS | rc=0 >>
Mon Sep 24 15:51:38 CST 2018
提示:1、用远程执行命令,不能执行带变量。2、在执行过程可以省略 ansible 172.16.1.8 -a 'date'(-m 默认添加)
3.2.6 cront 命令(添加定时任务)
[root@test2 ansible]# ansible-doc -s cron
cron:
backup: # If set, create a backup of the crontab before it is modified. The location of the backup is
returned in the `backup_file' variable by this module.
cron_file: # If specified, uses this file instead of an individual user's crontab. If this is a relative
path, it is interpreted with respect to /etc/cron.d. (If it
is absolute, it will typically be /etc/crontab). Many linux
distros expect (and some require) the filename portion to
consist solely of upper- and lower-case letters, digits,
underscores, and hyphens. To use the `cron_file' parameter
you must specify the `user' as well.
day: # Day of the month the job should run ( 1-31, *, */2, etc )
disabled: # If the job should be disabled (commented out) in the crontab. Only has effect if
state=present
env: # If set, manages a crontab's environment variable. New variables are added on top of crontab.
"name" and "value" parameters are the name and the value of
environment variable.
hour: # Hour when the job should run ( 0-23, *, */2, etc )
insertafter: # Used with `state=present' and `env'. If specified, the environment variable will be inserted
after the declaration of specified environment variable.
insertbefore: # Used with `state=present' and `env'. If specified, the environment variable will be inserted
before the declaration of specified environment variable.
job: # The command to execute or, if env is set, the value of environment variable. The command
should not contain line breaks. Required if state=present.
minute: # Minute when the job should run ( 0-59, *, */2, etc )
month: # Month of the year the job should run ( 1-12, *, */2, etc )
name: # Description of a crontab entry or, if env is set, the name of environment variable. Required
if state=absent. Note that if name is not set and
state=present, then a new crontab entry will always be
created, regardless of existing ones.
reboot: # If the job should be run at reboot. This option is deprecated. Users should use
special_time.
special_time: # Special time specification nickname.
state: # Whether to ensure the job or environment variable is present or absent.
user: # The specific user whose crontab should be modified.
weekday: # Day of the week that the job should run ( 0-6 for Sunday-Saturday, *, etc
其中比较重要的:
state:
其中 present (扑弱认特)目前 添加任务
absent (阿布森的) 缺席的 表示移除任务
3.2.6.1 例子:每十分钟执行一个echo hello world
[root@test2 ansible]# ansible 172.16.1.8 -m cron -a 'minute="*/10" job="/usr/bin/echo hello" name="test cront"' # 其中 -m 使用模块 -a 参数 minute 每十分钟 job 指定 任务 name 指定名字 ,本来还有指定state,默认是添加,先不用写。
# 返回结果
172.16.1.8 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"test cront"
]
}
3.2.6.2 检查:
[root@test2 ansible]# ansible 172.16.1.8 -a "crontab -l"
172.16.1.8 | SUCCESS | rc=0 >>
#Ansible: test cront
*/10 * * * * /usr/bin/echo hello
3.2.6.3 移除这个crontab 命令
[root@test2 ansible]# ansible 172.16.1.8 -m cron -a 'minute="*/10" job="/usr/bin/echo hello" name="test cront" state="absent"'
# 输出结果
172.16.1.8 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
[root@test2 ansible]# ansible 172.16.1.8 -a "crontab -l"
172.16.1.8 | SUCCESS | rc=0 >>
3.2.7 user (创建用户命令)
[root@test2 ansible]# ansible all -m user -a 'name="user1"'
172.16.1.8 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 1001,
"home": "/home/user1",
"name": "user1",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1001
}
172.16.1.10 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 1001,
"home": "/home/user1",
"name": "user1",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1001
}
3.2.7.1 删除用户:
[root@test2 ansible]# ansible all -m user -a 'name="user1" state="absent"'
172.16.1.10 | SUCCESS => {
"changed": true,
"force": false,
"name": "user1",
"remove": false,
"state": "absent"
}
172.16.1.8 | SUCCESS => {
"changed": true,
"force": false,
"name": "user1",
"remove": false,
"state": "absent"
}
3.2.8 group 组模块
[root@test2 ansible]# ansible 172.16.1.10 -m group -a 'name="mysql" gid=306 system=yes'
172.16.1.10 | SUCCESS => {
"changed": true,
"gid": 306,
"name": "mysql",
"state": "present",
"system": true
}
# 创建用户和指定组
[root@test2 ansible]# ansible 172.16.1.10 -m user -a 'name=mysql uid=306 system=yes group=mysql'
172.16.1.10 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 306,
"home": "/home/mysql",
"name": "mysql",
"shell": "/bin/bash",
"state": "present",
"system": true,
"uid": 306
}
3.2.9 copy 模块 (文件)
[root@test2 shell]# ansible all -m copy -a 'src=/home/shell/test.sh dest=/home/shell owner=root mode=640'
# 其中 src 是指当前管理机需要分发的文件,或者目录, dest 是集群的指定路径,owner 指定的用户,mode 指定的权限
172.16.1.10 | SUCCESS => {
"changed": true,
"checksum": "4e1243bd22c66e76c2ba9eddc1f91394e57f9f83",
"dest": "/home/shell/test.sh",
"gid": 0,
"group": "root",
"md5sum": "d8e8fca2dc0f896fd7cb4cb0031ba249",
"mode": "0640",
"owner": "root",
"size": 5,
"src": "/root/.ansible/tmp/ansible-tmp-1537778634.53-236653520973956/source",
"state": "file",
"uid": 0
}
172.16.1.8 | SUCCESS => {
"changed": true,
"checksum": "4e1243bd22c66e76c2ba9eddc1f91394e57f9f83",
"dest": "/home/shell/test.sh",
"gid": 0,
"group": "root",
"md5sum": "d8e8fca2dc0f896fd7cb4cb0031ba249",
"mode": "0640",
"owner": "root",
"size": 5,
"src": "/root/.ansible/tmp/ansible-tmp-1537778634.52-233814277329186/source",
"state": "file",
"uid": 0
}
# 检查
[root@test2 shell]# ansible all -a 'ls -lrth /home/shell'
172.16.1.8 | SUCCESS | rc=0 >>
total 4.0K
-rw-r----- 1 root root 5 Sep 24 16:43 test.sh
172.16.1.10 | SUCCESS | rc=0 >>
total 4.0K
-rw-r----- 1 root root 5 Sep 24 16:44 test.sh
3.2.9.1 也可以使用content 将指定的信息成为目标文件
[root@test2 shell]# ansible all -m copy -a 'content="hello Ansibe\nhi linux\n" dest=/home/shell/test.ansible'
172.16.1.10 | SUCCESS => {
"changed": true,
"checksum": "53ce690f3df49645e1ceaf55fdf0ebdfc6438668",
"dest": "/home/shell/test.ansible",
"gid": 0,
"group": "root",
"md5sum": "ee70c71dd291012551eb85552f677d5a",
"mode": "0644",
"owner": "root",
"size": 22,
"src": "/root/.ansible/tmp/ansible-tmp-1537780820.31-6945100634409/source",
"state": "file",
"uid": 0
}
172.16.1.8 | SUCCESS => {
"changed": true,
"checksum": "53ce690f3df49645e1ceaf55fdf0ebdfc6438668",
"dest": "/home/shell/test.ansible",
"gid": 0,
"group": "root",
"md5sum": "ee70c71dd291012551eb85552f677d5a",
"mode": "0644",
"owner": "root",
"size": 22,
"src": "/root/.ansible/tmp/ansible-tmp-1537780820.32-129767783004694/source",
"state": "file",
"uid": 0
}
查看
[root@test1 ~]# cat /home/shell/test.ansible
hello Ansibe
hi linux
3.2.10 file 模块
[root@test2 shell]# ansible all -m file -a 'owner=mysql group=mysql mode=644 path=/home/shell/test.ansible'
# 提示:指定用户 指定组 指定权限 和 路劲
172.16.1.10 | SUCCESS => {
"changed": true,
"gid": 306,
"group": "mysql",
"mode": "0644",
"owner": "mysql",
"path": "/home/shell/test.ansible",
"size": 22,
"state": "file",
"uid": 306
}
# 检查
[root@test3 ~]# ls -lrth /home/shell/
total 8.0K
-rw-r----- 1 root root 5 Sep 24 16:44 test.sh
-rw-r--r-- 1 mysql mysql 22 Sep 24 17:20 test.ansible
3.2.10.1 file创建符号连接
[root@test2 shell]# ansible 172.16.1.10 -m file -a 'path=/home/shell/test2.link src=/home/shell/test.ansible state=link'
# path 连接文件 src 原文件
172.16.1.10 | SUCCESS => {
"changed": true,
"dest": "/home/shell/test2.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 24,
"src": "/home/shell/test.ansible",
"state": "link",
"uid": 0
}
检查
[root@test2 shell]# ansible 172.16.1.10 -a 'ls -lrth /home/shell/'
172.16.1.10 | SUCCESS | rc=0 >>
total 8.0K
-rw-r----- 1 root root 5 Sep 24 16:44 test.sh
-rw-r--r-- 1 mysql mysql 22 Sep 24 17:20 test.ansible
lrwxrwxrwx 1 root root 24 Sep 24 17:31 test2.link -> /home/shell/test.ansible
3.2.11 ping 模块 (测试模块)
#测试主机是否能连接通
[root@test2 shell]# ansible all -m ping
172.16.1.10 | SUCCESS => {
"changed": false,
"ping": "pong"
}
172.16.1.8 | SUCCESS => {
"changed": false,
"ping": "pong"
}
3.2.12 service 模块
指定运行状态
enable= 是否开机自动启动 取值为 true 和false
name= :服务名称
state :状态 取值有 started,stopped,restarted
3.2.13 shell 模块
# 使用复杂用户使用shell
[root@test2 ~]# ansible all -m shell -a 'echo mageedu|passwd --stdin user1'
172.16.1.10 | SUCCESS | rc=0 >>
Changing password for user user1.
passwd: all authentication tokens updated successfully.
172.16.1.8 | SUCCESS | rc=0 >>
Changing password for user user1.
passwd: all authentication tokens updated successfully.
# 查看是否添加密码
[root@test3 ~]# cat /etc/shadow
3.2.14 script 模块
# 将本地模块复制到每台主机执行
[root@test2 ~]# ansible all -m script -a '/home/shell/test.sh'
172.16.1.8 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 172.16.1.8 closed.\r\n",
"stdout": "",
"stdout_lines": []
}
172.16.1.10 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 172.16.1.10 closed.\r\n",
"stdout": "",
"stdout_lines": []
}
附件:执行的测试shell
[root@test2 ~]# cat /home/shell/test.sh
#!/bin/bash
IP=`ip a|grep eth0|sed -n 2p|awk -F/ '{print $1}'|awk -F' ' '{print $2}'`
echo "hello ansible $IP" >/home/test.ansible
总结:1、其实发现调用的每个shell 目录都是自己2、因为我安装的ansible 是2.x系列,如果是1.x 系列需要注意sh 脚本需要当前目录执行。
3.2.15 yum 模块(安装程序包)
3.2.15.1 安装 zsh
[root@test2 ~]# ansible all -m yum -a 'name=zsh'
注意:需要注意 name = 需要安装的程序,可以加版本号,不加为最新包,默认是安装(latest表示安装),absent 表示卸载。
172.16.1.10 | SUCCESS => {
"changed": true,
"msg": "Warning: RPMDB altered outside of yum.\n",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror\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 zsh.x86_64 0:5.0.2-28.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n zsh x86_64 5.0.2-28.el7 base 2.4 M\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 2.4 M\nInstalled size: 5.6 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : zsh-5.0.2-28.el7.x86_64 1/1 \n Verifying : zsh-5.0.2-28.el7.x86_64 1/1 \n\nInstalled:\n zsh.x86_64 0:5.0.2-28.el7 \n\nComplete!\n"
]
}
172.16.1.8 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror\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 zsh.x86_64 0:5.0.2-28.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n zsh x86_64 5.0.2-28.el7 base 2.4 M\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 2.4 M\nInstalled size: 5.6 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : zsh-5.0.2-28.el7.x86_64 1/1 \n Verifying : zsh-5.0.2-28.el7.x86_64 1/1 \n\nInstalled:\n zsh.x86_64 0:5.0.2-28.el7 \n\nComplete!\n"
]
}
# 检查
[root@test2 ~]# ansible all -a 'rpm -qa zsh'
[WARNING]: Consider using yum, dnf or zypper module rather than running rpm
172.16.1.10 | SUCCESS | rc=0 >>
zsh-5.0.2-28.el7.x86_64
172.16.1.8 | SUCCESS | rc=0 >>
zsh-5.0.2-28.el7.x86_64
3.2.15.2 卸载zsh
[root@test2 ~]# ansible all -m yum -a 'name=zsh state=absent'
172.16.1.8 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror\nResolving Dependencies\n--> Running transaction check\n---> Package zsh.x86_64 0:5.0.2-28.el7 will be erased\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nRemoving:\n zsh x86_64 5.0.2-28.el7 @base 5.6 M\n\nTransaction Summary\n================================================================================\nRemove 1 Package\n\nInstalled size: 5.6 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Erasing : zsh-5.0.2-28.el7.x86_64 1/1 \n Verifying : zsh-5.0.2-28.el7.x86_64 1/1 \n\nRemoved:\n zsh.x86_64 0:5.0.2-28.el7 \n\nComplete!\n"
]
}
172.16.1.10 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror\nResolving Dependencies\n--> Running transaction check\n---> Package zsh.x86_64 0:5.0.2-28.el7 will be erased\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nRemoving:\n zsh x86_64 5.0.2-28.el7 @base 5.6 M\n\nTransaction Summary\n================================================================================\nRemove 1 Package\n\nInstalled size: 5.6 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Erasing : zsh-5.0.2-28.el7.x86_64 1/1 \n Verifying : zsh-5.0.2-28.el7.x86_64 1/1 \n\nRemoved:\n zsh.x86_64 0:5.0.2-28.el7 \n\nComplete!\n"
]
}
检查
[root@test2 ~]# ansible all -a 'rpm -qa zsh'
[WARNING]: Consider using yum, dnf or zypper module rather than running rpm
172.16.1.10 | SUCCESS | rc=0 >>
172.16.1.8 | SUCCESS | rc=0 >>
3.3 setup 收集远程主机的facts
每个被管理节点在接收并运行管理命令之前,会将自己主机信息,如操作系统版本,IP地址等报告给远程的ansible 主机。
第4章 ansible YAML
AML是一个类似 XML、JSON 的标记性语言。YAML 强调以数据为中心,并不是以标识语言为重点。因而 YAML 本身的定义比较简单,号称“一种人性化的数据格式语言”。
YAML有以下基本规则:
1、大小写敏感
2、使用缩进表示层级关系
3、禁止使用tab缩进,只能使用空格键
4、缩进长度没有限制,只要元素对齐就表示这些元素属于一个层级。
5、使用#表示注释
6、字符串可以不用引号标注
ansible 中使用的Yaml 基础元素:
变量
inventory
条件测试
迭代
playbookde 组成
tasks:任务,调用模块完成的某操作
variables:变量
templates: 模块
handlers: 处理器,某条件满足时,触发
roles: 角色
一、ansible-playbook介绍:
playbook是由一个或多个”play”组成的列表。play的主要功能在于将事先归为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来将,所谓的task无法是调用ansible的一个module。将多个paly组织在一个playbook中,即可以让他们联通起来按事先编排的机制同唱一台大戏。
1、playbook基础组件:
hosts playbook中的每一个paly的目的都是为了让某个或某些以某个指定用户的身份执行任务。hosts用于指定要执行指定任务的主机,其可以是一个或多个由冒号分割主机组。
user remote_user则用于指定远程主机上的执行任务的用户。
任务列表:
play的主体部分是task list. task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。
action
任务执行过程
handlers
用于当前关注的资源发生变化时采取一定指定的操作
2、实例:
[root@node1 playbook]# cat web.yml
- hosts: test \\主机组,在/etc/ansible/hosts定义
remote_user: root \\远端执行任务的用户
tasks: \\任务
- name: install httpd \\任务描述
command: yum -y install httpd \\调用ansible的command模块安装httpd
- name: provide httpd.conf \\任务描述
copy: src="/root/httpd.conf" dest="/etc/httpd/conf/httpd.conf" \\调用ansible的copy模块,httpd安装完成后将事先准备好的httpd.conf文件复制到/etc/httpd/conf目录下
tags: conf \\给此任务打标记,可单独执行标记的任务,使用 ansible-playbook -C 命令执行
notify: \\文件内容变更通知
- server restart \\通知到指定的任务
- name: server start \\任务描述
service: name=httpd state=started enabled=true \\调用ansible的service模块的属性定义安装完成httpd以后httpd服务的管理
handlers: \\定义接受关注的资源变化后执行的动作
- name: server restart \\任务描述
service: name=httpd state=restarted \\当关注的资源发生变化后调用service模块,采取的响应的动
nginx 例子:
[root@test2 shell]# cat nginx.yml
- hosts: webserver # 定义的主机名
remote_user: root #使用的用户
tasks:
- name: create nginx group #注释
group: name=nginx system=yes gid=208 #使用group 并给传参
- name: create nginx user #注释
user: name=nginx uid=2018 group=nginx system=yes #使用user 用户并传参
执行结果:
[root@test2 shell]# ansible-playbook nginx.yml
PLAY [webserver] ********************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [172.16.1.8]
TASK [create nginx group] ***********************************************************************************************************************
changed: [172.16.1.8]
TASK [create nginx user] ************************************************************************************************************************
changed: [172.16.1.8]
PLAY RECAP **************************************************************************************************************************************
172.16.1.8 : ok=3 changed=2 unreachable=0 failed=0
4.1.1 handlers
例子:nginx 安装
[root@test2 shell]# cat nginx-yum.yml
- hosts: webserver
remote_user: root
tasks:
- name: install -y nginx
yum: name=nginx state=latest
- name: config
copy: src=/home/shell/default.conf dest=/etc/nginx/conf.d/default.conf
notify:
- restart nginx
- name: start nginx
shell: systemctl start nginx
handlers:
- name: restart nginx
shell: systemctl restart nginx
加了注释的无法运行,只供参考
- hosts: webserver # 定义主机名
remote_user: root # 所使用的用户
tasks:
- name: install -y nginx # 注释
yum: name=nginx state=latest # 使用yum 模块安装
- name: config # 注释
copy: src=/home/shell/default.conf dest=/etc/nginx/conf.d/default.conf #使用copy 这个区别是,只要是 default.conf 里面文件修改了
notify:
- restart nginx # 定义的
- name: start nginx # 注释
shell: systemctl start nginx
handlers:
- name: restart nginx # 注释
shell: systemctl restart nginx
4.1.2 vars 变量
[root@test2 shell]# cat nginx-yum.yml
- hosts: webserver
remote_user: root
vars:
- package: nginx
tasks:
- name: install -y nginx
yum: name={{ package }} state=latest
- name: config
copy: src=/home/shell/default.conf dest=/etc/nginx/conf.d/default.conf
notify:
- restart nginx
- name: start nginx
shell: systemctl start nginx
handlers:
- name: restart nginx
shell: systemctl restart nginx
提示:其中一定要用 {{
4.1.3 when 条件判断语句
[root@test2 shell]# cat when.yml
- hosts: all
remote_user: root
vars:
- xue: test8
tasks:
- name: when test
shell: echo {{ xue }} >> /home/when.txt
when: ansible_nodename == "test1"
4.1.4 迭代机制
重复执行task 使用
调用使用 item 定义循环列表 when_items
nsible-playbook web.yml --syntax-check #检查语法
ansible-playbook web.yml #执行
4.1.5 template
4.1.6 tags
在playbook 可以在某些任务可以定义标签,可以执行此playbook时,通过为ansible-playbook 命令使用--tags选项实现仅指定的tasks 而非所有的。
例子:
[root@test2 shell]# cat template.yml
- hosts: webserver
remote_user: root
tasks:
- name: test shell
shell: echo {{ ansible_nodename }} > /home/test.hosts
tags:
- conf
- name: ip test
shell: echp {{ ansible_all_ipv4_addresses }} > /home/iptest.hosts
执行过程
[root@test2 shell]# ansible-playbook --tags="conf" template.yml
PLAY [webserver] ********************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************
ok: [172.16.1.8]
TASK [test shell] *******************************************************************************************************************************
changed: [172.16.1.8]
PLAY RECAP **************************************************************************************************************************************
172.16.1.8 : ok=2 changed=1 unreachable=0 failed=0
特殊tags: always
4.1.7 roles
ansible从1.2 版本引入的新的特性,用于层次性,结构化本地组织playbook,roles能够根据层次型结构自动装载变量文件、tasks 以及handers等。 要使用roles 只需要在playbook 中使用include 指令即可。
简单来说,roles 就是通过将变量,文件,任务,模块及处理器放置于单独的目录中,并可以方便的include他们的一种机制,角色一般用于基于主机构建服务的场景中,但也可以用于构建守护进程等场景中。
创建目录
[root@test2 shell]# mkdir -pv /home/ansible_playbooks/roles/{webserver,dbserver}/{tasks,files,templates,meta,handlers,vars}
mkdir: created directory ‘/home/ansible_playbooks/roles/webserver/tasks’
mkdir: created directory ‘/home/ansible_playbooks/roles/webserver/files’
mkdir: created directory ‘/home/ansible_playbooks/roles/webserver/templates’
mkdir: created directory ‘/home/ansible_playbooks/roles/webserver/meta’
mkdir: created directory ‘/home/ansible_playbooks/roles/webserver/handlers’
mkdir: created directory ‘/home/ansible_playbooks/roles/webserver/vars’
mkdir: created directory ‘/home/ansible_playbooks/roles/dbserver/tasks’
mkdir: created directory ‘/home/ansible_playbooks/roles/dbserver/files’
mkdir: created directory ‘/home/ansible_playbooks/roles/dbserver/templates’
mkdir: created directory ‘/home/ansible_playbooks/roles/dbserver/meta’
mkdir: created directory ‘/home/ansible_playbooks/roles/dbserver/handlers’
mkdir: created directory ‘/home/ansible_playbooks/roles/dbserver/vars’
有需要可以联系微信xuebao19930721和加入微信群