Ansible

Ansible

运维自动化平台,集群管理工具,通过管理机SSH远程管理N台服务器;

  • 批量管理,分组管理,单独管理
  • 命令模式:相对简单,适合简单任务
  • 剧本(playbook)模式:实现复杂任务编排,一键启动部署整个集群

安装部署Ansible

  1. 准备工作

    主机名称 IP地址
    manage01 192.168.25.50/24
    node1 192.168.25.51/24
    node2 192.168.25.52/24
    node3 192.168.25.53/24
    • 时间同步
    • 关防火墙,SELinux
    • 配置系统hosts文件
    • 免密登陆
    • 配置yum源/apt源
    • Manage 上安装ansible
#配置系统hosts文件(所有服务器操作)
vim /etc/hosts

127.0.0.1   localhost
::1         localhost 
192.168.25.50    manage01
192.168.25.51    node1
192.168.25.52    node2
192.168.25.53    node3

#免密登陆 (manage01 上操作)
#生成公私钥
ssh-keygen 

#将公钥传给node1
ssh-copy-id -i .ssh/id_rsa.pub root@node1
#将公钥传给node2
ssh-copy-id -i .ssh/id_rsa.pub root@node2
#将公钥传给node3
ssh-copy-id -i .ssh/id_rsa.pub root@node3

#公钥传过去后,先在主机上手动连接一下监控机
ssh root@192.168.25.51
ssh root@192.168.25.52
ssh root@192.168.25.53

#manage端安装 ansible(manage01 上操作)
sudo apt update
sudo apt install ansible

#编辑部署主机列表,定义被监控机
mkdir /etc/ansible/
cd /etc/ansible
touch hosts
vim /etc/ansible/hosts

[group1]                    #名字可以随便起  后面跟上业务机器的IP地址或者域名
192.168.25.51
192.168.25.52
192.168.25.53

#ping 模块测试网络连接是否正常
ansible -m ping all
#结果是绿色的就代表正常连接

ansible 常用模块

  • ansible 命令模式 (ad-hoc)格式
#格式
ansible -m 模块名 -a '参数1=值1 参数2=值2' 主机名/组名/all/ip
ping模块:测试服务器网络是否正常
ansible -m ping all
hostname模块:修改主机名
ansible -m hostname -a 'name=zuolaoshi_node3' 192.168.25.53
file模块:远程文件与权限操作
  • 包含touch,rm,mkdir,ln,chmod,chown 命令=
参数 说明
path 文件绝对路径
state 操作(touch文件新建、absent删除、link软连接、hard硬链接、directory目录创建)
owner 设置所有者
group 设置所属的组
mode 权限 0000
recurse 递归 yes or no
#批量创建文件 001
ansible -m file -a 'path=/root/001 state=touch owner=root group=root mode=777' group1 

#批量删除文件 001
ansible -m file -a 'path=/root/001 state=absent' group1

#批量创建软连接
ansible -m file -a 'src=/tmp/zuolaoshi path=/tmp/zuolaoshi_com state=link' group1

#批量修改文件权限,所有者,所属组
ansible -m file -a 'path=/tmp/zuolaoshi owner=sko group=nobody mode=0600' 192.168.25.52

#批量创建一个目录
ansible -m file -a 'path=/tmp/zuolaoshi123 state=directory' group1

#批量修改目录及子文件权限
ansible -m file -a "path=/tmp/zuolaoshi123 owner=sko mode=2755 recurse=yes" group1
copy模块:远程复制
参数 说明
src 文件源路径
dest 目标路径
content 往目标文件输入内容
force 强制 yes or no
backup 是否备份有冲突的源文件[文件名相同,内容不同] yes or no
checksum 拷贝完整性校验,使用sha1sum生成校验码
owner 目标文件所有者
group 目标文件所属组
mode 目标文件权限
#拷贝manage01机器/root/001文件到group1组的机器
#生成校验码
sha1sum 001
ansible -m copy group1 -a "src=/root/001 dest=/opt checksum=f8182e9ccdbe6efd13eb36a056a7db203fe66e40 owner=sko group=sko mode=0400"

