金鱼哥RHCA回忆录:DO447使用Ansible Tower创建简单的CI/CD流水线

举报
金鱼哥 发表于 2022/07/11 11:02:57 2022/07/11
【摘要】 第十三章 使用Ansible Tower创建简单的CI/CD流水线

🎹 个人简介:大家好,我是 金鱼哥,CSDN运维领域新星创作者,华为云·云享专家,阿里云社区专家博主
📚个人资质:CCNA、HCNP、CSNA(网络分析师),软考初级、中级网络工程师、RHCSA、RHCE、RHCA、RHCI、ITIL😜
💬格言:努力不一定成功,但要想成功就必须努力🔥

🎈支持我:可点赞👍、可收藏⭐️、可留言📝


13.1.1 持续集成(continuous integration)

持续集成是使用自动化将单个开发人员的贡献集成到共享代码存储库中的DevOps实践。持续交付将重点放在更快速、更频繁地执行过程上,通过将它们合并并执行它们。

这种实践鼓励更频繁地提交小的变更,而不是不频繁地提交大的变更。
在这里插入图片描述

自动化例程被分组到作业中,作业被放置在一个流水线中。流水线定义了作业执行的顺序。

对于流水线的内容没有规则,但基本前提是流水线有助于自动化质量控制。这种自动化以可靠的可重复的方式消除了人工干预的需要。

一些正在做的工作的例子包括:

  • 语法检查,以确保代码不包含任何阻止代码编译的语法错误。

  • “Linting”(运行一个程序来分析你的代码)来检测可能被改进的行为和实践。

  • 调用必要的步骤来构建代码以生成可部署的构件。

  • 在服务器上部署和安装代码。

  • “冒烟测试”的形式是粗略的、有限的测试,以确保最重要的功能工作。

  • 单元测试用于验证单个代码单元(函数)是否按预期工作。

  • 集成测试,以验证代码(功能)的各个单元是否如预期的那样协同工作。

  • 回归测试来验证新的或最近修改的代码不会对现有的特性(功能)产生负面影响。

这种做法有许多好处:

  • 一旦代码提交,关于代码运行状态的快速反馈。

  • 当代码被检入时,代码的端到端测试是自动化的,从而在处理代码的开发人员之间产生更快的反馈循环。

  • 方便集成来自不同开发人员的代码。

  • 为代码协作的开发人员提供更好的可视性。

  • 在同一个sprint中,开发人员和测试人员能够更快地失败,从而进一步减少反馈循环。

  • 减少长时间冲刺结束时的调试会话。

为了开始使用CI/CD流水线,需要:

  • 对分布式版本控制服务的访问

  • 对代码的测试

  • 访问CI/CD服务以运行测试

注意:可以将Red Hat Ansible Tower与各种CI/CD平台结合起来,为Ansible Playbook项目创建一个流水线。在本课程中,我们使用GitLab的一个课堂实例,它可以提供存储库管理和CI/CD平台服务。其他替代方案也可能具有不同的优点,但此配置提供了一个很好的示例。


13.1.2 使用gitlab构建CI/ CD流水线

在CI/CD流水线中,GitLab使用运行器在流水线中运行作业。运行程序提供了执行流水线的环境。执行者可以特定于一个项目,也可以在所有项目中共享。

运行执行器在作业中执行命令。

执行器可以:

  • 容器

  • 虚拟机

  • 本地shell(作业在GitLab机器本身的shell中执行)

  • SSH连接到另一台机器执行作业

理想情况下,运行程序独立于任何连接的系统,执行流水线中定义的代码。
在这里插入图片描述


13.1.3 CI/CD和Ansible Tower

使用CI/CD流水线,与Red Hat Ansible Tower集成,对Ansible Playbook项目的每个提交执行自动化例程。

典型的流水线执行以下步骤:

  1. 从开发分支提取剧本的最新版本。

  2. 执行语法检查以确保代码的完整性,并进行Linting以确保它遵循一组最佳实践规则。

  3. 同步从开发分支到Ansible Tower项目的剧本。

  4. 根据Ansible Tower中的开发目录执行作业模板,使用开发分支中的代码。

  5. 以单元测试的形式验证关键组件的功能在开发目录中的主机。

  6. 将dev分支合并到主分支

  7. 同步从主分支到Ansible Tower的一个项目的剧本。

  8. 使用来自主分支的代码,针对Ansible Tower中的Prod清单执行作业模板。

  9. 在Prod清单中以主机单元测试的形式验证关键组件的功能

  10. 发送通知通知开发人员工作的状态

