精读笔记(RHCA 英文教材)· DO447 Chapter 13 Creating a Simple CI/CD Pipeline with Ansible Tower
大约 10 分钟
精读笔记(RHCA 英文教材)· DO447 Chapter 13 Creating a Simple CI/CD Pipeline with Ansible Tower
教材原文:RHCA 官方英文教材(教材第 481~502 页)(OCR 整书版已从本站移除,本页为章节精读) 章节结构:本章只有 1 个 Section —— “Integrating CI/CD with Ansible Tower”(含 Guided Exercise
Integrating a GitLab CI/CD Pipeline,lab: cicd-tower) 关联知识:Ch9(Job Template 经 Tower 执行)、Ch11(Tower REST API/tower-cli)、Ch1(Git 分支管理/推荐实践)、02-08-Ansible自动化;CI/CD 属 DevOps 环节,Ansible Tower 在其中当“部署执行器”。
Chapter Goal / Objectives(原文+译)
- GOAL: Build and operate a proof-of-concept CI/CD pipeline based on Ansible automation and integrating Red Hat Ansible Tower.(构建并运行一个“基于 Ansible 自动化、集成 Ansible Tower”的 CI/CD 概念验证流水线)
- OBJECTIVES:把 Ansible Tower 与基于 Web 的 Git 仓库系统(如 GitLab/GitHub)集成,构建一条“代码一提交就自动部署 playbook”的简易流水线。
- SECTIONS:Integrating CI/CD with Ansible Tower(含 Guided Exercise)——学完本节应能在 GitLab 里建 CI/CD 流水线调用 Tower 的 Job Template。
13.1 CI/CD 基础概念(Continuous Integration / Continuous Delivery)
- CI(持续集成)=DevOps 实践:用自动化把各位开发者的小改动持续并入共享代码仓库;CD(持续交付)=把流程执行得更快、更频繁(bring and execute processes together)。
- 该实践鼓励“频繁提交小改动”,而不是“低频提交大改动”(Release often to keep your customers happy)。
- 自动化例程被分组成 jobs(作业),作业放进 pipeline(流水线);流水线决定作业执行的先后顺序。
- 流水线没有固定内容规则,核心前提是:pipeline 让自动化质量控制成为可能,用可靠可重复的方式消除人工介入。
- 流水线作业常见类型(可出选择题):语法检查(syntax checking)、Linting(代码质量分析)、构建(build,产出可部署工件)、部署安装(deploy/install)、冒烟测试(smoke testing,最关键功能的最小验证)、单元测试(unit,函数级)、集成测试(integration,单元间协作)、回归测试(regression,新改动不破坏旧功能)。
- CI/CD 收益:提交后快速反馈;签入即自动端到端测试(开发者反馈环更短);便于整合多人代码;协作更透明;同一迭代内更快失败;减少长迭代末尾的排错会议。
- 起步三要素:分布式版本控制系统(DVCS)访问权 + 针对代码的测试 + 跑测试的 CI/CD 服务。
- Tower 可与多种 CI/CD 平台集成;本课程用教室自带的 GitLab CE 实例(既能当 Git 仓库又能当 CI/CD 平台),其它平台亦可(各有优劣)。
13.2 GitLab 流水线机制(Building CI/CD Pipelines with GitLab)
- Runner(运行器):GitLab 中真正跑流水线作业的执行者,提供作业执行环境;可“项目专属”也可“跨项目共享”。
- Executor(执行器):runner 执行作业内命令的方式,可为:容器(Containers)、虚拟机(Virtual Machines)、本地 shell(在 GitLab 机器自身的 shell 里执行)、SSH(连到别的机器执行)。
- 理想情况:runner 应独立于任何被连接系统运行流水线代码(避免作业受目标环境影响)。
- 流水线 = stages(阶段)→ 每阶段一个或多个 jobs;阶段决定作业顺序,某作业失败则后续阶段/作业不再执行。
13.3 CI/CD × Ansible Tower(考点:典型 10 步流水线)
目的:每次向 Ansible Playbook 项目提交代码时,用 CI/CD 流水线自动执行例行自动化。 典型流程(原文字面照录,注意是“开发→测试→合并→生产→通知”的两段式):
- 从 dev 分支拉最新 playbook;
- 语法检查 + lint(确保符合最佳实践);
- 把 dev 分支 playbook 同步到 Tower 的一个 Project;
- 用 dev 分支代码,对 Dev Inventory 执行 Job Template;
- 对 Dev 环境主机做关键组件的单元/冒烟测试;
- 把 dev 合并进 master 分支;
- 把 master 分支 playbook 同步到 Tower Project;
- 用 master 代码对 Prod Inventory 执行 Job Template;
- 对 Prod 环境主机做关键功能测试;
- 发通知告知开发者作业状态。
- 效果:把原本人工操作全部自动化——开发者只专注写/改 playbook,提交后 CI 与 Tower 自动接棒,且生产部署前先经测试环境验证,保护生产不被坏 playbook 影响。
13.4 Ansible Lint(考点,命令级)
- ansible-lint:命令行工具,检测 playbook 的错误、bug、可疑结构、风格问题(stylistic errors)——Ansible Galaxy 项目用它给投稿内容做 lint 与质量评分。
- IMPORTANT(官方声明):ansible-lint 不随 Red Hat Ansible Automation 发行、也不受红帽官方支持,由上游 Ansible 社区开发;RHEL7 通过 EPEL 提供,也可查 https://docs.ansible.com/ansible-lint/ 安装。
- 规则实现:Python 模块,位于
${PYTHON_PATH}/site-packages/ansiblelint/rules/;方括号数字=命中规则号(tags)。 - 示例输出(考点可出“这是什么工具的输出”):
$ ansible-lint playbook.yml [301] Commands should not change things if nothing needs doing [303] systemctl used in place of systemd module [502] All tasks should be named- 301:command 不该做“无需做也改变状态”的事(非幂等);303:应改用 systemd 模块而不是 systemctl 命令;502:所有 task 必须有 name。输出还给出 文件名:行号 与出问题的 Task/Handler 名。
- 修复示范:把
command: systemctl mask iptables.service改成命名的systemd: name: iptables.service masked: true;其余 task 逐个补 name。 - 对比(考点):
ansible-playbook --syntax-check只查语法;ansible-lint比它更能验证 playbook 健全性——用了 ansible-lint 就不必再单独跑 syntax-check。无问题时 ansible-lint 无输出、echo $?返回 0。 - Style Guide(风格指南):很多组织自定 playbook 书写规范,例如布尔值写法统一(
True/true/Yes/yes/1含义相同,但一致风格可读性高、便于排错)。 - 自定义规则:默认规则照常可用、追加自定义规则用
ansible-lint -R ~/ansible-lint/custom_rules/ playbook.yml;只用自定义规则(覆盖默认)用ansible-lint -r ~/ansible-lint/custom_rules/ playbook.yml;列全部规则ansible-lint -L。
Guided Exercise 要点(lab: cicd-tower)
目标(OUTCOME):能从 GitLab CI/CD 流水线触发 Tower 里的 Job Template。
lab cicd-tower start后开始。
- 克隆项目:
mkdir -p ~/git-repos && cd ~/git-repos,git clone http://git.lab.example.com:8081/git/cicd-tower.git;仓库有 master/dev 两个分支(git branch -a见 origin/dev、origin/master)。 - 切 dev 分支看文件:
git checkout dev;dev 分支比 master 多了.gitlab-ci.yml(流水线定义)。 - ansible-lint 找错:playbook.yml 第 21 行报 “no action detected”,原因=第三个任务把模块写成
firewall(不存在),正确模块名是firewalld;改后 lint 又报[206] Variables should have spaces before and after: {{ var_name }}(第 12 行"{{packages}}")与[502] All tasks should be named(第 28 行 copy 任务没名字)。 - 修复后 playbook 结构(考点:Smoke Test 任务的写法):装 httpd/httpd-devel → service httpd enabled+started → firewalld 放行 http(immediate+permanent)→ copy
Hello World到 index.html → Smoke Test 任务用uri模块:url: "http://{{ inventory_hostname }}"、return_content: yes、status_code: 200、register: response、delegate_to: localhost、become: no、failed_when: '"Hello World" not in response.content'。 - .gitlab-ci.yml 三段流水线(考点原文示例,tower-cli 用法):
variables:
LAUNCH_TOWER_JOB: tower-cli job launch --monitor --insecure
TOWER_CREDENTIALS: -u admin -p redhat -h tower.lab.example.com
GIT_REPO: http://git:redhat321@git.lab.example.com:8081/git/cicd-tower.git
stages:
- lint
- deploy
- auto_merge- stage
lint:作业syntax check and linting(全分支)——先if ls *.yml; then true; else ... exit 1; fi再ansible-lint *.yml。 - stage
deploy:launch test job(only dev)→tower-cli config verify_ssl false后执行$LAUNCH_TOWER_JOB $TOWER_CREDENTIALS -J "Deploy Test WebServers";launch prod job(only master)→ 同样调用-J "Deploy Prod WebServers"。 - stage
auto_merge:push to master(only dev)——git remote set-url origin $GIT_REPO→ checkout dev & pull → checkout master & pull →git merge --no-ff dev→git push origin master。
- Tower 侧资源:Job Template
Deploy Test WebServers使用 CI/CD Test Inventory(serverc/d,webservers 组)、CI/CD Test Project(playbook.yml,从 cicd-tower.git 的 dev 分支拉取,用 gitlab credential)、webservers machine credential;Prod 侧对应资源用 servera/b——先测测试环境,冒烟通过才合并到 master 部署生产。 - 提交→失败→修复→通过:push dev 触发流水线;第 2 阶段失败——冒烟测试发现测试机内容是小写
Hello world而断言要求Hello World;Tower Jobs 里 Deploy Test WebServers 报错、Deploy Prod 未执行;把 copy 内容改成"Hello World\n"再 commit/push → dev 流水线全过 → auto_merge 触发 master 流水线(只有 lint+deploy 两段)→ 生产 servera/b 更新成功 →curl servera返回 Hello World。 - 收尾:
lab cicd-tower finish。
Summary(原文要点 + 中文归纳)
- Pipelines further automation efforts by allowing commands to be executed on merge by the developer.(流水线让“合并代码时自动执行命令”成为可能,进一步推进自动化)
- To create a pipeline, additional tooling is required such as GitLab or Jenkins.(建流水线需额外工具,如 GitLab/Jenkins)
- Using GitLab, pipelines execute in runners which provide the environment for the commands to be executed.(GitLab 里流水线跑在 runner 上)
- Pipelines consist of jobs that represent the various stages at which jobs execute.(流水线由作业组成,作业代表各个执行阶段)
- Pipeline jobs consist of commands that execute on the runner.(流水线作业=在 runner 上执行的一组命令)
- Developers merge code to the shared repository for pipelines to executed.(开发者把代码合并进共享仓库触发流水线)
- Pipelines can trigger Job Templates in Ansible Tower.(流水线可触发 Tower 的 Job Template)
命令速查表
| 命令/文件 | 用途 |
|---|---|
git clone/branch -a/checkout dev/add/commit/push | 分支化开发与提交(dev→master 两段式) |
ansible-playbook playbook.yml --syntax-check | 仅语法检查(lint 已覆盖时可不跑) |
ansible-lint playbook.yml | lint:语法+最佳实践([206]/[301]/[303]/[502]…) |
ansible-lint -L | 列出全部 lint 规则 |
ansible-lint -R <dir> playbook.yml | 默认规则 + 追加自定义规则目录 |
ansible-lint -r <dir> playbook.yml | 只用自定义规则(覆盖默认) |
tower-cli config verify_ssl false | 关闭 CLI 对 Tower 的证书校验(教室自签环境) |
tower-cli job launch --monitor --insecure -u admin -p redhat -h tower... -J "Deploy Test WebServers" | 流水线内启动 Tower Job Template |
.gitlab-ci.yml(variables/stages/script/only) | GitLab 流水线定义:lint→deploy→auto_merge |
git merge --no-ff dev + git push origin master | 流水线内把 dev 合并推送 master |
curl http://servera(等) | 冒烟/部署后验证 Web 内容 |
| uri 模块(return_content/status_code/register/failed_when) | playbook 内冒烟测试写法 |
核心词汇表
| 英文 | 中文速记 |
|---|---|
| Continuous Integration (CI) | 持续集成:自动化并入共享仓库 |
| Continuous Delivery (CD) | 持续交付:更快更频繁执行发布流程 |
| pipeline | 流水线:规定作业执行顺序 |
| stage | 阶段:控制作业顺序(失败即停) |
| job | 流水线作业:runner 上跑的命令组 |
| GitLab Runner | 作业执行环境(项目专属/共享) |
| executor(container/VM/shell/SSH) | runner 的执行器类型 |
| syntax check / lint / build / deploy | 语法检查/质量分析/构建/部署 |
| smoke / unit / integration / regression test | 冒烟/单元/集成/回归测试 |
| ansible-lint | 社区 lint 工具(规则号如 [502]) |
| Style Guide | playbook 风格规范(如布尔写法统一) |
| dev / master branch | 开发/主干分支(两段式发布) |
| tower-cli | Tower 命令行客户端(job launch) |
| auto_merge | 流水线自动合并 dev→master 的阶段 |
| Job Template | Tower 作业模板(流水线最终触发对象) |
本章自测
- CI 与 CD 的差别是什么?为什么“频繁提交小改动”优于“低频提交大改动”?
- 流水线作业常见类型有哪些?哪一种是“验证最关键功能是否可用”的最小测试?
- GitLab 里谁负责执行作业?Executor 有哪四类?
- 结合 Ansible Tower 的典型流水线,讲清 dev 与 master 分支各在什么阶段被使用、第 6 步“合并”发生在哪两个环境验证之间。
- ansible-lint 与 ansible-playbook --syntax-check 的能力差异?用 lint 后还需不需要 syntax-check?
- lint 输出
[502] All tasks should be named、[303] systemctl used in place of systemd module分别说明什么问题? ansible-lint -r与-R的区别是什么?自定义规则以什么形式实现、放在哪?- .gitlab-ci.yml 中 stages 顺序为 lint→deploy→auto_merge,某 job 失败后会发生什么?
only:关键字起什么作用? - 冒烟测试任务为什么通常
delegate_to: localhost+become: no?failed_when 怎么判断内容? - 对照 Summary:为什么说“流水线可触发 Job Template”?它把 Tower 放在 CI/CD 链条的什么位置?
