星期二, 八月 27, 2013

OCF开发者指南 第四章

4 资源代理结构

一个典型的(基于shell的)资源代理有一些标准的结构元素。本章将按顺序说明。在说明里将描述资源代理每一个支持的行为的细节内容。本章将以一个假想的foobar函数为例子。

4.1 资源代理解释器

每个资源代理都以标准的“shebang”(#!)抬头

#!/bin/sh

如果资源代理使用shell编写,最好是指定通用的shell解释器(#!/bin/sh),但也不强求。使用/bin/sh 兼容的资源代理一定不要使用某种特别shell的方言(如bash中的 ${!variable}),建议对资源代理使用检查器检查一下,如checkbashisms。

有人考虑使用一个patch来使得之前的sh兼容的资源代理只用于bash、ksh或者其他的非通用shell。然而,对于新完成的资源代理,最好显式的定义一个指定的shell解释器,比如/bin/bash。

4.2 作者和授权信息

资源代理应该包含一段注释,来说明作者和版权信息,并说明资源代理的授权信息,如:

#
#   Resource Agent for managing foobar resources.
#
#   License:      GNU General Public License (GPL)
#   (c) 2008-2010 John Doe, Jane Roe,
#                 and Linux-HA contributors

如果资源代理的使用的授权有不同版本,缺省可假设是当前版本。

4.3 初始化

任何 shell 资源代理都应该 运行 .ocf_shellfuncs 函数库。按下面的语法,如$OCF_FUNCTION_DIR,这里是为了测试和写文档,这个变量也许重复定义了。
# Initialization:
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs

4.4  资源行为的函数实现

下面将说明的是资源代理公布的行为的函数实现。每个行为的细节将在第五章描述。

4.5 执行块

下面是一个资源代理实际执行时的部分代码。通常遵循如下的标准结构:
# Make sure meta-data and usage always succeed
case $__OCF_ACTION in
meta-data)      foobar_meta_data
                exit $OCF_SUCCESS
                ;;
usage|help)     foobar_usage
                exit $OCF_SUCCESS
                ;;
esac

# Anything other than meta-data and usage must pass validation
foobar_validate_all || exit $?

# Translate each action into the appropriate function call
case $__OCF_ACTION in
start)          foobar_start;;
stop)           foobar_stop;;
status|monitor) foobar_monitor;;
promote)        foobar_promote;;
demote)         foobar_demote;;
reload)         ocf_log info "Reloading..."
                foobar_start
                ;;
validate-all)   ;;
*)              foobar_usage
                exit $OCF_ERR_UNIMPLEMENTED
                ;;
esac
rc=$?

# The resource agent may optionally log a debug message
ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION returned $rc"
exit $rc



OCF开发者指南 第三章

3 返回值

对于任意调用,资源代理必须在退出时给出一个返回值,这个值会告诉调用者。返回值的细节将在下面的章节中解释。

3.1 OCF_SUCCESS (0)

行为完全成功执行。这是所有成功的 start, stop, promote, demote, migrate_from, migrate_to, meta_data, help, 和 usage 执行成功后期望获得的返回值;

对于monitor(以及其被放弃的别名 status),使用一个约定来用此返回值:
  • 对于一些基本的(无状态)资源,monitor 行为的 OCF_SUCCESS 意思是这个资源正在运行,没有运行或者正常关闭的资源必须返回 OCF_NOT_RUNNING;
  • 对于master/slave (有状态)资源,OCF_SUCCESS 表示资源以slave 模式运行,以Master资源运行的资源应该返回 OCF_RUNNING_MASTER, 而正常关闭的资源必须返回OCF_NOT_RUNNING
3.2 OCF_ERR_GENERIC (1)

行为返回一个一般错误。没有其他的错误码时,资源代理应该使用这个exit码。

集群资源管理器解释这个退出码为一个软错误。这就意味着,除非另外说明,出现这种错误的资源通常是在相同节点上重启。

3.3 OCF_ERR_ARGS (2)

用错的资源调用参数。这是资源调用时的一个安全保障警示,比如使用错误数量的参数。
Note:资源调用如果使用了不支持的行为参数,不应该用这个返回码,而是使用OCF_ERR_UNIMPLEMENTED
3.4 OCF_ERR_UNIMPLEMENTED (3)

当资源代理执行一个未实现的行为时应该返回这个值。

不是所有资源代理的行为都是强制实现的。promote, demote, migrate_from,notify等都是可选的行为,资源代理可以不实现。比如,当一个无状态的资源代理被错误的配置成 master/slave 资源, 资源代理应该在promote和demote行为时返回OCF_ERR_UNIMPLEMENTED.

