比别人多一点志气,你就会多一份出息 [登录·注册]

吕滔博客

首页 开发 运维 工具 摄影

自动化系统管理工具cfengine系统原理与实践

运维 memory 发布于June 27, 2013 标签: none

在日常系统管理工作中,管理上千台服务器,需要临时的改变其一个配置,例如删掉某个帐号停掉某个服务
一般我们只能不厌其烦的登到每一台机器上重复的完成这些动作,或者写脚本循环登录及其执行操作
如果有了cfengine,一个命令就可以搞定了.是不是很看效率,请看如下实践之体会.
以下的所提到的cfengine是2.2版本的.

1. cfengine 概述

cfengine是一个功能强大的自动化系统管理工具.引用其官网的说法"cfengine是一种 UNIX 管理工具,其目的是使简单的管理的任务自动化,使困难的任务变得较容易.
它的目标是使系统从任何状态收敛到一种理想状态.使用cfengine,它可以保证你的系统总是维持你所希望的那个状态.
如果说有黑客进来了修改了某个重要的配置文件的内容或者权限,也会被cfengine自动修复!

1.1. cfengine 功能概述

1.2. 使用cfengine的益处

当你切换使用cfengine来管理系统配置时,你可以得到以下好处:

1.3. cfengine 组件说明

Cfengine是一个用于设置和维护计算机系统的工具,包含了以下几个组件:

cfagent自动配置代理,其配置文件为update.conf 和 cfagent.confcfservd文件服务和远程激活服务,其配置文件为cfservd.confcfexecd计划执行 cfagent 命令cfenvd异常检测服务cfrun远程通过cfservd调用cfagent的方法,其配置文件为cfrun.hostscfshow检查有帮助的数据库的内容的方法(辅助)cfenvgraph异常检测服务cfenvd的附属工具(辅助)
·cfkey 密匙生成工具(每台服务器运行一次)。

1.4. cfengine 配置文件

每个系统必须要有最少的配置文件.默认情况下,你需要将配置文件放到/var/cfengine/inputs 目录中.
可以集中化管理配置文件,通过拉的方式更新到所有客户端系统

update.conf此配置文件要保持简单,cfengine每次更新,它总是被首先解析和执行,此配置的主要任务就是从服务端拷贝一组配置文件.
如果其他配置文件有误,此配置文件也能够继续更新配置文件,在下次运行的时,就可以运行成功.
对大部分网站来说,这个文件在cfengine系统初初始运行后,不需要去变变更的.cfagent.conf此配置文件是cfengine的核心文件,它包含了所有功能操作配置. imports.png

可以使用文件导入功能(import功能),使配置文件易读,参考上图cfservd.conf此配置文件是 cfservd 守护进程的配置文件.文件定义了那些主机可以远程执行cfagent和那些主机可以传输特定的文件.

cfengine使用到配置文件,我们需要集中化版本控制(比如Subversion).这样就可以记录所有变更,以便在需要时,可以会滚到某个特定的版本配置.

2. 使用Classes(与group相同)标识系统

cfengine中最重要的概念就是Classes. 每种系统都属于一个或者多个 classes.
cfagent每次运行的时,会根据很多各种不同信息来定义classes.可以在特定的classes执行特定的操作.
因此,任何操作都可以在一台主机上执行,也可以在运行特定操作系统的主机上运行,也可以在所有的主机上运行.
Cfengine 使用内置的和用户定义的classes.

2.1. 预定义Classes的分类

主机本生根据其架构决定很多classes 比如主机名称,主机ip,操作系统等.
很多classes 根据当前的日期和时间定义的.