#copy模块拷贝时要注意拷贝目录后面是否带"/"符号,加/ 复制的是目录里的东西,不加/ 复制的是目录本身

#/etc/yum.repos.d后面不带/符号,则表示把/etc/yum.repos.d整个目录拷贝到/tmp/目录下
ansible group1 -m copy -a 'src=/etc/yum.repos.d dest=/tmp/'
#/etc/yum.repos.d/后面带/符号,则表示把/etc/yum.repos.d/目录里的所有文件拷贝到/tmp/目录下
ansible group1 -m copy -a 'src=/etc/yum.repos.d/ dest=/tmp/'

#使用content参数直接往远程文件里写内容(会覆盖原内容)

ansible -m file group1 -a "path=/tmp/zuolaoshi_333 state=touch"
ansible -m copy group1 -a "content='baism\nhello world\n' dest=/tmp/zuolaoshi_333"
#注意:ansible中-a后面的参数里也有引号时,记得要单引双引交叉使用,如果都为双引会出现问题

#使用force参数控制是否强制覆盖
#如果目标文件已经存在,则不覆盖
ansible group1 -m copy -a "src=/tmp/zuolaoshi_222 dest=/tmp/zuolaoshi_333 force=no"
#如果目标文件已经存在,则会强制覆盖
ansible group1 -m copy -a "src=/tmp/zuolaoshi_222 dest=/tmp/zuolaoshi_333 force=yes"

#使用backup参数控制是否备份文件
#backup=yes表示如果拷贝的文件内容与原内容不一样,则会备份一份

#如果拷贝过来的文件本机存在,group1的机器上会将/tmp/333备份一份(备份文件命名加上时间),再远程拷贝新的文件为/tmp/333
ansible group1 -m copy -a "src=/etc/fstab dest=/tmp/zuolaoshi_333 backup=yes"
fetch模块:从node节点下载文件到Manage节点
#远程下载文件
ansible -m fetch group1 -a "src=【远程路径】 dest=【本地路径】"
user模块:用于管理用户账号和用户属性
常用参数 说明
name="" 指定用户名
password="" 指定密码,必须是密文
state= absent|present 删除|创建
system= yes|no 是否为系统用户
shell="" 指定登陆shell
generate_ssh_key= yes|no 是否创建秘钥对
uid= 指定用户的uid
append= yes|no 用户是否追加到其他组
group= 用户属组
groups= 将现有用户加入到某个组,空值就会把该用户从所有所属组中删除
create_home= yes|no 是否建立家目录
remove= yes|no 删除家目录
#创建一个用户sky,密码是123,要求是系统用户,非交互式登陆,要求生成自己的秘钥对,不创建家目录
echo 123|openssl passwd -1 -stdin
ansible -m user -a 'name=sky password="$1$5V.qzSEd$Yr08MU8K.vXeBZcmavypk1" state=present system=yes shell=/sbin/nologin generate_ssh_key=yes create_home= no' group1

#创建用户zhangsan 密码为123456
echo "123456"|openssl passwd -1 -stdin
ansible -m user group1 -a 'name=zhangsan password="$1$BMPgiHeV$GskMFnvqBL17gTe/us5yK." uid=4423'

#用户删除
ansible -m user 192.168.8.21 -a "name=baishuming1 state=absent remove=yes"
group模块:用于管理用户组和用户组属性
参数 说明
name= 组名
state= persent|absent 创建|删除
system= yes|no 是否为系统组
gid gid
#组创建
ansible -m group group1 -a "name=admin gid=4444 state=present" 

