Linux运维7.2

ansible

概念

Ansible 是什么

Ansible 是一款开源、无代理(agentless) 的自动化运维工具,使用 Python 开发;

可以实现:批量远程执行命令、配置管理、应用部署、持续交付、编排任务。

核心特点:不需要在被管理机器安装客户端,依托 SSH 通信。

核心架构组成

1. 控制节点(Control Node)

运行 ansible 的服务器,只需要一台;

所有任务从控制节点发起,依赖:Python、OpenSSH。

2. 被管理节点(Managed Node / 被控主机)

被批量操作的服务器;

只需满足:开启 SSH、自带 Python(绝大多数 Linux 默认具备)。

3. Inventory 主机清单

定义所有被控主机列表,Ansible 知道要操作哪些机器。

默认文件:/etc/ansible/hosts

支持分组、变量、主机别名、动态清单。

示例:

[web]
192.168.1.10
192.168.1.11

[db]
192.168.1.20
4. Module 模块

Ansible 的最小执行单元,相当于一条条封装好的功能函数。

  • 执行单条命令:

    ansible 主机 -m 模块名
    

    常见模块:

    command/shell/copy/file/yum/apt/service/user
    

command:不支持管道;shell:支持管道、特殊符号

5. Ad-hoc 临时命令

一次性执行的简短命令,适合简单批量操作,不保存任务。

示例:

ansible web -m shell -a "df -h"
6. Playbook 剧本

使用 YAML 语言编写的任务文件,批量编排多步骤任务,可以持久保存、重复执行。

  • Play:定义对哪一组主机执行任务
  • Task:一个个要执行的动作(调用模块)

简易结构:

- name: 部署nginx
  hosts: web
  tasks:
    - name: 安装nginx
      yum: name=nginx state=present
    - name: 启动服务
      service: name=nginx state=started enabled=yes
7. Role 角色

Playbook 的规范化封装,用于复用、模块化大型项目。

固定目录结构,把变量、任务、模板、文件分离;多套环境直接调用 role,企业主流用法。

8. Facts 资产信息

Ansible 连接主机后自动采集的主机信息:CPU、内存、IP、系统版本等;

可以直接在 playbook 中作为变量引用。

9. Handler 处理器

只有当 changed 状态触发 才执行的任务,多用于服务重启。

例如:配置文件修改后,才执行重启 nginx。

10. Template 模板

基于 Jinja2 模板语法的配置文件,可以写入变量,推送至远端主机。后缀一般 .j2。

核心通信原理

控制节点 → SSH → 被控节点

  1. 控制节点生成临时 Python 脚本
  2. 通过 SSH 传输到远端
  3. 远端执行脚本并返回结果
  4. 执行完毕自动删除临时脚本

三种返回状态

  • ok:成功,没有发生变更
  • changed:成功,主机资源发生修改(安装软件、修改文件)
  • failed:执行失败

简单区分概念

  1. Ad-hoc:临时单行命令(一次性)
  2. Playbook:yaml 脚本,多任务流程
  3. Role:标准化打包的 playbook,方便复用
  4. Inventory:管理主机名单
  5. Module:实际干活的功能单元

安装配置

yum 安装

  1. 配置EPEL网络yum源
[root@ansible ~]# yum install -y epel-release
  1. 安装ansible
[root@ansible ~]# yum install ansible -y

pip 安装

[root@ansible ~]# yum install python-pip
[root@ansible ~]# pip install ansible

激活配置文件

[root@server1 ~]# cat /etc/ansible/ansible.cfg

image-20260813163745488

[root@server1 ~]# ansible-config init --disabled > ansible.cfg

配置文件生成

[root@server1 ansible]# vim /etc/ansible/ansible.cfg

image-20260813164028967

Inventory 主机清单配置文件

[root@server1 ansible]# vim /etc/ansible/hosts

image-20260813173618626

查看主机配置信息

[root@server1 ansible]# ansible-inventory --graph

image-20260813173700467

Ansible 命令

主机连通

