ansible基础篇_缓存

  • 1.主机清单语法,学会如何批量管理服务器组,配置服务器认证,服务器变量
  • 2.学习常见的模块,语法,参数,用法
  • 3.改造shell脚本为ansible模块
yum install rsync -y
yum remove rsync -y
这个shell命令就得转变为ansible的模块操作, yum模块,提供参数

useradd yiyuan
简单的linux命令,转变为ansible的模块操作
users模块,提供一些参数,用户名的名字,用户的uid,以及用户的过期时间等

自动化运维好处

  • 提高工作效率,减少重复性工作
  • 大大减少人为出错的可能性
  • 数据化管理、数据化汇报、问题可追溯
ansible
saltstack
这俩自动化运维工具

master-61机器,管理了100台目标机器
指标
shell 脚本结合for循环处理这100个机器
每一个指标就是每一个命令
free -m > xxx.file
cpuinfo

shell,命令导出的数据就是一堆普通的文本字符串,难以加工处理
如果能导出为数据交换格式,如json,如yaml,如xml就可以很轻松的发给各种编程语言,实现数据加工,格式化处理,发给前端去做网页展示

ansible几条命令就可以实现了
并且
ansible导出的服务器信息,如内存,磁盘,网卡,等等一堆信息,可以直接导出为json数据
json数据就可以直接发给前端,前端就可以展示出服务器的信息

这就是运维开发做的事
后端python+ansible获取数据,导出json,发给前端
前端写html,js,对json数据展示

运维平台就出来了
1.打开ansible官网,查看所有最新的功能,不要看其他的文档,可能已经很陈旧了,python3也已经更新了很多,导致用法变化等。
https://docs.ansible.com/ansible/latest/
最新官网文档

nfs服务
rsync服务

shell脚本,堆砌了各种部署的命令
↓
把这个脚本,所有的操作,全部替换为ansible的模块

2.你可能要执行的各种命令,ansible都提供了模块,如文件拷贝,如软件安装,服务重启等;
3.你使用ansible,必须严格按照ansible提供的语法来,否则只有报错
4.先学语法,语法基本功扎实后,面对千变万化的需求,才能游刃有余
5.多动手,ansible需要记忆的操作比较多

一.ansible安装部署

在master-61管理机安装

yum install epel-release ansible libselinux-python -y

前提你配置好了阿里云的epel源可以直接安装
yum install ansible -y 

[root@master-61 ~]#ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Apr 11 2018, 07:36:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]


主机清单文件(主机分组)

https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#inventory-basics-formats-hosts-and-groups

把综合架构需要用到的机器,进行分组

主机清单配置文件

vim /etc/ansible/hosts 

[web]
192.168.106.7
192.168.106.8
192.168.106.9

[nfs]
192.168.106.31

[backup]
192.168.106.41

主机分组后,执行命令测试,批量管理一组机器

管理所有的机器,使用特殊主机组,all

让所有的主机,远程执行hostname,返回主机名信息
[root@master-61 ~]#ansible all -m shell -a "hostname"
但是默认没配置认证方式,权限被拒绝

ansible主机登录认证

Ansible批量管理主机有两种方式:

  • 传统的密码认证
  • 公钥认证

ansible基于公私钥认证

1.将master61机器的公钥,分发给想免密登录的机器

2.后续在对该机器操作,就直接进行ssh的公钥认证了,可以免密码,直接远程执行

1.配置好master-61免密登录31机器
2.后续可以免密执行ansible的各种模块了
[root@master-61 ~]#ansible nfs -m command -a "hostname"
你可以配置所有机器的公钥一键分发,就可以实现all所有主机的远程命令执行
ansible all -m shell "hostname" # 返回结果给master-61机器
[root@master-61 ~]#ssh-copy-id root@192.168.106.31

基于密码认证

  • 在你的客户端机器、修改了ssh默认端口、以及密码需要修改主机清单文件才可以正确连接。
  • 注意你得配置允许密码登录才能进行如下测试,可以再开一个web-9机器。

ansible主机清单配置文件语法(重要)

/etc/ansible/hosts 主机清单文件

https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#connecting-to-hosts-behavioral-inventory-parameters

注意,部分资料里的主机配置文件语法,旧版如下
Ansible 2.0 has deprecated the “ssh” from ansible_ssh_user, ansible_ssh_host, and ansible_ssh_port to become 

这是旧版本的用法
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_password

最新的,去掉了中间的_ssh
新版参数
ansible_user
ansible_host
ansible_port
如果你写旧版本的语法,新版也也认识

新版参数

参数

参数类型

参数说明

ansible_host

主机地址

远程主机ip

ansible_port

主机端口

设置SSH连接端口,默认22

ansible_user

主机用户

默认SSH远程连接的用户身份

ansible_password

用户密码

指定SSH远程主机密码

给rsync机器,进行密码认证

1.给rsync机器,添加密码,端口等信息
[backup]
192.168.106.41  ansible_port=22  ansible_password='123456'  

2.如果目标机器的ssh信息都被改了,这里也得改
[backup]
192.168.106.41  ansible_port=22999  ansible_password='123456'
添加rsync机器的ssh信息

Ansible软件使用的前提是SSH+KEY免密验证的环境,如果没有配置也可以使用Ansible,如下

[root@master-61 ~]#tail -2 /etc/ansible/hosts 
[backup]
192.168.106.41 ansible_port=22 ansible_user=root ansible_password=123456

测试执行

[root@master-61 ~]#ansible backup -m ping
192.168.106.41 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
添加web机器组的信息

设置为不检查key

vim /etc/ansible/ansible.cfg
host_key_checking = False
[root@master-61 ~]#tail /etc/ansible/hosts 

