06 Ansible Roles

本文链接: https://www.jianshu.com/p/905cf0e51968
作者:闫立行

一、 Ansible Roles 介绍

一个数据中心有可能存在好多类型的服务器。比如WEB类型、DB类型、开发人员使用的开发类型、QA使用的测试类型等等。

实际生产中,基本每个类型的服务器的初始化行为都不一致。

那要在一个PlayBook中将这些动作完成,这个PlayBook将变得臃肿、庞大,且难以后续维护和更新。

如果能够针对每个类型的服务器单独编写PlayBook,最后通过某种方式整合这PlayBook, 在管理方式上就又会变得简单。

Ansible中提供了类似的概念,也就是Role。它允许管理员将他们复杂的PlayBook分解成一个个小的逻辑单元, 以便于维护和管理。

二、 Roles 结构

1. ROLE 是什么呢

先看一个示例:

webservers/
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── tasks
│   └── main.yml
├── templates
└── vars
    └── main.yml

从表面上看,它就是一个目录。目录的名字也就是role的名字,示例中,role 的名字叫做 webservers
进到这个role名字的目录里,会发现好多子目录。

使用时,每个目录必须包含一个main.yml文件,这个文件应该包含如下目录名称对应的内容:

  • tasks -包含角色要执行的任务的主要列表。
  • handlers -包含处理程序,此角色甚至该角色之外的任何地方都可以使用这些处理程序。
  • defaults-角色的默认变量。
  • vars-角色的其他变量。
  • files -包含可以通过此角色部署的文件。
  • templates -包含可以通过此角色部署的模板。
  • meta-为此角色定义一些元数据。

角色必须至少包含这些目录之一,但是最好排除任何未使用的目录。

三、 制作一个Role

我们将上文经过最终优化的PlayBook,分解成一个Role。 那么应该如何操作呢?

最终优化的PlayBook

- name: template playbook example
  hosts: webservers
  vars:
    createuser:
      - tomcat
      - www
      - mysql
  tasks:
    - name: create user
      user: name={{ item }} state=present
      with_items: "{{ createuser }}"

    - name: yum nginx webserver
      yum: name=nginx state=present

      # use ansible template
    - name: update nginx main config
      template: 
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      tags: updateconfig
      notify: reload nginx server
      
    - name: add virtualhost config
      copy:
        src: www.qfedu.com.conf
        dest: /etc/nginx/conf.d/
      tags: updateconfig
      notify: reload nginx server
      
    - name: check nginx syntax
      shell: /usr/sbin/nginx -t
      register: nginxsyntax
      tags: updateconfig
      
    - name: check nginx running
      stat: path=/var/run/nginx.pid
      register: nginxrunning
      tags: updateconfig
        
    - name: print nginx syntax
      debug: var=nginxsyntax
      
    - name: start nginx server
      service: name=nginx state=started
      when:
        - nginxsyntax.rc == 0
        - nginxrunning.stat.exists == false
  handlers:
    - name: reload nginx server
      service: name=nginx state=started
      when:
        - nginxsyntax.rc == 0
        - nginxrunning.stat.exists == true

分解这个PlayBook,命名role 的名字为 nginx

nginx/
│
├── files
├── handlers
│   └── main.yml
├── tasks
│   └── main.yml
├── templates
└── vars
    └── main.yml

files 文件夹存放文件

存放 www.qfedu.com.conf 配置文件

handlers 文件夹中的main.yml 文件

---
- name: reload nginx server
  service: name=nginx state=started
  when: nginxsyntax.rc == 0 and nginxrunning.stat.exists == true

tasks 文件夹中的 main.yml 文件

---
- name: create user
  user: name={{ item }} state=present
  with_items: "{{ createuser }}"

- name: yum nginx webserver
  yum: name=nginx state=present

  # use ansible template
- name: update nginx main config
  template: 
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  tags: updateconfig
  notify: reload nginx server
  
- name: add virtualhost config
  copy:
    src: www.qfedu.com.conf
    dest: /etc/nginx/conf.d/
  tags: updateconfig
  notify: reload nginx server
  
- name: check nginx syntax
  shell: /usr/sbin/nginx -t
  register: nginxsyntax
  tags: updateconfig
  
- name: check nginx running
  stat: path=/var/run/nginx.pid
  register: nginxrunning
  tags: updateconfig
    
- name: print nginx syntax
  debug: var=nginxsyntax
  
- name: start nginx server
  service: name=nginx state=started
  when:
    - nginxsyntax.rc == 0
    - nginxrunning.stat.exists == false
...

templates 文件夹存放模板

存放 nginx.conf.j2 模板

vars 文件夹中的 main.yml 文件

---
createuser:
  - tomcat
  - www
  - mysql

