【Ansible Playbook】实战秘籍:轻松实现服务器配置与管理的自动化(上)

🐇明明跟你说过:个人主页

🏅个人专栏:《Linux :从菜鸟到飞鸟的逆袭》🏅

🔖行路有良友,便是天堂🔖

目录

一、引言

1、什么是Ansible

2、Ansible应用场景

1. 配置管理

2. 应用部署

3. 云资源管理

4. 容器化部署

5. 基础设施自动化

二、Ansible Playbook基础

1、YAML语法简介

1. 基本结构

2. 键值对

3. 列表(数组)

4. 嵌套结构

5. 多行字符串

6. 注释

2、Playbook的基本元素

1. Play(剧本)

2. Task(任务)

3. Handler(处理器)

3、playbook工作流程

三、Tasks与Commands

1、Task的基本结构

2、循环(loops)在Tasks中的实现 

3、示例:管理用户账户与权限


一、引言

1、什么是Ansible

Ansible 是一个开源的自动化工具,广泛用于 IT 基础设施的配置管理、应用部署、任务自动化以及多节点系统的编排(Orchestration)。Ansible 由 Red Hat 维护,它以简洁、易用、无代理的设计理念受到广大开发者和运维人员的喜爱。

2、Ansible应用场景

1. 配置管理

Ansible 最常见的应用场景之一是 配置管理。它可以帮助自动化地配置服务器,确保系统和应用的配置一致。通过 Ansible Playbooks,我们可以定义系统的配置,安装软件包,修改文件内容,管理服务等。

示例场景:

  • 在多台服务器上安装和配置 Web 服务器(如 Apache、Nginx)。
  • 配置数据库服务器,确保配置一致性,如 MySQL、PostgreSQL。
  • 配置和部署应用程序环境(如 Java 环境、Node.js 环境等)。


2. 应用部署

Ansible 可以自动化 应用部署,确保应用的版本一致性,并简化多环境的部署过程。它支持从开发到生产环境的自动化流程,减少了人工操作的错误,并提高了发布效率。

示例场景:

  • 部署 Web 应用程序(如 Laravel、Django、Flask、Node.js 应用等)。
  • 自动化部署微服务架构中的不同服务。
  • 将应用程序自动发布到多个服务器或容器中。


3. 云资源管理

Ansible 能够与云平台(如 AWS、Azure、Google Cloud)集成,自动化云资源的创建、配置和管理。这使得云环境的资源部署变得更加高效和可重复。

示例场景:

  • 在 AWS 上自动创建 EC2 实例、配置安全组、设置负载均衡器。
  • 在 Azure 上管理虚拟机、存储账户和网络资源。
  • 自动化管理 Kubernetes 集群和云中的容器服务。

4. 容器化部署

Ansible 支持与容器化技术(如 Docker、Kubernetes)集成,可以自动化容器的构建、部署和管理。

示例场景:

  • 自动构建并部署 Docker 镜像。
  • 在 Kubernetes 集群中自动创建 Pods、部署服务和配置卷。
  • 管理 Docker Swarm 集群的节点和服务。


5. 基础设施自动化

Ansible 可以自动化基础设施的创建和配置,帮助管理员管理大规模基础设施,提升运维效率。

示例场景:

  • 自动化配置负载均衡器(如 HAProxy、Nginx)。
  • 自动配置网络设备、管理防火墙规则、配置 DNS。
  • 自动安装和配置监控工具,如 Prometheus、Zabbix 等。

  

二、Ansible Playbook基础

1、YAML语法简介

