纳斯达克上市公司招聘

2010年6月3日 admin 没有评论

职位名称:系统工程师
所属部门:技术部
招聘人数:1人
工作地点:北京市海淀区北四环西路58号理想国际大厦8层

工作职责:

1、负责地产、房产频道Linux/Unix系统维护,包括:部署、配置、调优、故障排除、应急响应等;
2、负责系统的整体架构设计;
3、开发系统日常管理工具,完成工作所需的文档;

任职资格:

1、熟悉网络理论(如 OSI七层模型,TCP状态机),网络协议(TCP/IP)等;
2、熟练配置apache、php、mysql、memcached、rsync、squid、nginx等服务;
3、熟练编写shell脚本,熟悉Perl、Python、PHP任其一种语言优先;
4、有大型网站运维经验者优先,熟悉分布式架构;
5、有较强的学习能力及良好的表达能力,愿意积极主动的思考如何把工作做好;
6、有团队合作精神,思维清晰,细致耐心,责任心强,能独立完成工作,承受较大工作压力;
7、大学专科以上学历,3年以上相关工作经验。

由于某些原因,具体公司名字不写了,有意者将简历请发至 dongliang[at]leju.sina.com.cn(有意者请发world档,发邮件时请将[at]改成@,邮件主题请包含关键词“系统工程师”,便于邮件识别)

分类: Linux System 标签:

配置管理工具Puppet简介、安装

2010年5月27日 admin 没有评论

前言:

系统管理员经常陷入一系列的重复任务中:如升级软件包、管理配置文件、系统服务、cron任务以及添加新的配置、修复错误等。这些任务通常是重复低效的,解决这类任务的第一反应是让他们自动化,于是出现了定制脚本。由于环境复杂,定制脚本和应用程序一再被重复开发,并且很难适合多种平台,灵活性和功能也很难保证,于是像Puppet这样的自动化配置管理工具便出现了。

在开源世界里,有很多配置工具可供选择,这个领域一些关键的产品有:

Puppet(http://puppet.reductivelabs.com/):

  • Ruby写成的配置管理工具,使用C/S架构,使用declarative language配置客户端。

Cfengine(http://www.cfengine.org):

  • 最先发布的开源配置工具之一,1993年发布,同样是C/S架构,通常应用于教育机构。

LCFG(http://www.lcfg.org/):

  • C/S架构的配置管理工具,使用XML定义配置。

Bcfg2

  • Python编写的C/S架构的配置管理工具,使用规格书和客户机响应配置目标主机。

本文档致力于描述使用Puppet管理你的主机、应用程序、后台程序和各种服务。

Puppet简介:

1. Puppet的用途

Puppet是开源的基于Ruby的系统配置管理工具,依赖于C/S的部署架构。主要开发者是Luke Kanies,遵循GPLv2版权协议。从1997年开始Kanies参与UNIX的系统管理工作,Puppet的开发源于这些经验。因为对已有的配置工具不甚满意,从2001年到2005年间,Kanies开始在Reductive实验室从事工具的开发。很快,Reductive实验室发布了他们的旗舰产品——Puppet。

2. Pupput的特性

许多系统配置管理工具工作的方式非常类似,如cfengine。是什么让Puppet与众不同?

Puppet的语法允许你创建一个单独脚本,用来在你所有的目标主机上建立一个用户。所有的目标主机会依次使用适用于本地系统的语法解释和执行这个模块。举例:如果这个配置是在Red Hat服务器上执行,建立用户使用useradd命令;如果这个配置是在FreeBSD主机上执行,使用的是adduser命令。

Puppet另一个卓越的地方是它的灵活性。源于开源软件的天性,你可以自由的获得Puppet的源码,如果你遇到问题并且有能力的话,你可以修改或者加强Puppet的代码去适用于你的环境。另外,社区开发者和捐献者还在不断增强Puppet的功能。一个大的开发者和用户社区也致力于提供Puppet的文档和技术支持。

Puppet也是易于扩展的。定制软件包的支持功能和特殊的系统环境配置能够快速简单的添加进Puppet的安装程序中。

3. Puppet的工作模式

Puppet是一个C/S架构的配置管理工具,在中央服务器上安装puppet-server软件包(被称作Puppet master)。在需要管理的目标主机上安装puppet客户端软件(被称作Puppet Client)。当客户端连接上Puppet master后,定义在Puppet master上的配置文件会被编译,然后在客户端上运行。每个客户端默认每半个小时和服务器进行一次通信,确认配置信息的更新情况。如果有新的配置信息或者配置信息已经改变,配置将会被重新编译并发布到各客户端执行。也可以在服务器上主动触发一个配置信息的更新,强制各客户端进行配置。如果客户端的配置信息被改变了,它可以从服务器获得原始配置进行校正。

4. Puppet的未来

最后,Puppet是一个年轻的工具,仍然处于开发和发展中。Puppet社区快速壮大,并且许多新的想法不断融入,促使开发、更新和模块每天都在呈现。

安装配置:

1. PuppetRedHat/CentOS系统上安装

Puppet是基于Ruby写成的,所以安装前要准备好Ruby环境。在中心的Server上安装puppet-server包,并运行puppetmasterd进程;在被管理机上安装puppet包,并运行puppetd进程。另外,在每台主机上配置好自己的hostname,之后每台机器要以hostname区分。

1). 安装ruby环境:

yum install ruby ruby-rdoc

2). 安装puppet

Server端安装:

rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm

yum install puppet-server

chkconfig –level 2345 puppetmaster on

修改hosts,添加下面行:

Vi /etc/hosts

172.16.228.30   puppet.sina.com.cn puppet

172.16.228.29   web1.sina.com.cn web1

客户端安装:

rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm

yum install puppet

chkconfig –level 2345 puppet on

修改hosts,添加下面行:

Vi /etc/hosts

172.16.228.30   puppet.sina.com.cn puppet

172.16.228.29   web1.sina.com.cn web1

3). 启动puppet

Server端首次运行前,编辑/etc/puppet/manifests/site.pp文件,内容可以用最基本的:

# Create “/tmp/testfile” if it doesn’t exist.

class test_class {

file { “/tmp/testfile”:

ensure => present,

mode => 644,

owner => root,

group => root

}

}

# tell puppet on which client to run the class

node web1.sina.com.cn {

include test_class

}

启动Server端:

service puppetmaster start

启动客户端:

/etc/init.d/puppet once -v

这时客户机会去连server,但是由于连接是在ssl上的,而Server还没有sign过客户端的cert,客户机被断开。

到Server端执行:puppetca -list,会显示等待签名的客户端的主机名,执行:puppetca -sign <客户端主机名> 即可为其签名。

在Server端为web1.sian.com.cn授权:

puppetca -list

web1.sian.com.cn

puppetca -sign web1.sian.com.cn

这时再到客户机上启动puppetd,即可看到客户在正常地连接server,并且应用Server上为客户端定制的配置策略。

启动客户端:

/etc/init.d/puppet once -v

4). 测试:

也可以将日志直接打印到终端上进行测试:

Server端:puppetmasterd -d –no-daemonize -v –trace

客户端:puppetd –test –trace –debug

2. puppet配置文件

主配置文件(puppet.conf):

1). 配置文件命名空间:

main 通用配置选项

puppetd 客户端配置选项

puppetmasterd 服务端配置选项

2). main命名空间选项:

confdir 配置文件目录,默认在/etc/puppet

vardir 动态数据目录,默认在/var/lib/puppet

logdir 日志目录,默认在/var/log/log

rundir puppet PID目录,默认在/var/run/puppet

statedir state目录,默认在$vardir/state