该流水线将必须手动执行的流程自动化。自动化允许开发人员使用他们选择的工具专注于创建和编辑剧本。开发人员可以简单地提交他们的工作,知道使用Cl流水线的自动化是与Red Hat Ansible Tower集成的。


13.1.4 Ansible LINT

Ansible Lint是一个命令行工具,用于检测可能被改进的错误、bug、可疑代码结构和样式错误。

它被Ansible Galaxy项目用于lint和计算为Galaxy Hub贡献的内容的质量分数。

重要:ansible-lint命令目前没有随Red Hat Ansible Automation一起发布,也没有得到Red Hat的官方支持,但是由上游的Ansible社区开发。这个命令包含在Red Hat Enterprise Linux 7和Fedora当前版本的EPEL中。在其他操作系统上的安装说明可以在https://docs.ansible.com/ansible-lint/上找到。

Ansible Lint以Python模块的形式使用来自${PYTHON_ PATH}/site-packages/ansiblelint/rules/的规则,这些规则可以原样使用,也可以编辑以满足你自己的需要。其他的用户定义规则可以与默认规则一起创建和使用,如下所示:

下面是一个写得很糟糕的剧本的例子。

[student@demo examples]$ cat playbook.yml
---
- name: A bad play
  hosts: demo.lab.example.com

tasks:
- command: systemctl mask iptables.service
...

语法上,剧本是没有任何错误的。

[student@demo examples]$ ansible-playbook playbook.yml --syntax-check

playbook: playbook.yml

ansible-lint揭示了这不是一个写得很好的剧本。

[student@demo examples]$ ansible-lint playbook.yml
[301] Commands should not change things if nothing needs doing   # 方括号中的数字告诉我们匹配了哪些linting规则(标记),以及对问题的简短描述。
playbook.yml:6       # 发现问题的文件名和行号。
Task/Handler: command systemctl mask iptables.service    # 有问题的任务的名称。

[303] systemctl used in place of systemd module
playbook.yml:6
Task/Handler: command systemctl mask iptables.service

[502] All tasks should be named
playbook.yml:6
Task/Handler: command systemctl mask iptables.service

ansible-lint中的规则作为Python模块实现,并存储在${Python-path}/site-packages/ansiblelint/ Rules /中。

由于ansible-lint,这些问题的补救被简化了。
在这里插入图片描述

注意:与ansible-playbook --syntax-check命令相比,ansible-lint命令更能验证剧本的完整性。因此。在使用ansible-lint命令时,不需要使用ansible-playbook --syntax-check

许多组织实施了风格指南,它定义了编写剧本的标准。例如,布尔值的声明方式可以是不同的: True vs true vs Yes vs yes vs 1。虽然所有这些值都意味着相同的思路,但是一致使用样式有助于剧本的可读性,从而进一步帮助排除剧本中的错误。
在这里插入图片描述

ansible-lint命令将规则实现为Python模块,您自己的规则可以用于默认规则之外。

[student@demo ~]$ ansible-lint -R ~/ansible-lint/custom_rules/ playbook.yml

覆盖$fPYTHON- PATH}/site-packages/ansiblelint/rules/中的默认规则。而只使用你的自定义规则,使用ansible-lint命令如下:

[student@demo ~]$ ansible-lint -r ~/ansible-lint/custom_rules/ playbook.yml

Ansible Lint规则检查变量名之前和之后的空格
在这里插入图片描述


13.1.5 课本练习

[student@workstation ~]$ lab cicd-tower start

1. 拉取实验代码。

[student@workstation ~]$ mkdir -p /home/student/git-repos
[student@workstation ~]$ cd /home/student/git-repos
[student@workstation git-repos]$ git clone \
http://git.lab.example.com:8081/git/cicd-tower.git
[student@workstation git-repos]$ cd cicd-tower

2. 检查存储库的master和dev分支中的文件。

[student@workstation cicd-tower]$ git branch 
* master
[student@workstation cicd-tower]$ ll
total 8
-rw-rw-r--. 1 student student 609 May 20 14:30 playbook.yml
-rw-rw-r--. 1 student student  19 May 20 14:30 README.md
[student@workstation cicd-tower]$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/dev
  remotes/origin/master
