ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

90DaysOfDevOps Ansible 实战:Tags、Variables、Inventory 与 MySQL 数据库服务器自动化配置

2026/10/8 7:25:26 拓冰建站 浏览量
90DaysOfDevOps Ansible 实战:Tags、Variables、Inventory 与 MySQL 数据库服务器自动化配置 文档/教程【免费下载链接】90DaysOfDevOpsThis repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.项目地址https://gitcode.com/gh_mirrors/90/90DaysOfDevOps点击查看免费下载本篇技术指南围绕 90DaysOfDevOps 项目第 68 天的 Ansible 自动化实战展开系统讲解 Tags 标签机制、两类变量的定义与优先级、Inventory 清单文件的按环境拆分以及如何从零编写 MySQL role 完成数据库服务器的自动化部署。读完本文你将能够用--tags精准控制大规模 playbook 的执行范围用group_vars/host_vars让 playbook 与配置解耦并通过 roles 模板化的方式一键部署并验证一个 MySQL 数据库节点。背景与实验环境本篇对应的实验发生在 Configmgmt 目录 下的 Vagrant 多机环境中Vagrantfile 定义了 webservers、proxy、database 等若干虚拟机控制节点上运行 Ansible通过默认的/etc/ansible/hosts定义主机分组。前几天的实验已完成 webservers 与 loadbalancernginx 反向代理的 playbookday68.md 是这一系列的延续先完善 playbook 的标签与变量管理再补上最后一台尚未启动的数据库服务器 db01。一、Tags让大型 Playbook 按需执行1.1 为什么需要 Tags前面的 playbook 一旦运行会把webservers与proxy两个 play 从头到尾全部执行。当 playbook 变得庞大复杂时往往只希望针对其中一部分 plays 或 tasks 做变更。Ansible 的 tags 机制正是为此设计的它可以把 plays 和 tasks 打上标签再由命令行按标签筛选执行范围。以场景 5 的 playbook5.yml 为例两个 play 分别被打上了web与proxy标签- hosts: webservers become: yes vars: http_port: 8000 https_port: 4443 html_welcome_msg: Hello 90DaysOfDevOps - Welcome to Day 66! roles: - common - apache2 tags: web - hosts: proxy become: yes roles: - common - nginx tags: proxy1.2 查看与按标签执行先列出 playbook 中定义过的所有标签确认标签名称无误ansible-playbook playbook5.yml --list-tags只针对 proxy 组执行ansible-playbook playbook5.yml --tags proxy此时只有proxyplay 及其关联的common、nginxroles 会被执行webservers相关任务全部跳过。1.3 Tags 的粒度task 级标签与always除了给 play 打标签tag 还可以加在单个 task 上实现更细粒度的控制。例如可以按用途给 tasks 打上installation、configuration、removal等应用型标签运行时按需挑选。特别值得记住的是tag: always任何被标记为always的 task无论命令行传入什么--tags值都会被执行。这对那些任何场景都必须先跑的基础任务如安装公共依赖非常有用。1.4 多标签组合与多标签定义多个标签可以一起使用命令行以逗号分隔ansible-playbook playbook5.yml --tags proxy,web上面这条命令会执行所有带proxy或web标签的 plays——在当前 playbook 中恰好等价于执行整个 playbook但当 playbook 新增了其他 plays 时这种组合筛选的价值就体现出来了。另外一个 play 或 task 也可以同时定义多个标签YAML 列表形式如后文 scenario7 的写法。二、VariablesAnsible Facts 与用户自定义变量Ansible 中有两大类变量Ansible Facts自动采集的系统事实与User created用户自定义变量。2.1 Ansible Facts系统自动采集的免费变量每次运行 playbook 时第一阶段都会自动执行一个未在 playbook 中显式定义的 task——Gathering Facts收集事实。这些 facts 是目标主机的系统级信息可以直接在 playbook、模板和条件判断中引用用来驱动自动化决策。把事实数据导出成文件便于检索分析ansible proxy -m setup facts.jsonsetup模块会返回目标主机的大量 JSON 事实数据。本仓库中的 facts.json 就是 loadbalancer 主机的完整事实快照共约 990 行从中可以看到ansible_all_ipv4_addresses如192.168.169.134、10.0.2.15、ansible_architecturex86_64、ansible_bios_vendorinnotek GmbH/VirtualBox等丰富信息这些都可以在 playbook 中按需引用。2.2 用 Facts 动态生成 nginx 负载均衡配置场景 5 的 mysite.j2 最初是把两台 webserver 的 IP 硬编码进 nginx 的 upstream 块upstream webservers { server 192.168.169.131:8000; server 192.168.169.132:8000; }硬编码的缺陷在于新增或移除 webserver 时代理配置不会自动跟随。可以利用 facts 与groups[webservers]循环把 nginx 配置模板改为动态生成#Dynamic Config for server {{ ansible_facts[nodename] }} upstream webservers { {% for host in groups[webservers] %} server {{ hostvars[host][ansible_facts][nodename] }}:8000; {% endfor %} } server { listen 80; location / { proxy_pass http://webservers; } }要点解释groups[webservers]是 Ansible 内置的魔法变量返回webservers主机组的所有成员hostvars[host][ansible_facts][nodename]用于跨主机访问组内每台机器的 fact即取其主机名运行效果与当前硬编码配置完全一致但此后无论往webservers组里添加还是移除机器重新渲染出的代理配置都会自动同步变化前提是目标环境已配置好 name resolution名称解析否则主机名无法正确解析为 IP。2.3 用户自定义变量从 playbook 内嵌到 group_vars 解耦用户自定义变量由我们自己定义。此前变量直接写在 playbook 的vars:块中例如- hosts: webservers become: yes vars: http_port: 8000 https_port: 4443 html_welcome_msg: Hello 90DaysOfDevOps - Welcome to Day 68! roles: - common - apache2 tags: web为了让 playbook 更干净、变量更易维护可以把变量移到独立文件中。进入场景 6 目录 ansible-scenario6创建目录结构group_vars/all/并在其中新建 common_variables.ymlhttp_port: 8000 https_port: 4443 html_welcome_msg: Hello 90DaysOfDevOps - Welcome to Day 68!同时把 playbook 中的vars:块及其变量删除。由于放在group_vars/all/下这些变量对所有主机组全局生效还可以把 NTP、DNS 服务器等全局配置一并加进来。此时 playbook6.yml 变得非常简洁- hosts: webservers become: yes roles: - common - apache2 tags: web - hosts: proxy become: yes roles: - common - nginx tags: proxy全局变量在模板中同样可用。把 mysite.j2 中硬编码的端口号替换为变量{{ http_port }}#Dynamic Config for server {{ ansible_facts[nodename] }} upstream webservers { {% for host in groups[webservers] %} server {{ hostvars[host][ansible_facts][nodename] }}:{{ http_port }}; {% endfor %} } server { listen 80; location / { proxy_pass http://webservers; } }同理在 apache2 role 的 index.html.j2 中既引用自定义变量html_welcome_msg又引用 factansible_facts[nodename]用于标识当前响应请求的是哪台 webserverhtml h1{{ html_welcome_msg }}! Im webserver {{ ansible_facts[nodename] }} /h1 /html执行ansible-playbook playbook6.yml后轮询负载均衡器地址会发现请求交替落在两台 webserver 上页面中显示的nodename也随之切换直观验证了变量与 facts 的联动效果。更细粒度的场景还可以创建host_vars目录并在其中放web01.yml实现按单台主机定制消息或页面外观。2.4 变量优先级与目录约定小结group_vars/all/对所有主机组生效的全局变量group_vars/group/只对指定主机组生效host_vars/host.yml只对单台主机生效优先级高于 group_varsplay 内联vars:的优先级高于上述基于目录的文件变量。这些目录需与 playbook 同级即 playbook 所在的根目录Ansible 会按目录位置自动加载。三、Inventory为不同环境准备独立主机清单此前一直使用/etc/ansible/hosts这个默认清单文件。对于 production、staging 等多环境场景可以为每个环境准备独立的 inventory 文件运行 playbook 时通过-i指定ansible-playbook -i dev playbook.ymlInventory 文件里除了定义主机与分组同样可以声明变量。例如可以在 dev 清单中定义env: dev之类的环境变量然后在负载均衡器网页模板中引用该变量把环境名渲染到页面消息里让访问者一眼看出当前处于哪个环境。四、实战自动化部署 MySQL 数据库服务器4.1 启动虚拟机并打通 SSH最后一台 db01 机器此前尚未启动。在存放 Vagrantfile 的目录下执行vagrant up db01机器启动并可达后把控制节点的 SSH 公钥复制过去以便免密管理ssh-copy-id db014.2 初始化 MySQL role 骨架进入场景 7 目录 ansible-scenario7用ansible-galaxy生成名为 mysql 的 role 目录骨架ansible-galaxy init roles/mysql该命令会自动创建tasks/、handlers/、templates/、defaults/、vars/、meta/、tests/等标准目录与 README见 roles/mysql 目录结构。4.3 在 playbook 中新增 database play在 playbook7.yml 中追加第三个 play 块目标组为/etc/ansible/hosts中定义的database组挂载common与新建的mysql两个 roles并打上database标签此处采用列表形式定义标签- hosts: webservers become: yes roles: - common - apache2 tags: web - hosts: proxy become: yes roles: - common - nginx tags: proxy - hosts: database become: yes roles: - common - mysql tags: database4.4 编写 handler重启 MySQL 服务handlers/main.yml 定义了一个名为restart mysql的 handler由任务通过notify触发仅在状态发生变化时才执行# handlers file for roles/mysql - name: restart mysql service: name: mysql state: restarted4.5 编写 tasks安装、建库、建用户tasks/main.yml是纯指针文件通过import_tasks依次引入两个任务文件从 源码 可见# tasks file for roles/mysql - import_tasks: install_mysql.yml - import_tasks: setup_mysql.ymlinstall_mysql.yml负责安装 MySQL 相关软件包并确保服务运行详见 install_mysql.yml- name: Install Common packages apt: name{{ item }} statelatest with_items: - python3-pip - mysql-client - python3-mysqldb - libmysqlclient-dev - name: Ensure mysql-server is installed latest version apt: namemysql-server statelatest - name: Installing python module MySQL-python pip: name: PyMySQL - name: Ensure mysql-server is running service: name: mysql state: started各 task 作用说明安装python3-pip、mysql-client、python3-mysqldb、libmysqlclient-dev等依赖with_items遍历列表逐项执行apt以statelatest安装最新版mysql-server通过 pip 安装PyMySQL它是后续mysql_user/mysql_db模块与 MySQL 通信所需的 Python 驱动确保mysql服务处于started状态。setup_mysql.yml负责生成配置文件、创建数据库用户与数据库见 setup_mysql.yml- name: Create my.cnf configuration file template: srctemplates/my.cnf.j2 dest/etc/mysql/conf.d/mysql.cnf notify: restart mysql - name: Create database user with name devops and password DevOps90 with all database privileges community.mysql.mysql_user: login_unix_socket: /var/run/mysqld/mysqld.sock login_user: {{ mysql_user_name }} login_password: {{ mysql_user_password }} name: {{db_user}} password: {{db_pass}} priv: *.*:ALL host: % state: present - name: Create a new database with name 90daysofdevops mysql_db: login_user: {{ mysql_user_name }} login_password: {{ mysql_user_password }} name: {{ db_name }} state: present各 task 关键点用模板生成/etc/mysql/conf.d/mysql.cnf并notify触发restart mysqlhandlercommunity.mysql.mysql_user创建数据库用户用户名/密码分别取db_user、db_passpriv: *.*:ALL授予全部库全部权限host: %允许从任意主机登录state: present表示存在即幂等login_unix_socket: /var/run/mysqld/mysqld.sock用于通过本地 socket 连接 db01 上的 MySQL 实例——这是作者实测后补充的关键连接参数否则无法成功连接mysql_db模块创建名为db_name的数据库。4.6 变量集中管理与模板上面任务引用的用户名、密码、库名等敏感配置全部来自 common_variables.ymlhttp_port: 8000 https_port: 4443 html_welcome_msg: Hello 90DaysOfDevOps - Welcome to Day 68! mysql_user_name: root mysql_user_password: vagrant db_user: devops db_pass: DevOps90 db_name: 90DaysOfDevOps模板目录中的 my.cnf.j2 内容如下注意仓库实际模板比文中示例多了[client]段内置了 root 登录凭据以便模块连接[mysql] bind-address 0.0.0.0 [client] userroot passwordvagrantbind-address 0.0.0.0让 MySQL 监听所有网络接口从而允许从外部如负载均衡器或控制节点访问[client]段为客户端工具提供默认登录凭据。4.7 运行 playbook 与排错全量执行包含此前所有 webservers、proxy 的 plays或只针对数据库组执行ansible-playbook playbook7.yml ansible-playbook playbook7.yml --tags database只运行--tags database时作者遇到了一个典型错误提示未安装 pip3Python。修复方式是把 pip3 的安装补充进 common 角色的公共任务里再重新运行 playbook即可成功完成变更。4.8 验证数据库服务器从控制节点登录 db01ssh db01以 root 身份连接 MySQL提示时输入 root 的 vagrant 密码sudo /usr/bin/mysql -u root -p确认用户是否已创建select user, host from mysql.user;查看新数据库是否已就绪SHOW DATABASES;还可以用刚创建的 DevOps 账号以同样方式登录验证密码为DevOps90sudo /usr/bin/mysql -u devops -p作者在验证过程中还发现一个待优化点setup_mysql.yml中必须显式加上login_unix_socket: /var/run/mysqld/mysqld.sock才能成功连接 db01 的 MySQL 实例但每次运行时创建用户的 task 都会报告变更幂等性不理想这正是把用户名、密码抽到group_vars管理后进一步向 Ansible Vault 迁移敏感信息的动机所在。五、小结回顾本系列的技术要点主题核心命令/文件作用Tags--list-tags、--tags proxy、--tags proxy,web、tag: always按 play/task 粒度控制执行范围Factsansible -m setup、facts.json、ansible_facts[nodename]利用系统自动采集信息驱动模板与任务用户变量group_vars/all/、host_vars/、vars:配置与 playbook 解耦按组/按主机分层Inventoryansible-playbook -i dev playbook.yml多环境独立清单可内嵌变量MySQL roleansible-galaxy init roles/mysql标准化目录骨架一键安装、建库、建用户至此90DaysOfDevOps 的 Ansible 自动化场景已覆盖 Web 服务器、负载均衡器与数据库服务器三大类节点并引入了标签筛选、事实变量、分组变量与自定义 inventory 等核心工程实践。下一阶段可继续探索 第 69 天 的内容把这套配置管理的知识体系推向更深的自动化场景。赞分享文档/教程【免费下载链接】90DaysOfDevOpsThis repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.项目地址https://gitcode.com/gh_mirrors/90/90DaysOfDevOps点击查看免费下载相关推荐90DaysOfDevOps Day 68Ansible Tags、Variables、Inventory 与 MySQL 数据库服务器自动化配置实战90DaysOfDevOps Day 68Ansible Tags、Variables、Inventory 与 MySQL 数据库服务器自动化配置实战 本篇是文档/教程90DaysOfDevOps 实战 Day 68Ansible Tags、Variables、Inventory 与 MySQL 数据库服务器部署90DaysOfDevOps 实战 Day 68Ansible Tags、Variables、Inventory 与 MySQL 数据库服务器部署 本篇技术指文档/教程90DaysOfDevOps Day 68Ansible Tags、变量、Inventory 与 MySQL 数据库服务器配置实战90DaysOfDevOps Day 68Ansible Tags、变量、Inventory 与 MySQL 数据库服务器配置实战 本篇技术指南围绕 90Da文档/教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考