statefile state文件,默认在$statedir/state.yaml

ssldir SSL证书目录,默认在$vardir/ssl

trace 发生错误时显示跟踪信息,默认false

filetimeout 检测配置文件状态改变的时间周期,单位秒,默认15秒

syslogfacility 指定syslog功能为user级,默认为daemon级

3). puppetmasterd命名空间选项:

user 后台进程执行的用户

group 后台进程执行的组

mainfestdir mainfests文件存储目录,默认为$confdir/mainfests

mainfest mainfest站点文件的名字,默认为site.pp

bindaddress 后台进程绑定的网卡地址接口

masterport 后台进程执行的端口,默认为8140

4). puppet命名空间选项:

server puppet puppet服务器名,默认为puppet

runinterval seconds puppet应用配置的时间间隔,默认1800秒(0.5小时)

puppetdlockfie file puppet lock文件位置,默认$statedir/puppetdlock

puppetport port 后台进程执行的端口,默认8139

文件服务配置文件(fileserver.conf):

[files]

path /var/lib/puppet/files

allow 121.14.1.*

allow 60.28.228.0/24

allow *.house.sina.com.cn

deny *.sina.com.cn

path定义文件存放路径,通过allow/deny来控制访问权限。

3. puppet命令集

1). puppet 用于执行用户所写独立的mainfests文件

# puppet -l /tmp/manifest.log manifest.pp

2). puppetd 运行在被管理主机上的客户端程序

# puppetd –server puppet.leju.com

3). puppetmasterd 运行在管理机上的服务器程序

# puppetmasterd

4). puppetca puppet认证程序

# puppetca -l

pclient.leju.com

# puppetca -s pclient.leju.com

5). puppetrun 用于连接客户端,强制运行本地配置文件

# puppetrun -p 10 –host host1 –host host2 -t remotefile -t webserver

6). filebucket 客户端用于发送文件到puppet file bucket的工具

# filebucket -b /tmp/filebucket /my/file

7). ralsh 转换配置信息到puppet配置代码

# ralsh user luke

user { ‘luke’:

home => ‘/home/luke’,

uid => ‘100′,

ensure => ‘present’,

comment => ‘Luke Kanies,,,’,

gid => ‘1000′,

shell => ‘/bin/bash’,

groups => ['sysadmin','audio','video','puppet']

}

8). puppetdoc 打印puppet参考文档

# puppetdoc -r type > /tmp/type_reference.rst

# puppetdoc –outputdir /tmp/rdoc –mode rdoc /path/to/manifests

# puppetdoc /etc/puppet/manifests/site.pp

分类: Linux配置管理 标签: ,

Nginx、php-cgi启动停止脚本

2009年12月18日 admin 2 条评论

为了方便Nginx和php-cgi的启动停止写了一个脚本,将下面脚本保存为/etc/init.d/nginxd,支持service nginxd start|stop|restart|reload|status

注意:标亮的行可能需要按你的环境修改

#!/bin/sh

# source function library
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

RETVAL=0
prog="nginx"

nginxDir=/usr/local/nginx
nginxd=$nginxDir/sbin/nginx
nginxConf=$nginxDir/conf/nginx.conf
nginxPid=$nginxDir/logs/nginx.pid

nginx_check()
{
	if [[ -e $nginxPid ]]; then
		ps aux |grep -v grep |grep -q nginx
		if (( $? == 0 )); then
			echo "$prog already running..."
			exit 1
		else
			rm -rf $nginxPid &> /dev/null
		fi
	fi
}

phpcgi_check()
{
	netstat -tunlp |grep -q php-cgi
	if (( $? == 0 )); then
		echo "php-cgi already running..."
		return 1
	fi
}

phpcgi_start()
{
	phpcgi_check
	if (( $? == 0 )); then
		echo -n $"Starting php-cgi:"
		daemon /usr/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -u nobody -g nobody -C 64 -f /usr/bin/php-cgi
		RETVAL=$?
		echo
                [ $RETVAL = 0 ] && touch /var/lock/subsys/php-cgi
                return $RETVAL
	fi
}

phpcgi_stop()
{
	echo -n $"Stopping php-cgi:"
	phpcgi_pid=`netstat -tnlp |grep php-cgi |awk '{print $7}' |awk -F'/' '{print $1}'`
        kill -9 $phpcgi_pid &>/dev/null
        RETVAL=$?
	killall -9 php-cgi &>/dev/null
	RETVAL=$RETVAL+$?
	if (( $RETVAL == 0 )); then
		echo_success
	else
		echo_failure
	fi
        echo
	[ $RETVAL = 0 ] && rm -f /var/lock/subsys/php-cgi
}

start()
{
	nginx_check
	if (( $? != 0 )); then
		true
	else
		echo -n $"Starting $prog:"
		daemon $nginxd -c $nginxConf
		RETVAL=$?
		echo
		[ $RETVAL = 0 ] && touch /var/lock/subsys/nginx
		return $RETVAL
	fi
}

stop()
{
	echo -n $"Stopping $prog:"
	killproc $nginxd
	RETVAL=$?
        echo
        [ $RETVAL = 0 ] && rm -f /var/lock/subsys/nginx $nginxPid
}

reload()
{
	echo -n $"Reloading $prog:"
	killproc $nginxd -HUP
	RETVAL=$?
        echo
}

case "$1" in
        start)
		phpcgi_start
                start
                ;;
        stop)
		phpcgi_stop
                stop
                ;;
        restart)
		phpcgi_stop
                stop
		phpcgi_start
                start
                ;;
        reload)
                reload
                ;;
        status)
                status $prog
                RETVAL=$?
                ;;
        *)
                echo $"Usage: $0 {start|stop|restart|reload|status}"
                RETVAL=1
esac
exit $RETVAL

MySQL-Nginx-Pacemaker-corosync(openais)-drbd active/passive cluster

2009年12月11日 admin 没有评论

系统:CentOS 5.4
IP分配:

HA1		eth0:192.168.0.66	eth1:192.168.10.1
HA2		eth0:192.168.0.69	eth1:192.168.10.2
VIP		192.168.0.120

DRBD(Distributed Replicated Block Device),DRBD 号称是 “网络 RAID”,开源软件,由
LINBIT 公司开发。DRBD
实际上是一种块设备的实现,主要被用于Linux平台下的高可用(HA)方案之中。他有内核模块和相关程序而组成,通过网络通信来同步镜像整个设备,有点
类似于一个网络RAID-1的功能。也就是说当你将数据写入本地的DRBD设备上的文件系统时,
数据会同时被发送到网络中的另外一台主机之上,并以完全相同的形式记录在文件系统中。本地节点与远程节点的数据可以保证实时的同步,并保证IO的一致性。
所以当本地节点的主机出现故障时,远程节点的主机上还会保留有一份完全相同的数据,可以继续使用,以达到高可用的目的。

一、安装DRBD

在HA1和HA2上安装DRBD。
wget http://oss.linbit.com/drbd/8.3/drbd-8.3.5.tar.gz

[root@HA1 ~]# tar xzvf drbd-8.3.5.tar.gz
[root@HA1 ~]# cd drbd-8.3.5
[root@HA1 drbd-8.3.5]# make clean all
[root@HA1 drbd-8.3.5]# make install
[root@HA1 drbd-8.3.5]# cd

[root@HA1 ~]# vi /etc/drbd.conf

global {
    usage-count yes;    # 是否参加使用者统计,yes为参加
}
common {
  syncer { rate 100M; }    # 设置网络同步速率,建议改为实际网络速率
}