为了确定在给定系统上定义了那些标准classes,可以运行如下命令:

  [root@linux]# /var/cfengine/bin/cfagent -p -v | grep Defined
  Defined Classes = ( 172_22_5 172_22_5_90 172_22_5_91 64_bit Day17 Hr11 Hr11_Q1 March Min10_15 Min11 Q1 Redhat_AS5 Wednesday Yr2010 addr_ 
  alidc_net alidc_net_hzidc_com any cfengine_01 cfengine_01_hst_xyi_cn_alidc_net cfengine_01_hst_xyi_cn_alidc_net_hzidc_com cfengine_2 
  cfengine_2_2 cfengine_2_2_3 cfengine_server cn_alidc_net cn_alidc_net_hzidc_com com compiled_on_linux_gnu fe80__216_3eff_fe16_55b 
  hst_xyi_cn_alidc_net hst_xyi_cn_alidc_net_hzidc_comhzidc_com ipv4_172 ipv4_172_22 ipv4_172_22_5 ipv4_172_22_5_90 ipv4_172_22_5_91 linux
  linux_2_6_18_131_el5_customxen linux_x86_64 linux_x86_64_2_6_18_131_el5_customxen 
  linux_x86_64_2_6_18_131_el5_customxen__1_SMP_Tue_Sep_15_15_46_11_CST_2009 lsb_compliant net net_hzidc_com
  net_iface_bond0 net_iface_lo redhat redhat_s redhat_s_5 redhat_s_5_3 redhatenterpriseserver redhatenterpriseserver_5 
  redhatenterpriseserver_5_3 redhatenterpriseserver_tikanga x86_64 xyi_cn_alidc_net xyi_cn_alidc_net_hzidc_com )

正如你所看到的,这个系统中包含了很多预定义classes,他们属于几个分类:

每个系统都属于 any 这个 class,当你需要对 未定义或者不能使用classes标识的系统进行操作时候,可以使用 any 这个 class.

2.2. 自定义Classes

自定义classes 配置都是在cfagent.conf 中的groups区域中,请看如下例子:

  groups:
  		web_app1 = ( IPRange(172.16.2.1-250) IPRange(172.16.3.1-250) IPRange(172.16.4.1-250) )
  		web_app1 = ( IPRange(172.16.6.1-250) IPRange(172.16.7.1-250) IPRange(172.16.14.1-250) )
  		ntp_server= ( nagios1 nagios2 nagios3 monitor_xy7 monitor_xy8 monitor_xy9 )
  		
  		# 通过配置文件 判断是否属于某一类型的主机
  		dns = ( '/usr/bin/test -f /etc/named.conf' )
  		web_normal = ( '/usr/bin/test -f /etc/httpd/conf/httpd.conf' )
  		
  		# 通过cfengine内部命令来判断
  		first_ten_server = ( RegCmp("webserver[0-9]i","${host}") )
  
  		# all server
  		all_server= ( dns web_app1 ) 
  copy:
  	any::
  		# 根据拷贝结果,定义新的classes
  		$(clientconf)/syslog.conf	dest=$(etcdir)/syslog.conf
          			                owner=$(fowner) group=$(fgroup)
                                    	mode=644
                                    	server=$(cfserver) trustkey=true 
                                    	define=new_syslog
  shellcommands:
  	new_syslog::
       "/etc/init.d/syslog restart > /dev/null 2>&1"

以上配置只是cfagent.conf 中的一段而已,从上面可以看出:

比如上面的配置例子,当syslog.conf配置改变了,当拷贝完成时,会定义一个new_syslog的class.
在shellcommands的操作中,会根据new_syslog class 来重启syslog服务.

3. cfengine系统的搭建与使用

3.1. cfengine 配置文件管理方式

cfg_svn.png

一般来说,cfengine 的配置文件,都是集中化方式管理,配置文件都通过版本控制软件进行修改和更新.
系统管理更新配置文件后,提交到svn后,cfengine server 更新配置文件,推送到客户端.

3.2. cfengine 运行方式

cf_run.png

  1. 管理员登录主服务器更新配置文件(svn),通过运行cfrun命令通知客户端进行更新.cfrun在cfrun.hosts 文件中查找客户端的列表.
    请注意,主服务器可以自行充当客户端。此图中有两个客户端:主服务器和远程客户端.
  2. cfrun与每个客户端上的 cfservd 进行通信,cfservd 然后运行cfagent.
  3. cfagent连接主服务器,首先检查update.conf是否有新版本,如果有更新,将它传输到客户端.
  4. cfagent 先评估 update.conf 的内容,并获取策略文件(cfagent.conf 和相关文件)的最新版本.
  5. 随后评估 cfagent.conf以确定客户端是否处于所需状态。如果有偏差,cfagent 将执行已定义的操作来更正客户端配置.