[student@workstation cicd-tower]$ git checkout dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
Switched to a new branch 'dev'
[student@workstation cicd-tower]$ git branch
* dev
  master
[student@workstation cicd-tower]$ ls -la
total 12
drwxrwxr-x.  3 student student   77 May 20 14:32 .
drwxrwxr-x. 15 student student  277 May 20 14:30 ..
drwxrwxr-x.  8 student student  163 May 20 14:32 .git
-rw-rw-r--.  1 student student 1167 May 20 14:32 .gitlab-ci.yml
-rw-rw-r--.  1 student student  869 May 20 14:32 playbook.yml
-rw-rw-r--.  1 student student   19 May 20 14:30 README.md

3. 使用ansible-lint命令识别剧本中的任何问题。可以使用这个剧本来部署测试和生产web服务器。

[student@workstation cicd-tower]$ ansible-lint playbook.yml
Couldn't parse task at playbook.yml:21 (no action detected in task. This often indicates a misspelled module name, or incorrect module path.

The error appears to be in '<unicode string>': line 21, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

(could not open file to display line))
{ 'firewall': { '__file__': 'playbook.yml',
                '__line__': 22,
                'immediate': True,
                'permanent': True,
                'service': 'http',
                'state': 'enabled'},
  'name': 'Open the port in the firewall'}

修改正确的模块名:
    - name: Open the port in the firewall
      firewalld:
        service: http
        state: enabled
        immediate: true
        permanent: true

[student@workstation cicd-tower]$ ansible-lint playbook.yml
[206] Variables should have spaces before and after: {{ var_name }}
playbook.yml:12
        name: "{{packages}}"

[502] All tasks should be named
playbook.yml:28
Task/Handler: copy content=Hello world
 dest=/var/www/html/index.html __line__=28 __file__=playbook.yml

4. 处理再次检查到的错误。

 10     - name: Install the webserver software
 11       yum:
 12         name: "{{ packages }}"
 13         state: installed

 28     - name: Install sample web content
 29       copy:
 30         content: "Hello world\n"
 31         dest: /var/www/html/index.html

5. 验证ansible-lint命令没有识别出任何其他问题。

如果剧本没有问题或错误,ansiblelint命令不会返回任何输出。

[student@workstation cicd-tower]$ ansible-lint playbook.yml
[student@workstation cicd-tower]$ echo $?
0

6. 如果GitLab项目包含 .gitlab-ci.yml文件,GitLab为项目创建一个CI/CD流水线。

该文件定义了一系列阶段,每个阶段执行一个或多个作业。阶段控制作业执行的顺序。如果某个作业失败,后续的阶段和作业就不会执行。

GitLab流水线作业在一个可用的GitLab Runner实例上执行。您可以配置一个GitLab Runner来在任何机器上执行您的CI/CD流水线。配置GitLab runner超出了本课程的范围。

在教室环境中,在GitLab服务器上配置一个GitLab Runner实例。使用这个运行程序执行简单的bash命令来实现Cl/CD流水线。

回顾 .gitlab-ci.yml文件定义了这个项目的Cl/CD流水线:

[student@workstation cicd-tower]$ cat .gitlab-ci.yml 
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

# First stage; all branches
syntax check and linting:
  stage: lint
  script:
    - if ls *.yml; then true; else echo "No playbooks found!"; exit 1; fi
    - ansible-lint *.yml

#Second stage; only dev branch
launch test job:
  stage: deploy
  script:
    - tower-cli config verify_ssl false
    - $LAUNCH_TOWER_JOB $TOWER_CREDENTIALS -J "Deploy Test WebServers"
    - echo $?
  only:
    - dev

#Second stage; only the master branch
launch prod job:
  stage: deploy
  script:
    - tower-cli config verify_ssl false
    - $LAUNCH_TOWER_JOB $TOWER_CREDENTIALS -J "Deploy Prod WebServers"
    - echo $?
  only:
    - master

#Third stage; only applies to the dev branch
push to master:
  stage: auto_merge
  script:
    - git remote set-url origin $GIT_REPO
    - git checkout dev && git pull
    - git checkout master && git pull
    - git merge --no-ff dev
    - git push origin master
  only:
    - dev

这个流水线配置文件定义了一个有三个阶段的流水线: lint、deploy和auto_merge。