# 一个DRBD设备(即:/dev/drbdX),叫做一个"资源"。
resource "r0" {
  protocol C;    #  数据同步协议,C表示收到远程主机的写入确认后才认为写入完成
  startup {
  }
  disk {
    on-io-error detach;
  }
  handlers {
    split-brain "/usr/lib/drbd/notify-split-brain.sh root"; # 自动修复脑裂问题
  }
  net {
    # 设置主备机之间通信使用的信息算法.
    cram-hmac-alg sha1;
    shared-secret "FooFunFactory";
    # 自动修复脑裂问题
    after-sb-0pri discard-zero-changes;
    after-sb-1pri discard-secondary;
    after-sb-2pri disconnect;
  }
  syncer {
  }
  # 每个主机的说明以"on"开头,后面是主机名
  on HA1 {
    device    /dev/drbd0;
    disk    /dev/sdb;
    # 设置DRBD的监听端口,用于与另一台主机通信
    address    192.168.0.66:7789;
    # metadata的存放位置
    # internal表示将metadata存放到drbd挂在的磁盘分区的最后的位置上
    meta-disk    internal;
  }

  on HA2 {
    device     /dev/drbd0;
    disk       /dev/sdb;
    address    192.168.0.69:7789;
    meta-disk  internal;
  }
}

DRBD将数据的各种信息块保存在一个专用的区域里,这些metadata包括了

a,DRBD设备的大小
b,产生的标识
c,活动日志
d,快速同步的位图

metadata的存储方式有内部和外部两种方式,使用哪种配置都是在资源配置中定义的

内部metadata:内部metadata存放在同一块硬盘或分区的最后的位置上

优点:metadata和数据是紧密联系在一起的,如果硬盘损坏,metadata同样就没有了,同样在恢复的时候,metadata也会一起被恢复回来
缺点:metadata和数据在同一块硬盘上,对于写操作的吞吐量会带来负面的影响,因为应用程序的写请求会触发metadata的更新,这样写操作就会造成两次额外的磁头读写移动。

外部metadata:外部的metadata存放在和数据磁盘分开的独立的块设备上

优点:对于一些写操作可以对一些潜在的行为提供一些改进
缺点:metadata和数据不是联系在一起的,所以如果数据盘出现故障,在更换新盘的时候就需要认为的干预操作来进行现有node对心硬盘的同步了

[root@HA1 ~]# scp /etc/drbd.conf HA2:/etc/

初始化并启动两个系统上的 DRBD 服务:
[root@HA1 ~]# drbdadm create-md r0
[root@HA1 ~]# service drbd start
Starting DRBD resources: [ d(r0) s(r0) n(r0) ].

将 HA1 配置为主节点:
[root@HA1 ~]# drbdadm –overwrite-data-of-peer primary r0

两个设备开始同步数据:
[root@HA2 ~]# service drbd status
drbd driver loaded OK; device status:
version: 8.3.5 (api:88/proto:86-91)
GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA2, 2009-11-13 01:58:29
m:res  cs          ro                 ds                     p  mounted  fstype
…    sync’ed:    0.6%               (6108/6140)M
0:r0   SyncTarget  Secondary/Primary  Inconsistent/UpToDate  C

………

[root@HA2 ~]# service drbd status
drbd driver loaded OK; device status:
version: 8.3.5 (api:88/proto:86-91)
GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA2, 2009-11-13 01:58:29
m:res  cs          ro                 ds                     p  mounted  fstype
…    sync’ed:    45.6%              (3344/6140)M
0:r0   SyncTarget  Secondary/Primary  Inconsistent/UpToDate  C

………

同步数据完成:
[root@HA2 ~]# service drbd status
drbd driver loaded OK; device status:
version: 8.3.5 (api:88/proto:86-91)
GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA2, 2009-11-13 01:58:29
m:res  cs              ro                 ds                     p  mounted  fstype
…    sync’ed:100.0%  (4/6140)M
0:r0   SyncTarget      Secondary/Primary  Inconsistent/UpToDate  C
[root@HA2 ~]# service drbd status
drbd driver loaded OK; device status:
version: 8.3.5 (api:88/proto:86-91)
GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA2, 2009-11-13 01:58:29
m:res  cs         ro                 ds                 p  mounted  fstype
0:r0   Connected  Secondary/Primary  UpToDate/UpToDate  C

[root@HA1 ~]# cat /proc/drbd
version: 8.3.5 (api:88/proto:86-91)
GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA1, 2009-11-13 01:53:51
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r—-
ns:6291228 nr:0 dw:0 dr:6291228 al:0 bm:384 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0

两个节点上的块设备都完全同步之后,使用诸如ext3的文件系统格式化主节点上的 DRBD 设备。
[root@HA1 ~]# mkfs.ext3 /dev/drbd0

测试DRBD服务:
手动挂载DRBD设备,并测试写入文件。
[root@HA1 ~]# mount -o rw /dev/drbd0 /data/
[root@HA1 ~]# echo “This is a test line.” > /data/test.txt
卸载DRBD设备并将HA1设置为从设备。
[root@HA1 ~]# umount /data/
[root@HA1 ~]# drbdadm secondary r0
将HA2设置为主设备。
[root@HA2 ~]# drbdadm primary r0
[root@HA2 ~]# service drbd status
drbd driver loaded OK; device status:
version: 8.3.5 (api:88/proto:86-91)
GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA2, 2009-11-13 01:58:29
m:res  cs         ro                 ds                 p  mounted  fstype
0:r0   Connected  Primary/Secondary  UpToDate/UpToDate  C
挂载DRBD设备并验证能够读出在HA1上写入的文件。
[root@HA2 ~]# mount -o rw /dev/drbd0 /data/
[root@HA2 ~]# cat /data/test.txt
This is a test line.
卸载DRBD设备并将HA2设置为从设备。
[root@HA2 ~]# umount /data/
[root@HA2 ~]# drbdadm secondary r0

将HA1设置为主设备。
[root@HA1 ~]# drbdadm primary r0

查看HA2的DRDB状态:
[root@HA2 ~]# service drbd status
drbd driver loaded OK; device status:
version: 8.3.5 (api:88/proto:86-91)
GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA2, 2009-11-13 01:58:29
m:res  cs         ro                 ds                 p  mounted  fstype
0:r0   Connected  Secondary/Primary  UpToDate/UpToDate  C

在HA1和HA2上配置hosts
[root@HA1 ~]# cat /etc/hosts

# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1 vpc localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
192.168.10.1 HA1
192.168.10.2 HA2

在HA1和HA2上配置时间同步:
[root@HA1 ~]# crontab -e

*/5     *       *       *       *       /usr/sbin/ntpdate ntp.api.bz


二、在HA1和HA2安装MySQL和Nginx并将数据迁移到/data目录
[root@HA1 ~]# yum install -y mysql-server
[root@HA1 ~]# cat /etc/my.cnf