[web]
192.168.106.7 ansible_port=22 ansible_user=root ansible_password=123456
192.168.106.8 ansible_port=22 ansible_user=root ansible_password=123456

[nfs]
192.168.106.31

[backup]
192.168.106.41 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=123456

测试执行

[root@master-61 ~]#ansible web -m ping
192.168.106.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.106.7 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
拿web机器测试(单独操作某主机)
1.先配置主机组的参数
[web]
192.168.106.7 ansible_port=22999 ansible_password='123456'
192.168.106.8 ansible_port=22999 ansible_password='123456'
192.168.106.9 ansible_port=22999 ansible_password='123456'

2.执行ping模块,看下是否和远程主机通信
[root@master-61 ~]#ansible  web -m ping
192.168.106.7 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.106.9 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.106.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
故障解决

你可能会遇见如下问题,关于新机器的指纹确认问题。

[root@master-61 ~]#
[root@master-61 ~]#ansible 192.168.106.9 -m ping
192.168.106.9 | FAILED! => {
    "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host."
}

解决办法1,手动ssh连接,进行指纹确认,写入到本机的

[root@master-61 ~]#ssh root@192.168.106.9
[root@master-61 ~]#cat ~/.ssh/known_hosts

解决办法2,ansible配置文件中忽略指纹确认

[root@master-61 ~]#grep 'host_key_checking' /etc/ansible/ansible.cfg 
host_key_checking = False

问题以及解决,可以正确操作web-9机器

[root@master-61 ~]#ansible 192.168.106.9 -m ping
192.168.106.9 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
踩坑记录(ansible缓存)

由于ansible在对远程主机操作之前,默认会先通过setup模块获取机器的facts(静态属性),并且会生成缓存,便于加速远程主机的操作;

但缓存也会导致一些奇怪的现象,比如客户端的机器信息更新了,服务端依旧使用的是旧数据,那就不准确了,因此可以删除缓存。

关于缓存导致bug的文章,https://serverfault.com/questions/630253/ansible-stuck-on-gathering-facts

清理ansible的缓存目录即可
[root@master-61 ~]#rm -rf ~/.ansible/cp/*
同一组连续的ip

可以修改主机清单文件如下,前提是该些主机的配置一致

[web]
192.168.106.[7:9]
公共变量

当主机清单里,很多主机组,有相同的变量属性,可以写成公共变量

这部分配置是针对web主机组,抽象的变量

[root@master-61 ~]#grep -vE '^#|^$' /etc/ansible/hosts 
[web:vars]
ansible_ssh_port=22
ansible_ssh_user=root
ansible_ssh_pass=123456
[web]
192.168.106.[7:9]
[nfs]
192.168.106.31 ansible_ssh_port=22
[backup]
192.168.106.41 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=123456

测试web组和backup组是否可用

1.主机清单
[web:vars]
ansible_port=22
ansible_password='123456'

[web]
192.168.106.[7:9]

[nfs]
192.168.106.31

[backup]
192.168.106.41  ansible_port=22  ansible_password='123456'

2.ansible ad-hoc命令

web机器组
[root@master-61 ~]#ansible web -m ping

rsync机器
[root@master-61 ~]#ansible backup -m shell -a "touch /opt/鸡你太美miao    warn=false"
192.168.106.41 | CHANGED | rc=0 >>

[root@master-61 ~]#ansible backup -m shell -a "ls /opt/"
192.168.106.41 | CHANGED | rc=0 >>
鸡你太美miao
[root@master-61 ~]#ansible web -m ping
192.168.106.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.106.7 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.106.9 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}


# 获取主机名
[root@master-61 ~]#ansible web -m shell -a hostname
192.168.106.8 | CHANGED | rc=0 >>
web-8
192.168.106.7 | CHANGED | rc=0 >>
web-7
192.168.106.9 | CHANGED | rc=0 >>
web-9
所有主机都生效的变量(最终版)

指定主机组名all,即可针对所有主机生效,前提是,你要确保这个信息是所有主机通用的。

[root@master-61 ~]#grep -vE '^#|^$' /etc/ansible/hosts 
[all:vars]
ansible_port=22999
#ansible_user=root
#ansible_password=123123

[web]
172.16.1.7
172.16.1.8
172.16.1.9

[nfs]
172.16.1.31

[backup]
172.16.1.41

远程执行命令

[root@master-61 ~]#rm -rf ~/.ansible/cp/*
[root@master-61 ~]#
[root@master-61 ~]#ansible all -m shell -a hostname

[root@master-61 ~]#ansible all -m shell -a hostname
172.16.1.31 | CHANGED | rc=0 >>
nfs-31
172.16.1.8 | CHANGED | rc=0 >>
web-8
172.16.1.41 | CHANGED | rc=0 >>
rsync-41
172.16.1.7 | CHANGED | rc=0 >>
web-7
172.16.1.9 | CHANGED | rc=0 >>
web-9

关于ansible连接指纹确认的问题

1.master-61需要确认目标机器的指纹,记录到本地known_hosts文件
ls ~/.ssh/known_hosts文件中 这里就存放了目标机器的指纹信息
可以进行认证方式,密码,还是公钥

2.首次远程连接,需要指纹确认,可以忽略该指纹
ssh的连接参数,忽略指纹的确认
ansible的配置文件中也有一个参数忽略指纹的确认
一般用法是
总之ansible就是以ssh连接标准来

1.指纹确认 yes/no
2.密码认证/公钥认证

关于ansible如何初始化的使用,有三个方案

方案1
已经基于ssh完成了指纹确认,认证方式
ansible直接用就可以
你可以先一键分发公钥,实现批量免密登录,再ansible免密远程执行命令

