简体中文 繁體中文 English Deutsch 한국 사람 بالعربية TÜRKÇE português คนไทย Français Japanese

站内搜索

搜索

活动公告

02-12 00:01
通知:春节期间开放常规注册【2026-2-15 00:00】至【2026-2-17 00:00】(UTC+8)
02-12 00:00
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

Ansible自动化运维实战课程系统管理员提升工作效率简化IT管理必备技能从入门到精通

SunJu_FaceMall

3万

主题

451

科技点

3万

积分

大区版主

碾压王

积分
32179

立华奏

发表于 2025-10-7 11:00:00 | 显示全部楼层 |阅读模式 [标记阅至此楼]

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言:为什么需要Ansible自动化运维

在当今快速发展的IT环境中,系统管理员面临着日益复杂的基础设施管理挑战。手动配置和管理数十、数百甚至数千台服务器不仅耗时耗力,而且容易出错。Ansible作为一款领先的IT自动化工具,为系统管理员提供了强大的解决方案,能够显著提升工作效率,简化IT管理流程。本文将带您从Ansible的基础概念开始,逐步深入到实际应用和高级技巧,帮助您全面掌握这一必备技能。

一、Ansible基础入门

1.1 什么是Ansible

Ansible是一款开源的IT自动化工具,它允许系统管理员自动化配置管理、应用部署、云 provisioning 和许多其他IT任务。与其他自动化工具相比,Ansible的最大优势在于其简单性和无代理架构。

Ansible的核心特点:

• 无代理架构:不需要在被管理节点上安装任何客户端软件
• 简单易学:使用YAML语言编写自动化任务,语法直观易懂
• 强大的模块系统:提供大量预置模块,覆盖各种IT管理需求
• 可扩展性:支持自定义模块和插件
• 推送式配置:通过SSH推送配置,确保系统状态一致

1.2 Ansible工作原理

Ansible采用控制节点(Control Node)和被管理节点(Managed Nodes)的架构。控制节点是安装Ansible的机器,被管理节点则是需要被配置和管理的目标服务器。
  1. +----------------+      SSH      +------------------+
  2. |                | <-----------> |                  |
  3. |  Control Node  |              |  Managed Node    |
  4. |  (Ansible)     |              |  (Target Server)|
  5. |                |              |                  |
  6. +----------------+              +------------------+
复制代码

工作流程如下:

1. 管理员在控制节点上编写Playbook(定义任务的YAML文件)
2. Ansible通过SSH连接到被管理节点
3. 在被管理节点上执行定义的任务
4. 收集并返回执行结果

1.3 安装Ansible

安装Ansible非常简单,支持多种操作系统:

在CentOS/RHEL上安装:
  1. # 安装EPEL仓库
  2. sudo yum install epel-release -y
  3. # 安装Ansible
  4. sudo yum install ansible -y
复制代码

在Ubuntu/Debian上安装:
  1. # 更新包索引
  2. sudo apt update
  3. # 安装Ansible
  4. sudo apt install ansible -y
复制代码

使用pip安装(推荐最新版本):
  1. # 安装pip
  2. sudo apt install python3-pip -y  # Ubuntu/Debian
  3. sudo yum install python3-pip -y  # CentOS/RHEL
  4. # 使用pip安装Ansible
  5. pip3 install ansible
复制代码

安装完成后,可以通过以下命令验证安装:
  1. ansible --version
复制代码

1.4 Ansible基本配置

Ansible的主配置文件位于/etc/ansible/ansible.cfg,您可以根据需要进行自定义配置。以下是一些常用配置项:
  1. [defaults]
  2. # 库存文件的位置
  3. inventory = /etc/ansible/hosts
  4. # SSH连接的用户名
  5. remote_user = ansible
  6. # 是否检查SSH主机密钥
  7. host_key_checking = False
  8. # 并行执行任务的数量
  9. forks = 10
  10. # 默认执行模块的超时时间(秒)
  11. timeout = 30
复制代码

二、Ansible核心组件详解

2.1 Inventory(清单)

Inventory是Ansible管理的主机列表,它定义了哪些服务器需要被管理以及如何组织它们。Inventory可以是静态的文本文件,也可以是动态生成的脚本。

静态Inventory示例:
  1. # /etc/ansible/hosts
  2. [webservers]
  3. web1.example.com
  4. web2.example.com
  5. 192.168.1.10
  6. [databases]
  7. db1.example.com ansible_user=admin ansible_port=2222
  8. db2.example.com
  9. [all:vars]
  10. ansible_ssh_private_key_file=~/.ssh/ansible_key
  11. [webservers:vars]
  12. http_port=8080
复制代码

动态Inventory示例:
  1. #!/bin/bash
  2. # 简单的动态inventory脚本示例
  3. case $1 in
  4.     --list)
  5.         echo '{
  6.             "webservers": {
  7.                 "hosts": ["web1.example.com", "web2.example.com"],
  8.                 "vars": {
  9.                     "http_port": 8080
  10.                 }
  11.             },
  12.             "databases": {
  13.                 "hosts": ["db1.example.com", "db2.example.com"]
  14.             }
  15.         }'
  16.         ;;
  17.     --host)
  18.         echo '{"ansible_host": "'$2'"}'
  19.         ;;
  20.     *)
  21.         echo "Usage: $0 --list or --host <hostname>"
  22.         exit 1
  23.         ;;
  24. esac
复制代码

2.2 Modules(模块)

Ansible模块是执行具体任务的工具,它们是Ansible的核心功能单元。Ansible提供了大量内置模块,同时也支持自定义模块。

常用模块示例:

1. ping模块- 测试主机连通性
  1. - name: Test connectivity
  2.   ping:
复制代码

2. yum/apt模块- 管理软件包
  1. # CentOS/RHEL系统
  2. - name: Install nginx
  3.   yum:
  4.     name: nginx
  5.     state: present
  6. # Ubuntu/Debian系统
  7. - name: Install nginx
  8.   apt:
  9.     name: nginx
  10.     state: present
  11.     update_cache: yes
复制代码

3. copy模块- 复制文件到远程主机
  1. - name: Copy configuration file
  2.   copy:
  3.     src: /local/path/to/file.conf
  4.     dest: /remote/path/to/file.conf
  5.     owner: root
  6.     group: root
  7.     mode: '0644'
  8.     backup: yes
复制代码

4. template模块- 使用Jinja2模板生成文件
  1. - name: Generate configuration from template
  2.   template:
  3.     src: /templates/config.j2
  4.     dest: /etc/app/config.conf
  5.     owner: appuser
  6.     group: appgroup
  7.     mode: '0640'
复制代码

5. service模块- 管理系统服务
  1. - name: Start and enable nginx service
  2.   service:
  3.     name: nginx
  4.     state: started
  5.     enabled: yes
复制代码

2.3 Playbooks(剧本)

Playbook是Ansible的核心配置、部署和编排语言,它使用YAML格式定义一系列任务。Playbook可以非常简单,也可以非常复杂,取决于您的需求。

基本Playbook示例:
  1. ---
  2. - name: Install and configure web server
  3.   hosts: webservers
  4.   become: yes  # 使用sudo权限执行任务
  5.   
  6.   tasks:
  7.     - name: Install nginx
  8.       yum:
  9.         name: nginx
  10.         state: present
  11.    
  12.     - name: Create website directory
  13.       file:
  14.         path: /var/www/html
  15.         state: directory
  16.         owner: nginx
  17.         group: nginx
  18.         mode: '0755'
  19.    
  20.     - name: Copy website content
  21.       copy:
  22.         src: files/index.html
  23.         dest: /var/www/html/index.html
  24.    
  25.     - name: Start nginx service
  26.       service:
  27.         name: nginx
  28.         state: started
  29.         enabled: yes
复制代码

带变量的Playbook示例:
  1. ---
  2. - name: Configure application server
  3.   hosts: appservers
  4.   become: yes
  5.   vars:
  6.     app_user: appuser
  7.     app_group: appgroup
  8.     app_dir: /opt/myapp
  9.     app_version: 1.2.3
  10.   
  11.   tasks:
  12.     - name: Create application user
  13.       user:
  14.         name: "{{ app_user }}"
  15.         group: "{{ app_group }}"
  16.         system: yes
  17.    
  18.     - name: Create application directory
  19.       file:
  20.         path: "{{ app_dir }}"
  21.         state: directory
  22.         owner: "{{ app_user }}"
  23.         group: "{{ app_group }}"
  24.         mode: '0755'
  25.    
  26.     - name: Download and extract application
  27.       unarchive:
  28.         src: "https://example.com/releases/myapp-{{ app_version }}.tar.gz"
  29.         dest: "{{ app_dir }}"
  30.         remote_src: yes
  31.         owner: "{{ app_user }}"
  32.         group: "{{ app_group }}"
复制代码

2.4 Roles(角色)

Roles是Ansible中组织Playbook的一种方式,它允许您将任务、变量、文件和模板按照逻辑结构组织在一起,提高代码的可重用性和可维护性。

Role的目录结构:
  1. site.yml
  2. webservers.yml
  3. fooservers.yml
  4. roles/
  5.     common/
  6.         tasks/
  7.         handlers/
  8.         files/
  9.         templates/
  10.         vars/
  11.         defaults/
  12.         meta/
  13.     webservers/
  14.         tasks/
  15.         handlers/
  16.         files/
  17.         templates/
  18.         vars/
  19.         defaults/
  20.         meta/
复制代码

使用Role的Playbook示例:
  1. ---
  2. - name: Configure web servers
  3.   hosts: webservers
  4.   become: yes
  5.   
  6.   roles:
  7.     - common
  8.     - nginx
  9.     - php-fpm
复制代码

Role中的tasks/main.yml示例:
  1. ---
  2. # roles/nginx/tasks/main.yml
  3. - name: Install nginx
  4.   yum:
  5.     name: nginx
  6.     state: present
  7.   
  8. - name: Create nginx directories
  9.   file:
  10.     path: "{{ item }}"
  11.     state: directory
  12.     owner: nginx
  13.     group: nginx
  14.     mode: '0755'
  15.   with_items:
  16.     - /etc/nginx/conf.d
  17.     - /var/www/html
  18.   
  19. - name: Copy nginx configuration
  20.   template:
  21.     src: nginx.conf.j2
  22.     dest: /etc/nginx/nginx.conf
  23.     owner: root
  24.     group: root
  25.     mode: '0644'
  26.   notify: Restart nginx
复制代码

三、Ansible实战案例

3.1 Web服务器自动化部署

在这个案例中,我们将使用Ansible自动化部署一个LEMP(Linux, Nginx, MariaDB, PHP)栈。