[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
user=mysql
bind-address=192.168.0.120

[root@HA1 ~]# cp -r /var/lib/mysql/ /data/
[root@HA1 ~]# cd /data/
[root@HA1 data]# chown -R mysql.mysql mysql/
[root@HA1 data]# service mysqld start
Starting MySQL:                                            [  OK  ]
[root@HA1 data]# service mysqld stop
Stopping MySQL:                                            [  OK  ]

注意:数据迁移只需在HA1上做。

安装Nginx略,具体见Nginx 0.7.x + PHP 5.2.8(FastCGI)搭建胜过Apache十倍的Web服务器(http://blog.s135.com/post/366/)

[root@HA1 ~]# chkconfig –level 2345 mysqld off
[root@HA2 ~]# chkconfig –level 2345 mysqld off
注意:不要在外部启动HA使用的资源,一切让HA去控制。

编写nginx lsb资源代理脚本(注意nginx安装路径):
[root@HA1 ~]# cat /etc/init.d/nginxd

#!/bin/sh

# source function library
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

RETVAL=0
prog="nginx"

nginxDir=/usr/local/nginx
nginxd=$nginxDir/sbin/nginx
nginxConf=$nginxDir/conf/nginx.conf
nginxPid=$nginxDir/nginx.pid

nginx_check()
{
    if [[ -e $nginxPid ]]; then
        ps aux |grep -v grep |grep -q nginx
        if (( $? == 0 )); then
            echo "$prog already running..."
            exit 1
        else
            rm -rf $nginxPid &> /dev/null
        fi
    fi
}

start()
{
    nginx_check
    if (( $? != 0 )); then
        true
    else
        echo -n $"Starting $prog:"
        daemon $nginxd -c $nginxConf
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch /var/lock/subsys/nginx
        return $RETVAL
    fi
}

stop()
{
    echo -n $"Stopping $prog:"
    killproc $nginxd
    RETVAL=$?
    echo
    [ $RETVAL = 0 ] && rm -f /var/lock/subsys/nginx $nginxPid
}

reload()
{
    echo -n $"Reloading $prog:"
    killproc $nginxd -HUP
    RETVAL=$?
    echo
}

case "$1" in
        start)
                start
                ;;
        stop)
                stop
                ;;
        restart)
                stop
                start
                ;;
        reload)
                reload
                ;;
        status)
                status $prog
                RETVAL=$?
                ;;
        *)
                echo $"Usage: $0 {start|stop|restart|reload|status}"
                RETVAL=1
esac
exit $RETVAL

[root@HA1 ~]# chmod +x  /etc/init.d/nginxd
[root@HA1 ~]# scp  /etc/init.d/nginxd HA2: /etc/init.d/nginxd

三、安装配置corosync和pacemaker

corosync是基于OpenAIS构建的集群引擎,可替代heartbeat进行心跳检测。
The Corosync Cluster Engine is an open source project Licensed under the BSD License derived from the OpenAIS project. OpenAIS uses a UDP multicast based communication protocol to periodically check for node availability.

[root@HA1 ~]# wget -O /etc/yum.repos.d/pacemaker.repo http://clusterlabs.org/rpm/epel-5/clusterlabs.repo
[root@HA1 ~]# wget ftp://ftp.pbone.net/mirror/centos.karan.org/el5/extras/testing/i386/RPMS/libesmtp-1.0.4-6.el5.kb.i386.rpm
[root@HA1 ~]# rpm -ivh libesmtp-1.0.4-6.el5.kb.i386.rpm
[root@HA1 ~]# yum install -y pacemaker corosync

[root@HA1 ~]# corosync-keygen
Corosync Cluster Engine Authentication key generator.
Gathering 1024 bits for key from /dev/random.
Press keys on your keyboard to generate entropy.
Writing corosync key to /etc/corosync/authkey.

[root@HA1 ~]# scp /etc/corosync/authkey HA2:/etc/corosync/
[root@HA1 ~]# cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf
[root@HA1 ~]# vi !$

# Please read the corosync.conf.5 manual page
compatibility: whitetank

totem {
version: 2
secauth: off
threads: 0
interface {
ringnumber: 0
bindnetaddr: 192.168.10.0
mcastaddr: 226.94.1.1
mcastport: 5405
}
}

logging {
fileline: off
to_stderr: yes
to_logfile: yes
to_syslog: yes
logfile: /var/log/corosync.log
debug: off
timestamp: on
logger_subsys {
subsys: AMF
debug: off
}
}

amf {
mode: disabled
}

service {
        # Load the Pacemaker Cluster Resource Manager
        ver:       0
        name:      pacemaker
        use_mgmtd: yes
}

[root@HA1 ~]# scp /etc/corosync/corosync.conf HA2:/etc/corosync/corosync.conf
[root@HA1 ~]# service corosync start
Starting Corosync Cluster Engine (corosync):               [  OK  ]
[root@HA1 ~]# chkconfig –level 2345 corosync on

在HA2上执行:
[root@HA2 ~]# chown root:root /etc/corosync/authkey
[root@HA2 ~]# chmod 400 /etc/corosync/authkey
[root@HA2 ~]# service corosync start
Starting Corosync Cluster Engine (corosync):               [  OK  ]
[root@HA2 ~]# chkconfig –level 2345 corosync on

四、配置CRM资源

[root@HA1 ~]# crm
crm(live)# configure
crm(live)configure# node HA1
crm(live)configure# node HA2
# 配置drbd原始资源
crm(live)configure# primitive drbd ocf:linbit:drbd \
 params drbd_resource="r0" \
 meta migration-threshold="10"
# 配置drbd资源监控
crm(live)configure# monitor drbd 30s:20s
# 配置文件系统原始资源
crm(live)configure# primitive fs ocf:heartbeat:Filesystem \
 params device="/dev/drbd0" directory="/data" fstype="ext3"
# 配置mysql原始资源,使用lsb代理
crm(live)configure# primitive mysqld lsb:mysqld
# 配置nginx原始资源,使用lsb代理
crm(live)configure# primitive nginxd lsb:nginxd
# 配置共享IP原始资源
crm(live)configure# primitive vip ocf:heartbeat:IPaddr2 \
 params ip="192.168.0.120" nic="eth0:0"
# 创建资源组保障资源在某一节点上按顺序启动和停止
crm(live)configure# group mysql-group fs vip mysqld nginxd
# 配置drbd主资源约束
crm(live)configure# ms ms-drbd-mysql drbd \
 meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"
# 配置资源位置约束,保证mysql-group资源组启动在drbd主资源上
crm(live)configure# colocation mysql-on-drbd inf: mysql-group ms-drbd-mysql:Master
# 配置资源启动顺序约束,保证drbd启动后启动mysql-group资源组
crm(live)configure# order mysql-after-drbd inf: ms-drbd-mysql:promote mysql-group:start
crm(live)configure# property $id="cib-bootstrap-options" \
 expected-quorum-votes="2" \
 stonith-enabled="false" \
 no-quorum-policy="ignore" \
 start-failure-is-fatal="false"
crm(live)configure# commit
crm(live)configure# end
crm(live)#

五、测试

[root@HA1 ~]# crm status

============
Last updated: Fri Nov 20 22:47:51 2009
Stack: openais
Current DC: HA2 – partition with quorum
Version: 1.0.6-f709c638237cdff7556cb6ab615f32826c0f8c06
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ HA1 HA2 ]

Master/Slave Set: ms-drbd-mysql
Masters: [ HA1 ]
Slaves: [ HA2 ]
Resource Group: mysql-group
fs    (ocf::heartbeat:Filesystem):    Started HA1
vip    (ocf::heartbeat:IPaddr2):    Started HA1
mysqld    (lsb:mysqld):    Started HA1
nginxd    (lsb:nginxd):    Started HA1

关闭HA1,在HA2上查看HA状态:
[root@HA2 ~]# crm_mon -i1

============
Last updated: Sat Nov 21 01:31:13 2009
Stack: openais
Current DC: HA2    - partition WITHOUT quorum
Version: 1.0.6-f709c638237cdff7556cb6ab615f32826c0f8c06
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ HA2 ]
OFFLINE: [ HA1 ]

Master/Slave Set: ms-drbd-mysql
Masters: [ HA2 ]
Stopped: [ drbd:1 ]
Resource Group: mysql-group
fs (ocf::heartbeat:Filesystem):    Started HA2
vip        (ocf::heartbeat:IPaddr2):    Started HA2
mysqld     (lsb:mysqld):   Started HA2
nginxd     (lsb:nginxd):   Started HA2