方案2
ssh root@192.168.106.7
手动确认yes,写入到本地的known_hosts
你可以手动ssh连接,确认指纹后,再ansible去远程操作,选择认证方式就行

方案3,
你可以直接忽略指纹确认,在主机清单文件中定义好ssh连接配置参数
这个是最简单的,修改ansible配置文件,打开忽略指纹确认的参数即可
修改如下参数即可
 72 # uncomment this to disable SSH key host checking
 73 host_key_checking = False
 
后续就进入了认证方式阶段,选择密码,还是公钥,
常见错误
- 端口错了
- 密码错了
- 用户错了

如果出错
1.找ansible的/etc/ansible/hosts中语法是否出错
2.看目标机器,到底提供了什么样的ssh连接形式(sshd_config)

三.ansible命令执行方式

ansible提供了多少个模块给你用
[root@master-61 ~]#ansible-doc -l |wc -l
3387

Ansible实现批量管理主机的模式主要有俩:

  • 利用ansible命令实现批量管理(ad-hoc)模式
  • 利用ansible剧本实现批量管理(playbook)模式

Ad-hoc和playbook的关系就好比shell命令与shell scripts的关系

ad-hoc模式

Ansible的ad-hoc模式也就是ansible的命令行模式,该模式通常用来临时处理一些任务。例如

  • 临时批量查看所有被管控机器的内存、负载、磁盘
  • 临时批量分发某个特定文件

Playbook模式

Ansible的playbook模式就是针对特定的具体较大的任务,事先写好执行剧本,然后在其他机器上批量执行相同的任务,属于定制化的批量执行任务,例如

  • 一键安装Rsync
  • 一键搭建LNMP集群等

ansible-doc命令

列出ansible所有支持的模块,这就是ansible这个万能工具箱所有的零件了。

[root@master-61 ~]#ansible-doc -l |grep ^ping
ping                                                          Try to connect to host, verify a usable python and re...
pingdom                                                       Pause/unpause Pingdom alerts   

[root@master-61 ~]#ansible-doc -l |grep ^shell
shell  

当前ansible支持3387个模块
[root@master-61 ~]#ansible-doc -l |wc -l
3387

当前ansible支持的模块数量

[root@master-61 ~]#ansible-doc -l |wc -l
3387

查看某个模块的具体用法

[root@master-61 ~]#ansible-doc -s shell
[root@master-61 ~]#ansible-doc -s ping

四.ansible核心内容(模块学习)

ansible执行命令结果(状态颜色)

你后续使用各种模块操作,会有不同的颜色结果,都是有意义的

运维远程执行命令,有2个方式
shell脚本,远程执行
ansible模块,远程执行
区别在哪
shell脚本不够智能,不会记录上一次的执行状态,以及修改的状态,因此导致,傻瓜式的,重复性执行。效率是极其低下的,不做状态记录
shell yum install  rsync  ;  mkdir -p ;

ansible的模块,yum模块会记录执行的状态
第一次执行,装完之后,的确对目标机器产生了修改的状态,会给master-61返回一个命令的执行结果,执行状态,存储下来
ansible web -m yum -a "name=rsync  state=installed"

ansible会检测目标机器,对比这个状态,如果状态没变,ansible就不会再执行该命令,因此效率很高
ansible web -m yum -a "name=rsync  state=installed"

ansible的状态,就是如下的颜色区分,看到不同的状态

这俩是命令成功了
绿色:命令以用户期望的执行了,但是状态没有发生改变;
黄色:命令以用户期望的执行了,并且状态发生了改变;
紫色:警告信息,说明ansible提示你有更合适的用法;出现了warning警告
红色:命令错误,执行失败;
蓝色: 详细的执行过程;

官网文档

如果说学ansible该去哪找正确玩法

1.看官网https://docs.ansible.com/ansible/latest/collections/ansible/builtin/index.html#plugins-in-ansible-builtin

Ansible自动化软件的核心功能就在于其众多的模块,可以说学习Ansible就是学习模块的使用。

剩余的是对Ansible剧本编写的熟练度。

题外话

如今的运维只需要学这几样东西,可以横着走

  • ansible
  • docker k8s
  • 阿里云运维
  • shell

ping测试连通性

1.通过master-61查看目标机器是否运行
ansible all -m ping

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/ping_module.html#ansible-collections-ansible-builtin-ping-module

命令语法

ansible 主机组 -m 模块名  [模块参数]

查看模块解释

[root@master-61 ~]#ansible-doc -s ping
- name: Try to connect to host, verify a usable python and return `pong' on success
  ping:
      data:                  # Data to return for the `ping' return value. If this parameter is set to `crash', the
                               module will cause an exception.
[root@master-61 ~]#

执行

[root@master-61 ~]#ansible web -m ping
192.168.106.9 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.106.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.106.7 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

command 简单命令模块

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/command_module.html#ansible-collections-ansible-builtin-command-module

语法

[root@master-61 ~]#ansible-doc -s command
ansible 主机组 -m command -a "需要批量执行的命令"

该模块作用:在远程节点上执行一个命令

  • command模块是ansible默认的模块,也就是默认就指定了 -m command
  • 只支持简单命令命令执行,比如你想远程看下服务器的资源信息,普通的linux命令

command模块是ansible命令基本模块

  • 使用command模块执行远程命令,命令不得用变量($HOME)
  • 不得出现特殊符号
< 、>、|、;、&

,否则无法识别,需要则使用shell模块实现

  • 也就是无法使用复杂的linux命令

远程查看主机名