经过以上对PlayBook 的拆分,就形成了一个nginx 的 ROLE。
回到本章开始的问题,当一个数据中心存在多种类型的服务器时,我们可以针对每个类型去单独写一个ROLE,这些ROLE 有可能分给不同的人去开发,这样不但使开发的逻辑变得简单,且开发效率也随着人员的增加而提升。

四、如何在PlayBook中使用 Role

Role 本身不能被直接执行,还是需要借助PlayBook进行间接的调用。
- name: a playbook used role
  hosts: all
  roles:
    - nginx

五、使用角色

1. 经典(原始)方式

在 playbook 中给定 roes:属性

- name: use  role
  hosts: webservers
  roles:
    - webservers

2. 新方式

在 playbook 中给定 import_role 属性
这种方式适用于 Ansible 2.4及以上

- name: use rose
  hosts: webservers
  tasks:
    - debug:
      msg: "before we run our role"
    - import_role:
        name: webservers
    - debug:
        msg: "after we ran our role"

六、如何使用 Galaxy

Ansible的galaxy 工具,类似程序员使用的github。运维人员可以将自己编写的Role通过galaxy这个平台进行分享。同样,我们也可以通过galaxy 这个平台去获取一些我们想要的role。官网为:https://galaxy.ansible.com
而ansible-galaxy 则是一个使用 galaxy 命令行的工具。它使我们不用访问galaxy 的网站而获取到需要的内容。
接下来我们将通过 ansible-galaxy 这个命令行去学习galaxy的使用。

获取帮助

# ansible-galaxy  --help
Usage: ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] ...

Options:
  -h, --help     show this help message and exit
  -v, --verbose  verbose mode (-vvv for more, -vvvv to enable connection
                 debugging)
  --version      show program's version number and exit

获取具体某个子指令的帮助

在 ansible-galaxy  --help 中可以看到子指令
子指令包含: delete|import|info|init|install|list|login|remove|search|setup
ansible-galaxy delete|import|info|init|install|list|login|remove|search|setup --help
# ansible-galaxy install --help
Usage: ansible-galaxy install [options] [-r FILE | role_name(s)[,version] | scm+role_repo_url[,version] | tar_file(s)]

Options:
  -f, --force           Force overwriting an existing role
  -h, --help            show this help message and exit
  -c, --ignore-certs    Ignore SSL certificate validation errors.
  -i, --ignore-errors   Ignore errors and continue with the next specified
                        role.
  -n, --no-deps         Don't download roles listed as dependencies
  -r ROLE_FILE, --role-file=ROLE_FILE
                        A file containing a list of roles to be imported
  -p ROLES_PATH, --roles-path=ROLES_PATH
                        The path to the directory containing your roles. The
                        default is the roles_path configured in your
                        ansible.cfg file (/etc/ansible/roles if not
                        configured)
  -s API_SERVER, --server=API_SERVER
                        The API server destination
  -v, --verbose         verbose mode (-vvv for more, -vvvv to enable
                        connection debugging)
  --version             show program's version number and exit

常用指令

// 在galaxy 上搜索共享的ROLE
# ansible-galaxy search
// 安装 galaxy 上共享的 ROLE
# ansible-galaxy install
// 列举已经通过 ansible-galaxy 工具安装的ROLE
# ansible-galaxy list
// 创建一个ROLE 的空目录架构, 这样我们在开发一个ROLE的时候,就不需要手动创建目录了。
# ansible-galaxy init --offline

Example

// 创建了名字为testrole的空ROLE目录结构,默认在执行命令的目录生产。
# ansible-galaxy init  testrole
# tree testrole/
testrole/
├── defaults
│   └── main.yml
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── tests
│   ├── hosts
│   └── test.yml
└── vars
    └── main.yml
1.2 动态资产

动态资产, -i 参数后面接的是一个可运行的脚本。脚本的结果为一个 Ansible 可理解的 JSON 格式字符串。

为什么要存在动态资产呢? 往往我们在使用 Ansible 管理服务器前,公司中有可能已经将服务器信息存储在了特定位置,比如 CMDB, 数据库等系统。
此时若我们再使用静态资产去管理服务器,势必会造成资产管理入口不统一的问题。

因此我们只能抛弃原先的静态资产,通过脚本从已存在的系统中获取要管理的节点,并按照特定的形式传给 Ansible。这样既解决了公司资产统一入口, 也解决了Ansible 的服务器管理来源。

动态资产实例

{
  "_meta": {
    "hostvars": {
      "192.168.100.10": {
        "host_var": "hoge"
      },
      "192.168.100.20": {
        "host_var": "fuga"
      }
    }
  },
  "sampledb_servers": {
    "hosts": [
      "192.168.100.10",
      "192.168.100.20"
    ],
    "vars": {
      "group_var": "hogefuga"
    }
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342