随着虚拟化和云计算技术的兴起,计算机集群的自动化管理和配置成为了数据中心运维管理的热点。对于 IaaS、Paas、Saas 来说,随着业务需求的提升,后台计算机集群的数量也会线性增加。对于数据中心的运维人员来说,如何自动化管理、配置这些大规模的计算机集群节点,对于数据中心的稳定运行以及运维成本控制都显得至关重要。
Puppet 是一个开源系统配置管理工具,它有着简明的架构以及良好的扩展性;同时,Puppet 还提供了自有的系统配置描述语言以及完善的公用库,非常适合用于管理和部署大规模集群系统。
Puppet 使用简明的 C/S 架构,分为 Puppet Server 和 Puppet Node。
Puppet Server
Puppet Server 是配置和管理整个集群的大脑,管理着所有节点。系统管理员在 Puppet Server 上用 Puppet 特有的配置描述语言为各个节点编写配置文件 (manifest),配置文件描述了节点的目标状态——资源的集合。这些资源可以是文件、服务、软件包等等。各个节点会周期性的查询 Puppet Server,获得自己的最新配置文件,并且在本地应用这些配置文件,使得自身的资源和状态达到配置文件要求。
Puppet Node(Agent)
被 Puppet Master 管理着的计算机节点称为 Puppet node。Puppet node 会周期性的查询 Puppet Master,来获取自己的配置文件,并且在本地应用。在每次应用配置文件之后,Puppet node 会提供上传一份报告给 Puppet Master,以便以后的统计和分析。系统管理员也可以手动地在 Puppet Node 上执行命令,让 Puppet Node 立即查询 Puppet Server 获取自身最新的配置文件,并且在本地应用。
Puppet 的工作流程可以概括成这几步:定义、模拟、应用、报告。
管理员为各个节点编写配置文件,配置文件中定义了该节点所需要的资源的集合以及资源之间的关系。这些资源可以是文件、服务、软件包、可执行的命令等等。Puppet 内置的配置管理语言对这些资源提供了较为完整的底层抽象,减轻了编写配置文件的复杂度。
根据节点的配置文件,我们可以了解到该节点需要什么样的资源并且处于什么样的状态。配置文件描述了节点的状态,而不是具体的配置步骤。Puppet 会将配置文件 Manifest 编译成更为详细的一种配置文件 Catalog。通过 Catalog,Puppet 会根据节点的当前状态,模拟出节点达到该目标状态所需要的步骤。
节点周期性地向 Puppet Server 来请求自己最新的配置文件。Puppet 会将节点的实际状态与节点配置文件中所表述的目标状态做比较,并根据得到的所需要的步骤,对节点执行操作,使其达到配置文件所表述的状态。
当每次应用执行过后,节点都会给 Puppet Server 发送一份运行报告,报告该节点的状态,以便以后的分析和统计。
Puppet 配置管理语言中的核心概念是资源,资源可以是一个软件包,一个文件,一种服务等等。一个节点的状态可以用资源的集合以及他们之间的关系来表示。管理员不需要详细地描述配置和部署系统的具体步骤,Puppet 只需要管理员来描述系统的目标状态,即资源的集合以及它们之间的关系。Puppet 内置的执行引擎会根据节点的现有状态将配置文件转化为具体的执行步骤并且执行。
在 Puppet 中,类是一系列相关资源的集合;模块是一系列类的集合。Puppet 内置提供了一些常用的类和模块,同时用户可以定义自己的类和模块。通过类和模块使用,配置模块重用和共享变的非常容易。
由于 Puppet Server 和节点之间通过主机名来通信,所以需要双方可以通过彼此的主机名来找到对应的 IP 地址。可以通过配置 DNS 或者配置/ets/hosts 文件来实现。
在安装官方提供的开源版本的 Puppet 软件之前,Puppet Server 和 agent 首先需要都安装官方的软件源 (Puppet 对各种 Linux 发行版都有提供支持,本文以 Ubuntu 14.04 系统为例):
下载官方软件源的安装包:
1 | wget https://apt.puppetlabs.com/puppetlabs-release-pc1-trusty.deb |
更新软件源:
1 2 | sudo dpkg -i puppetlabs-release-pc1-trusty.deb sudo apt-get update |
安装 Puppet Server
1 | sudo apt-get install puppetserver |
启动 PuppetServer
1 | sudo service puppetservice start |
安装 PuppetAgent
1 | sudo apt-get install puppet-agent |
编辑/etc/puppetlabs/puppet/puppet.conf 文件,设置该 agent 的 puppet server 的地址:
1 2 | [main] server = puppetmaster |
注:puppetmaster 是 puppetserver 的主机名。
启动 puppet service
1 | sudo /opt/puppetlabs/bin/puppet resource service puppet ensure=running enable=true |
作为第一个实例配置文件,我们想让节点做一件最简单的事情:在/etc/文件夹下面创建一个文件 helloworld.txt,文件的内容是”hello world from puppet!/n”。
首先我们在 puppetserver 上进入/etc/puppetlabs/code/environments/production/manifests 文件夹,创建 site.pp 文件:
1 2 3 4 5 6 7 8 9 10 11 12 | node puppetagent { file { 'helloworld': path => '/etc/helloworld.txt', owner => 'root', group => 'root', mode => '655', content => "hello world from puppet!/n", } } |
site.pp 就是节点的配置文件,里面可以包含对各个节点的配置描述。在实例配置文件中,”puppetagent”就是节点的主机名。包含在 puppetagent 中的配置描述就是该节点的资源集合的描述。
配置文件创建好后,节点会周期性地查询 PuppetServer 来获取自己的配置文件并在本地应用。当然 Puppet 也支持手动获取自己的配置。在本例中,我们通过手动的方式来进行配置更新。我们在 PuppetAgent 上手动执行命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 | root@puppetAgent:/opt/puppetlabs/bin# ./puppet agent --test 2016-05-21 14:24:14.858673 WARN puppetlabs.facter - locale environment variables were bad; continuing with LANG=C LC_ALL=C Info: Using configured environment 'production' Info: Retrieving pluginfacts Info: Retrieving plugin Info: Caching catalog for puppetagent Info: Applying configuration version '1463811856' Notice: /Stage[main]/Main/Node[puppetagent]/File[helloworld]/ensure: defined content as '{md5}c3aa68786c58c94ef6f3e2399920f268' Notice: Applied catalog in 0.02 seconds root@puppetAgent:/opt/puppetlabs/bin# cat /etc/helloworld.txt hello world from puppet! |
我们看到节点成功从 Puppet Server 获取配置文件,并且在本地应用,对应的文件成功创建。
作为进阶的任务,我们希望节点可以执行一些更加复杂一点的任务。我们希望节点可以从 PuppetServer 获取一个命令脚本,并且执行该脚本。
我们首先在/etc/puppetlabs/code/environments/production/modules 中创建一个名叫”test”的模块,在 test 模块下面创建一个”files”文件夹。在这个文件夹里的文件是可以被节点获取的。然后我们在这个”files”文件夹里创建一个 shell 脚本 test.sh,路径如下:
/etc/puppetlabs/code/environments/production/modules/test/files/test.sh
test.sh 文件内容:
1 2 | touch /etc/helloworld.log echo "helloworld" >> /etc/helloworld.log |
该脚本会在/etc/目录下创建 helloworld.log 文件,然后在文件里添加”hello world”内容。
进入目录/etc/puppetlabs/code/environments/production/manifests,然后我们再来编辑 site.pp 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | node puppetagent { file { 'test.sh': path => '/etc/test.sh', owner => 'root', group => 'root', mode => '655', source => 'puppet:///modules/test/test.sh', } exec { 'execute ': command => 'bash /etc/test.sh', require => File['test.sh'], path => ["/bin/"], } } |
其中,我们定义了两个资源:一个文件资源和一个执行命令资源。同时这两个资源有依赖关系,命令执行资源依赖于文件资源,所以 Puppet 会优先处理文件资源。执行命令资源会在文件资源存在后再执行。
我们看下客户端的执行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | root@puppetAgent:/opt/puppetlabs/bin# ./puppet agent --test 2016-05-21 15:39:39.817370 WARN puppetlabs.facter - locale environment variables were bad; continuing with LANG=C LC_ALL=C Info: Using configured environment 'production' Info: Retrieving pluginfacts Info: Retrieving plugin Info: Caching catalog for puppetagent Info: Applying configuration version '1463816381' Notice: /Stage[main]/Main/Node[puppetagent]/File[test.sh]/ensure: defined content as '{md5}2ce060ad2ddab2fe416ca8fb6f8da32a' Notice: /Stage[main]/Main/Node[puppetagent]/Exec[execute ]/returns: executed successfully Notice: Applied catalog in 0.05 seconds root@puppetAgent:/opt/puppetlabs/bin# cat /etc/helloworld.log helloworld |
我们可以看到,helloworld.log 文件被正确的创建,说明脚本文件被正确地执行。
Puppet 是基于 Ruby 的开源系统配置和管理工具,它提供的独特的系统配置语言极大程度地简化了系统管理员管理和配置系统的过程。本文首先介绍了 Puppet 的系统架构和工作流程,并且介绍了 Puppet 独特的系统配置语言,之后我们简单介绍了安装和配置 Puppet 的具体步骤。最后,本文以两个实例介绍了如何在 Puppet 中为节点编写配置文件,来达到创建文件和执行命令的效果。希望本文能对系统管理员,Puppet 初学者有所帮助。
https://www.ibm.com/developerworks/cn/opensource/os-cn-puppet/index.html