[root@master-61 ~]#ansible web -m command -a "hostname"
192.168.106.8 | CHANGED | rc=0 >>
web-8
192.168.106.9 | CHANGED | rc=0 >>
web-9
192.168.106.7 | CHANGED | rc=0 >>
web-7
[root@master-61 ~]#ansible web -a "hostname"
192.168.106.8 | CHANGED | rc=0 >>
web-8
192.168.106.9 | CHANGED | rc=0 >>
web-9
192.168.106.7 | CHANGED | rc=0 >>
web-7

简写,command是ansible的基础模块,默认就是-m command

ansible web -a "hostname"

查看远程主机内存

ansible web -a "free -m"

远程创建文件、查看文件

[root@master-61 ~]#ansible web  -m command -a "touch /opt/姬霓太美.log"
[root@master-61 ~]#ansible web -m command -a "cat /opt/姬霓太美.log"

远程获取机器负载

[root@master-61 ~]#ansible web -a "uptime"
192.168.106.7 | CHANGED | rc=0 >>
 17:34:42 up 2 days,  1:53,  2 users,  load average: 0.08, 0.03, 0.05
192.168.106.9 | CHANGED | rc=0 >>
 17:34:42 up  7:37,  2 users,  load average: 0.00, 0.01, 0.05
192.168.106.8 | CHANGED | rc=0 >>
 17:34:42 up  7:37,  2 users,  load average: 0.00, 0.01, 0.05

关闭告警信息

[root@master-61 ~]#ansible web  -m command -a "touch /opt/姬霓太美.log  warn=false  "
192.168.106.8 | CHANGED | rc=0 >>

192.168.106.9 | CHANGED | rc=0 >>

192.168.106.7 | CHANGED | rc=0 >>

在所有机器上,创建yuchao01用户

[root@master-61 ~]#ansible web -m command -a "useradd yiyuan01"
删除
[root@master-61 ~]#ansible web -m command -a "userdel yiyuan01"

使用command提供的专有命令

这些命令用于编写ansible-playbook,完成服务器部署的各种复杂条件限定。

选项参数

选项说明

chdir

在执行命令执行,通过cd命令进入指定目录

creates

定义一个文件是否存在,若不存在,则运行相应命令;存在则跳过

free_form(必须)

参数信息中可以输入任何系统命令,实现远程管理

removes

定义一个文件是否存在,如果存在,则运行相应命令;如果不存在则跳过

Command练习

备份/var/log日志目录,需要先进入根目录

cd / && tar -zcvf /opt/log.tgz /var/log

注意你备份文件存放的文件夹是否存在

ansible web -m command -a "tar -zcf /opt/log.tgz   /var/log   chdir=/"
ansible web -a "ls -l /opt"

在/opt下创建chaoge666.log

2个写法
ansible web -a "touch /opt/yiyuan666.log"
ansible web -a "touch yiyuan666.log  chdir=/opt"

备份/etc所有配置文件到 /backup_config/etc.tgz 。

ansible web -a "tar -zcf /backup_config/etc.tgz   etc chdir=/"
目标目录不存在则会报错

练习removes命令

1.这里就得提前考虑 /backup_config文件夹是否存在,必须先有文件夹,才能执行该备份命令

2.判断如果该文件夹不存在,则不执行备份
目标文件夹不存在,这个命令不会对目标机器产生任何修改,因此绿色结果
ansible web -a "tar -zcf /backup_config/etc.tgz   etc chdir=/  removes=/backup_config"

3.你必须先创建该文件夹
ansible web -a "mkdir -p /backup_config"
ansible web -a "tar -zcf /backup_config/etc.tgz   etc chdir=/  removes=/backup_config"

4.再次执行该命令

测试creates命令,如果目标目录已经存在了,就别创建该目录了

[root@master-61 ~]#ansible backup -m command -a 'mkdir /opt creates=/opt'
192.168.106.41 | SUCCESS | rc=0 >>
skipped, since /opt exists

远程过滤进程信息,无法使用,因为command不支持特殊符号

想用特殊符号,更复杂的linux命令用shell模块
虽然ansible提供了大量的模块
万能模块shell
但是你在学习阶段,还是尽量的用专有的模块

shell模块(万能模块)

shell模块功能:在远程节点上执行命令(复杂的命令)

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/shell_module.html#ansible-collections-ansible-builtin-shell-module

也就是等于你在linux上直接执行任何复杂的命令都可以

但是ansible的使用理念是,人家提供了几千个模块,并且有很复杂的功能,你在用shell模块之前,先查一查是否有对应的模块。

你如果想使用ansible提供的状态功能,记录你每次执行命令的结果,你就必须得使用专有的模块,否则无法使用该功能

Shell练习

shell模块可以识别特殊符号,就等于远程执行命令了

远程过滤ssh进程信息

ansible all -m shell -a "ps -ef|grep ssh"

使用重定向符号,创建文件

>>
>
# 远程获取时间信息,且写入到文件中
command
command不认识重定向
# ansible web -m command -a "date > /tmp/date.log"

[root@master-61 ~]#ansible web -m shell -a "date '+%F %T' > /tmp/date.log"
192.168.106.8 | CHANGED | rc=0 >>

192.168.106.9 | CHANGED | rc=0 >>

192.168.106.7 | CHANGED | rc=0 >>

[root@master-61 ~]#ansible web -m shell -a "cat /tmp/date.log"
192.168.106.8 | CHANGED | rc=0 >>
2023-12-21 13:41:16
192.168.106.7 | CHANGED | rc=0 >>
2023-12-21 13:41:16
192.168.106.9 | CHANGED | rc=0 >>
2023-12-21 13:41:16

远程执行复杂linux命令