lint阶段包含单个作业,名称为syntax check and linting。该作业对每个YAML文件执行ansible-lint命令。如果存储库中不存在YAML文件,那么作业将失败。

deploy阶段触发Ansible Tower作业模板的执行。对于dev分支,执行Deploy Test Web Servers作业模板,而主分支执行Deploy Prod Web Servers模板。

auto_merge阶段仅为dev分支定义了一个作业。此作业将dev分支中的更改合并到主分支中,并推送到远程存储库。


7. 在Ansible Tower中测试资源。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Prod对象也有类似的资源。剧本首先根据我们的测试目录进行测试,如果冒烟测试通过,剧本将从开发分支合并到主分支。通过在您的流水线中执行测试,此过程可以保护我们的生产服务器免受剧本中发现的错误的负面影响。


8. 提交代码。

[student@workstation cicd-tower]$ git add .
[student@workstation cicd-tower]$ git commit -m "Implemented CI pipeline"
[student@workstation cicd-tower]$ git push

9. 查看最近的流水线执行。

这些执行是由于在上一步中推送到开发分支的更改而被三分之一化的。流水线在第二个阶段中失败。确定导致管道失败的错误。

在这里插入图片描述

当您看到管道作业完成时,第二个阶段的状态为失败。
在这里插入图片描述

因此,第三个阶段不会执行,代码也不会自动从dev分支合并到主分支。点击失败阶段的图标查看失败的作业的名称。单击launch_test_job打开一个新的Firefox选项卡,其中显示作业的输出。
在这里插入图片描述

测试环境web服务器冒烟测试失败。根据冒烟测试,测试服务器上的内容没有正确大写。web服务器上的消息应该是Hello World,而不是Hello world。这意味着名为Deploy Prod Webservers的Ansible Tower作业模板从未从流水线中调用过。

[student@workstation cicd-tower]$ curl http://servera
This is a test message RedHat 8.0 <br>
Current Host: servera <br>
Server list: <br>
servera.lab.example.com <br>
serverb.lab.example.com <br>

[student@workstation cicd-tower]$ curl http://serverb
This is a test message RedHat 8.0 <br>
Current Host: serverb <br>
Server list: <br>
servera.lab.example.com <br>
serverb.lab.example.com <br>

[student@workstation cicd-tower]$ curl http://serverc
Hello world
[student@workstation cicd-tower]$ curl http://serverd
Hello world

10. 查看Ansible Tower中的报错。

在这里插入图片描述


11. 纠正剧本的内容。

playbook.yml部署到每个web服务器上。提交并推动更改。验证您对开发分支的代码更改已集成到主分支中,并且生产服务器已使用这些更改进行更新。

[student@workstation cicd-tower]$ vim playbook.yml
    - name: Install sample web content
      copy:
        content: "Hello World\n"
        dest: /var/www/html/index.html

[student@workstation cicd-tower]$ git branch 
* dev
  master
[student@workstation cicd-tower]$ git add .
[student@workstation cicd-tower]$ git commit -m "Fixes content error."
[student@workstation cicd-tower]$ git push

12. 验证最近对存储库的推送是否触发了两次管道执行,从而导致对生产服务器的更新。

在这里插入图片描述

[student@workstation cicd-tower]$ curl http://servera
Hello World
[student@workstation cicd-tower]$ curl http://serverb
Hello World

在这里插入图片描述


13. 清除实验。

[student@workstation $ lab cicd-tower finish

💡总结

RHCA认证需要经历5门的学习与考试,还是需要花不少时间去学习与备考的,好好加油,可以噶🤪。

以上就是【金鱼哥】对 第十三章 使用Ansible Tower创建简单的CI/CD流水线 的简述和讲解。希望能对看到此文章的小伙伴有所帮助。

💾红帽认证专栏系列:
RHCSA专栏:戏说 RHCSA 认证
RHCE专栏:戏说 RHCE 认证
此文章收录在RHCA专栏:RHCA 回忆录

如果这篇【文章】有帮助到你,希望可以给【金鱼哥】点个赞👍,创作不易,相比官方的陈述,我更喜欢用【通俗易懂】的文笔去讲解每一个知识点。

如果有对【运维技术】感兴趣,也欢迎关注❤️❤️❤️ 【金鱼哥】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💕💕!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。