3.5 OCF_ERR_PERM (4)

这个错误源于权限不够。也许是资源无权打开一个文件、一个socket、一个目录或者类似。

集群资源管理将这个错误解释为一个硬错误。这意味着,如果没有特别配置,资源管理器将尝试在另外的节点重启资源(也许新节点上没有那个权限问题)。

3.6 OCF_ERR_INSTALLED (5)

这个错误源于行为执行需要的一个组件缺失。这个可能是因为一个需要的二进制文件没有执行或者,或一个至关重要的配置文件不可读。

集群资源管理将这个错误解释为一个硬错误。这意味着,如果没有特别配置,资源管理器将尝试在另外的节点重启资源(也许新节点上相关文件或二进制代码是可得的)。

3.7 OCF_ERR_CONFIGURED (6)

这个错误源于资源错误的配置。比如,比如用户在需要整数的地方配置成一个字母组成的字符串。

集群资源管理将这个错误解释为一个致命错误。因为这个配置文件会扩散到全集群范围,所以无法在另一个节点恢复这个错误。当资源运行出现这个错误,集群管理器会尝试关闭资源,等待系统管理员介入。

3.8 OCF_ERR_RUNNING (7)

资源没有被发现正在运行。这是monitor行为会返回的退出码。注意,返回这个值意味着资源或者安全的关闭了,或者没有启动。

如果资源是因为在一种错误条件下没有运行,monitor行为应该返回OCF_ERR_ 退出码中的一个,或者OCF_FAILED_MASTER

3.9 OCF_RUNNING_MASTER (8)

资源没有以Master身份运行。这个返回值只应用于有状态(Master/Slave)资源,也值针对monitor行为。

注意:没有“slave 身份运行”的退出码。这是因为和无状态资源正常运行没有区别。所以以slave身份运行的有状态资源,monitor行为的返回码应该是 OCF_SUCCESS。

3.10 OCF_FAILED_MASTER (9)

资源被发现以master身份运行失败。这个返回值只应用于有状态的(Master/Slave)资源的monitor行为。

资源管理器将这个错误解释为一个软错误。这意味着,如果没有别的配置,这个资源将就地(在同一节点)降级(demoting),停止,启动并提升(promoting)。

星期四, 八月 22, 2013

OCF开发者指南 第二章

2. API 定义

2.1 环境变量

一个资源代理通过环境变量来获得资源的全部配置信息。那些环境变量的名字往往前缀是OCF_RESKEY, 名字就是资源的名字。比如,如果资源有一个ip 参数设为 192.168.1.1, 资源代理就使用环境变量 OCF_RESKEY_ip来保存这个值。

对于任何不需要用户设置的资源----即在资源代理元数据参数定义没有被设置成 required="true"----资源代理必须:
  • 提供一个合理的缺省值。这个必须在元数据里明确。为了方便,资源代理使用一个形如OCF_RESKEY_<parametername>_default 的变量保存这个值;
  • 另一个选择,就是这个值为空,但程序可以正确运行;
另外,集群管理器也可以支持元资源参数。这些不直接应用到资源配置,而是指定集群资源管理器如何管理资源。比如,pacemaker使用target-role元参数来指定资源是应该启动还是停止。

元参数通过OCF_RESKEY_CRM_meta_ 命名方式传给资源代理,注意所有连字符都是转为下划线。这样 target-role 属性都映射都环境变量 OCF_RESKEY_CRM_meta_target_role

2.2 Actions

任何资源代理必须支持一个命令行参数,这个参数指定资源代理的执行。下列的行为是资源代理必须支持的:
  • start --- 启动资源
  • stop ---  停止资源
  • monitor --- 查询资源状态
  • meta-data --- 导出资源代理元数据
另外,资源代理可以选择支持如下行为:
  • promote --- 将一个资源提升为Master 角色 (只对 Master/Slave 资源)
  • demote  --- 将一个资源转为Slave 角色(只对 Master/Slave 资源)
  • migrate_to 和 migrate_from --- 实现资源的热迁移
  • validate_all --- 校验资源的配置
  • usage 或 help --- 显示usage信息或者help信息。是资源本身用命令行运行时候的显示
  • status --- 已经丢弃。是monitor之前使用的行为
2.3 Timeouts

action timeouts 是用来从外部强制资源代理正确运行的。集群管理器负责监视资源代理的某个动作运行了多长时间,如果没有在限定时间内完成,则会终止这个程序。这样资源代理不用去检查时间过期。

然而,资源代理可以建议这个timeout值(这个值如果设置了,会被集群管理器按时强制实行)。后面章节会详细讲到细节。

