Ansible

bilibili:

https://gitee.com/luzhenxiong/bilibili-ansible

example:

https://gitee.com/luzhenxiong/examples-ansible

docs:

https://docs.ansible.com/ansible/latest/index.html

github:

https://github.com/ansible/ansible

教材:

吃透Ansible核心源码剖析与项目实战

相关阅读

渐进式使用

第一阶段: 手工运维

直接上手ansible部署项目是困难的且容易打击积极性,应该手工运维一次,记录流程

第二阶段: 将手工运维的过程转成ansible剧本

整理手工运维流程,转换成单个playbook.yml文件, 持久化,可复用, 例如

---
- name: Ping servers
  hosts: all
  remote_user: root

  tasks:
  - name: Example from an Ansible Playbook
    ansible.builtin.ping:

小技巧

从这个阶段开始,使用ansible-lint工具验证剧本

第三阶段: playbook文件使用各种高级语法

register、handles、when、loop、ansible galaxy等

使用开源的ansible剧本

正确用法:

安装collection或role后,在自建的yml导入role,然后通过修改变量来实现定制化需求

以prometheus为例

---
- hosts: all
  roles:
  - prometheus.prometheus.prometheus
  vars:
    # 修改默认变量
    prometheus_targets:
      node:
      - targets:
        - localhost:9100
        - node.demo.do.prometheus.io
        labels:
          env: demosite

第四阶段: playbook.yml->playbooks目录

标准的目录结构

playbooks/
├── files/code.py
├── defaults/main.yml  -- 默认变量
├── vars/env.prd
├── templates/
├── tasks/main.yml
├── playbook.yml
└── playbook2.yml

第五阶段: playbooks目录->collection目录

https://docs.ansible.com/ansible/latest/dev_guide/developing_collections_structure.html

目录结构:

collection/
├── docs/
├── galaxy.yml
├── meta/
│   └── runtime.yml
├── plugins/
│   ├── modules/
│   │   └── module1.py
│   ├── inventory/
│   └── .../
├── README.md
├── roles/
│   ├── role1/
│   ├── role2/
│   └── .../
├── playbooks/
│   ├── files/
│   ├── vars/
│   ├── templates/
│   └── tasks/
└── tests/

最佳实践

ansible在cicd平台的使用

优先在宿主机安装ansible,也就是说专门搭建一个ansible master服务器, 该服务器同时作为cicd服务器的worker服务器。

ansible在项目的使用

根目录创建playbook.yml, 编写各种任务调用role, 类似makefile的格式, 用tags区分任务。 对于roles, 存放到单独的仓库来管理、测试

ai的建议

以下是一些Ansible的最佳实践:

  1. 使用适当的目录结构:建议使用具有清晰层次结构的目录来组织Ansible项目。主机清单(inventory)文件、角色(roles)、变量(vars)、任务(tasks)等可以根据需要进行分组。

  2. 使用变量:通过使用变量,可以使Playbooks更具可重用性和灵活性。将常用的值定义为变量,以便在不同的地方引用。

  3. 使用角色进行模块化:将相关任务和变量组织成角色可以使代码更易于管理和复用。角色可以按照功能或者服务进行划分,例如web服务、数据库等。

  4. 使用模板:使用Jinja2模板引擎可以使Playbooks更加动态和可扩展。在模板中,可以使用变量和条件语句来生成配置文件或其他需要动态生成的内容。

  5. 尽量使用idempotency:Ansible的设计理念之一是idempotency(幂等性),即无论执行多少次,结果都应该是相同的。在Playbooks中,应该尽量遵循这个原则,确保任务的可重复性。

  6. 处理错误和失败:在Playbooks中,应该合理处理错误和失败的情况。通过使用fail模块、变量检查和错误处理策略,确保在出现问题时能够及时停止或恢复。

  7. 使用Git进行版本控制:将Ansible项目纳入版本控制是一个良好的实践,可以更好地管理代码、进行版本控制,以及促进多人协作。

  8. 使用适当的插件和模块:Ansible提供了丰富的插件和模块,可以扩展其功能。根据需要,了解并使用适当的插件和模块,可以简化任务的实现。

  9. 使用适当的标签(Tags):通过使用标签,可以选择性地运行特定的任务或角色。这在大型Playbooks中特别有用,可以避免运行不必要的任务。

  10. 定期测试和验证:将正确性和可靠性视为一个持续的过程,定期测试和验证Playbooks以确保其功能和预期结果。

以上是一些建议,但具体实践应该根据项目需求和团队实际情况来进行调整和完善。

常用的collection

community.docker

https://docs.ansible.com/ansible/latest/collections/community/docker/index.html#plugins-in-community-docker

踩坑经验

当存在name的镜像名称时就不会构建了,即使Dockerfile的内容发生了变更。

添加force_source: true可以解决这个问题

community.general.archive

排除指定目录: https://github.com/ansible-collections/community.general/issues/6857

需求:

打包src目录, 想排除src/gbackend/core/api_json文件夹下的所有json文件, 同时解压出来首先显示src目录

小技巧

核心点: 要expanded_exclude_paths和expanded_paths下的路径完全匹配时才过滤

 src/...
    gbackend/...
             core/...
                 api_json/.gitignore
                          file1.json
                          file2.json
                          file3.json
docs/
Dockerfile
.gitignore
...
- name: 发布
  community.general.archive:
    path:
      - /buildbot/tag/build/.gitignore  # 占位符文件,为了让src目录也打包进去
      # 必须用通配符,否则exclude_path不生效,排除不了指定文件
      - /buildbot/tag/build/src/*
      # 不能删除,exclude_path已经排除gbackend目录
      - /buildbot/tag/build/src/gbackend/*
      # 不能删除,exclude_path已经排除core目录
      - /buildbot/tag/build/src/gbackend/core/*
      # 占位符文件,为了打包空的api_json目录
      - /buildbot/tag/build/src/gbackend/core/api_json/.gitignore
    dest: /usr/share/nginx/downloads/gather-{{ version }}.tgz
    exclude_path:
      # 避免(path:src/*)直接打包gbackend, 里面可能包含需要排除的core/api_json/*.json文件
      - /buildbot/tag/build/src/gbackend
      # 避免(path:gbackend/*)直接打包core, 里面可能包含需要排除的api_json/*.json文件
      - /buildbot/tag/build/src/gbackend/core
      # 避免(path:core/*)直接打包api_json, 里面可能包含需要排除的*.json文件
      - /buildbot/tag/build/src/gbackend/core/api_json

源码剖析

ansible提供的模块代码文件: ansible.modules