这个命令就无法在command中执行

通过一条命令,做如下事情

  • 创建文件夹
  • 生成sh脚本文件(查看主机名)
  • 赋予脚本可执行权限
  • 执行脚本
  • 忽略warning信息
ansible web  -m shell  -a "mkdir /2226/;echo 'hostname' > /2226/hostname.sh;chmod +x /2226/hostname.sh;/2226/hostname.sh;  warn=false"

小结shell模块

shell命令别过度依赖,那就等于用ansible远程帮你执行了个普通的shell命令;

你应该多去琢磨其他模块,如文件模块、拷贝模块,脚本模块,定时任务模块,yum模块等等等

copy拷贝文件

copy模块是远程推送数据模块,只能把数据推送给远程主机节点,无法拉取数据到本地。

既然是文件拷贝,可用参数也就是围绕文件属性。

ansible基础篇_python_02

将master-61管理机器上的数据,拷贝到目标机器上

copy练习

语法

ansible 主机组 -m copy -a "参数"

简单发送文件

src

dest

参数练习

并且ansible的模块记录了文件属性,文件的md5值,得到了文件的唯一校验值,判断文件内容是否变化,如果未变化,不做处理,提升批量管理的效率

[root@master-61 ~]#ansible web -m copy -a "src=/tmp/61-dnf.log   dest=/tmp/web-dnf.log"

发送文件且指定文件属性

61
↓
web机器组(属性变化,www,600)

权限改为600、修改为www用户(要求目标机器存在该用户)

创建www用户
远程拷贝文件,且修改权限,为600
ansible web -m copy -a "src=/tmp/61-dnf.log  dest=/opt/web-dnf.log  group=www owner=www  mode=600"

远程检查文件信息
[root@master-61 ~]#ansible web -m shell -a "ls -l  /opt/web-dnf.log"
192.168.106.9 | CHANGED | rc=0 >>
-rw------- 1 www www 26 Dec 21 12:49 /opt/web-dnf.log
192.168.106.7 | CHANGED | rc=0 >>
-rw------- 1 www www 26 Dec 21 12:49 /opt/web-dnf.log
192.168.106.8 | CHANGED | rc=0 >>
-rw------- 1 www www 26 Dec 21 12:49 /opt/web-dnf.log

发送文件且先做好备份

使用backup参数,防止覆盖远程文件,丢失备份,提前备份该目标机器的数据

1.检查目标机器的文件
[root@master-61 ~]#ansible web -m shell -a "ls -l  /opt/web-dnf.log"
192.168.106.9 | CHANGED | rc=0 >>
-rw------- 1 www www 26 Dec 21 12:49 /opt/web-dnf.log
192.168.106.7 | CHANGED | rc=0 >>
-rw------- 1 www www 26 Dec 21 12:49 /opt/web-dnf.log
192.168.106.8 | CHANGED | rc=0 >>
-rw------- 1 www www 26 Dec 21 12:49 /opt/web-dnf.log

2.远程拷贝文件,且做好备份
[root@master-61 ~]#ansible web -m copy -a "src=/tmp/61-dnf.log dest=/opt/web-dnf.log backup=yes"  

3.发现ansible帮你做好了备份
[root@master-61 ~]#ansible web -m copy -a "src=/tmp/61-dnf.log dest=/opt/web-dnf.log backup=yes"
[root@master-61 ~]#ansible web -m shell -a "ls -l /opt/web*"
192.168.106.9 | CHANGED | rc=0 >>
-rw------- 1 www www 39 Dec 21 12:53 /opt/web-dnf.log
-rw------- 1 www www 26 Dec 21 12:49 /opt/web-dnf.log.15910.2023-12-21@12:53:14~
192.168.106.8 | CHANGED | rc=0 >>
-rw------- 1 www www 39 Dec 21 12:53 /opt/web-dnf.log
-rw------- 1 www www 26 Dec 21 12:49 /opt/web-dnf.log.16044.2023-12-21@12:53:14~
192.168.106.7 | CHANGED | rc=0 >>
-rw------- 1 www www 39 Dec 21 12:53 /opt/web-dnf.log
-rw------- 1 www www 26 Dec 21 12:49 /opt/web-dnf.log.27707.2023-12-21@12:53:14~

指定数据写入到远程文件中

向rsyncd.conf中填入账号密码,覆盖其原有的文件内容

content参数

[root@master-61 ~]#ansible web -m copy -a "content='一原666' dest=/opt/web-dnf.log"
查看文件内容
[root@master-61 ~]#ansible web -m shell -a "cat /opt/web-dnf.log"
192.168.106.8 | CHANGED | rc=0 >>
一原666
192.168.106.7 | CHANGED | rc=0 >>
一原666
192.168.106.9 | CHANGED | rc=0 >>
一原666

注意像这样的覆盖操作,还是添加备份参数更合适

ansible web -m copy -a "content='一原666' dest=/opt/web-dnf.log backup=yes"

复制文件夹,注意结尾斜杠

练习src、dest,以及分隔符的添加

远程拷贝/opt/ 下的所有内容到目标机器
[root@master-61 ~]#ansible web -m copy -a "src=/opt/  dest=/tmp/"
远程拷贝/opt  整个目录到目标机器
[root@master-61 ~]#ansible web -m copy -a "src=/opt  dest=/tmp/"

目前已学的模块