启动HA1,资源自动迁移到HA1:
[root@HA1 ~]# crm_mon -i1

============
Last updated: Mon Nov 23 15:42:52 2009
Stack: openais
Current DC: HA2    - partition with quorum
Version: 1.0.6-f709c638237cdff7556cb6ab615f32826c0f8c06
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ HA1 HA2 ]

Master/Slave Set: ms-drbd-mysql
Masters: [ HA1 ]
Slaves: [ HA2 ]
Resource Group: mysql-group
fs (ocf::heartbeat:Filesystem):    Started HA1
vip        (ocf::heartbeat:IPaddr2):    Started HA1
mysqld     (lsb:mysqld):   Started HA1
nginxd     (lsb:nginxd):   Started HA1

手动迁移资源到HA2
[root@HA1 ~]# crm resource migrate mysql-group HA2

[root@HA2 ~]# crm_mon -i1

============
Last updated: Mon Nov 23 15:43:42 2009
Stack: openais
Current DC: HA2    - partition with quorum
Version: 1.0.6-f709c638237cdff7556cb6ab615f32826c0f8c06
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ HA1 HA2 ]

Master/Slave Set: ms-drbd-mysql
Masters: [ HA2 ]
Slaves: [ HA1 ]
Resource Group: mysql-group
fs (ocf::heartbeat:Filesystem):    Started HA2
vip        (ocf::heartbeat:IPaddr2):    Started HA2
mysqld     (lsb:mysqld):   Started HA2
nginxd     (lsb:nginxd):   Started HA2


六、解决脑裂(split brain
)问题:

在“双机热备”高可用(HA)系统中,当联系2个节点的“心跳线”断开时,本来为一整体、动作
协调的HA系统,就分裂成为2个独立的个体。由于相互失去了联系,都以为是对方出了故障,2个节点上的HA软件像“裂脑人”一样,“本能”地争抢“共享资
源”、争起“应用服务”,就会发生严重后果:或者共享资源被瓜分、2边“服务”都起不来了;或者2边“服务”都起来了,但同时读写“共享存储”,导致数据
损坏(常见如数据库轮询着的联机日志出错)。

对付HA系统“裂脑”的对策大概有以下几条:

1)添加冗余的心跳线,例如双线条线。尽量减少“裂脑”发生机会。

2)启用磁盘锁。正在服务一方锁住共享磁盘,“裂脑”发生时,让对方完全“抢不走”共享磁盘资源。但使用锁磁盘也会有一个不小的问题,如果占用共
享盘的一方不主动“解锁”,另一方就永远得不到共享磁盘。现实中假如服务节点突然死机或崩溃,就不可能执行解锁命令。后备节点也就接管不了共享资源和应用
服务。于是有人在HA中设计了“智能”锁。即,正在服务的一方只在发现心跳线全部断开(察觉不到对端)时才启用磁盘锁。平时就不上锁了。

3)设置仲裁机制。例如设置参考IP(如网关IP),当心跳线完全断开时,2个节点都各自ping一下 参考IP,不通则表明断点就出在本端,
不仅“心跳”、还兼对外“服务”的本端网络链路断了,即使启动(或继续)应用服务也没有用了,那就主动放弃竞争,让能够ping通参考IP的一端去起服
务。更保险一些,ping不通参考IP的一方干脆就自我重启,以彻底释放有可能还占用着的那些共享资源。

手动解决DRBD脑裂问题:
[root@HA2 ~]# drbdadm down all
[root@HA2 ~]# drbdadm create-md all

六、参考

Integrating DRBD with Pacemaker clusters
DRBD MySQL HowTo
Split brain notification and automatic recovery
Manual split brain recovery


Heartbeat/corosync+pacemaker+ldirectord 实现Nginx负载均衡

2009年12月10日 admin 没有评论

系统:CentOS 5.4
IP分配:

HA1		eth0:192.168.0.66	eth1:192.168.10.1
HA2		eth0:192.168.0.69	eth1:192.168.10.2
VIP		192.168.0.120

1. 安装pacemaker和heartbeat
[root@HA1 ~]# wget -O /etc/yum.repos.d/pacemaker.repo http://clusterlabs.org/rpm/epel-5/clusterlabs.repo
[root@HA1 ~]# wget ftp://ftp.pbone.net/mirror/centos.karan.org/el5/extras/testing/i386/RPMS/libesmtp-1.0.4-6.el5.kb.i386.rpm
[root@HA1 ~]# rpm -ivh libesmtp-1.0.4-6.el5.kb.i386.rpm
[root@HA1 ~]# yum install -y pacemaker heartbeat

2. 安装ldirectord
[root@HA1 ~]# yum install -y ldirectord

3. 配置
3.1 配置Heartbeat
[root@HA1 ~]# cp /usr/share/doc/heartbeat-3.0.1/{ha.cf,authkeys} /etc/ha.d/

[root@HA1 ~]# cat /etc/ha.d/authkeys

auth 1
1 crc

[root@HA1 ~]# cat /etc/ha.d/ha.cf |grep -v “#”

logfile	/var/log/ha-log
logfacility	local0
keepalive 2
deadtime 30
warntime 10
initdead 120
udpport	695
ucast eth1 192.168.10.2     # 注意此处HA2改为:ucast eth1 192.168.10.1
auto_failback on
watchdog /dev/watchdog
node	HA1
node	HA2
ping 192.168.0.1
respawn hacluster /usr/lib/heartbeat/ipfail
apiauth ipfail gid=haclient uid=hacluster
crm	on

3.2 用corosync替换heartbeat(可选)
corosync是基于OpenAIS构建的集群引擎,可替代heartbeat进行心跳检测。
The Corosync Cluster Engine is an open source project Licensed under the BSD License derived from the OpenAIS project. OpenAIS uses a UDP multicast based communication protocol to periodically check for node availability.

[root@HA1 ~]# yum install -y corosync
[root@HA1 ~]# corosync-keygen
Corosync Cluster Engine Authentication key generator.
Gathering 1024 bits for key from /dev/random.
Press keys on your keyboard to generate entropy.
Writing corosync key to /etc/corosync/authkey.

[root@HA1 ~]# scp /etc/corosync/authkey HA2:/etc/corosync/
[root@HA1 ~]# cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf
[root@HA1 ~]# vi !$

# Please read the corosync.conf.5 manual page
compatibility: whitetank

totem {
version: 2
secauth: off
threads: 0
interface {
ringnumber: 0
bindnetaddr: 192.168.10.0
mcastaddr: 226.94.1.1
mcastport: 5405
}
}

logging {
fileline: off
to_stderr: yes
to_logfile: yes
to_syslog: yes
logfile: /var/log/corosync.log
debug: off
timestamp: on
logger_subsys {
subsys: AMF
debug: off
}
}

amf {
mode: disabled
}

service {
        # Load the Pacemaker Cluster Resource Manager
        ver:       0
        name:      pacemaker
        use_mgmtd: yes
}

[root@HA1 ~]# scp /etc/corosync/corosync.conf HA2:/etc/corosync/corosync.conf
[root@HA1 ~]# service corosync start
Starting Corosync Cluster Engine (corosync):               [  OK  ]
[root@HA1 ~]# chkconfig –level 2345 corosync on
[root@HA1 ~]# chkconfig –level 2345 heartbeat off