#删除组
ansible -m group group1 -a "name=admin state=absent"
cron模块:用于管理周期性时间任务
参数 说明
name=“” 计划任务的名称
user 执行计划任务的用户
job=“” 计划任务命令
minute 执行计划任务的分 默认为*
hour 执行计划任务的时 默认为*
day 执行计划任务的日 默认为*
month 执行计划任务的月 默认为*
week 执行计划任务的周 默认为*
state=absent 删除计划任务
#创建一个cron任务,不指定user的话,默认就是root(因为我这里是用root操作的)。 如果minute,hour,day,month,week不指定的话,默认都为*
#每天10:23 执行echo “haha”>/tmp/test
ansible -m cron group1 -a 'name="cron test" user=root job="echo haha > /tmp/test" minute=23 hour=10'

#删除cron任务
ansible -m cron group1 -a 'name="cron test" state=absent'
yum_repository模块:用于配置yum仓库
参数 说明
name 仓库名 name.repo 源的名称 [name]
description 描述
baseurl 包下载路径
gpgcheck= 1 or 0 包gpg验证
enabled = yes|no 是否开启本源
state= absent 删除源
#增加一个/etc/yum.repos.d/dvd.repo配置文件
ansible -m yum_repository group1 -a "name=dvd description=BaseOS baseurl=file:///media/cdrom gpgcheck=0 enabled=yes"

#删除某个yum源
ansible -m yum_repository group1 -a "name=dvd state=absent"
apt_repository模块:管理 APT 仓库
参数 说明
repo 指定要添加的仓库字符串
filename 指定生成的 APT 配置文件的名称(不包括 .list 扩展名)
state 指定仓库的状态,present 表示添加仓库,absent 表示删除仓库
#本地主机上(或远程主机)添加一个名为 myrepo 的 APT 仓库
ansible localhost -m ansible.builtin.apt_repository -a "repo='deb http://example.com/repo stable main' filename='myrepo' state=present"

#删除myrepo仓库
ansible localhost -m ansible.builtin.apt_repository -a "repo='deb http://example.com/repo stable main' filename='myrepo' state=absent"

#添加一个带有 GPG 密钥的仓库,可以在添加仓库的同时指定密钥文件路径,或者在添加仓库后单独添加密钥
# 添加仓库
ansible localhost -m ansible.builtin.apt_repository -a "repo='deb https://packages.cloud.google.com/apt cloud-sdk main' filename='google-cloud-sdk' state=present update_cache=yes"
# 添加 GPG 密钥
ansible localhost -m ansible.builtin.apt_key -a "url=https://packages.cloud.google.com/apt/doc/apt-key.gpg state=present"

yum/apt模块:软件包的安装与卸载
参数 说明
name 需要安装软件包的名称
list= installed, updates, available and repos 列出已安装 需要更新 可获得的 和 yum源
state= absent removed installed present latest 删除、删除、安装确认、安装确认、安装最新版本
#使用yum安装一个软件
ansible -m yum/apt group1 -a "name=vsftpd"

#list:列出包信息
ansible -m yum/aptgroup1 -a "list=repos"

#删除软件包
ansible -m yum/apt 192.168.8.21 -a "state=absent name=vsftpd"
service模块:用于控制服务的启动,关闭,开机自启动等
参数 说明
name 服务名称
state=reloaded, restarted, started, stopped 服务管理
enabled=on|false / yes|no 开启是否开机自启动
#启动vsftpd服务,并设为开机自动启动
ansible -m service 192.168.8.22 -a "name=vsftpd state=started enabled=on"

#关闭vsftpd服务,并设为开机不自动启动
ansible -m service 192.168.8.22 -a "name=vsftpd state=stopped enabled=false"

script模块: 远程执行管理机上的脚本
#在manage01上创建脚本,通过ansible将脚本分发到被管理端
cat ansible_test.sh 
#!/bin/bash
#ansible script module test script
mkdir /opt/log
find / -name "*.log" -exec cp -rpf {} /opt/log \;

#脚本不用给执行权限
 ansible -m script group1 -a "/root/ansible_test.sh"
 
 
command模块/shell模块/raw模块:远程执行linux命令
  • command模块:
    • command模块用于在给的的节点上运行系统命令,比如echo hello
    • 本质是调用Python模块执行Linux命令,客户端要有Python才能执行
    • 它不会通过shell处理命令,因此不支持像$HOME这样的变量和,以及<, >, |, ;&等都是无效的。也就是在command模块中无法使用管道符
