puppet-rsync
模块
Rsync
(remote sync)是一款通过网络进行数据同步的软件,由于Rsync会对需要同步的源和目的进行对比,只同步有改变的部分,所以相比常见的scp命令更加高效。
puppet-rsync
模块由puppet官方维护的项目,用于管理rsync的客户端、服务器,命令行的配置。puppet-rsync
项目地址:https://github.com/puppetlabs/puppetlabs-rsync
1.先睹为快
不想看下面大段的代码解析,已经跃跃欲试了?
OK,我们开始吧!
打开虚拟机终端并输入以下命令:
$ puppet apply -e "class { 'rsync': }"
以上命令会在目标服务器上安装rsync软件包。
接下来,我们打开puppet-sysctl
模块下manifests/base.pp
文件来一探究竟吧。
2.代码讲解
2.1 class rsync
在class rsync
中,除了package
资源对rsync
进行了声明以外,还有上一节提到的create_resources
函数,分别传递了rsync::put
和rsync::get
参数。
class rsync(
$package_ensure = 'installed',
$manage_package = true,
$puts = {},
$gets = {},
) {
if $manage_package {
package { 'rsync':
ensure => $package_ensure,
} -> Rsync::Get<| |>
}
create_resources(rsync::put, $puts)
create_resources(rsync::get, $gets)
}
rsync命令行下有两种不同的执行模式:pull和push。在puppet-rsync
模块中define rsync::put
对应push模式,define rsync::get
则对应pull模式。下面来看相关的两段代码示例。
# rsync push模式
rsync::put { '${rsyncDestHost}:/repo/foo':
user => 'user',
source => "/repo/foo/",
}
#rsync pull模式
rsync::get { '/foo':
source => "rsync://${rsyncServer}/repo/foo/",
require => File['/foo'],
}
2.2 class: rsync::server
class rsync::server
则用于管理rsync server,rsync
在server模式下以守护进程存在,能够接收客户端的数据请求。使用时,可以在客户端使用rsync命令把文件发送到服务器端,也可以向服务器请求获取文件。class rsync::server
使用xinetd来管理rsync服务,使用concat
模块来管理rsync配置文件。我们会在下一节谈到puppet-xinetd
模块。
class rsync::server(
$use_xinetd = true,
$address = '0.0.0.0',
$motd_file = 'UNSET',
$use_chroot = 'yes',
$uid = 'nobody',
$gid = 'nobody',
$modules = {},
) inherits rsync {
$conf_file = $::osfamily ? {
'Debian' => '/etc/rsyncd.conf',
'suse' => '/etc/rsyncd.conf',
'RedHat' => '/etc/rsyncd.conf',
default => '/etc/rsync.conf',
}
...
if $use_xinetd {
include xinetd
xinetd::service { 'rsync':
bind => $address,
port => '873',
server => '/usr/bin/rsync',
server_args => "--daemon --config ${conf_file}",
require => Package['rsync'],
}
...
concat { $conf_file: }
concat::fragment { 'rsyncd_conf_header':
target => $conf_file,
content => template('rsync/header.erb'),
order => '00_header',
}
...
}
在代码片段中,出现了inherits
关键字,与面向对象编程中的继承概念类似,其允许某个指定类从另一个类中扩展其功能和参数。
为了让读者更易于理解,称:被继承的类为基类
,在基类上建立的新类称为派生类
。
在使用inherits
关键字时,将产生以下效果:
- 当派生类被声明时,基类在此之前自动被声明
- 基类成为派生类的父作用域(parent scope),派生类将拥有基类所有的参数和资源
- 派生类可以重写基类中任何资源的属性
在此此例中,派生类rsync::server
继承了基类rsync
,得到了管理rsync软件包的package资源,得到了$package_ensure等参数,若要在rsync::server
中使用该参数,则其作用域为:$rsync::package_ensure
。
需要注意的是,inherits
的使用需要谨慎,尤其是多层继承时,会严重影响代码的可读性。在最佳实践中,仅推荐用于获取class param
中的参数时使用,例如:
class example (
String $my_param = $example::params::myparam
) inherits example::params
{ ... }
2.3 define rsync::module
rsync::module
用于设置rsync服务实例,代码实现比较简单,以下看一段示例:class swift::ringserver
,通过声明了rsync::server
和rsync::module
来搭建同步ring文件的rsync服务器:
class swift::ringserver(
$local_net_ip,
$max_connections = 5
) {
include ::swift::deps
Class['swift::ringbuilder'] -> Class['swift::ringserver']
if !defined(Class['rsync::server']) {
class { '::rsync::server':
use_xinetd => true,
address => $local_net_ip,
use_chroot => 'no',
}
}
rsync::server::module { 'swift_server':
path => '/etc/swift',
lock_file => '/var/lock/swift_server.lock',
uid => 'swift',
gid => 'swift',
max_connections => $max_connections,
read_only => true,
}
}
在rsync::module {'swift_server'}
实例中,swift_server的路径为/etc/swift
,所有者和所属组是swift
,设置了默认的最大连接数,设为只读权限。
2.4 class rsync::repo
class rsync::repo
对rsync::module
进行了简单的封装,为用户创建一个存放数据的rsync仓库,包括用于存放数据的目录和rsync服务。
class rsync::repo {
include rsync::server
$base = '/data/rsync'
file { $base:
ensure => directory,
}
# setup default rsync repository
rsync::server::module { 'repo':
path => $base,
require => File[$base],
}
3.扩展阅读
- 动态域的使用 https://docs.puppet.com/puppet/5.0/lang_scope.html#dynamic-scope
- 关于继承的使用 https://docs.puppet.com/puppet/5.0/lang_classes.html#inheritance
4.动手练习
1.请说明上述代码中的$conf_file = $::osfamily ? { ...}
的作用和用法
2.搭建一个用于同步软件包的rsync服务器,incoming_chmod设为’0755’,outgoing_chmod设为’0644’,只读权限。