在HA2上执行:
[root@HA2 ~]# chown root:root /etc/corosync/authkey
[root@HA2 ~]# chmod 400 /etc/corosync/authkey
[root@HA2 ~]# service corosync start
Starting Corosync Cluster Engine (corosync):               [  OK  ]
[root@HA2 ~]# chkconfig –level 2345 corosync on
[root@HA2 ~]# chkconfig –level 2345 heartbeat off

3.3 安装配置ldirectord
[root@HA1 ~]# cat /etc/ha.d/ldirectord.cf

checktimeout=5
checkinterval=7
autoreload=yes
logfile="/var/log/ldirectord.log"
quiescent=yes
emailalert=shidl@baihe.com
# A server with a page at the main root of the site that displays "Nginx"
virtual=192.168.0.120:80
real=192.168.0.66:80 gate
real=192.168.0.69:80 gate
service=http
request="/lb.html"    # 在根目录下编写lb.html,内容为live
receive="live"
scheduler=wlc
protocol=tcp
checktype=negotiate

3.4 配置hosts
[root@HA1 ~]# cat /etc/hosts

# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1		vpc localhost.localdomain localhost
::1		localhost6.localdomain6 localhost6
192.168.10.1	HA1
192.168.10.2	HA2

3.5 配置lo:0设备

[root@HA1 ~]# cat >>/etc/sysconfig/network-scripts/ifcfg-lo:0<<EOF
<pre>DEVICE=lo:0
IPADDR=192.168.0.120
NETMASK="255.255.255.255"
ONBOOT=yes
NAME=loopback

EOF

3.6 启用转发,禁用arp
[root@HA1 ~]# vi /etc/sysctl.conf
修改net.ipv4.ip_forward = 0为net.ipv4.ip_forward = 1
添加下面行:

net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.eth0.arp_announce = 2

[root@HA1 ~]# sysctl -p

# 将配置拷贝到HA2
[root@HA1 ~]# scp /etc/ha.d/{ha.cf,authkeys,ldirectord.cf} HA2:/etc/ha.d/
[root@HA1 ~]# scp /etc/{hosts,sysctl.conf} HA2:/etc/
[root@HA1 ~]# scp /etc/sysconfig/network-scripts/ifcfg-lo:0 HA2:/etc/sysconfig/network-scripts/

在HA2上修改/etc/ha.d/ha.cf
将ucast eth1 192.168.10.2 改为:ucast eth1 192.168.10.1
并使sysctl.conf配置生效:
[root@HA2~]# sysctl -p

3.7 在HA1和HA2上配置并安装好nginx
编写nginx lsb资源代理脚本(注意nginx安装路径):
[root@HA1 ~]# cat /etc/init.d/nginxd

#!/bin/sh

# source function library
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

RETVAL=0
prog="nginx"

nginxDir=/usr/local/nginx
nginxd=$nginxDir/sbin/nginx
nginxConf=$nginxDir/conf/nginx.conf
nginxPid=$nginxDir/nginx.pid

nginx_check()
{
    if [[ -e $nginxPid ]]; then
        ps aux |grep -v grep |grep -q nginx
        if (( $? == 0 )); then
            echo "$prog already running..."
            exit 1
        else
            rm -rf $nginxPid &> /dev/null
        fi
    fi
}

start()
{
    nginx_check
    if (( $? != 0 )); then
        true
    else
        echo -n $"Starting $prog:"
        daemon $nginxd -c $nginxConf
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch /var/lock/subsys/nginx
        return $RETVAL
    fi
}

stop()
{
    echo -n $"Stopping $prog:"
    killproc $nginxd
    RETVAL=$?
    echo
    [ $RETVAL = 0 ] && rm -f /var/lock/subsys/nginx $nginxPid
}

reload()
{
    echo -n $"Reloading $prog:"
    killproc $nginxd -HUP
    RETVAL=$?
    echo
}

case "$1" in
        start)
                start
                ;;
        stop)
                stop
                ;;
        restart)
                stop
                start
                ;;
        reload)
                reload
                ;;
        status)
                status $prog
                RETVAL=$?
                ;;
        *)
                echo $"Usage: $0 {start|stop|restart|reload|status}"
                RETVAL=1
esac
exit $RETVAL

[root@HA1 ~]# chmod +x  /etc/init.d/nginxd
[root@HA1 ~]# scp  /etc/init.d/nginxd HA2: /etc/init.d/nginxd

[root@HA1 ~]# service network restart
[root@HA1 ~]# service heartbeat start

[root@HA2 ~]# service network restart
[root@HA2 ~]# service heartbeat start

4. 配置集群资源:

Heartbeat和其他应用提供的ocf代理脚本或许会有错误,我们可以用下面方法排错:
要检查 OCF 脚本,请首先设置所需的环境变量。例如,当测试IPaddr OCF 脚本时,您必须通过设置一个变量名称前缀为 OCF_RESKEY_的环境变量来设置变量 ip 的值。对于此示例,可运行以下命令:

export OCF_RESKEY_ip=
/usr/lib/ocf/resource.d/heartbeat/IPaddr validate-all
/usr/lib/ocf/resource.d/heartbeat/IPaddr start
/usr/lib/ocf/resource.d/heartbeat/IPaddr stop

如果此操作不成功,很可能是您缺少某个必需变量或者只是输错了参数。

排错ldirectord ocf代理脚本:
export OCF_ROOT=/usr/lib/ocf
根据自己的环境设置修改下面两行:
[root@HA1 ~]# vi /usr/lib/ocf/resource.d/heartbeat/ldirectord

LDIRCONF=${OCF_RESKEY_configfile:-/etc/ha.d/ldirectord.cf}
LDIRECTORD=${OCF_RESKEY_ldirectord:-/usr/sbin/ldirectord}

[root@HA1 ~]# /usr/lib/ocf/resource.d/heartbeat/ldirectord monitor
[root@HA1 ~]# echo $?
7     # ldirectord未运行返回7,运行正常返回0

[root@HA1 ~]# crm
crm(live)# configure
crm(live)configure# node HA1
crm(live)configure# node HA2
crm(live)configure# primitive ldirectord ocf:heartbeat:ldirectord \
> params configfile=”/etc/ha.d/ldirectord.cf” \
> op monitor interval=”30s” timeout=”20s” \
> meta migration-threshold=”10″ target-role=”Started”
crm(live)configure# primitive vip ocf:heartbeat:IPaddr2 \
> params lvs_support=”true” ip=”192.168.0.120″ cidr_netmask=”24″ broadcast=”192.168.0.255″ \
> op monitor interval=”1m” timeout=”20s” \
> meta migration-threshold=”10″
crm(live)configure# primitive nginxd lsb:nginxd \
> op monitor interval=”30s” timeout=”20s” \
> meta migration-threshold=”10″ target-role=”Started”
crm(live)configure# group load-balancing vip ldirectord
crm(live)configure# clone cl-nginxd nginxd
crm(live)configure# location perfer-ha1 load-balancing \
> rule $id=”prefer-ha1-rule” 100: #uname eq HA1
crm(live)configure# property stonith-enabled=”false” \
> no-quorum-policy=”ignore” \
> start-failure-is-fatal=”false” \
> expected-quorum-votes=”2″
crm(live)configure# verify
crm(live)configure# commit
crm(live)configure# end
crm(live)# status

============
Last updated: Thu Nov 12 01:00:13 2009
Stack: Heartbeat
Current DC: HA2 – partition with quorum
Version: 1.0.6-f709c638237cdff7556cb6ab615f32826c0f8c06
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ HA2 HA1 ]

Clone Set: cl-nginxd
Started: [ HA2 HA1 ]
Resource Group: load-balancing
vip    (ocf::heartbeat:IPaddr2):    Started HA1
ldirectord    (ocf::heartbeat:ldirectord):    Started HA1