名称 必选 备注
chdir no 运行command命令前先cd到这个目录
creates no 如果这个参数对应的文件存在,就不运行command
free_form yes 需要执行的脚本(没有真正的参数为free_form)
executable no 改变用来执行命令的shell,应该是可执行文件的绝对路径。
removes no 如果这个参数对应的文件不存在,就不运行command,与creates参数的作用相反
stdin(2.4后新增) no 将命令的stdin设置为指定的值
ansible -m command 192.168.8.21 -a "ls /root"

ansible -m command 192.168.8.21 -a "echo 'baism hello' > /tmp/baism_123"

ansible -m command 192.168.8.21 -a "cat /tmp/baism_123"
  • shell模块:
    • 让远程主机在shell进程下执行命令,从而支持shell的特性,如管道等
    • 本质是调用Python模块执行Linux命令,客户端要有Python才能执行
名称 必选 备注
chdir no 运行command命令前先cd到这个目录
creates no 如果这个参数对应的文件存在,就不运行command
executable no 改变用来执行命令的shell,应该是可执行文件的绝对路径。
free_form yes 需要执行的脚本(没有真正的参数为free_form)
removes no 如果这个参数对应的文件不存在,就不运行command,与creates参数的作用相反
stdin(2.4后新增) no 将命令的stdin设置为指定的值
ansible -m shell 192.168.8.21 -a "ls /root"

ansible -m shell 192.168.8.21 -a "echo 'hello world' > /tmp/baishuming"

ansible -m shell 192.168.8.21 -a "cat /tmp/baishuming"
  • raw模块:最原始的方式运行命令(不依赖python,仅通过ssh实现)
名称 必选 备注
executable no 改变用来执行命令的shell,应该是可执行文件的绝对路径。
free_form yes 需要执行的脚本(没有真正的参数为free_form)
案列:清除yum缓存
#案列:清除yum缓存

ansible 192.168.8.21 -m raw -a "yum clean all"
setup模块:用于收集远程主机的基本信息(如操作系统类型,主机名,ip,cpu信息,内存信息等)
#打印192.168.8.21机器的所有信息
ansible -m setup 192.168.8.21

#使用filter过滤输出,打印192.168.8.21机器的CPU信息
ansible -m setup 192.168.8.21 -a "filter='ansible_processor'"

#打印192.168.8.21机器的内核信息
ansible -m setup 192.168.8.21 -a "filter='ansible_kernel'"

#打印192.168.8.21机器的主机名
ansible -m setup 192.168.8.21 -a "filter='ansible_hostname'"

#打印192.168.8.21机器的网卡信息
ansible -m setup 192.168.8.21 -a "filter='ansible_ens*'"

# 其它常见的过滤条件
ansible_all_ipv4_addresses:显示ipv4的信息。
ansible_devices:显示磁盘设备信息。
ansible_distribution_major_version:显示是系统主版本。
ansible_distribution_version:仅显示系统版本。
ansible_machine:显示系统类型,例:32位,还是64位。
ansible_lvm:显示lvm相关信息。
ansible_memtotal_mb:显示系统总内存。
ansible_memfree_mb:显示可用系统内存。
ansible_memory_mb:详细显示内存情况。
ansible_swaptotal_mb:显示总的swap内存。
ansible_swapfree_mb:显示swap内存的可用内存。
ansible_mounts:显示系统磁盘挂载情况。
ansible_processor:显示cpu个数(具体显示每个cpu的型号)。
ansible_processor_vcpus:显示cpu个数(只显示总的个数)。
stat模块:用于获取文件的状态信息
#获取/etc/fstab文件的状态信息
ansible -m stat 192.168.8.21 -a "path=/etc/fstab"
blockinfile模块和lineinfile模块
  • blockinfile模块:在文件中插入文本块,插入的文本块会有一个标记,方便修改和删除