ping       检测目标机器是否存活
command    远程执行简单linux命令不支持特殊符号
shell      万能模块,远程执行简单linux命令,支持特殊符号
copy       批量分发文件 master-61机器要给所有被管理的机器,批量的发送,更新某文件,某文件夹
/etc/hosts文件  master-61机器上 ,所有被管理的机器集群,都可以使用这个本地
hosts 域名解析
ansible all -m copy  -a "src=/etc/hosts  dest=/etc/hosts   backup=yes"
准备了一些列的数据文件,网站的所有静态页面,图片等
master-61机器的 /www目录下,全部发给共享存储/nginx-html/,提供给web服务器组使用
/www/static/logo.png
/www/html/index.html
ansible  nfs  -m copy  -a "src=/www/  dest=/nginx-html/"

file文件操作模块

copy区别开

file模块作用是创建、以及设置文件目录属性。

copy模块,src(管理机器上 )  dest(目标机器上)
file专门用于在远程机器上,关于文件的所有操作
file  src(目标机器上的文件)   dest(目标机器上的文件)

file模块主要用于创建文件、目录数据,以及对现有的文件、目录权限进行修改

对文件属性各种操作的

请看官网

https://docs.ansible.com/ansible/latest/modules/file_module.html#file-module

直接看examples示例用法即可

或者看命令帮助
[root@master-61 ~]#ansible-doc -s file

远程创建文件

ansible每次命令的执行,都会记录下当前的状态

state参数、path参数

远程在web服务器组中,创建一个文本,  hello_ansible.log
ansible web -m file -a "path=/opt/hello_ansible.log state=touch"
[root@master-61 ~]#ansible web -m shell -a "ls -ld /opt/hello*"
192.168.106.8 | CHANGED | rc=0 >>
drwxr-xr-x 2 root root 6 Dec 22 12:48 /opt/hello_ansible
-rw-r--r-- 1 root root 0 Dec 22 12:36 /opt/hello_ansible.log

创建文件夹

state参数、path参数

[root@master-61 ~]#ansible web -m file -a "path=/opt/hello_ansible state=directory"

创建文件且设定权限

state参数、path参数、owner参数、group参数

path=/opt/hello-linux.log

ansible web -m file -a "path=/opt/hello-linux.log  state=touch owner=www group=www"

远程修改文件属性

[root@master-61 ~]#ansible web -m file -a "path=/opt/hello-linux.log  state=touch owner=www group=www mode=777"

创建软连接文件

软连接,也就是在目标机器上,指定源文件,创建软连接

src、dest、state

给web服务器组的 /etc/hosts文件,添加软连接到/opt/hosts文件

ansible web -m file -a "src=/etc/hosts  dest=/opt/hosts state=link"

强制性创建文件(软连接)

意义不大,查看force参数的作用
[root@master-61 ~]#ansible web -m file -a "src=/etc/hostsss  dest=/opt/hosts state=link  force=yes"

修改已存在文件/文件夹的属性

修改文件 Path、mode
[root@master-61 ~]#ansible 192.168.106.7 -m file -a "path=/opt/yiyuan666.log owner=www group=www  mode=666"

修改文件夹 Path、mode owner,group
[root@master-61 ~]#ansible 192.168.106.7 -m file -a "path=/opt/hello_ansible owner=www group=www"

关于file模块的所有参数作用

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html#parameters

关于file模块的实例用法

playbook剧本的写法,yaml写法

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html#examples

script脚本模块

一键部署rsync,nfs,nginx等
1.把脚本发到目标机器上执行,
2.远程执行,目标机器上不需要存在这个脚本

官网

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/script_module.html#ansible-collections-ansible-builtin-script-module

模块功能:把本地脚本传输到远程节点上并运行脚本

比起shell模块,script模块功能更强大,管理机本地有一份脚本,就可以在所有机器上运行。

scripts模块的功能参数

选项参数

选项说明



creates

定义一个文件是否存在,若不存在,则运行相应命令;存在则跳过

free_form(必须)

参数信息中可以输入任何系统命令,实现远程管理

removes

定义一个文件是否存在,如果存在,则运行相应命令;如果不存在则跳过

远程执行脚本

为什么要用ansible,主要是ansible使用对应的模块,执行完命令后,记录了每一次文件修改的状态,这个状态,一是让你更清晰文件的情况、而是也防止反复修改文件,提升效率。

1.管理机创建测试脚本
master-61创建该脚本
[root@master-61 ~]#cat echo_server_info.sh 
echo "$(hostname -I)" >> /tmp/server_info.log
echo "$(uptime)" >> /tmp/server_info.log
echo "$(free -m)" >> /tmp/server_info.log

2.添加执行权限
[root@master-61 ~]#chmod +x echo_server_info.sh 

3.远程执行
发给nfs机器去执行
ansible nfs -m script -a "/root/echo_server_info.sh"

4.检查结果

利用script模块批量让所有被管控机器执行脚本,该脚本不用在远程主机上存在

远程在目标机器执行脚本

远程安装nginx脚本
[root@master-61 ~]#cat install_nginx.sh 
#yum install nginx -y
yum remove nginx -y
echo "一原666"

[root@master-61 ~]#ansible nfs -m script -a "/root/install_nginx.sh"

查看命令执行详细过程

-vvvvv参数显示详细过程,v越多,越详细

[root@master-61 ~]#ansible nfs -vvvvv  -m shell -a "df -h"
显示命令执行的详细过程,开启了debug日志模式

cron定时任务模块

官网文档 https://docs.ansible.com/ansible/latest/modules/cron_module.html#cron-module

cron模块用于管理定时任务的记录,编写任务

定时任务的记录,语法格式
* * * * *   要执行的命令

对比ansible的cron模块,和crontab

常见的参数如此,使用ansible编写定时任务,和直接编写是没有什么区别的

添加ntpdate定时任务

添加每5分钟执行一次和阿里云时间同步

*/5  * * * *     ntpdate -u ntp.aliyun.com