crm(live)# quit
bye

5. 验证
[root@HA1 ~]# ipvsadm -l
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.120:http wlc
-> 192.168.0.69:http            Route   1      0          0
-> 192.168.0.66:http            Local   1      0          0

用浏览器访问网站看是否正常。

禁用HA1的eth1网卡,在HA2上看故障转移情况。
[root@HA2 ~]# crm
crm(live)# status

============
Last updated: Thu Nov 12 18:40:54 2009
Stack: Heartbeat
Current DC: HA2 – partition WITHOUT quorum
Version: 1.0.6-f709c638237cdff7556cb6ab615f32826c0f8c06
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ HA2 ]
OFFLINE: [ HA1 ]

Clone Set: cl-nginxd
Started: [ HA2 ]
Stopped: [ nginxd:0 ]
Resource Group: load-balancing
vip    (ocf::heartbeat:IPaddr2):    Started HA2
ldirectord    (ocf::heartbeat:ldirectord):    Started HA2

启用HA1的eth1网卡,在HA1上看故障转移情况。

[root@HA1 ~]# crm status

============
Last updated: Thu Nov 12 18:42:55 2009
Stack: Heartbeat
Current DC: HA1 – partition with quorum
Version: 1.0.6-f709c638237cdff7556cb6ab615f32826c0f8c06
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ HA2 HA1 ]

Clone Set: cl-nginxd
Started: [ HA1 HA2 ]
Resource Group: load-balancing
vip    (ocf::heartbeat:IPaddr2):    Started HA1
ldirectord    (ocf::heartbeat:ldirectord):    Started HA1

6. 参考:

Load Balanced MySQL Replicated Cluster
Debian Lenny HowTo

用CRM命令行工具配置集群资源

2009年12月10日 admin 没有评论

1. 创建群集资源

可以创建以下类型的资源:
原始资源:原始资源是最基本的资源类型。
资源组:资源组包含一系列需要放置在一起、按顺序启动和以反序停止的资源。
克隆资源:克隆资源是可以在多个主机上处于活动状态的资源。如果各个资源代理支持,则任何资源均可克隆。
主资源:主资源是一种特殊的克隆资源,主资源可以具有多种模式。主资源必须只能包含一个组或一个常规资源。

资源选项:
您可以为添加的每个资源定义选项。群集使用这些选项来决定资源的行为方式,它们会告知 CRM 如何对待特定的资源。可使用 crm_resource –meta 命令或 GUI 来设置资源选项。

原始资源选项:
priority 如果不允许所有的资源都处于活动状态,群集会停止优先级较低的资源以便保持较高优先级资源处于活动状态。
target-role 群集应试图将此资源保持在何种状态,允许的值:Stopped 和 Started。
is-managed 是否允许群集启动和停止资源,允许的值:true和 false。
resource-stickiness 资源留在所处位置的自愿程度如何,默认为default- resource-stickiness 的值。
migration-threshold 节点上的此资源应发生多少故障后才能确定该节点没有资格主管此资源,默认值:none。
multiple-active 如果发现资源在多个节点上活动,群集该如何操作,允许的值:block(将资源标记为未受管)、stop_only 和 stop_start。
failure-timeout 在恢复为如同未发生故障一样正常工作(并允许资源返回它发生故障的节点)之前,需要等待几秒钟,默认值:never。

资源操作:
默认情况下,群集将不会确保您的资源一直正常。要指示群集如此操作,需要向资源的定义中添加一个监视操作。可为所有类或资源代理添加监视操作。
ID :您的操作名称。必须是唯一的。
name :要执行的操作。常见值:monitor、start 和 stop。
interval :执行操作的频率。单位:秒。
timeout : 需要等待多久才能声明操作失败。
requires :需要满足什么条件才能发生此操作。允许的值:nothing、quorum 和 fencing。默认值取决于是否启用屏障和资源的类是否为 stonith。对于 STONITH 资源,默认值为 nothing。
on-fail :此操作失败时执行的操作。允许的值:
ignore:假装资源没有失败。
block:不对资源执行任何进一步操作。
stop:停止资源并且不在其他位置启动该资源。
restart:停止资源并(可能在不同的节点上)重启动。
fence:关闭资源失败的节点 (STONITH)。
standby:将所有资源从资源失败的节点上移走。
enabled 如果值为 false,将操作视为不存在。允许的值:true、false。

原始资源包含的参数:
元属性:元属性是可以为资源添加的选项。它们告诉 CRM 如何处理特定资源。
实例属性:实例属性是特定资源类的参数,用于确定资源类的行为方式及其控制的服务实例。
操作:可以为资源添加监视操作。监视操作指示群集确保资源状况依然正常。所有资源代理类都可以添加监视操作。您还可以设置特定参数,如为 start 或stop 操作设置 timeout值。

定义原始资源:primitive   唯一ID   资源代理类型:资源代理的提供程序:资源代理名称  实例属性   操作  元属性
例如:

primitive Virtual-IP-Tomcat ocf:heartbeat:IPaddr2
params lvs_support="true" ip="192.168.1.100" cidr_netmask="24" broadcast="192.168.1.255" \
        op monitor interval="1m" timeout="10s" \
        meta migration-threshold="10"
primitive ldirectord ocf:heartbeat:ldirectord \
        params configfile="/etc/ha.d/ldirectord.cf" \
        op monitor interval="2m" timeout="20s" \
        meta migration-threshold="10" target-role="Started"
primitive tomcat lsb:tomcat \
        op monitor interval="30s" timeout="10s" \
        meta migration-threshold="10" target-role="Started"
primitive mysql ocf:heartbeat:mysql \
        params binary="/usr/bin/mysqld_safe" config="/etc/my.cnf" datadir="/var/lib/mysql" user="mysql" pid="/var/lib/mysql/mysql.pid" socket="/var/lib/mysql/mysql.sock" test_passwd="password" test_table="ldirectord.connectioncheck" test_user="slave_user" \
        op monitor interval="20s" timeout="10s" \
        meta migration-threshold="10" target-role="Started"

migration-threshold用来定义资源的故障次数,假设已经为资源配制了一个首选在节点上运行的位置约束。如果那里失败了,系统会检查 migration-threshold 并与故障计数进行比较。如果故障计数 >= migration-threshold,会将资源迁移到下一个自选节点。
默认情况下,一旦达到阈值,就只有在管理员手动重置资源的故障计数后(在修复故障原因后),才允许在该节点上运行有故障的资源。
但是,可以通过设置资源的 failure-timeout 选项使故障计数失效。如果设置migration-threshold=2 和 failure-timeout=60s ,将会导致资源在两次故障后迁移到新的节点,并且可能允许在一分钟后移回(取决于黏性和约束分数)。
迁移阈值概念有两个例外,在资源启动失败或停止失败时出现:启动故障会使故障计数设置为 INFINITY,因此总是导致立即迁移。停止故障会导致屏障(stonith-enabled 设置为 true 时,这是默认设置)。如果不定义 STONITH资源(或 stonith-enabled 设置为 false),则该资源根本不会迁移。

重置资源的故障计数:对指定节点上的指定资源执行 crm_resource -C 和 crm_failcount -D 命令。

如果在创建时将资源的初始状态设置为 stopped(target-role 元属性的值为 stopped),则资源在创建后不会自动启动。要想启动资源使用命令:crm resource start 资源ID

配置资源监视(可以在定义资源时用op monitor命令定义)