注意:没有绝对的服务端和客户端,在需要的情况下,客户端也可以作服务器端.

3.3. cfengine 更新触发机制

3.3.1. 服务器集中通知更新方式

  1. 服务器上运行cfrun,cfrun会根据cfrun.hosts中的主机列表来连接到某个客户机的cfservd程序
  2. 客户机上cfservd调用本机的cfagent程序
  3. 客户机上cfagent程序执行update.conf,连接到服务器的cfservd,下载策略文件cafagent.conf
  4. 客户机下载成功后执行最新版本的策略文件,不成功就执行旧版本的.

注意:update.conf的内容要简单,一般来说就是下载cfagent.conf策略文件,基本上这个文件创建好了之后就不会更改了.

3.3.2. 客户端自主激活方式

  1. 客户机自动执行cfagent程序执行update.conf,连接到服务器的cfservd,下载策略文件cafagent.conf
  2. 客户机下载成功后执行最新版本的策略文件,不成功就执行旧版本的.

注意:客户端定期执行cfagent,可以通过添加到crontab 或者 cfexecd定期调用.这样的情况下,客户端就不需要运行cfservd程序.

3.4. cfengine 服务器端设置

  1. 安装cfengine软件包,可以使用源码或者rpm包,请参考互联网.
  2. cfengine服务端目录结构

      /var/cfengine/
      |-- backup
      |-- bin
      |-- clientconf			#客户端从此目录下载和更新配置文件
      |-- inputs				#服务端自身的配置文件
      |-- lib
      |-- modules
      |-- outputs
      |-- ppkeys
      |-- rpc_in
      |-- rpc_out
      |-- share
      `-- state
    
  3. 设置cfservd.conf配置文件,文件内容如下

      #cat /var/cfengine/clientconf/cfservd.conf (为了简化一点,服务端和客户端使用同样的cfservd.conf配置)
      ###############################################################################
      # Who and what we allow access to, and who we trust
      # Master Server conf and Client cfservd conf
      ###############################################################################
      control:
         domain = ( hzidc.com )
         cfrunCommand = ( "/var/cfengine/bin/cfagent" )
         MaxConnections = ( 100 )
         MultipleConnections = ( true )
         IfElapsed = ( 1 )
         DenyBadClocks = ( false )
         AllowConnectionsFrom = ( 172.0.0.0/8 )
         TrustKeysFrom = ( 172.0.0.0/8 )				#自动交换key,不需要拷贝key
         LogAllConnections = ( true )
         AllowUsers = ( root admin )
         HostnameKeys = ( off )
         ChecksumDatabase = ( /var/cfengine/cfdb )
      
      grant:
         $(cfrunCommand)			172.0.0.0/8			#允许ip在172.0.0.0/8范围内的主机,可以cfrun方式远程执行cfagent
         /var/cfengine			172.0.0.0/8			#允许ip在172.0.0.0/8范围内的主机,通过cfagent访问拷贝此目录下的文件
    


    注意:此cfservd.conf配置文件比较宽松,可以根据需要进行权限的限制
  4. 设置update.conf配置文件(cfagent运行时,第一解析的配置文件)

      #cat /var/cfengine/clientconf/update.conf
      ###############################################################################
      # update.conf - ensure that the inputs and binaries in /var/cfengine are
      # synced to those on the server. 
      ###############################################################################
      
      control:
         actionsequence  = ( copy )    # sequence of actions to perform
         domain          = ( hzidc.com )              # our domain
         DefaultCopyType = ( checksum )               # Copy based on checksum, not mtime
         HostnameKeys = ( off )
         cfserver        = ( 172.16.20.100 )  	  # host running cfservd
         workdir         = ( /var/cfengine )           	  # the workdir
         clientconf = ( /var/cfengine/clientconf )
         input_mode      = ( 700 )                    	  # mode for input files
         bin_mode        = ( 755 )                    	  # mode for binaries
         fowner          = ( root )                   	  # file owner
         ogroup          = ( root )                  	  # file group
          
        any::                                         # the class to match
      
         SplayTime       = ( 1 )                     # max number of minutes over
                                                      # which cfengine will share
                                                      # its load on the server
      ############################################################################
      copy:
        $(clientconf)/cfagent.conf   dest=$(workdir)/inputs/cfagent.conf
                                     owner=$(fowner) group=$(ogroup)
                                     mode=700
                                     server=$(cfserver) trustkey=true encrypt=true
    


    注意:要尽可能保持update.conf文件简单,只让它更新必要的cfagent.conf配置文件,其他的具体功能操作都在cfagent.conf文件中定义.
  5. 设置cfagent.conf配置文件(cfengine的核心配置文件,所有的功能操作都在此配置文件中定义)

      #cat /var/cfengine/clientconf/cfagent.conf
      ###############################################################################
      # cfagent.conf for client
      ###############################################################################
      # group区块定义群组(classes),可以在后续的配置中指定特定的组群执行特定的操作,这样就可以将不同类的配置文件都写在同一个cfagent.conf文件中.
      
      groups:
      	Redhat_AS3 = ( redhat_as_3 )
      	Redhat_AS4 = ( redhat_as_4 )
      	Redhat_2u1 = ( redhat_as_2_1 )
      	Redhat_7u3 = ( redhat_7_3 )
      	Redhat_AS5 = ( redhat_s_5 )
      
      control:
       
       any::
       
          ## Basic Cfengine configurations
          access = ( root )
          editfilesize = ( 0 ) # 0 turns off the editfilesize limit.
          netmask = ( 255.255.255.0 ) # Sets the netmask if you use netconfig.
          timezone = ( CST )
       
          ## How and Where do we output stuff?
          sysadmin = ( admin@admin.com )
          smtpserver = ( smtp.admin.com )
          EmailMaxLines = ( n ) # No maximum lines
          Syslog = ( on )
      
          ## How many cfengines can run, what do we do when the server's busy
          SplayTime = ( 45 ) # Run everything immediately
          MaxCfengines = ( 20 )
      	Repository = ( /var/cfengine/backup )
      
          # 如果使用cfexecd定时运行cfagent,它会读取 下面 schedule 中定义时间来运行cfagent
          schedule   = ( Monday.Hr10 Tuesday.Hr10 Wednesday.Hr10 Thursday.Hr10 Friday.Hr10 Monday.Hr15 )  
          
          ## Set some defaults
          DefaultCopyType = ( checksum ) # Copy based on checksum, not mtime
          DeleteNonUserFiles = ( false ) # Do not delete unowned files
          Exclamation = ( on ) # Inform us of problems.
          ExpireAfter = ( 30 ) # Don't let cfengine run longer then 60 minutes.
          HostnameKeys = ( off ) # Store keys based on hostname, not IP
          Inform = ( on ) # Show diagnostic output
          ShowActions = ( off ) # Do not show verbose diagnostic output
          domain = ( hzidc.com ) # Obtain our domain name automatically
      
      	# 可以自定义一些变量,方便后面引用,引用方式 $(cfserver)
          cfserver = ( 172.16.20.100 )
          clientconf = ( /var/cfengine/clientconf )
          workdir = ( /var/cfengine )
          etcdir = ( /etc )
          optdir = ( /opt )
      
          bin_mode        = ( 755 )                    # mode for binaries
          fowner          = ( root )                   # file owner
          fgroup          = ( root )                   # file group
          actionsequence = ( copy editfiles shellcommands processes )
       
       ###############################################################################
       ## copy 区块: 从服务器拷贝配置文件,也可以递归拷贝目录
       copy:
       any::
      
           $(clientconf)/cfservd.conf   dest=$(workdir)/inputs/cfservd.conf
                                        owner=$(fowner) group=$(fgroup)
                                        mode=700
                                        server=$(cfserver) trustkey=true 
         
           $(clientconf)/update.conf    dest=$(workdir)/inputs/update.conf
                                        owner=$(fowner) group=$(fgroup)
                                        mode=700 
                                        server=$(cfserver) trustkey=true
        
       # 引用前面自定义个group(classes),属于Redhat_AS4这个组的拷贝以下配置文件
       Redhat_AS4::
          $(clientconf)/sysctl.conf     dest=/etc/sysctl.conf
                                        owner=$(fowner) group=$(fgroup)
                                        mode=777
                                        server=$(cfserver) trustkey=true
      
          $(clientconf)/limits.conf     dest=/etc/security/limits.conf 
                                        owner=$(fowner) group=$(fgroup)
                                        mode=777
                                        server=$(cfserver) trustkey=true
      
       ###############################################################################
       ## editfiles 区块: 此块操作是自动编辑系统配置文件
       editfiles: 
       any::
      
       { /root/.bashrc
          AutoCreate
          DeleteLinesContaining "export PS1"
          AppendIfNoSuchLine "export PS1='\n\e[1;37m[\e[m\e[1;32m\u\e[m\e[1;33m@\e[m\e[1;35m\h\e[m \e[4m`pwd`\e[m\e[1;37m]\e[m\e[1;36m\e[m\n\$'"
       }
       	
       ###############################################################################
       ## processes 区块: 定义检查系统进程,如果没有在ps里发现相应进程,cfagent将根据指定的命令启动该进程
       processes:
       any::
      
          # Make sure these processes are always running
          "cfservd" restart "/var/cfengine/bin/cfservd"
      
       ###############################################################################
       ## shellcommands 区块: 定义了需要运行的系统命令,可以是脚本,也可以是命令
       shellcommands:
       any::
      
          # restart apache
          "/etc/init.d/httpd restart"
      
          # execute cmd
      	"/bin/echo client no do ser with domain "
      
       ###############################################################################
       ## files区块: 定义了检查系统文件属性,如有不符将自动修正
       files:
       any::
          /etc/passwd
               mode=644        # make sure the file permissions are right
               owner=root      # make sure it's owned by root
               action=fixall   # if anything is wrong, fix it immediately!
               checksum=md5    # keep a "tripwire" checksum to tell us
      
         /etc/ssh/sshd_config        m=644 o=root g=0 act=fixall
    
  6. 设置cfrun.hosts配置文件(在服务端使用cfrun命令"推"配置到客户端,文件定义要"推"的客户端主机名列表,存放于Server端的/var/cfengine/inputs目录)

      #####################################################################
      #list of hosts you're going to manage (remote client must run cfservd)
      #####################################################################
      domain = hzidc.com
      access = root admin
      hostnamekeys = off
      outputdir= /var/cfengine/output
      
      #-------host list----------#
      test_name1
      test_name2
      test_name3
      test_name4
      test_name5
      test_name6
      test_name7
      test_name8
      test_name9
      test_name10
    


    注意:此配置文件中的主机名要能解析(通过/etc/hosts 或者dns),否则运行会找不到客户端ip,服务端需要配置hosts 或者dns.此配置文件只需要在服务端使用.
  7. 服务端使用cfkey生成密钥,并且运行cfservd守护进程

      /var/cfengine/bin/cfkey
      /var/cfengine/bin/cfservd
    


    说明: 服务端生成的密钥保存在/var/cfengine/ppkeys目录下.
    至此cfengine 服务端已经基本配置完成了,下面我们就要在客户端初始化运行cfengine

3.5. 客户端运行cfengine

  1. 运行 /var/cfengine/bin/cfkey 生成密钥
  2. update.conf 配置从服务端拷贝到客户端 /var/cfengine/inputs 目录中
  3. 运行 /var/cfengine/bin/cfagent -qv,cfagent根据update.conf的配置到Server端相应目录下载cfservd.conf和cfagent.conf,并根据里面的规则进行各种操作.
    说明:在运行的过程中,客户端和服务端会自动交换公钥,交换公钥后,都会以root-x.x.x.x.pub(x.x.x.x代表ip地址)形式保存在各自的/var/cfengine/ppkeys目录中.

4. 总结(Summary)

  1. 通过客户机本身的cfexecd 和
    服务器的cfrun如果是同时执行cfagent会不会出现冲突?答案是不会,cfengine有很好的锁的机制来避免这种情况的发生.通常来说,客户机
    定时执行cfexecd来单独激活自己的cfagent和服务器执行cfrun集中激活客户机这两种方式在实际中都会使用,只是场合不同:
  2. cfengine本身并没有客户机服务器的严格区分,每一台主机同时可以是服务器,也可以当作客户机.cfengine也是这种概念.当然,一般来讲方便于集中控制,我们会选定一台机作为服务器.
  3. inputs 目录的作用,它是 cfengine 默认的当前有效配置文件所在的目录.cfengine运行所需要的 *.conf 之类的配置文件都是存放在这个目录下
  4. cfengine
    的所有程序都带有-v参数,用于详细的输出,这对我们排错调试带来了很大方便.而且对于cfagent程序,-n参数是十分有用的.对于一个刚刚建立的策
    略文件直接执行是十分危险的,-n参数是模拟执行,所以带上它来运行cfagent就给我们带来很大的安全性,特别是调试的时候.所以首先应该使用 cfagent -n -v

当然在真实生产线部署,管理大量的服务器,要对cfengine进行一些改进,才能满足特定的需要.

相关推荐

添加新评论

网站状态

  • 栏目分类:49个
  • 发布文章:1560篇
  • 用户评论:853条
  • 开博至今:4435天

正则速查

[abc] 匹配中括号中的单个字符,如a或b或c
[^abc] 匹配除了a、b、c等字符的其他单个字符
[a-z] 匹配一个字符范围,如a到z
[a-zA-Z] 匹配一个字符范围,如a-z 或 A-Z
^ 匹配行的开始
$ 匹配行的结束
\A 匹配一个字符串的开始
\z 匹配一个字符串的结束
. 匹配任意单个字符
\s 匹配空白字符,如空格,TAB
\S 匹配非空白字符
\d 匹配一个数字
\D 匹配非数字
\w 匹配一个字母
\W 匹配非字母
\b 匹配字符边界
(...) 引用所有括号中的内容
(a|b) a或者b
a? 零个或1个a
a* 零个或多个a
a+ 1个或多个a
a{3} 3次重复的a
a{3,} 3次或3次以上重复的a
a{3,6} 3到6次重复的a

修正符

/g 查找所有可能的匹配
/i 不区分大小写
/m 多行匹配
/s 单行匹配
/x 忽略空白模式
/e 可执行模式,PHP专有
/A 强制从目标字符串开头匹配
/D 使用$限制结尾字符,则不允许结尾有换行
/U 只匹配最近的一个字符串;不重复匹配

最新回复

  • chen: 感谢大师,搞定
  • memory: 你把采集和文章相关content的字段text类型改为bigte...
  • chen: 请教大师,phpcms采集超过1万2字就无法采集,哪里可以修改?
  • 11: 很棒
  • s站: 学习了
  • 基地小组: 好文章,非常详细,博主辛苦了
  • memory: 没事儿,这个插件有些问题。我现在已经不使用了。。。
  • 小白: 还有会缓存用户状态给下一位用户!我评论留个记录而已,,,,,
  • 小白: 再次留个记录,不知道为什么缓存页面点击文章或者分类会跳转自己解析...
  • weich: 用数据库那个缓存就正常了!有得用不错了!作者也幸苦了!
  • weich: 有点奇怪,,,哈哈哈哈!原来是那个模板登陆标签被我注释了,所以不...
  • weich: 很强大,就是有个问题登陆了可用看见网页底部模板,不登陆就看不到,...
  • J Zhiguang: valued article for a new learnner.
  • VPS234: 写得不错啊,支持一下,证书现在很多免费的吧
  • 游客: 感谢,我终于明白了markdown原来就是快捷键啊。
  • 楚狂人博客: 感谢博主分享干货
  • 天津网站建设: 写的很棒,感谢博主