[root@server ~]# ansible web -m ping

注意需要免密配置或者主机之间至少远程连接过一次

屏幕截图 2026-08-13 210801

command模块

示例——获取主机名

屏幕截图 2026-08-13 212410

屏幕截图 2026-08-13 212510

file模块

增加文件

ansible rocky9 -a 'touch /tmp/test.txt'

屏幕截图 2026-08-13 212706

删除文件

ansible rocky9 -a 'rm -f  /tmp/test.txt'

屏幕截图 2026-08-13 212815

创建目录

[root@server ~]# ansible web -m file -a 'path=/data/app state=directory'

创建链接文件

path=链接文件

src=源文件

[root@server ~]# ansible web -m file -a 'path=/data/bbb.jpg src=aaa.jpg state=link'

copy模块

src #被复制到远程主机的本地文件。可以是绝对路径,也可以是相对路径。如果路径是一个目录,则会递 归复
制,用法类似于"rsync"
content #用于替换"src",可以直接指定文件的内容
dest #必选项,将源文件复制到的远程主机的**绝对路径**
backup #当文件内容发生改变后,在覆盖之前把源文件备份,备份文件包含时间信息
directory_mode #递归设定目录的权限,默认为系统默认权限
force #当目标主机包含该文件,但内容不同时,设为"yes",表示强制覆盖;设为"no",表示目标主机的 目标
位置不存在该文件才复制。默认为"yes"
others #所有的 file 模块中的选项可以在这里使用

复制文件

[root@server ~]# ansible web -m copy -a 'src=~/hello dest=/data/hello'

给定内容生成文件,并制定权限

[root@server ~]# ansible web -m copy -a 'content="I am keer\n" dest=/data/name mode=666'

覆盖

[root@server ~]# ansible web -m copy -a 'content="I am keerya\n" backup=yes dest=/data/name mode=666'

fetch模块

该模块用于从远程某主机获取(复制)文件到本地。

dest #用来存放文件的目录
src #在远程拉取的文件,并且必须是一个file,不能是目录

cron模块

用于管理cron计划任务的。

day # 日应该运行的工作( 1-31, *, */2, )
hour # 小时 ( 0-23, *, */2, )
minute # 分钟( 0-59, *, */2, )
month # 月( 1-12, * , */2, )
weekday # 周 ( 0-6 for Sunday-Saturday,, )
job # 指明运行的命令是什么
name # 定时任务描述
reboot # 任务在重启时运行,不建议使用,建议使用special_time
special_time # 特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly (每周),
daily(每天),hourly(每小时)
state # 指定状态,present表示添加定时任务,也是默认设置,absent表示删除定时任务
user # 以哪个用户的身份执行

yum模块

name #所安装的包的名称
state #present--->安装, latest--->安装最新的, absent---> 卸载软件。
update_cache #强制更新yum的缓存
conf_file #指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
disable_pgp_check #是否禁止GPG checking,只用于`present`or `latest`。
disablerepo #临时禁止使用yum库。 只用于安装或更新时。
enablerepo #临时使用的yum库。只用于安装或更新时。

service模块

arguments #命令行提供额外的参数
enabled #设置开机启动。 =yes/true 开机自启 ; =no/flase 开机关闭
name #服务名称
runlevel #开机启动的级别,一般不用指定。
sleep #在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。(定义在剧本中。)
state #有四种状态,分别为:#started--->启动服务
#stopped--->停止服务
#restarted--->重启服务
#reloaded--->重载配置

user模块

comment # 用户的描述信息
createhome # 是否创建家目录
force # 在使用state=absent时, 行为与userdel –force一致.
group # 指定基本组
groups # 指定附加组,如果指定为(groups=)表示删除所有组
home # 指定用户家目录
move_home # 如果设置为home=时, 试图将用户主目录移动到指定的目录
name # 指定用户名
non_unique # 该选项允许改变非唯一的用户ID值
password # 指定用户密码
remove # 在使用state=absent时, 行为是与userdel –remove一致; remove=yes //删除干净
shell # 指定默认shell
system # 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
uid # 指定用户的uid