虽然 High Availability Extension 可以检测节点故障,但也能够检测节点上的各个资源何时发生故障。如果希望确保资源运行,则必须为该资源配置资源监视。资源监视包括指定超时和/或启动延迟值以及间隔。间隔告诉 CRM 检查资源状态的频率。

[root@HA1 ~]# crm
crm(live)# configure
crm(live)configure# monitor mysql monitor interval="20s" timeout="10s"

2. 配置资源约束:
配置好所有资源只是完成了该作业的一部分。即便群集熟悉所有必需资源,它可能还无法进行正确处理。资源约束允许您指定在哪些群集节点上运行资源、以何种顺序装载资源,以及特定资源依赖于哪些其他资源。

三种不同的约束:
Resource Location(资源位置): 位置约束定义资源可以、不可以或首选在哪些节点上运行。
Resource Collocation(资源排列): 排列约束告诉群集资源可以或不可以在某个节点上一起运行。
Resource Order(资源顺序):排序约束定义操作的顺序。

定义约束时,还需要指定分数。各种分数是群集工作方式的重要组成部分。其实,从迁移资源到决定在已降级群集中停止哪些资源的整个过程是通过以某种方式操纵
分数来实现的。分数按每个资源来计算,资源分数为负的任何节点都无法运行该资源。在计算出资源分数后,群集选择分数最高的节点。INFINITY(无穷
大)目前定义为 1,000,000。加减无穷大遵循以下 3 个基本规则:
任何值 + 无穷大 = 无穷大
任何值 – 无穷大 = -无穷大
无穷大 – 无穷大 = -无穷大
定义资源约束时,也可以指定每个约束的分数。分数表示您指派给此资源约束的值。分数较高的约束先应用,分数较低的约束后应用。通过使用不同的分数为既定资源创建更多位置约束,可以指定资源要故障转移至的目标节点的顺序。

指定资源故障转移节点
资源在出现故障时会自动重启动。如果在当前节点上无法实现重启动,或如果在当前节点上发生 N 次故障,则资源会试图故障转移到其他节点。您可以多次定义资源的故障次数(migration-threshold),在该值之后资源会迁移到新节点。

指定资源故障回复节点(资源黏性)
当原始节点恢复联机并位于群集中时,资源可能会故障回复到该节点。如果希望阻止资源故障回复到故障转移前运行的节点上,或如果希望指定其他的节点让资源进行故障回复,则必须更改资源黏性值。在创建资源时或在创建资源后,都可以指定指定资源黏性。

在指定资源黏性值时,请考虑以下情况:
值为 0:这是默认选项。资源放置在系统中的最适合位置。这意味着当负载能力“较好”或较差的节点变得可用时才转移资源。此选项的作用几乎等同于自动故障回复,只是资源可能会转移到非之前活动的节点上。
值大于 0:资源更愿意留在当前位置,但是如果有更合适的节点可用时会移动。值越高表示资源越愿意留在当前位置。
值小于 0:资源更愿意移离当前位置。绝对值越高表示资源越愿意离开当前位置。
值为 INFINITY:如果不是因节点不适合运行资源(节点关机、节点待机、达到migration-threshold 或配置更改)而强制资源转移,资源总是留在当前位置。此选项的作用几乎等同于完全禁用自动故障回复。
值为 -INFINITY:资源总是移离当前位置。

定义位置约束:location  唯一ID  资源ID  规则

location Prefer-Node1 ldirectord
rule $id="prefer-node1-rule" 100: #uname eq NODE1

资源排列约束:
colocation 命令用于定义哪些资源应在相同主机上运行,哪些资源应在不同主机上运行。通常情况下使用以下顺序:

crm(live)configure# order rsc1 rsc2
crm(live)configure# colocation rsc2 rsc1

只能设置 +INFINITY 或 -INFINITY 的分数来定义必须始终或决不能在同一节点上运行的资源。例如,要始终在同一个主机上运行 ID 为filesystem_resource 和 nfs_group 的两个资源,可使用以下约束:

crm(live)configure# colocation nfs_on_filesystem inf: nfs_group filesystem_resource

对于主从属配置,除在本地运行资源以外,还有必要了解当前节点是否为主节点。这可以通过附加 to_role 或 from_role 属性来检查。

排序约束:
有时提供启动资源的顺序是必要的。例如,在设备可用于系统之前,您不能装入文件系统。使用排序约束可在另一个资源满足某个特殊条件之前或之后启动或停止某项服务,如已启动、已停止或已升级到主资源。可使用 crm 中的以下命令来配置排序约束:

crm(live)configure# order nfs_after_filesystem mandatory: filesystem_resource nfs_group

3. 配置群集资源组:
某些群集资源与其他组件或资源相关,要求每个组件或资源以特定的顺序启动并在相同的服务器上运行。为了简化配置,引入资源组的概念。
资源组具有以下属性:
启动和停止资源:资源以显示顺序启动,以相反顺序停止。
相关性:如果组中某个资源在某处无法运行,则该组中位于其之后的任何资源都不允许运行。
组内容:组可能仅包含一些原始群集资源。要引用组资源的子代,请使用子代的 ID代替组的 ID。
限制:尽管在约束中可以引用组的子代,但通常倾向于使用组的名称。
黏性:黏性在组中可以累加。每个活动的组成员可以将其黏性值累加到组的总分中。因此,如果默认的 resource-stickiness 值为 100,而组中有七个成员,其中五个成员是活动的,则组总分为 500,更喜欢其当前位置。

定义资源组:group  唯一ID  资源列表
例如:

group Load-Balancing Virtual-IP-Tomcat ldirectord

4. 配置克隆资源:
可能希望某些资源在群集的多个节点上同时运行。为此,必须将资源配置为克隆资源。可以配置为克隆资源的资源示例包括 STONITH 和群集文件系统(如OCFS2)。如果受资源的资源代理支持,则可以克隆任何资源。克隆资源的配置甚至也有不同,具体取决于资源驻留的节点。
资源克隆有三种类型:
匿名克隆:这是最简单的克隆类型。这种克隆类型在所有位置上的运行方式都相同。因此,每台计算机上只能有一个匿名克隆实例是活动的。
全局唯一克隆:这些资源各不相同。一个节点上运行的克隆实例与另一个节点上运行的实例不同,同一个节点上运行的任何两个实例也不同。
状态克隆:这些资源的活动实例分为两种状态:主动和被动。有时也称为主要和辅助,或主和从。状态克隆可以是匿名克隆也可以是全局唯一克隆。

定义克隆资源:clone  唯一ID  资源ID
例如:

clone cl-tomcat tomcat
clone cl-mysql mysql

状态克隆:

primitive drbd_mysql ocf:linbit:drbd \
        params drbd_resource="mysql" \
        op monitor interval="15s"
ms ms_drbd_mysql drbd_mysql \
        meta master-max="1" master-node-max="1" \
        clone-max="2" clone-node-max="1" \
        notify="true"

5. 设置CRM其他属性
如果是两个节点的集群,应该设置no-quorum-policy为ignore,如果一个节点down掉,另一个节点仍能正常运行。设置start-failure-is-fatal 为false 允许你为每一个资源设置migration-threshold属性。如果没有定义stonith资源则必须设置stonith-enabled为false。

property no-quorum-policy="ignore" \
        start-failure-is-fatal="false" \
        stonith-enabled="false"

6. 迁移群集资源:

crm(live)# resource
crm(live)resource# migrate VIP node2

7. 启动/停止资源:

crm resource start resource-ID
crm resource stop resource-ID

8. 在特定节点上执行:
使节点变成备份节点

crm node standby

使节点变成活动节点

crm node online
分类: 高可用性 标签: , , ,