Nebula Graph 的 Ansible 实践

本文首发于 Nebula Graph 公众号 NebulaGraphCommunity,Follow & 看大厂图数据库技术实践

Nebula Graph 的 Ansible 实践

背景

在 Nebula-Graph 的日常测试中,我们会经常在服务器上部署 Nebula-Graph。为了提高效率,我们需要一种工具,能帮我们做到快速部署,主要的需求:

  • 可以使用非 root 账户部署 Nebula Graph,这样我们可以针对这个用户设置 cgroup 做资源限制。
  • 可以在操作机上更改配置文件,然后分发到部署的集群上,方便我们做各种调参的测试。
  • 可以使用脚本调用,方便以后我们继承在测试的平台或工具上。

工具选择上,早期有 Fabric 和 Puppet,比较新的工具有 Ansible 和 SaltStack。

Ansible 在 GitHub 上有 40K+ star, 而且在 2015年被 Red Hat 收购,社区比较活跃。很多开源项目都提供了 Ansible 的部署方式,比如 Kubernetes 中的 kubespray和 TiDB 中的 tidb-ansible

综合下来,我们使用 Ansible 来部署 Nebula Graph。

Ansible 介绍

特点

Ansible 是开源的,自动化部署工具(Ansible Tower 是商业的)。具有以下的几个特点:

  • 默认协议是基于 SSH,相比于 SaltStack不 需要额外部署 agent。
  • 使用 playbook, role, module 来定义部署过程,比较灵活。
  • 操作行为幂等。
  • 模块化开发,模块比较丰富。

优缺点比较明显

  • 使用 SSH 协议,优点是大多数机器默认只要有账号密码就可以通过 Ansible 完成部署,而缺点性能上会差一些。
  • 使用 playbook 来定义部署过程,Python 的 Jinja2 作为模板渲染引擎,对于熟悉的人来说会比较方便,而对于没有使用过的人,会增加学习成本。

综上,适用于小批量机器的批量部署,不需要关心额外部署 agent 的场景,和我们的需求比较匹配。

部署逻辑

通常为了离线部署,可以把机器分为 3种角色。

  • Ansible 执行机:运行 Ansible 的机器,需要能通过 SSH 连到所有机器。
  • 有外网的资源机:运行需要连接外网的任务,比如下载 RPM 包。
  • 服务器:即运行服务的服务器,可以网络隔离,通过执行机来部署
Nebula Graph 的 Ansible 实践

任务逻辑

Ansible 中,主要有三种层次的任务:

  • Module
  • Role
  • Playbook

Module 分为 CoreModule 和 CustomerModule,是 Ansible 任务的基本单元。

在运行任务的时候,首先 Ansible 会根据 module 的代码,将参数代入,生成一个新的 Python 文件,通过 SSH 放到远程的 tmp 文件夹,然后通过 SSH 远程执行 Python 将输出结果返回,最后把远程目录删除。

Nebula Graph 的 Ansible 实践
# 设置不删除 tmp 文件
export ANSIBLE_KEEP_REMOTE_FILES=1

# -vvv 查看 debug 信息
ansible -m ping all -vvv
<192.168.8.147> SSH: EXEC ssh -o ControlMaster=auto -o ControlPersist=30m -o ConnectionAttempts=100 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="nebula"' -o ConnectTimeout=10 -o ControlPath=/home/vesoft/.ansible/cp/d94660cf0d -tt 192.168.8.147 '/bin/sh -c '"'"'/usr/bin/python /home/nebula/.ansible/tmp/ansible-tmp-1618982672.9659252-5332-61577192045877/AnsiballZ_ping.py && sleep 0'"'"''

可以看到有这样的日志输出,AnsiballZ_ping.py 就是根据 module 生成的 Python 文件,可以登录到那台机器,执行 Python 语句看一下结果。

python3 AnsiballZ_ping.py

#{"ping": "pong", "invocation": {"module_args": {"data": "pong"}}}

返回了运行 Python 文件的标准输出,然后 Ansible 再对返回的结果做额外处理。

Role 是串联 module 的一系列任务,可以通过 register 来传递上下文参数。

典型例子:

  1. 创建目录
  2. 如果创建目录成功,继续安装,否则退出整个部署工程。

Playbook 是组织部署机器和 role 之间的关联。

通过在 inventory 对不同机器进行分组,对不同分组使用不同的 role 来部署,完成非常灵活的安装部署任务。

当 playbook 定义好之后,不同的环境,只要变更 inventory 中的机器配置,就可以完成一样的部署过程。

模块定制

自定义 filter

Ansible 使用 Jinja2 作为模板渲染引擎,可以用 Jinja2 自带的 filter ,比如