YAML(YAML Ain't Markup Language)是一种简洁、可读性强的数据序列化格式,常用于配置文件、数据交换和自动化工具(如 Ansible、Kubernetes、Docker Compose 等)的配置。YAML 以其简洁性和易读性,成为了许多现代工具和应用程序的首选配置格式。

1. 基本结构

YAML 使用缩进来表示层级结构,缩进通常使用 2 或 4 个空格,不使用制表符(Tab)。

key: value

例如:

name: John Doe
age: 30


2. 键值对

YAML 文件的基本构成是 键值对。键和值之间用冒号 : 分隔,冒号后必须有空格。

name: Alice
age: 25

 3. 列表(数组)

YAML 支持使用短横线 - 来表示列表(数组)。每个元素前面有一个短横线和一个空格。

fruits:
  - Apple
  - Banana
  - Cherry


4. 嵌套结构

YAML 通过缩进来表示嵌套结构。缩进通常是 2 个空格,表示层级。

person:
  name: John
  age: 30
  address:
    street: "123 Main St"
    city: "New York"


5. 多行字符串

YAML 提供了两种方式来表示多行字符串:

  • |:保留换行符,将文本按行存储(每个换行会保留)。
  • >:将换行符转换为空格,将文本合并为一行(多行文本会变成一个长字符串,换行会被转化为空格)。
text_with_newlines: |
  This is a line.
  This is another line.
  This is the third line.

text_without_newlines: >
  This is a very long line
  that is actually split
  into multiple lines.


6. 注释

YAML 支持使用 # 来添加注释。注释从 # 开始,直到行尾。

# This is a comment
name: Alice  # This is an inline comment

  

2、Playbook的基本元素

在 Ansible 中,Playbook 是自动化流程的核心,它包含了一系列的 plays。每个 play 会执行一些任务(tasks),而任务的执行顺序由 Playbook 中定义的 handlers 来控制。

1. Play(剧本)

Play 是 Playbook 中的一个基本单元,表示你希望在目标主机上执行的操作。每个 Play 定义了:

  • 目标主机:Playbook 中的主机(hosts)字段指定哪些主机将执行任务。
  • 任务执行顺序:Playbook 中的任务(tasks)会按顺序在目标主机上执行。
  • 权限:become 用来指定是否以超级用户(root)身份运行任务。


2. Task(任务)

Task 是 Play 中的具体操作,它定义了你希望在目标主机上执行的命令或动作。任务通常由一个模块(如 yum、apt、service、copy)执行。每个任务有以下组成部分:

  • 任务名称(name):描述任务目的。
  • 模块名称:任务中用来执行操作的模块(例如 yum、apt、copy、service 等)。
  • 模块参数:指定模块的参数(例如,安装的软件包名、服务名、文件路径等)。


3. Handler(处理器)

Handler 是 Playbook 中的一种特殊类型的任务,它们通常用于执行某些需要在任务变化时触发的操作。与普通任务不同,handler 只有在被显式通知时才会执行。通常用于执行诸如重启服务、重新加载配置等操作。

  • 触发条件:当任务执行导致某些变化时,才会通知相关的 handler。
  • 通知触发:任务可以使用 notify 字段来通知 handler 执行某个操作。

   

3、playbook工作流程

1. 加载和解析 Playbook:

  • Ansible 开始执行 Playbook 时,首先会加载并解析 Playbook 文件。Playbook 是 YAML 格式的文件,Ansible 会通过解析文件来理解里面定义的各个 Play 和任务(tasks)。
  • 每个 Playbook 文件可以包含多个 Play,每个 Play 会指定需要在哪些主机上执行任务。

2. 加载清单(Inventory):

  • Inventory(清单)是一个包含主机和主机组的文件(通常是一个INI或YAML格式文件)。Ansible 会根据清单文件来确定需要执行 Playbook 的目标主机。
  • 清单文件可以是静态的(手动配置)或者动态的(由某些脚本或 API 动态生成)。

3. 进入每个 Play 的执行:

  • Ansible 会逐个 Play 地执行 Playbook 文件中的每个 Play。
  • 每个 Play 会指定 hosts(目标主机),也可以定义运行任务时是否需要 become(是否以超级用户身份运行)等相关属性。

4. 执行 Tasks:

  • 在每个 Play 中,Ansible 会逐个执行 task。每个任务对应着在目标主机上执行的操作(例如安装软件、修改配置文件、启动服务等)。
  • 每个任务执行时,Ansible 会使用相应的模块(如 yum、apt、service、file)来完成任务,并根据任务的状态(成功或失败)记录执行结果。
  • 每个任务执行时会检查其状态,并根据任务的结果决定是否执行下一个任务。

   

5. 触发 Handlers:

  • Handler 是 Ansible 中的一种特殊类型的任务。与普通任务不同,handler 只有在任务执行时发生变更(例如文件被修改、服务被重启等)时才会被触发。
  • 如果某个任务成功地通知了 handler(通过 notify),handler 会在所有任务完成后执行(通常用于重启服务或重新加载配置等操作)。

6. 处理任务的状态:

  • 每个任务执行后,Ansible 会检查任务的状态并记录其结果。任务可能的状态包括:
  • changed:任务的执行导致目标主机的状态发生了变化(例如文件被更新、服务被启动)。
  • ok:任务执行没有导致状态变化,但执行仍然成功(例如服务已经处于预期状态,无需更改)。
  • failed:任务执行失败(例如软件包安装失败、服务启动失败)。
  • skipped:任务被跳过,通常是因为条件语句(如 when)不满足。

7. 执行完所有 Plays:

  • Playbook 中的所有 Play 执行完后,Ansible 会检查是否有未执行的 handlers。如果有,Ansible 会执行相应的 handler。

8. 结果报告:

  • Playbook 执行完毕后,Ansible 会生成一个执行报告。报告包含了每个任务的执行状态、目标主机的状态以及每个任务是否发生了变化。你可以查看执行日志来确认每个任务的成功与失败。

   

三、Tasks与Commands

1、Task的基本结构

一个 Task 通常包含以下几部分:

  1. name:任务名称,用于描述这个任务的目的,通常是一个简短的文本。
  2. module_name:执行任务的模块。Ansible 提供了丰富的模块库,每个模块实现不同的功能。
  3. module_parameters:模块的参数,用来指定该任务所需的具体配置或操作细节。
  4. when:条件判断,只有满足某个条件时才会执行任务。
  5. notify:当任务发生变化时,通知触发 handler 执行。
  6. register:将任务的执行结果存储到一个变量中,可以在后续的任务中使用。
  7. tags:标签,用于给任务打标签,便于运行时选择性执行。
  8. become:是否以超级用户身份执行该任务。

Task 示例结构
 

- name: Install Nginx
  apt:
    name: nginx
    state: present
  become: yes
  when: ansible_facts['distribution'] == 'Ubuntu'
  notify:
    - Restart Nginx
  register: nginx_installation
  tags:
    - webserver

  • name: Install Nginx 是任务的描述,用来标明该任务的目的。
  • apt 是 Ansible 提供的模块,用来管理 Debian 系统上的软件包。在这个例子中,apt 模块用于安装 nginx 软件包。
  • name: nginx 指定了要安装的软件包名称。
  • state: present 表示确保软件包 nginx 已安装。如果已经安装,它不会进行任何更改。如果没有安装,它会安装该软件包。
  • become: yes 表示该任务需要以 root 用户身份执行。如果没有该选项,任务将作为当前用户执行。
  • when: ansible_facts['distribution'] == 'Ubuntu' 表示该任务仅在目标主机的操作系统为 Ubuntu 时才会执行。ansible_facts['distribution'] 是 Ansible 收集的主机事实信息,存储了关于目标主机的详细信息。
  • notify: - Restart Nginx 表示如果该任务导致目标主机状态发生变化(例如软件包被安装),则会触发名为 Restart Nginx 的 handler 执行。
  • register: nginx_installation 将该任务的执行结果保存到变量 nginx_installation 中。后续可以使用该变量判断任务是否执行成功或获取其输出。
  • tags: [webserver] 给任务打上标签,便于在运行时选择性地执行特定的任务。例如,在执行 Playbook 时,可以使用 --tags webserver 参数只执行标记为 webserver 的任务。

     

2、循环(loops)在Tasks中的实现 

loop 是现代版本的 Ansible 推荐使用的循环语法。它可以遍历任何类型的可迭代对象,例如列表、字典等。

示例:循环安装多个软件包
 

- name: Install multiple packages
  apt:
    name: "{{ item }}"
    state: present
  loop:
    - nginx
    - vim
    - curl


在这个示例中,任务会循环安装列表中的软件包 nginx、vim 和 curl。item 是循环中的当前元素,它会依次取 nginx、vim 和 curl。

3、示例:管理用户账户与权限

目标

  1. 创建用户账户。
  2. 设置密码。
  3. 将用户添加到一个或多个组。
  4. 设置用户的主目录权限。
  5. 管理用户的 SSH 公钥。

Playbook 示例

---
- name: Manage user accounts and permissions
  hosts: all
  become: yes  # 以 root 用户身份执行

  tasks:
    # 创建用户 user1 和 user2
    - name: Ensure user user1 is present
      user:
        name: user1
        state: present
        shell: /bin/bash
        comment: "User 1"
        home: /home/user1
        create_home: yes
        password: "{{ 'password123' | password_hash('sha512') }}"
        update_password: on_create  # 仅在用户创建时设置密码

    - name: Ensure user user2 is present
      user:
        name: user2
        state: present
        shell: /bin/bash
        comment: "User 2"
        home: /home/user2
        create_home: yes
        password: "{{ 'password456' | password_hash('sha512') }}"
        update_password: on_create

    # 创建一个用户组
    - name: Ensure group developers exists
      group:
        name: developers
        state: present

    # 将用户添加到开发者组
    - name: Add user user1 to developers group
      user:
        name: user1
        group: developers
        append: yes

    - name: Add user user2 to developers group
      user:
        name: user2
        group: developers
        append: yes

    # 设置用户的主目录权限
    - name: Set permissions for user1's home directory
      file:
        path: /home/user1
        owner: user1
        group: developers
        mode: '0755'

    - name: Set permissions for user2's home directory
      file:
        path: /home/user2
        owner: user2
        group: developers
        mode: '0755'

    # 管理 SSH 公钥(可选)
    - name: Add SSH public key for user1
      authorized_key:
        user: user1
        state: present
        key: "{{ lookup('file', '/path/to/user1_ssh_key.pub') }}"  # 公钥的文件路径

    - name: Add SSH public key for user2
      authorized_key:
        user: user2
        state: present
        key: "{{ lookup('file', '/path/to/user2_ssh_key.pub') }}"  # 公钥的文件路径


解释
user 模块:

  • 创建用户:使用 user 模块来确保 user1 和 user2 用户存在。
  • state: present:确保用户存在。
  • password: "{{ 'password123' | password_hash('sha512') }}":为用户设置密码,并使用 password_hash 过滤器对密码进行加密。
  • create_home: yes:如果用户没有主目录,则会自动创建主目录。
  • update_password: on_create:仅在用户创建时设置密码。

group 模块:

  • 创建用户组:使用 group 模块创建一个名为 developers 的组,确保该组存在。

user 模块(添加用户到组):

  • 使用 group: developers 参数将用户添加到 developers 组。
  • append: yes 表示如果用户已经属于该组,不会移除其他组。

file 模块:

  • 设置主目录权限:使用 file 模块设置用户主目录的权限,确保主目录的所有者是对应的用户,组是 developers,权限是 0755。

authorized_key 模块:

  • 管理 SSH 公钥:使用 authorized_key 模块将 SSH 公钥添加到用户的 ~/.ssh/authorized_keys 文件中,从而允许用户通过 SSH 公钥认证登录。
  • key 参数通过 lookup('file', 'path_to_key') 引用本地文件的内容。

   

   💕💕💕每一次的分享都是一次成长的旅程,感谢您的陪伴和关注。希望这些关于Linux的文章能陪伴您走过技术的一段旅程,共同见证成长和进步!😺😺😺

🧨🧨🧨让我们一起在技术的海洋中探索前行,共同书写美好的未来!!!  

评论 60
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明明跟你说过

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值