group模块

gid #设置组的GID号
name #指定组的名称
state #指定组的状态,默认为创建,设置值为absent为删除
system #设置值为yes,表示创建为系统组

script模块

该模块用于将本机的脚本在被管理端的机器上运行。

[root@server ~]# vim /tmp/df.sh
#!/bin/bash
date >> /tmp/disk_total.log
df -lh >> /tmp/disk_total.log
[root@server ~]# chmod +x /tmp/df.sh

setup模块

该模块主要用于收集信息,是通过调用facts组件来实现的。

facts组件是Ansible用于采集被管机器设备信息的一个功能,我们可以使用setup模块查机器的所有facts信息,可以使用filter来查看指定信 息。整个facts信息被包装在一个JSON格式的数据结构中,ansible_facts是最上层的值。

facts就是变量,内建变量 ,每个主机的各种信息,cpu颗数、内存大小等。会存在facts中的某个变量中。调用后返回很多对应主机的信 息,在后面的操作中可以根据不同的信息来做不同的操作。如redhat系列用yum安装,而debian系列用apt来安装软件。

lineinfile

功能:修改或删除文件内容,与系统中的 sed 命令类似;

主要参数如下:
path #指定要操作的文件
regexp #使用正则表达式匹配对应的行
line #修改为新的内容
insertafter #将文本插入到“指定的行”之后
insertbefore #将文本插入到“指定的行”之前
state #删除对应的文本时,需要state=absent
backrefs #1.支持后向引用、2.当未匹配到内容则不操作文件
backup #是否在修改文件之前对文件进行备份
create #当要操作的文件并不存在时,是否创建对应的文件

Ansible Playbook

示例——httpd

---
- hosts: web
  become: yes
  tasks:
    - name: Install the Apache
      ansible.builtin.yum:
        name: httpd
        state: present

    - name: Start service httpd, if not started
      ansible.builtin.service:
        name: httpd
        state: started
        enable: yes

    - name: creat index.html
      ansible.builtin.copy:
        content: "www.westos.org\n"
        dest: /var/www/html/index.html

image-20260814102131881

测试运行

[devops@server1 ansible]$ ansible-playbook apache.yml 

image-20260814103007637

[devops@server1 ~]$ curl server2

屏幕截图 2026-08-14 103035

示例——返回httpd网页内容

---
- hosts: lamp
  become: yes
  tasks:
    - name: Install the Apache
      ansible.builtin.yum:
        name: httpd
        state: present

    - name: Start service httpd, if not started
      ansible.builtin.service:
        name: httpd
        state: started
        enabled: yes

    - name: creat index.html
      ansible.builtin.copy:
        content: "{{ ansible_hostname }}\n"
        dest: /var/www/html/index.html

    - name: Ensure the default Apaceh port is 80
      ansible.builtin.lineinfile:
        path: /etc/httpd/conf/httpd.conf
        regexp: '^Listen'
        insertafter: '^#Listen'
        line: Listen 80
      notify: restart service httpd

  handlers:
    - name: restart service httpd
      ansible.builtin.service:
        name: httpd
        state: restarted

- hosts: localhost
  gather_facts: false
  become: false
  tasks:
    - name: Check that you can connect (GET) to a page and it returns a status 200
      ansible.builtin.uri:
        url: http://192.168.234.162                                                         return_content: true
      register: result
    - name: Print return information from the previous task
      ansible.builtin.debug:
        var: result

image-20260814114902463

示例——keepalived

[devops@server1 root]$ cd /home/devops/ansible/
[devops@server1 ansible]$ sudo vim /etc/ansible/hosts

[hacluster]
192.168.234.161 state=MASTER pri=100
192.168.234.162 state=BACKUP pri=80

[hacluster:vars]
interface=eth0
router_id=61
vip=192.168.234.200

image-20260814140229739