name、job、minute参数

cron模块创建定时任务
[root@master-61 ~]#ansible nfs -m cron -a "name='ntp aliyun' minute=*/5 job='ntpdate -u ntp.aliyun'"
192.168.106.31 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": [
        "一句话", 
        "ntp aliyun"
    ]
}

查看远程机器的crontab记录
[root@master-61 ~]#ansible nfs -m shell -a "crontab -l"
192.168.106.31 | CHANGED | rc=0 >>
* * * * * /usr/sbin/ntpdate time1.aliyun.com > /dev/null 2>&1
#Ansible: ntp aliyun
*/5 * * * * ntpdate -u ntp.aliyun.com

删除定时任务

只能基于cron模块指定名字的修改

name参数,state参数
先检查远程的定时任务
[root@master-61 ~]#ansible nfs -m shell -a "crontab -l"
192.168.106.31 | CHANGED | rc=0 >>
* * * * * /usr/sbin/ntpdate time1.aliyun.com > /dev/null 2>&1
#Ansible: ntp aliyun
*/5 * * * * ntpdate -u ntp.aliyun.com

正统用法
ansible nfs -m cron -a "name='ntp aliyun' state=absent"

歪门邪道
[root@master-61 ~]#ansible nfs -m shell -a "crontab -r"
192.168.106.31 | CHANGED | rc=0 >>

创建每分钟执行的任务

不指定任何时间规则,默认是每分钟

[root@master-61 ~]#ansible nfs -m cron -a "name='一句话'  job='echo "人定胜天" >>/tmp/hello.log'"
192.168.106.31 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": [
        "一句话"
    ]
}

[root@master-61 ~]#ansible nfs -m shell -a "crontab -l"
192.168.106.31 | CHANGED | rc=0 >>
#Ansible: 一句话
30 23 * * * echo 人定胜天 >>/tmp/hello.log

修改指定名称的定时任务

[root@master-61 ~]#ansible nfs -m cron -a "name='一句话' minute=30 hour=23 job='echo 人定胜天 >>/tmp/hello.log'"
192.168.106.31 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": [
        "一句话"
    ]
}

[root@master-61 ~]#ansible nfs -m shell -a "crontab -l"
192.168.106.31 | CHANGED | rc=0 >>
#Ansible: 一句话
30 23 * * * echo 人定胜天 >>/tmp/hello.log

group模块

管理系统用户组的模块

官网文档https://docs.ansible.com/ansible/latest/modules/group_module.html#group-

语法

模块参数    参数描述
name    创建指定的组名
gid        组的GID
state        absent,移除远程主机的组
             present,创建远端主机的组

对组管理,也就是创建、删除、查看了

创建yiyuan_ops组,gid=1234

name、gid

ansible nfs -m group -a "name=yiyuan_ops gid=1234"

删除组

name、gid、state

ansible nfs -m group -a "name=yiyuan_ops gid=1234 state=absent"

user用户模块

用户管理,也就是关于用户的

  • uid
  • 用户名
  • 用户主组
  • 用户附加组
  • 创建用户
  • 删除用户
  • 创建关于用户的公私钥
  • 用户过期时间
  • 用户密码过期时间

官网文档https://docs.ansible.com/ansible/latest/modules/user_module.html#user-module

语法参数

实例用法 https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html#examples

模块参数

参数描述

create_home

创建家目录,设置no则不创建家目录

group

创建用户组

name

创建用户的名字

password

创建用户的密码

uid

创建用户的UID

shell

用户登录解释器

state

Absent(删除用户)present(默认参数,创建)

expires

账户过期时间



创建yiyuan用户,uid为8888

ansible nfs -m user -a "name=yiyuan uid=8888"

创建用户eryuan

  • uid、gid为1777
  • 没有家目录、不允许登录
注意该用户组是否存在,否则报错
group、name、gid
ansible nfs -m group -a "name=eryuan gid=1777"

创建用户,设置权限
user、name、uid、group、create_home、shell
ansible nfs -m group -a "name=eryuan gid=1777"

[root@master-61 ~]#ansible nfs -m user -a "name=yiyuan uid=1777 group=1777 create_home=no shell=/sbin/nologin"
检查用户

yum安装软件

ansible基础篇_配置文件_03

yum模块明显就是一个专门用于管理软件的模块。

官网文档示例用法https://docs.ansible.com/ansible/latest/collections/ansible/builtin/yum_module.html#examples

yum模块其实就是在远程节点上,执行yum命令,你可以快速登录到目标机器,查看进程

安装net-tools最新版本

latest参数也用于升级软件包

ansible backup -m yum -a "name=net-tools state=latest"
ansible all -m yum  -a "name=net-tools  state=installed"

卸载net-tools软件

ansible backup -m yum -a "name=net-tools state=absent"

卸载rsync服务

ansible backup -m yum -a "name=rsync state=abesent"

安装rsync服务

ansible backup -m yum -a "name=rsync state=installed"

检查rsync
ansible backup -m shell -a "rpm -qa rsync"

service/systemd模块

该模块作用是针对yum包管理

service适用于centos6前的系统

systemd命令应用于centos7系统

要注意的是service模块依旧对centos7有效,但是建议大家使用systemd模块

  • systemd模块用于控制远程主机的systemd服务,说白了,就是Linux下的systemd命令。需要远程主机支持systemd
  • 用法和service模块基本相同

systemd模块参数

如果使用systemctl 管理程序的话,可以使用systemd模块,systemctl 可以 控制程序启/停,reload,开机启动,观察程序状态(status)等,掌握使用后管理就更方便了