2.4 Metadata (元数据)

每个资源代理都要必须在一个XML元数据里说明其目的支持的参数。这个元数据表被集群管理器用来提供在线帮助,资源代理的man手册也可以从这里导出。下面是一个虚构的资源代理元数据:
 
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="foobar" version="0.1">
  <version>0.1</version>
  <longdesc lang="en">
This is a fictitious example resource agent written for the
OCF Resource Agent Developers Guide.
  </longdesc>
  <shortdesc lang="en">Example resource agent
  for budding OCF RA developers</shortdesc>
  <parameters>
    <parameter name="eggs" unique="0" required="1">
      <longdesc lang="en">
      Number of eggs, an example numeric parameter
      </longdesc>
      <shortdesc lang="en">Number of eggs</shortdesc>
      <content type="integer"/>
    </parameter>
    <parameter name="superfrobnicate" unique="0" required="0">
      <longdesc lang="en">
      Enable superfrobnication, an example boolean parameter
      </longdesc>
      <shortdesc lang="en">Enable superfrobnication</shortdesc>
      <content type="boolean" default="false"/>
    </parameter>
    <parameter name="datadir" unique="0" required="1">
      <longdesc lang="en">
      Data directory, an example string parameter
      </longdesc>
      <shortdesc lang="en">Data directory</shortdesc>
      <content type="string"/>
    </parameter>
  </parameters>
  <actions>
    <action name="start"        timeout="20" />
    <action name="stop"         timeout="20" />
    <action name="monitor"      timeout="20"
                                interval="10" depth="0" />
    <action name="reload"       timeout="20" />
    <action name="migrate_to"   timeout="20" />
    <action name="migrate_from" timeout="20" />
    <action name="meta-data"    timeout="5" />
    <action name="validate-all"   timeout="20" />
  </actions>
</resource-agent>


上面定义resouce-agent 元素,必须有一个,并用name和version定义。

longdesc 和 shortdec 元素提供长的和短的资源代理功能描述。shortdesc只提供一句话,提供简介列表。longdesc提供更多细节的完整描述。

parameters 元素描述资源代理参数,可以有多个parameter 子元素,每一个都是资源代理支持的参数。

每一个parameter参数用应该有一个shortdesc和一个longdesc 用来描述参数的细节,一个content元素描述参数期望的内容。parameter支持如下属性:
  • required 指示参数是强制的(required="0")还是可选的(require=""1)
  • unique (允许值:0和1)指示指定的值在整个集群是唯一的。比如,一个高可用的浮动IP地址会被定义为unique,因为这个地址在整个集群里面只能有一个,不能重复。
content元素有两个属性:
  • type 描述参数的类型(string,integer,或者是 boolean),如果未设置,type 缺省是string
  • 对于一些可选parameter,通常通过default属性设置一个合适的
actions 列表定义了资源代理声明的支持的行为。

每一个action 都有自己的timeout值。这是指示用户这个行为最小的timeout值。这种方式适应某些可以很快启动的资源(如IP地址、文件系统)和需要数分钟才启动的资源(如数据库)。

另外,一些重复的行为(如monitor)则应该有一个推荐的最小时间间隔 interval,这个时间间隔是两次相同行为的连续调用的时间。和timeout一样,这个值没有缺省值。这个值仅仅提供一个参考的最小值。

星期三, 八月 21, 2013

OCF开发者指南 第一章

原文作者:Florian Haas, Hastexo
版本:1.03
发布日期: 2012年7月26日

1. 介绍


本文档是为所有OCF (Open Cluster Framework)的开发者、维护者和贡献者准备的一份指南。本文解释了资源代理(resouce agent)的术语和通用函数的功能,描述了资源代理的API,并给资源代理的开发者一些提示。

1.1 什么是资源代理

资源代理是管理集群资源的可执行程序,现在也没有正式的定义,或者定义成:集群管理的任何东西都是资源。集群资源可以是IP地址、文件系统、数据库服务和虚拟机等等。

1.2 谁或者什么使用资源代理


任何和Open Cluster Faramework(OCF)适应的集群管理应用都和使用资源代理管理资源。在本指南写作时,在linux平台有有两种OCF适应的集群管理应用:


  • Pacemaker:支持corosync 和 heartbeat的集群消息框架的集群管理器。Pacemaker发源于Linux-HA项目;
  • RGmanager:是Redhat 集群管理组件。它只支持corosync集群消息框架;
1.3 用什么编程语言

OCF兼容的资源代理可以用任何语言来实现。API没有指定语言。然而,多数的资源代理都用shell脚本来实现,这也是为什么本指南的例子都是用shell脚本完成。