[devops@server1 ansible]$ vim keepalived.yml
---
- hosts: hacluster
  #become: yes
  tasks:
    - name: Install the keepalived
      ansible.builtin.yum:
        name: keepalived
        state: present

    - name: configure the keepalived
      ansible.builtin.template:
        src: keepalived.conf.j2
        dest: /etc/keepalived/keepalived.conf
      notify: restart service keepalived


    - name: Start service kepalived
      ansible.builtin.service:
        name: keepalived
        state: started
        enabled: yes


  handlers:
    - name: restart service keepalived
      ansible.builtin.service:
        name: keepalived
        state: restarted

image-20260814140845647

[devops@server1 ansible]$ yum install -y keepalived.x86_64
[devops@server1 ansible]$ cd
[devops@server1 ~]$ cd /etc/keepalived/
[devops@server1 keepalived]$ ls
keepalived.conf
[devops@server1 keepalived]$ cp keepalived.conf /home/devops/ansible/
[devops@server1 keepalived]$ cd /home/devops/ansible/
[devops@server1 ansible]$ ls
apache.yml  keepalived.conf  keepalived.yml
[devops@server1 ansible]$ mv keepalived.conf keepalived.conf.j2
[devops@server1 ansible]$ vim keepalived.conf.j2
[devops@server1 ansible]$sudo ansible-playbook keepalived.yml

! Configuration File for keepalived

global_defs {
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}

vrrp_instance VI_1 {
state {{ state }}
interface {{ interface }}
virtual_router_id {{ router_id }}
priority {{ pri }}
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
{{ vip }}
}
}

image-20260814142002169

运行

[devops@server1 ansible]$ ansible-playbook keepalived.yml

image-20260814142622028

测试

[devops@server1 ansible]$ ip a

image-20260814142651271

示例——批量创建用户

[devops@server1 ansible]$ vim user.yml
---
- hosts: db
  tasks:
    - name: Add the user
      ansible.builtin.user:
        name: "{{  item.user  }}"
        password: "{{  item.pass | password_hash('sha512')  }}"
        state: present
      loop:
        - {user: user1, pass: pass1}
        - {user: user2, pass: pass2}

image-20260814151136023

运行

[devops@server1 ansible]$ ansible-playbook user.yml

image-20260814151448128

[root@node1 ~]# cat /etc/shadow

image-20260814151432604

示例——结合haproxy

[devops@server1 ansible]$ vim hosts

image-20260814172227978

[devops@server1 ansible]$ vim haproxy.yml
---
- hosts: haproxy,webservers
  become: yes
  tasks:
    - name: deploy haproxy
      block:
        - name: Install the haproxy
          ansible.builtin.yum:
            name: haproxy
            state: present

        - name: configure the haproxy
          ansible.builtin.template:
            src: haproxy.cfg.j2
            dest: /etc/haproxy/haproxy.cfg
          notify: restart service haproxy

        - name: Start service haproxy
          ansible.builtin.service:
            name: haproxy
            state: started
            enabled: yes
            
      when: ansible_hostname == 'server1'

    - name: deploy apache
      block:
        - name: Install the Apache
          ansible.builtin.yum:
            name: httpd
            state: present

        - name: Start service httpd
          ansible.builtin.service:
            name: httpd
            state: started
            enabled: yes
        - name: creat index.html
          ansible.builtin.copy:
            content: "{{ ansible_hostname }}\n"
            dest: /var/www/html/index.html

        - name: Ensure the default Apaceh port is {{ http_port }}
          ansible.builtin.template:
            src: httpd.conf.j2
            dest: /etc/httpd/conf/httpd.conf
          notify: restart service httpd
      when: ansible_hostname in groups['webservers']
      
  handlers:
    - name: restart service haproxy
      ansible.builtin.service:
        name: haproxy
        state: restarted
    - name: restart service httpd
      ansible.builtin.service:
        name: httpd
        state: restarted

image-20260814174626338

运行测试

[devops@server1 ansible]$ ansible-playbook haproxy.yml

image-20260816084721339

image-20260816084941528

image-20260816084948876

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