主要参数
daemon_reload:在执行任何其他操作之前运行守护进程重新加载,以确保systemd已经读取其他更改
enabled:服务是否开机自动启动yes|no。enabled和state至少要有一个被定义
masked:是否将服务设置为masked状态,被mask的服务是无法启动的
name:必选项,服务名称
no_block(2.3后新增):不要同步等待操作请求完成
state:对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)
user:使用服务的调用者运行systemctl,而不是系统的服务管理者

安装、启动nginx服务

1.安装nginx服务
ansible 192.168.106.7 -m yum -a "name=nginx state=installed"

2.启动服务
ansible web -m systemd -a "name=nginx state=started"

3.查询状态,这里ansible未直接提供status参数,你可以借助command模块即可
ansible web -a "systemctl status nginx"

4.停止nginx服务
ansible web -m systemd -a "name=nginx state=stopped"

5.设置nginx开机自启
ansible web -m systemd -a "name=nginx state=started enabled=yes"

6.检查nginx状态
ansible web -a "systemctl is-enabled nginx"
ansible web -a "systemctl status nginx"

7.关闭开机自启、且停止服务
ansible web -m systemd -a "name=nginx state=stopped  enabled=no"

8.再次检查状态
ansible web  -m shell -a "systemctl is-enabled nginx;systemctl status nginx"

mount挂载模块

官网https://docs.ansible.com/ansible/latest/collections/ansible/posix/mount_module.html#mount-

state参数

mounted
	1.立即挂载
	2.写入fstab文件
	3.创建挂载点

unmounted
	1.卸载挂载设备
	2.不会删除fstab文件的记录

present
	1.只写入fstab文件记录
	2.不会立即挂载

absent
	1.删除fstab中记录
	2.卸载设备
	3.删除挂载点

remounted
	1.重新挂载这个设备

 

给web-7机器挂载nfs目录(只写入/etc/fstab而不挂载)

[root@nfs-31 ~]#yum install nfs-utils rpcbind -y
[root@nfs-31 ~]#mkdir /nfs-data
[root@nfs-31 ~]#vim /etc/exports
You have new mail in /var/spool/mail/root
[root@nfs-31 ~]#systemctl start nfs
[root@nfs-31 ~]#showmount -e 127.0.0.1
Export list for 127.0.0.1:
/nfs-data 192.168.106.0/24
挂载设备
1.立即挂载,可以访问该设备的资料
[root@master-61 ~]#ansible 192.168.106.7 -m mount -a "src='172.16.1.31:/nfs-data' path='/test-nfs' state=present fstype=nfs"
2.设置重启后,开机自动挂载, /etc/fstab文件
[root@master-61 ~]#ansible 192.168.106.7 -m shell -a "cat /etc/fstab"
192.168.106.7 | CHANGED | rc=0 >>

#
# /etc/fstab
# Created by anaconda on Wed Dec  6 09:39:04 2023
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=25ef620d-b95f-4c8f-b31f-abea6cc783a9 /boot                   xfs     defaults        0 0
#/dev/mapper/centos-swap swap                    swap    defaults        0 0
192.168.106.31:/nfs-data /test-nfs nfs defaults 0 0

给web-7机器挂载nfs目录(立即挂载且写入/etc/fstab)

ansible 192.168.106.7 -m mount -a "src='192.168.106.31:/nfs-data' path='/test-nfs' state=mounted fstype=nfs"

检查
ansible web -a "df -h"
ansible web -a "cat /"

取消挂载,以及删除fstab记录

1.删除fstab
2.卸载设备
3.删除挂载点

ansible 192.168.106.7 -m mount -a "src='192.168.106.31:/nfs-data' path='/test-nfs' state=absent fstype=nfs"

取消挂载,不删除fstab记录

ansible 192.168.106.7 -m mount -a "src='192.168.106.31:/nfs-data' path='/test-nfs' state=unmounted fstype=nfs"

archive压缩模块

官网文档 https://docs.ansible.com/ansible/latest/collections/community/general/archive_module.html

支持压缩类型

bz2
gz ← (default)
tar
xz
zip 
用法文档
https://docs.ansible.com/ansible/latest/collections/community/general/archive_module.html#examples
指定format即可

压缩/etc配置文件到指定路径

压缩整个/etc文件夹到 /tmp/all_etc.tar.gz

path=/etc
dest=/tmp/all_etc.tar.gz

backup机器
ansible backup -m archive -a "path=/etc dest=/tmp/all_etc.tar.gz"

压缩/var/log为zip类型到指定路径

ansible backup -m archive -a "path=/var/log  dest=/tmp/all_log.zip  format=zip "

unarchive解压缩模块

ansible远程管理机器
解压缩,准备好原文件
原文件在61机器上
61机器的压缩文件,解压到 41机器的某目录
还是在目标机器上
41机器上,解压缩到41机器的本地

注意了,你现在是远程解压缩,而不是在本机直接解压缩

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/unarchive_module.html#examples

解压缩etc.tgz到指定目录(远程解压)

远程的解压缩
41机器的/tmp下有 all_etc.tar.gz
解压到/test-etc/
ansible backup -m unarchive -a "src=/tmp/all_etc.tar.gz dest=/test-etc/ remote_src=yes"

解压缩出了整个etc目录到 /test-etc/
[root@rsync-41 ~]#cd /test-etc/
[root@rsync-41 /test-etc]#ls
etc

将管理机的压缩包,解压到远程机器上

将master-61的压缩文件,解压到web-7机器上

1.生成 all_png.tgz数据
2.远程解压到web-7机器上
[root@master-61 /opt]#ansible backup -m unarchive  -a "src=/opt/all_png.tgz   dest=/test-etc/"
3.检查