项目结构:
  1. lemp-deploy/
  2. ├── inventory.ini
  3. ├── site.yml
  4. └── roles/
  5.     ├── common/
  6.     │   ├── tasks/
  7.     │   │   └── main.yml
  8.     │   └── handlers/
  9.     │       └── main.yml
  10.     ├── nginx/
  11.     │   ├── tasks/
  12.     │   │   └── main.yml
  13.     │   ├── handlers/
  14.     │   │   └── main.yml
  15.     │   ├── templates/
  16.     │   │   └── nginx.conf.j2
  17.     │   └── vars/
  18.     │       └── main.yml
  19.     ├── mariadb/
  20.     │   ├── tasks/
  21.     │   │   └── main.yml
  22.     │   ├── handlers/
  23.     │   │   └── main.yml
  24.     │   └── templates/
  25.     │       └── my.cnf.j2
  26.     └── php/
  27.         ├── tasks/
  28.         │   └── main.yml
  29.         ├── handlers/
  30.         │   └── main.yml
  31.         ├── templates/
  32.         │   └── php.ini.j2
  33.         └── vars/
  34.             └── main.yml
复制代码

inventory.ini文件:
  1. [webservers]
  2. web1.example.com ansible_user=admin
  3. web2.example.com ansible_user=admin
  4. [webservers:vars]
  5. ansible_python_interpreter=/usr/bin/python3
复制代码

site.yml文件:
  1. ---
  2. - name: Deploy LEMP stack
  3.   hosts: webservers
  4.   become: yes
  5.   
  6.   roles:
  7.     - common
  8.     - nginx
  9.     - mariadb
  10.     - php
复制代码

roles/common/tasks/main.yml文件:
  1. ---
  2. - name: Update system packages
  3.   yum:
  4.     name: '*'
  5.     state: latest
  6.     update_cache: yes
  7.   when: ansible_os_family == "RedHat"
  8. - name: Update system packages
  9.   apt:
  10.     upgrade: dist
  11.     update_cache: yes
  12.   when: ansible_os_family == "Debian"
  13. - name: Install common packages
  14.   package:
  15.     name:
  16.       - vim
  17.       - htop
  18.       - tree
  19.       - git
  20.       - wget
  21.       - curl
  22.     state: present
  23. - name: Set timezone to UTC
  24.   timezone:
  25.     name: UTC
  26. - name: Configure firewall
  27.   firewalld:
  28.     service: "{{ item }}"
  29.     permanent: yes
  30.     state: enabled
  31.     immediate: yes
  32.   with_items:
  33.     - ssh
  34.     - http
  35.     - https
  36.   when: ansible_os_family == "RedHat"
复制代码

roles/nginx/tasks/main.yml文件:
  1. ---
  2. - name: Install nginx
  3.   package:
  4.     name: nginx
  5.     state: present
  6. - name: Create nginx directories
  7.   file:
  8.     path: "{{ item }}"
  9.     state: directory
  10.     owner: nginx
  11.     group: nginx
  12.     mode: '0755'
  13.   with_items:
  14.     - /etc/nginx/conf.d
  15.     - /var/www/html
  16.     - /var/log/nginx
  17. - name: Copy nginx configuration
  18.   template:
  19.     src: nginx.conf.j2
  20.     dest: /etc/nginx/nginx.conf
  21.     owner: root
  22.     group: root
  23.     mode: '0644'
  24.   notify: Restart nginx
  25. - name: Create default website index page
  26.   copy:
  27.     content: |
  28.       <!DOCTYPE html>
  29.       <html>
  30.       <head>
  31.           <title>Welcome to Nginx!</title>
  32.       </head>
  33.       <body>
  34.           <h1>Nginx is working!</h1>
  35.           <p>This page is served by Nginx on {{ ansible_hostname }}</p>
  36.       </body>
  37.       </html>
  38.     dest: /var/www/html/index.html
  39.     owner: nginx
  40.     group: nginx
  41.     mode: '0644'
  42. - name: Start and enable nginx
  43.   service:
  44.     name: nginx
  45.     state: started
  46.     enabled: yes
复制代码