# 使用 default filter,默认输出 5

ansible -m debug -a 'msg={{ hello | default(5) }}' all

有时候,我们会需要自定义的 filter 来操作变量,典型的场景就是 nebula-metad 的 地址 --meta_server_addrs

  • 当只有 1 个 metad 的时候,格式是 metad1:9559
  • 当有 3 个 metad 的时候,格式是 metad1:9559,metad2:9559,metad3:9559

在 ansible playbook 的工程下,新建 filter_plugins 目录,创建一个 map_fomat.py Python文件,文件内容:

# -*- encoding: utf-8 -*-
from jinja2.utils import soft_unicode

def map_format(value, pattern):
    """
    e.g.  
    "{{ groups['metad']|map('map_format', '%s:9559')|join(',') }}"
    """
    return soft_unicode(pattern) % (value)

class FilterModule(object):
    """ jinja2 filters """
    def filters(self):
        return {
            'map_format': map_format,
        }

{{ groups['metad']|map('map_format', '%s:9559')|join(',') }} 即为我们想要的值。

自定义 module

自定义 module 需要符合 Ansible 框架的格式,包括获取参数,标准返回,错误返回等。

写好的自定义 module,需要在 ansible.cfg 中配置 ANSIBLE_LIBRARY,让 ansible 能够获取到。

具体参考官网:https://ansible-docs.readthedocs.io/zh/stable-2.0/rst/developing_modules.html

Nebula Graph 的 Ansible 实践

因为 Nebula Graph 本身启动并不复杂,使用 Ansible 来完成 Nebula-Graph 的部署十分简单。

  1. 下载 RPM 包。
  2. 复制 RPM 包到部署机,解压后,放到目的文件夹。
  3. 更新配置文件。
  4. 通过 shell 启动。

使用通用的 role

Nebula Graph 有三个组件,graphd、metad、storaged,三个组件的命名和启动使用一样的格式,可以使用通用的 role,graphd、metad、storaged 分别引用通用的 role。

一方面更容易维护,另一方面部署的服务更有细粒度。比如 A B C 机器部署 storaged, 只有 C 机器部署 graphd,那 A B 机器上,就不会有 graphd 的配置文件。

# 通用的 role, 使用变量 install/task/main.yml
- name: config {{ module }}.conf
  template:
    src: "{{ playbook_dir}}/templates/{{ module }}.conf.j2"
    dest: "{{ deploy_dir }}/etc/{{ module }}.conf"
    
# graphd role,将变量传进来 nebula-graphd/task/main.yml
- name: install graphd
  include_role:
    name: install
  vars:
    module: nebula-graphd

在 playbook 中,graphd 的机器组来运行 graphd 的 role,如果 A B 不在 graphd 的机器组,就不会将 graphd 的配置文件上传。

这样部署后,就不能使用 Nebula-Graph 的 nebula.service start all 来全部启动,因为有的机器上会没有 nebula-graphd.conf 的配置文件。类似的,可以在 playbook 中,通过参数,来指定不同的机器组,传不同的参数。

# playbook start.yml
- hosts: metad
  roles:
    - op
  vars:
    - module: metad
    - op: start

- hosts: storaged
  roles:
    - op
  vars:
    - module: storaged
    - op: start

- hosts: graphd
  roles:
    - op
  vars:
    - module: graphd
    - op: start

这样会相当于多次 ssh 去执行启动脚本,虽然执行效率没有 start all 更好,但是服务的启停会更为灵活。

Nebula Graph 的 Ansible 实践

使用 vars_prompt 结束 playbook

当只想更新二进制,不想删除数据目录的时候,

可以在 remove 的 playbook 中,添加 vars_prompt 二次确认,如果二次确认了,才会删除数据,否则会退出 playbook。

# playbook remove.yml
- hosts: all
  vars_prompt:
    - name: confirmed
      prompt: "Are you sure you want to remove the Nebula-Graph? Will delete binary only  (yes/no)"
 
  roles:
    - remove

而在 role 里,会校验二次确认的值

# remove/task/main.yml
---
- name: Information
  debug:
    msg: "Must input 'yes', abort the playbook "
  when:
    - confirmed != 'yes'

- meta: end_play
  when:
    - confirmed != 'yes

效果如图,删除时可以二次确认,如果不为 yes,就会取消执行这次的 playbook,这样可以只删除二进制,而不删除 nebula 集群的数据。

Nebula Graph 的 Ansible 实践

交流图数据库技术?加入 Nebula 交流群请先填写下你的 Nebulae 名片,Nebula 小助手会拉你进群~~

推荐阅读

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

推荐阅读更多精彩内容