参数名 描述信息
path 操作的文件对象
block 也可用content,指定内容。
marker 使用marker参数自定义”标记”,方便我们通过对应的标记找到对应的内容
state 默认是present,state=absent,则表示从文件中删除对应标记的内容。
backup 在修改文件之前是否对文件进行备份,默认是no.
create 当要操作的文件并不存在时,是否创建对应的文件。
#创建/tmp/test文件,并初始化文件内容hello world
ansible group1 -m raw -a 'echo "hello world">/tmp/test'
ansible group1 -m raw -a 'cat tmp/test'
#使用marker插入文本“start httpd、stop httpd \restart httpd”,插入文本内容使用 httpd server进行标记
ansible group1 -m blockinfile -a 'path=/tmp/test block="start httpd \n stop ttpd \n restart httpd " marker="#{mark} httpd server
#查看
ansible group1 -m raw -a 'cat tmp/test'

#删除http server标记的文本内容
ansible group1 -m blockinfile -a 'path=/tmp/test state=absent marker="#{mark} httpd server" '    
  • lineinfile模块:对文件行进行操作,默认添加文件是在行尾
参数名 描述信息
path 操作的文件对象
line 指定行内容。
state 默认值为present,state=absent表示删除。
backup 是否在修改文件之前对文件进行备份。
insertbefore 插在匹配值之前
insertafter 插在匹配值之后,在该该选项不写的情况下默认插在文本最后
create 当要操作的文件并不存在时,是否创建对应的文件。
#添加"这是测试行"到/tmp/test文件中,如果不指定位置,默认是在末尾添加
ansible group1 -m lineinfile -a 'path=/tmp/test line="这是测试行" ' 
#查看
ansible test -m raw -a 'cat tmp/test'  
#使用insertbefore指定插入到"hello world"行之前,insertafter则相反
ansible test -m lineinfile -a 'path=/tmp/test line="这是测试行-行首" insertbefore="hello world" '
#查看
ansible test -m raw -a 'cat tmp/test'

Playbook剧本

  • YAML格式
    • 格式要求:
      • 严格区分大小写
      • 缩进统一,同一级别配置要对齐
      • 不允许使用制表符,只能使用空格
基础结构模板
---
- name: 剧本名称(描述这个剧本的用途,比如“安装Nginx”)
  hosts: 目标主机/组(比如 group1、192.168.1.100,需在inventory中定义)
  become: 是否提权(true 表示用sudo执行,安装软件/管理服务必须设为true)
  tasks:  # 任务列表(核心!按顺序执行)
    - name: 任务1描述(比如“安装Nginx包”)
      模块名:  # 用什么模块完成任务(比如 apt、service、copy等)
        参数1: 值1  # 模块的具体参数(比如 name: nginx)
        参数2: 值2  # 比如 state: present(确保安装)
    - name: 任务2描述(比如“启动Nginx服务”)
      模块名:
        参数1: 值1

Ansible-role 角色

  • 将剧本根据功能拆分成不同的组件;
  • 每个组件只完成一项简单任务;
  • 复杂任务通过组合多个组件来实现;
  • 优点:灵活、低耦合、高复用;
  • 缺点:编写的复杂性高,对技术要求高;
roles的目录结构
  • files:用来存放由copy模块或script模块调用的文件。
  • tasks:至少有一个main.yml文件,定义各tasks。
  • handlers:有一个main.yml文件,定义各handlers。
  • templates:用来存放jinjia2模板。
  • vars:有一个main.yml文件,定义变量。
  • meta:有一个main.yml文件,定义此角色的特殊设定及其依赖关系。

作业

  1. Ansible剧本配置 yum 源、APT 源
  2. Ansible剧本修改 IP 地址与主机名
  3. Ansible剧本实现系统优化:设置时区、时间同步、更新软件、关闭防火墙、SELinux
  4. Ansible剧本安装单机 LNMP、LNMT
  5. Ansible剧本安装集群:MySQL 主从、Redis 哨兵
  6. 将大剧本拆分成角色
posted @ 2025-10-31 11:07  落无一  阅读(4)  评论(0)    收藏  举报