roles/nginx/templates/nginx.conf.j2文件:
  1. user nginx;
  2. worker_processes {{ ansible_processor_vcpus }};
  3. error_log /var/log/nginx/error.log;
  4. pid /run/nginx.pid;
  5. events {
  6.     worker_connections 1024;
  7. }
  8. http {
  9.     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
  10.                       '$status $body_bytes_sent "$http_referer" '
  11.                       '"$http_user_agent" "$http_x_forwarded_for"';
  12.     access_log  /var/log/nginx/access.log  main;
  13.     sendfile            on;
  14.     tcp_nopush          on;
  15.     tcp_nodelay         on;
  16.     keepalive_timeout   65;
  17.     types_hash_max_size 2048;
  18.     include             /etc/nginx/mime.types;
  19.     default_type        application/octet-stream;
  20.     include /etc/nginx/conf.d/*.conf;
  21. }
复制代码

roles/mariadb/tasks/main.yml文件:
  1. ---
  2. - name: Install MariaDB
  3.   package:
  4.     name:
  5.       - mariadb-server
  6.       - MariaDB-client
  7.       - python3-PyMySQL
  8.     state: present
  9.   when: ansible_os_family == "RedHat"
  10. - name: Install MariaDB
  11.   package:
  12.     name:
  13.       - mariadb-server
  14.       - mariadb-client
  15.       - python3-pymysql
  16.     state: present
  17.   when: ansible_os_family == "Debian"
  18. - name: Start and enable MariaDB
  19.   service:
  20.     name: mariadb
  21.     state: started
  22.     enabled: yes
  23. - name: Set MariaDB root password
  24.   mysql_user:
  25.     name: root
  26.     password: "{{ mariadb_root_password }}"
  27.     host: localhost
  28.     login_unix_socket: /var/lib/mysql/mysql.sock
  29. - name: Remove anonymous users
  30.   mysql_user:
  31.     name: ''
  32.     host_all: yes
  33.     state: absent
  34.     login_user: root
  35.     login_password: "{{ mariadb_root_password }}"
  36. - name: Remove test database
  37.   mysql_db:
  38.     name: test
  39.     state: absent
  40.     login_user: root
  41.     login_password: "{{ mariadb_root_password }}"
  42. - name: Create application database
  43.   mysql_db:
  44.     name: "{{ app_db_name }}"
  45.     state: present
  46.     login_user: root
  47.     login_password: "{{ mariadb_root_password }}"
  48. - name: Create application database user
  49.   mysql_user:
  50.     name: "{{ app_db_user }}"
  51.     password: "{{ app_db_password }}"
  52.     priv: "{{ app_db_name }}.*:ALL"
  53.     host: 'localhost'
  54.     state: present
  55.     login_user: root
  56.     login_password: "{{ mariadb_root_password }}"
复制代码

roles/php/tasks/main.yml文件:
  1. ---
  2. - name: Install PHP and extensions
  3.   package:
  4.     name:
  5.       - php
  6.       - php-fpm
  7.       - php-mysqlnd
  8.       - php-gd
  9.       - php-xml
  10.       - php-mbstring
  11.       - php-json
  12.     state: present
  13.   when: ansible_os_family == "RedHat"
  14. - name: Install PHP and extensions
  15.   package:
  16.     name:
  17.       - php
  18.       - php-fpm
  19.       - php-mysql
  20.       - php-gd
  21.       - php-xml
  22.       - php-mbstring
  23.       - php-json
  24.     state: present
  25.   when: ansible_os_family == "Debian"
  26. - name: Configure PHP
  27.   template:
  28.     src: php.ini.j2
  29.     dest: /etc/php.ini
  30.     owner: root
  31.     group: root
  32.     mode: '0644'
  33.   notify: Restart PHP-FPM
  34. - name: Start and enable PHP-FPM
  35.   service:
  36.     name: php-fpm
  37.     state: started
  38.     enabled: yes
复制代码

执行这个Playbook:
  1. ansible-playbook -i inventory.ini site.yml
复制代码

3.2 数据库集群自动化配置

在这个案例中,我们将使用Ansible自动化配置一个MariaDB Galera集群。

项目结构:
  1. mariadb-cluster/
  2. ├── inventory.ini
  3. ├── site.yml
  4. └── roles/
  5.     └── mariadb-galera/
  6.         ├── tasks/
  7.         │   ├── main.yml
  8.         │   ├── install.yml
  9.         │   ├── configure.yml
  10.         │   └── bootstrap.yml
  11.         ├── handlers/
  12.         │   └── main.yml
  13.         ├── templates/
  14.         │   ├── galera.cnf.j2
  15.         │   └── my.cnf.j2
  16.         └── vars/
  17.             └── main.yml
复制代码

inventory.ini文件:
  1. [galera_nodes]
  2. db1.example.com ansible_user=admin
  3. db2.example.com ansible_user=admin
  4. db3.example.com ansible_user=admin
  5. [galera_nodes:vars]
  6. ansible_python_interpreter=/usr/bin/python3
  7. cluster_name=galera_cluster
  8. wsrep_sst_method=xtrabackup-v2
  9. wsrep_sst_auth=sst_user:sst_password
复制代码

site.yml文件:
  1. ---
  2. - name: Configure MariaDB Galera Cluster
  3.   hosts: galera_nodes
  4.   become: yes
  5.   
  6.   roles:
  7.     - mariadb-galera
复制代码

roles/mariadb-galera/tasks/main.yml文件:
  1. ---
  2. - name: Include installation tasks
  3.   include_tasks: install.yml
  4. - name: Include configuration tasks
  5.   include_tasks: configure.yml
  6. - name: Bootstrap the cluster on the first node
  7.   include_tasks: bootstrap.yml
  8.   when: inventory_hostname == groups['galera_nodes'][0]
  9.   run_once: true
复制代码

roles/mariadb-galera/tasks/install.yml文件:
  1. ---
  2. - name: Install MariaDB repository
  3.   yum_repository:
  4.     name: mariadb
  5.     description: MariaDB Repository
  6.     baseurl: http://yum.mariadb.org/10.5/centos7-amd64
  7.     gpgkey: https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
  8.     gpgcheck: yes
  9.   when: ansible_os_family == "RedHat"
  10. - name: Install MariaDB and Galera packages
  11.   package:
  12.     name:
  13.       - MariaDB-server
  14.       - MariaDB-client
  15.       - MariaDB-backup
  16.       - galera-4
  17.       - rsync
  18.       - python3-PyMySQL
  19.     state: present
  20.   when: ansible_os_family == "RedHat"
  21. - name: Install MariaDB and Galera packages
  22.   package:
  23.     name:
  24.       - mariadb-server
  25.       - mariadb-client
  26.       - mariadb-backup
  27.       - galera-3
  28.       - rsync
  29.       - python3-pymysql
  30.     state: present
  31.   when: ansible_os_family == "Debian"
  32. - name: Stop MariaDB service
  33.   service:
  34.     name: mariadb
  35.     state: stopped
复制代码

roles/mariadb-galera/tasks/configure.yml文件:
  1. ---
  2. - name: Create MariaDB configuration directory
  3.   file:
  4.     path: /etc/mysql/mariadb.conf.d
  5.     state: directory
  6.     owner: root
  7.     group: root
  8.     mode: '0755'
  9. - name: Copy MariaDB server configuration
  10.   template:
  11.     src: my.cnf.j2
  12.     dest: /etc/mysql/my.cnf
  13.     owner: root
  14.     group: root
  15.     mode: '0644'
  16. - name: Copy Galera configuration
  17.   template:
  18.     src: galera.cnf.j2
  19.     dest: /etc/mysql/mariadb.conf.d/galera.cnf
  20.     owner: root
  21.     group: root
  22.     mode: '0644'
  23. - name: Create SST user
  24.   mysql_user:
  25.     name: "{{ wsrep_sst_auth.split(':')[0] }}"
  26.     password: "{{ wsrep_sst_auth.split(':')[1] }}"
  27.     priv: "*.*:RELOAD,LOCK TABLES,REPLICATION CLIENT"
  28.     host: localhost
  29.     login_unix_socket: /var/run/mysqld/mysqld.sock
  30.   ignore_errors: yes
复制代码

roles/mariadb-galera/tasks/bootstrap.yml文件:
  1. ---
  2. - name: Bootstrap the first node
  3.   command: galera_new_cluster
  4.   when: inventory_hostname == groups['galera_nodes'][0]
  5. - name: Start MariaDB on other nodes
  6.   service:
  7.     name: mariadb
  8.     state: started
  9.   when: inventory_hostname != groups['galera_nodes'][0]
  10. - name: Check cluster status
  11.   command: mysql -ne "SHOW STATUS LIKE 'wsrep_cluster_size'"
  12.   register: cluster_status
  13.   changed_when: false
  14. - name: Display cluster status
  15.   debug:
  16.     msg: "Cluster size: {{ cluster_status.stdout.split()[3] }}"
复制代码

roles/mariadb-galera/templates/galera.cnf.j2文件:
  1. [galera]
  2. # Mandatory settings
  3. wsrep_on=ON
  4. wsrep_provider=/usr/lib/galera/libgalera_smm.so
  5. wsrep_cluster_name="{{ cluster_name }}"
  6. wsrep_cluster_address="gcomm://{% for host in groups['galera_nodes'] %}{{ host }}{% if not loop.last %},{% endif %}{% endfor %}"
  7. wsrep_node_address="{{ ansible_default_ipv4.address }}"
  8. wsrep_node_name="{{ inventory_hostname }}"
  9. # Optional settings
  10. wsrep_sst_method={{ wsrep_sst_method }}
  11. wsrep_sst_auth={{ wsrep_sst_auth }}
  12. binlog_format=ROW
  13. default_storage_engine=InnoDB
  14. innodb_autoinc_lock_mode=2
复制代码

执行这个Playbook:
  1. ansible-playbook -i inventory.ini site.yml
复制代码

3.3 Docker容器自动化管理

在这个案例中,我们将使用Ansible自动化部署和管理Docker容器。

项目结构:
  1. docker-deploy/
  2. ├── inventory.ini
  3. ├── site.yml
  4. └── roles/
  5.     ├── docker/
  6.     │   ├── tasks/
  7.     │   │   └── main.yml
  8.     │   └── handlers/
  9.     │       └── main.yml
  10.     └── webapp/
  11.         ├── tasks/
  12.         │   └── main.yml
  13.         ├── templates/
  14.         │   ├── docker-compose.yml.j2
  15.         │   └── nginx.conf.j2
  16.         └── vars/
  17.             └── main.yml
复制代码

inventory.ini文件:
  1. [docker_hosts]
  2. app1.example.com ansible_user=admin
  3. app2.example.com ansible_user=admin
  4. [docker_hosts:vars]
  5. ansible_python_interpreter=/usr/bin/python3
复制代码

site.yml文件:
  1. ---
  2. - name: Deploy Docker containers
  3.   hosts: docker_hosts
  4.   become: yes
  5.   
  6.   roles:
  7.     - docker
  8.     - webapp
复制代码

roles/docker/tasks/main.yml文件:
  1. ---
  2. - name: Install required packages
  3.   package:
  4.     name:
  5.       - yum-utils
  6.       - device-mapper-persistent-data
  7.       - lvm2
  8.     state: present
  9.   when: ansible_os_family == "RedHat"
  10. - name: Install required packages
  11.   package:
  12.     name:
  13.       - apt-transport-https
  14.       - ca-certificates
  15.       - curl
  16.       - gnupg2
  17.       - software-properties-common
  18.     state: present
  19.   when: ansible_os_family == "Debian"
  20. - name: Add Docker repository
  21.   yum_repository:
  22.     name: docker-ce
  23.     description: Docker CE Repository
  24.     baseurl: https://download.docker.com/linux/centos/7/$basearch/stable
  25.     gpgkey: https://download.docker.com/linux/centos/gpg
  26.     gpgcheck: yes
  27.   when: ansible_os_family == "RedHat"
  28. - name: Add Docker GPG key
  29.   apt_key:
  30.     url: https://download.docker.com/linux/ubuntu/gpg
  31.     state: present
  32.   when: ansible_os_family == "Debian"
  33. - name: Add Docker repository
  34.   apt_repository:
  35.     repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable
  36.     state: present
  37.   when: ansible_os_family == "Debian"
  38. - name: Install Docker
  39.   package:
  40.     name: docker-ce
  41.     state: present
  42. - name: Install Docker Compose
  43.   get_url:
  44.     url: https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64
  45.     dest: /usr/local/bin/docker-compose
  46.     mode: '0755'
  47. - name: Start and enable Docker service
  48.   service:
  49.     name: docker
  50.     state: started
  51.     enabled: yes
  52. - name: Add user to docker group
  53.   user:
  54.     name: "{{ ansible_user }}"
  55.     groups: docker
  56.     append: yes
复制代码

roles/webapp/tasks/main.yml文件:
  1. ---
  2. - name: Create application directory
  3.   file:
  4.     path: /opt/webapp
  5.     state: directory
  6.     owner: "{{ ansible_user }}"
  7.     group: "{{ ansible_user }}"
  8.     mode: '0755'
  9. - name: Copy docker-compose file
  10.   template:
  11.     src: docker-compose.yml.j2
  12.     dest: /opt/webapp/docker-compose.yml
  13.     owner: "{{ ansible_user }}"
  14.     group: "{{ ansible_user }}"
  15.     mode: '0644'
  16. - name: Create nginx configuration directory
  17.   file:
  18.     path: /opt/webapp/nginx/conf.d
  19.     state: directory
  20.     owner: "{{ ansible_user }}"
  21.     group: "{{ ansible_user }}"
  22.     mode: '0755'
  23. - name: Copy nginx configuration
  24.   template:
  25.     src: nginx.conf.j2
  26.     dest: /opt/webapp/nginx/nginx.conf
  27.     owner: "{{ ansible_user }}"
  28.     group: "{{ ansible_user }}"
  29.     mode: '0644'
  30. - name: Start services with docker-compose
  31.   docker_compose:
  32.     project_src: /opt/webapp
  33.     state: present
  34.     restarted: yes
复制代码

roles/webapp/templates/docker-compose.yml.j2文件:
  1. version: '3'
  2. services:
  3.   web:
  4.     image: nginx:alpine
  5.     container_name: webapp_nginx
  6.     ports:
  7.       - "80:80"
  8.       - "443:443"
  9.     volumes:
  10.       - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
  11.       - ./nginx/conf.d:/etc/nginx/conf.d:ro
  12.       - ./www:/var/www/html:ro
  13.     depends_on:
  14.       - app
  15.     networks:
  16.       - webnet
  17.   app:
  18.     image: php:7.4-fpm-alpine
  19.     container_name: webapp_php
  20.     volumes:
  21.       - ./www:/var/www/html:ro
  22.     networks:
  23.       - webnet
  24.   db:
  25.     image: mariadb:10.5
  26.     container_name: webapp_db
  27.     environment:
  28.       MYSQL_ROOT_PASSWORD: "{{ db_root_password }}"
  29.       MYSQL_DATABASE: "{{ db_name }}"
  30.       MYSQL_USER: "{{ db_user }}"
  31.       MYSQL_PASSWORD: "{{ db_password }}"
  32.     volumes:
  33.       - dbdata:/var/lib/mysql
  34.     networks:
  35.       - webnet
  36. volumes:
  37.   dbdata:
  38. networks:
  39.   webnet:
  40.     driver: bridge
复制代码

roles/webapp/templates/nginx.conf.j2文件:
  1. user nginx;
  2. worker_processes auto;
  3. error_log /var/log/nginx/error.log;
  4. pid /var/run/nginx.pid;
  5. events {
  6.     worker_connections 1024;
  7. }
  8. http {
  9.     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
  10.                       '$status $body_bytes_sent "$http_referer" '
  11.                       '"$http_user_agent" "$http_x_forwarded_for"';
  12.     access_log  /var/log/nginx/access.log  main;
  13.     sendfile            on;
  14.     tcp_nopush          on;
  15.     tcp_nodelay         on;
  16.     keepalive_timeout   65;
  17.     types_hash_max_size 2048;
  18.     include             /etc/nginx/mime.types;
  19.     default_type        application/octet-stream;
  20.     include /etc/nginx/conf.d/*.conf;
  21. }
复制代码

执行这个Playbook:
  1. ansible-playbook -i inventory.ini site.yml
复制代码

四、Ansible高级技巧与最佳实践

4.1 条件执行与循环

Ansible提供了强大的条件执行和循环功能,使您能够更灵活地控制任务执行流程。

条件执行示例:
  1. ---
  2. - name: Configure web servers
  3.   hosts: webservers
  4.   become: yes
  5.   
  6.   tasks:
  7.     - name: Install Apache on RedHat systems
  8.       yum:
  9.         name: httpd
  10.         state: present
  11.       when: ansible_os_family == "RedHat"
  12.    
  13.     - name: Install Apache on Debian systems
  14.       apt:
  15.         name: apache2
  16.         state: present
  17.       when: ansible_os_family == "Debian"
  18.    
  19.     - name: Start Apache service
  20.       service:
  21.         name: "{{ 'httpd' if ansible_os_family == 'RedHat' else 'apache2' }}"
  22.         state: started
  23.         enabled: yes
  24.    
  25.     - name: Configure firewall for RedHat
  26.       firewalld:
  27.         service: http
  28.         permanent: yes
  29.         state: enabled
  30.         immediate: yes
  31.       when: ansible_os_family == "RedHat"
  32.    
  33.     - name: Configure firewall for Debian
  34.       ufw:
  35.         rule: allow
  36.         name: Apache Full
  37.       when: ansible_os_family == "Debian"
复制代码

循环示例:
  1. ---
  2. - name: Install multiple packages
  3.   hosts: all
  4.   become: yes
  5.   
  6.   tasks:
  7.     - name: Install required packages
  8.       package:
  9.         name: "{{ item }}"
  10.         state: present
  11.       with_items:
  12.         - vim
  13.         - htop
  14.         - tree
  15.         - git
  16.         - curl
  17.    
  18.     - name: Create multiple users
  19.       user:
  20.         name: "{{ item.name }}"
  21.         shell: "{{ item.shell }}"
  22.         groups: "{{ item.groups }}"
  23.       with_items:
  24.         - { name: 'devuser1', shell: '/bin/bash', groups: 'developers' }
  25.         - { name: 'devuser2', shell: '/bin/bash', groups: 'developers' }
  26.         - { name: 'opsuser', shell: '/bin/bash', groups: 'operators' }
  27.    
  28.     - name: Create multiple directories
  29.       file:
  30.         path: "/opt/{{ item }}"
  31.         state: directory
  32.         owner: root
  33.         group: root
  34.         mode: '0755'
  35.       loop:
  36.         - app1
  37.         - app2
  38.         - app3
  39.         - shared
复制代码

带条件的循环示例:
  1. ---
  2. - name: Configure services based on environment
  3.   hosts: all
  4.   become: yes
  5.   
  6.   vars:
  7.     environment: production
  8.     services:
  9.       - name: nginx
  10.         envs: ["development", "staging", "production"]
  11.       - name: apache
  12.         envs: ["development", "staging"]
  13.       - name: tomcat
  14.         envs: ["staging", "production"]
  15.   
  16.   tasks:
  17.     - name: Start services based on environment
  18.       service:
  19.         name: "{{ item.name }}"
  20.         state: started
  21.         enabled: yes
  22.       loop: "{{ services }}"
  23.       when: environment in item.envs
复制代码

4.2 错误处理与调试

在自动化过程中,错误处理和调试是非常重要的。Ansible提供了多种机制来处理错误和调试问题。

错误处理示例:
  1. ---
  2. - name: Demonstrate error handling
  3.   hosts: all
  4.   become: yes
  5.   
  6.   tasks:
  7.     - name: This task might fail
  8.       command: /usr/bin/false
  9.       ignore_errors: yes
  10.       register: result
  11.    
  12.     - name: Print result of previous task
  13.       debug:
  14.         msg: "The previous task failed as expected: {{ result.failed }}"
  15.    
  16.     - name: This task will fail and stop execution
  17.       command: /usr/bin/false
  18.    
  19.     - name: This task will never run
  20.       debug:
  21.         msg: "You will never see this message"
复制代码

使用block和rescue进行错误处理:
  1. ---
  2. - name: Demonstrate block and rescue
  3.   hosts: all
  4.   become: yes
  5.   
  6.   tasks:
  7.     - name: Attempt to configure application
  8.       block:
  9.         - name: Install application
  10.           package:
  11.             name: non-existent-package
  12.             state: present
  13.         
  14.         - name: Start application
  15.           service:
  16.             name: non-existent-service
  17.             state: started
  18.       
  19.       rescue:
  20.         - name: Handle installation failure
  21.           debug:
  22.             msg: "Failed to install application, installing alternative instead"
  23.         
  24.         - name: Install alternative application
  25.           package:
  26.             name: nginx
  27.             state: present
  28.         
  29.         - name: Start alternative application
  30.           service:
  31.             name: nginx
  32.             state: started
  33.       
  34.       always:
  35.         - name: Always run cleanup
  36.           debug:
  37.             msg: "Cleaning up temporary files"
复制代码

调试技巧示例:
  1. ---
  2. - name: Demonstrate debugging
  3.   hosts: all
  4.   
  5.   tasks:
  6.     - name: Gather system information
  7.       setup:
  8.    
  9.     - name: Display all facts
  10.       debug:
  11.         var: ansible_facts
  12.    
  13.     - name: Display specific fact
  14.       debug:
  15.         msg: "System {{ ansible_hostname }} has {{ ansible_processor_vcpus }} CPU cores"
  16.    
  17.     - name: Display variable content with verbosity
  18.       debug:
  19.         var: hostvars[inventory_hostname]
  20.         verbosity: 2
  21.    
  22.     - name: Pause for debugging
  23.       pause:
  24.         prompt: "Check if everything is okay before continuing"
  25.         seconds: 30
  26.    
  27.     - name: Assert that required variables are defined
  28.       assert:
  29.         that:
  30.           - required_var is defined
  31.           - required_var | length > 0
  32.         fail_msg: "required_var must be defined and non-empty"
  33.         success_msg: "required_var is properly defined"
复制代码

4.3 Ansible Vault与密钥管理

在自动化过程中,处理敏感信息(如密码、API密钥等)是一个重要问题。Ansible Vault提供了一种加密敏感数据的方法。

创建加密文件:
  1. # 创建新的加密文件
  2. ansible-vault create secret.yml
  3. # 加密现有文件
  4. ansible-vault encrypt secret.yml
  5. # 查看加密文件
  6. ansible-vault view secret.yml
  7. # 编辑加密文件
  8. ansible-vault edit secret.yml
  9. # 更改密码
  10. ansible-vault rekey secret.yml
复制代码

使用加密文件示例:
  1. ---
  2. - name: Demonstrate Ansible Vault
  3.   hosts: all
  4.   become: yes
  5.   
  6.   vars_files:
  7.     - secret.yml
  8.   
  9.   tasks:
  10.     - name: Create database user with encrypted password
  11.       mysql_user:
  12.         name: "{{ db_user }}"
  13.         password: "{{ db_password }}"
  14.         priv: "*.*:ALL"
  15.         host: "%"
  16.         state: present
  17.    
  18.     - name: Create API configuration file
  19.       copy:
  20.         content: |
  21.           {
  22.             "api_key": "{{ api_key }}",
  23.             "api_secret": "{{ api_secret }}"
  24.           }
  25.         dest: /etc/app/api_config.json
  26.         owner: appuser
  27.         group: appgroup
  28.         mode: '0600'
复制代码

在命令行中使用Vault密码:
  1. # 使用密码文件
  2. ansible-playbook --vault-password-file vault_pass.txt site.yml
  3. # 交互式输入密码
  4. ansible-playbook --ask-vault-pass site.yml
复制代码

4.4 Ansible Tower与AWX

Ansible Tower(商业版)和AWX(开源版)是Ansible的Web界面和REST API,提供了更强大的自动化能力,包括:

• 可视化仪表板和报告
• 基于角色的访问控制
• 工作流和调度
• 集成通知系统
• 凭证管理
• 作业模板和调查

安装AWX示例:
  1. ---
  2. - name: Install AWX
  3.   hosts: localhost
  4.   become: yes
  5.   
  6.   tasks:
  7.     - name: Install required packages
  8.       package:
  9.         name:
  10.           - git
  11.           - python3-pip
  12.           - docker
  13.         state: present
  14.    
  15.     - name: Start Docker service
  16.       service:
  17.         name: docker
  18.         state: started
  19.         enabled: yes
  20.    
  21.     - name: Install Docker Compose
  22.       get_url:
  23.         url: https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64
  24.         dest: /usr/local/bin/docker-compose
  25.         mode: '0755'
  26.    
  27.     - name: Clone AWX repository
  28.       git:
  29.         repo: https://github.com/ansible/awx.git
  30.         dest: /opt/awx
  31.    
  32.     - name: Install AWX requirements
  33.       pip:
  34.         requirements: /opt/awx/requirements.txt
  35.    
  36.     - name: Configure AWX
  37.       template:
  38.         src: inventory.j2
  39.         dest: /opt/awx/inventory
  40.    
  41.     - name: Run AWX installer
  42.       command: /opt/awx/install.yml -i /opt/awx/inventory
  43.       args:
  44.         chdir: /opt/awx
复制代码

五、Ansible学习路径与进阶

5.1 从入门到精通的学习路径

第一阶段:基础入门(1-2周)

• 了解Ansible的基本概念和架构
• 学习YAML语法基础
• 安装和配置Ansible
• 掌握Inventory的使用
• 学习基本模块的使用(ping, command, shell, copy, file等)
• 编写简单的Playbook

第二阶段:核心技能(2-4周)

• 深入学习常用模块(yum, apt, service, user, group, template等)
• 掌握变量和事实(Facts)的使用
• 学习条件语句和循环
• 了解Handlers的工作机制
• 学习使用Roles组织Playbook

第三阶段:实战应用(1-2个月)

• 参与实际项目的自动化部署
• 学习使用Ansible管理网络设备
• 掌握Ansible与云服务(AWS, Azure, GCP)的集成
• 学习使用Ansible管理容器(Docker, Kubernetes)
• 掌握Ansible Vault的使用

第四阶段:高级技能(2-3个月)

• 学习开发自定义模块和插件
• 掌握Ansible Tower/AWX的使用
• 学习使用Ansible进行持续集成/持续部署(CI/CD)
• 掌握Ansible的最佳实践和性能优化
• 学习使用Ansible进行大规模自动化管理

5.2 推荐资源

官方资源:

• Ansible官方文档
• Ansible Galaxy- 社区角色集合
• Ansible博客
• Ansible GitHub仓库

书籍推荐:

• 《Ansible Up & Running》
• 《Ansible: From Beginner to Pro》
• 《Learning Ansible》
• 《Mastering Ansible》

在线课程:

• Udemy: “Ansible for the Absolute Beginner”
• Pluralsight: “Getting Started with Ansible”
• Linux Academy: “Ansible Fundamentals”
• A Cloud Guru: “Automate Your Infrastructure with Ansible”

社区资源:

• Ansible subreddit
• Ansible论坛
• Stack Overflow
• Ansible Meetup

5.3 认证路径

红帽认证:

• 红帽认证系统管理员(RHCSA)- 基础Linux系统管理技能
• 红帽认证工程师(RHCE)- 高级Linux系统管理技能
• 红帽认证Ansible自动化专家(EX407)- Ansible自动化专业技能

其他认证:

• Linux Foundation认证系统管理员(LFCS)
• CompTIA Linux+
• LPIC-1: Linux Administrator

5.4 职业发展路径

初级职位:

• 系统管理员
• 运维工程师
• DevOps工程师助理

中级职位:

• 高级系统管理员
• DevOps工程师
• 自动化工程师
• 云工程师

高级职位:

• DevOps架构师
• 基础设施架构师
• 自动化专家
• SRE(网站可靠性工程师)
• 技术经理

六、总结与展望

Ansible作为一款强大的IT自动化工具,已经成为现代IT基础设施管理的必备技能。通过本文的学习,您已经了解了Ansible的基础概念、核心组件、实战案例以及高级技巧。从简单的配置管理到复杂的多层应用部署,Ansible都能提供简洁而强大的解决方案。

随着云计算、容器化和微服务架构的普及,自动化运维的需求将持续增长。掌握Ansible不仅能提高您的工作效率,还能为您的职业发展打开新的机会。无论您是系统管理员、DevOps工程师还是云架构师,Ansible都将成为您工具箱中的重要组成部分。

未来,Ansible将继续发展,与新兴技术如Kubernetes、Serverless和AI/ML更好地集成,为IT自动化提供更全面的解决方案。持续学习和实践,将帮助您在这个快速变化的领域保持竞争力。

现在,是时候开始您的Ansible自动化之旅了!从简单的任务开始,逐步构建更复杂的自动化流程,您将很快体验到自动化带来的效率和一致性提升。祝您学习愉快!
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

联系我们|小黑屋|TG频道|RSS |网站地图

Powered by Pixtech

© 2025-2026 Pixtech Team.

>