设为首页 收藏本站
查看: 1124|回复: 0

[经验分享] 运维自动化管理工具之Puppet

[复制链接]

尚未签到

发表于 2018-8-2 06:18:07 | 显示全部楼层 |阅读模式
  一、相关概念
  1、puppet是什么?
  a、开源的集中式配置管理工具。通过自有配置语言对节点进行目标状态定义,并能够基于网络实现目标状态的维护。
  b、采用C/S架构即master和agent,master作为中心配置库,agent用来读取并应用配置的节点。
  c、puppet定义目标状态的核心组件:"资源",
  d、发行版本: 0.24,0.25,2.6,2.7(巨大变化),3.x(基于2.7为原型)
  e、管理目标:众多linux发行版本,windows等几乎所有操作系统。
  2、puppet认证方式是什么?
  puppet的master与agent是基于ssl认证,而证书的颁布依赖于使用主机的主机名。(好处:ip变了,主机名没变那么证书还依然能用),因此master需要可以解析所有agent的主机名。
  3、master与agent是怎么通讯的?
  通讯基于https的XMLRPC协议进行的,master不会主动发起对agent的请求,而是客户端每个固定时长(默认半个小时)去服务器端查找是否有关于本节点的配置信息,如果有master就将配置模板发给agent,然后agent读到后,就根据模板进行操作了。
  4、puppet的工作原理(重点理解部分):
  宏观理解工作原理:要想使某台主机到达某目标状态需要每隔一段时间去master查找配置文件,这个配置文件定义了需要安装哪些模块,而模块组织了所有的依赖关系,agent拿到配置需求进行执行,然后将结果返回给master,master将结果保存到databases中,这些结果可以用通过puppet dashboard或foreman来进行展示。
  微观:define -> 模拟 -> 强制 -> REPORT, 即(define) 在master端定义了资源信息 (模拟)agent读到这些信息后不会立即执行而是先模拟执行一次,如果成功,(强制)则执行这些变更,最后(report)报告自己的工作状态。
  master与agent信息交互细节:agent通过factor将执行结果(主机名,ip等)发给master,master会根据agent的情况来选择一些清单manifest然后,将其进行编译成伪代码catalog,然后交给agent,agent在进行上边所述的"模拟"->"报告"的工作。
  二、puppet安装
  #puppet(2.7比较流行的稳定版本)
  1、下载地址:
https://yum.puppetlabs.com/el/6.5/products/x86_64/puppet-2.7.25-1.el6.noarch.rpm  
https://yum.puppetlabs.com/el/6.5/products/x86_64/facter-1.7.6-1.el6.x86_64.rpm
  2、使用模型:
a、单机使用  
安装puppet
  
b、master/agent
  
master:puppet,puppet-server
  
agent:puppet
  3、安装:
  安装部分比较简单,也不是本文介绍的重点所以这里就不多介绍了,我这里采用rpm安装。
rpm -ivh xxxx.rpm  三、puppet详解
  1、定义资源:
  资源是以.pp结尾的。
  格式:
type {"title":  
v1 => k1,
  
v2 => k2,
  
}
  说明:
  1、在定义资源时候,资源类型必须使用字符串;
  2、同一个类型中其必须唯一   比如:package app1 与 service app1可以,都是package则不行。
[root@l-mem-test2 tmp]# cat test.pp  
notify{'notice':
  
message => 'welcome to puppet.',
  
}
  
[root@l-mem-test2 tmp]# puppet apply test.pp    ## 应用这个puppet
  
notice: welcome to puppet.
  
notice: /Stage[main]//Notify[notice]/message: defined 'message' as 'welcome to puppet.'
  
notice: Finished catalog run in 0.02 seconds
  
[root@l-mem-test2 tmp]# puppet apply test.pp -v    ## 详细的信息 包括版本号
  
info: Applying configuration version '1483548877'
  
notice: welcome to puppet.
  
notice: /Stage[main]//Notify[notice]/message: defined 'message' as 'welcome to puppet.'
  
notice: Finished catalog run in 0.05 seconds
  
[root@l-mem-test2 tmp]# puppet apply test.pp -v     ## 你会发现及时没变更版本号也会变更
  
info: Applying configuration version '1483548887'
  
notice: welcome to puppet.
  
notice: /Stage[main]//Notify[notice]/message: defined 'message' as 'welcome to puppet.'
  
notice: Finished catalog run in 0.05 seconds
  2、核心资源:notify、package、user、group、file、exec,cron、service
  notify通知,用于调试输出:
  常用参数:
  message:要输出什么信息
  name:名称
  package(管理软件包):
  常用属性:
  ensure:程序包的目标状态;
  name:资源的名称,即软件包的名字;
  provider:软件包管理器(yum,rpm,apt,ports,gem,msi,dpkg,pkg)
  source:指定程序包文件路径
  install_options:指定安装选项 最常用的通过INSTALLDIR来指定安装目录
  例如windows下安装mysql
  package {'mysql':
  ensure   => installed,
  provider => 'msi',
  source   => 'D:\software\mysql-5.5.36.msi',
  install_options => {'INSTALLDIR' => 'C:\mysql'},
  }
  service(管理服务):
  常用属性:
  ensure:服务目标状态,true和false
  enable:是否开机自启动,true和false
  name:服务名称
  path:服务脚本路径(如果不写默认到/etc/init.d/找name相同的脚本);
  start:订制启动命令
  stop:停止命令
  restart:订制重启命令
  status:状态信息获取命令
  file(管理文件、目录、符号连接、生成文件内容、管理文件权限、管理文件属性、通过source属性到制定位置下载文件、通过recurse属性来获取整个目录)
  常用属性:
  ensure:目标状态present,absent,file,directory
  backup:通过filebucket资源来备份文件;对应值通常问filebucket资源名称;
  content:文件内容,生成方式有三种(content,source,target),这三种互斥仅能使用一种;
  source:通过指定的url下载文件至本地;获取方式通常为puppet url,格式puppet:///modules/MODULES_NAME/file_names;
  target:为符号链接指定目标;
  links:文件为符号链接(follow|manage);
  path:文件路径,注意必须使用双引号;
  mode:定义权限;
  owner:属主;
  group:属组;
  force:强制执行删除文件、连接、或目录,因此该属性仅用于ensure为absent时;
  purge:清空指定目录中存在,但未在资源中定义的文件;
  recurse:用于目录递归,值true,false,inf,remote
  replace:替换;如果本地存在的文件与资源中指定的文件内容不同时是否执行替换,默认为否;
  #####示例:
[root@l-mem-test2 tmp]# cat test3.pp  
file {'abc4.txt':
  
    ensure  => present,
  
    content => "hello puppet",
  
    path    => "/tmp/abc4.txt",
  
}
  
file {'fstab.symbolic':
  
    ensure  => present,
  
    target  => "/etc/fstab",
  
    path    => "/tmp/fstab.symbolic",
  
    links  => follow,
  
}
  
[root@l-mem-test2 tmp]# ls -l |grep fstab
  
lrwxrwxrwx. 1 root root   10 1月   5 18:27 fstab.symbolic -> /etc/fstab
  exec(执行命令,通常在不得不用时才使用,通常用于完成puppet自身无法完成的功能):
  常用属性:
  command:要执行的命令,通常为命令的完成路径;
  path:命令搜索路径;
  group:以谁为属主执行;
  user:以谁为属主执行;
  onlyif:0,表示仅在命令状态返回值为0时才执行此命令;
  refresh:接收到其他资源的通知时,重新执行此命令;
  refreshonly:仅当被以来的资源发生改变时,才被触发;
  tries:尝试次数,默认为1;
  try_sleep;尝试次数大于1时的时间间隔;
  ####示例:
[root@l-mem-test2 tmp]# cat test4.pp  
exec {'echo command':
  
    command => 'touch /tmp/tmp.xxx',
  
    path    => '/bin:/sbin:/usr/bin:/usr/sbin'
  
}
  
[root@l-mem-test2 tmp]# puppet apply test4.pp
  
notice: /Stage[main]//Exec[echo command]/returns: executed successfully
  
notice: Finished catalog run in 0.09 seconds
  
[root@l-mem-test2 tmp]# ls |grep tmp
  
tmp.xxx
  group管理系统上的用户组:
  常用属性:
  ensure:目标状态 present,absent
  name:组名
  gid:GID
  system:系统组
  ###示例:
[root@l-mem-test2 tmp]# cat group.pp  
group {'testgrp':
  
    ensure => present,
  
    gid    => 1001,
  
}
  
[root@l-mem-test2 tmp]# puppet apply group.pp
  
notice: /Stage[main]//Group[testgrp]/ensure: created
  
notice: Finished catalog run in 0.53 seconds
  
[root@l-mem-test2 tmp]# tail /etc/group|grep test
  
testgrp:x:1001:
  user管理用户:
  常用属性:
  ensure:目标状态
  uid:UID
  name:用户名
  system:是不是系统用户
  home:家目录
  shell:
  gid:用户组id
  password:密码(要是用加密后的密码串)
  managehome:是否创建家目录 ture,false
  ###示例:
user {'testuser':  
    ensure  => present,
  
    gid     => 1001,
  
    uid     => 1001,
  
    home    => '/home/test',
  
    shell   => '/bin/tcsh',
  
    password => '$1$25fb0f71$M3Ny.rWQjSy.mOcONDEO9.',
  
    managehome => true,
  
}
  cron定义周期性任务:
  常用属性:
  ensure:目标状态present absent
  command:命令或脚本
  environment:运行时的环境变量
  hour
  minute
  month
  monthday
  weekday
  name:名字
  user:运行时的用户身份(默认为root)
  ###示例:
[root@l-mem-test2 tmp]# cat cron.pp  
cron {'ntpdate':
  
    ensure => present,
  
    command => '/usr/sbin/ntpdate time.nist.gov',
  
    minute => '*/3',### 每三分钟,只定义分钟,其他可以省略
  
}
  
[root@l-mem-test2 tmp]# crontab -l
  
# HEADER: This file was autogenerated at Fri Jan 06 00:15:11 +0800 2017 by puppet.
  
# HEADER: While it can still be managed manually, it is definitely not recommended.
  
# HEADER: Note particularly that the comments starting with 'Puppet Name' should
  
# HEADER: not be deleted, as doing so could cause duplicate cron jobs.
  
# Puppet Name: ntpdate
  
*/3 * * * * /usr/sbin/ntpdate time.nist.gov
  3、元参数与资源引用
资源引用:  
Type['title']  #type开通字母大写
  
例如:
  
Package['httpd']
  属性中的特殊属性
  1、name(都有,一般不写调用title)
  2、ensure
  3、元参数
  用于定于资源间的依赖关系,及应用次序,通知机制;
require:  
package {'nginx':
  
ensure => present,
  
}
  
service {'nginx':
  
ensure => true,
  
enable => true,
  
require => Package['nginx'],   ### 表示该服务依赖 package
  
}
  
## 另一种写法:
  
before
  
package {'nginx':
  
ensure => present,
  
before => Service['nginx']
  
}
  
service {'nginx':
  
ensure => true,
  
enable => true,
  
}
  notify,subscribe 通知与订阅 同require和before一个意思 一个写在前面一个写在后面
[root@l-mem-test2 tmp]# cat test5.pp  
file {'/tmp/tt.txt':
  
    ensure => present,
  
    content => "hello",
  
}
  
exec {'monitor':
  
    command => 'echo "/tmp/tt.txt changed">>/tmp/monitor.txt',
  
    subscribe => File['/tmp/tt.txt'],### 订阅了资源
  
    refreshonly => true,## 检查文件改变时重新执行
  
    path     => "/bin:/sbin:/usr/bin:/use/sbin/",## 给echo定义path路径
  
}
  资源间的应用次序链
  "->"用于定义次序链,而"~>"用于定于通知链
  例如:nginx先安装软件包在操作nginx配置文件,当nginx配置文件改变时通知service服务启动
package{"nginx":ensure => present,} ->  
file {'nginx.conf': ensure => present,} ~>
  
service {'nginx':
  
ensure => running,
  
enable => true,
  
}
  4、puppet变量
  a、puppet变量:
  (1)、名称必须以“$”开头,赋值操作符为“=”
  (2)、任何正常数据类型(非正则)的值都可以赋予puppet中的变量,如字符串、数值、布尔值、数组、hash以及特殊的undef值(即变量未被赋值)
  (3)、puppet的每个变量都有2个名字,简短名称和长格式完全限定名称(FQN),完全限定名称格式为“$scope::variable”
  b、puppet分为哪几种?
  (1)、自定义变量
  (2)、facter变量
  (3)、内置变量:
  agent:$environment、$clientcert、$clientversion
  master:$serverip,$serverversion,$servername
  c、puppet变量的数据类型:
  1、字符型
  非结构化的文本字符串,可以使用双引号,也可以不用;
  单引号中的变量不会被替换,而双引号中的能够替换变量
  字符型值也支持使用转移符 例如“\n”
  2、数值型
  可为整数或浮点数,不过puppet只有在数值上下文才能把数值当数值型对待,其他情况一律以字符串处理
  3、数组
  数组值为中括号"[]"中的以逗号分隔的项目列表,最后一个项目后面可以有逗号
  数组中的元素可以为任意可用数据类型,包含hash或其他数组
  数组索引为从0开始的整数,也可以使用负数索引。
  4、布尔型
  true和false,不能加引号
  if语句的测试条件和比较表达式都会返回布尔型值
  另外其他数据类型也可自动转换为布尔型,如空字符串为false等。
  5、undef
  未被声明的变量的值类型undef
  也可以手动为某变量赋予undef,即直接使用不加引号的undef字符串。
  6、hash
  即为外键值数据类型,建和值之间使用“=>”分隔,建值对儿定义在“{}”中,彼此间以逗号分隔
  其建为字符型数据,而值可以为puppet支持的任意数据类型
  访问hash类型的数据元素要使用“键”当做索引进行
  7、正则表达式
  属于puppet的非标准数据类型,不能复制给变量,仅能用于有限的几个接受正则表达式的地方,即接受使用“=~”及“!~”匹配操作符的位置,通常包括case语句中的selector,以及节点名称匹配的位置;
  它们不能传递给函数或用于资源属性的定义;
  puppet中的正则表达式支持使用(?<ENABLED OPTION>:<SUBPATTERN)和(?-<DISENABLED OPTION>:<SUBPATTERN)2个特殊符号
  例如下面的实例表示做正则表达式匹配时已用选项“i”(忽略字符大小写),但不支持使用"m"(把.当做换行符)和"x"(忽略模式中的空白字符和注释)
  $packages = $operatingsystem ? {
  /(?i-mx:ubuntu|debian)/=> 'apache2',   ### ?固定格式,i启动忽略大小写,禁用吧.当做换行符,启用忽略模式中的空白字符和注释
  /(?i-mx:centos|fedora|redhat)/ => 'httpd',
  }
  ###示例:自定义变量
[root@l-mem-test2 tmp]# cat test7.pp  
$pkgname='haproxy'
  
package {$pkgname:## 注意:title可不用引号,或使用双引号,不能使用单引号
  
    ensure => present,
  
}
  
[root@l-mem-test2 tmp]# rpm -q haproxy
  
package haproxy is not installed
  
[root@l-mem-test2 tmp]# puppet apply test7.pp  -v
  
info: Applying configuration version '1483605620'
  
notice: /Stage[main]//Package[haproxy]/ensure: created
  
notice: Finished catalog run in 7.32 seconds
  
[root@l-mem-test2 tmp]# rpm -q haproxy
  
haproxy-1.5.4-3.el6.x86_64
  例子factor变量:
[root@l-mem-test2 tmp]# cat test8.pp  
file {'/tmp/issue.test':
  
    ensure  => file,
  
    content => $operatingsystem,
  
}
  
[root@l-mem-test2 tmp]# cat issue.test
  
CentOS
  5、常见的变量操作符
  常用操作符:
比较操作符  
== 等于
  
!= 不等于
  
<
  
>
  
<=
  
>=
  
=~ 正则匹配
  
!~ 不匹配
  
in 是否存在某个集合中
  
布尔操作符
  
and
  
or
  
!
  
运算操作符
  
+
  
-
  
*
  
/
  
<< 左移位
  
>> 右移位
  6、puppet的条件表达式
  (1、)if语句
单分之  
if 1>3 {
  
}
  
       双分之
  
if 1>2{
  
}
  
else{
  
}
  
多分支
  
if 1>2{
  
}elsif 1>3{
  
}else{
  
}
  if的条件
  变量:有值为真,无值为假, 未定义变量也为假
  表达式: 大于、小于、等于、不等于 可以嵌套
  函数:支持函数
  ###示例1:
[root@l-mem-test2 tmp]# cat test10.pp  
if $operatingsystem =~ /^(?i-mx:(centos|redhat|fedora))/{
  
    notice ("Welcome to $1 system.")
  
}
  
[root@l-mem-test2 tmp]# puppet apply test10.pp
  
notice: Scope(Class[main]): Welcome to CentOS system.
  
notice: Finished catalog run in 0.02 seconds
  ###示例2:
[root@l-mem-test2 tmp]# cat test11.pp  
if $operatingsystem == 'CentOS'{
  
    notify {'centos':message => "welcome to CentOS system.",}
  
}elsif $operatingsystem == 'RedHat'{
  
    notify {'redhat':message => "welcome to RedHat system.",}
  
}else{
  
    notify {'other':message => "welcome to the system",}
  
}
  (2)、case语句(匹配第一个满足的执行就结束)
  语法:
case CONTORL_EXPRESS{  
case2:{xx}
  
case1,case4: {xxx}
  
case2,case5:{xxx}
  
/^(Debian|Ubuntu)$/:{notice{"welcome to $1 system"}}  ## 可基于正则匹配,用引用$1
  
default:{xxx}
  
}
  case语句的条件
  可是一个值
  可以是变量
  可以使表达式
  可以使函数
  (3)、selectors语句
  跟case语句很像,但区别是case直接返回一个动作,而selectors返回一个值
  语法:
CONTORL_VARIABLE ? {  
case1 => value1
  
case2 => value2
  
...
  
defalut => valueN
  
}
  ###示例:
[root@l-mem-test2 tmp]# cat test12.pp  
$webserver = $operatingsystem ? {
  
    /^(?i-mx:centos|fedora|redhat)/ => 'httpd',
  
    /^(?i-mx:ubutu|debian)/ => 'apache',
  
}
  
$webprovider = $operatingsystem ? {
  
    /^(?i-mx:centos|fedora|redhat)/ => 'yum',
  
    /^(?i-mx:ubutu|debian)/ => 'apt',
  
}
  
package {"$webserver":
  
    ensure => present,
  
    provider => $webprovider,
  
}
  
上边的例子表示 $operationgsystem匹配如果是 ubuntu或者是debian那么 值是apache2,最后再将apache2赋值给$webserver
  7、puppet的类class

  (1)、概述:puppet类(为了通用目的或目标组织在一起的一个或多个资源;只有调用才能执行,声明才能被使用),使用 include>  ###示例1:
[root@l-mem-test2 tmp]# cat test13.pp  
class nginx {
  
    package {'httpd':
  
        ensure => present,
  
    }
  
    service {'httpd':
  
        ensure => true,
  
        require => Package['httpd'],
  
    }
  
}
  
# 常用的两种方式
  
#include nginx              # 第一种声明方式
  
class {'nginx':}            # 第二种声明方式
  
[root@l-mem-test2 tmp]# puppet apply test13.pp
  
notice: /Stage[main]/Nginx/Package[httpd]/ensure: created
  
notice: /Stage[main]/Nginx/Service[httpd]/ensure: ensure changed 'stopped' to 'running'
  
notice: Finished catalog run in 10.06 seconds
  (2)、带参数的类:
  格式:
class my_class (para1='val1',para2='val2'){  
... puppet code ...
  
}
  ###示例:
class myql ($user = 'mysql',$port = 3306){  
...
  
}
  
class {'mysql':
  
user = mysqlserver,     #给user赋值,不给port赋值则使用默认值3306
  
}
  ###示例:
[root@l-mem-test2 tmp]# cat test14.pp  
$webserver = $operatingsystem ?{
  
    /^(?i-mx:redhat|centos|fedora)/ => "httpd",
  
    /^(?i-mx:ubuntu|debian)/ => "apache2",
  
}
  
class httpd ($pkgname = 'apache2'){
  
    package {"$pkgname":
  
        ensure => present,
  
    }
  
    service {"$pkgname":
  
        ensure => true,
  
        require => Package["$pkgname"],
  
    }
  
}
  
class {"httpd":
  
    pkgname => $webserver,
  
}
  
执行:
  
[root@l-mem-test2 tmp]# puppet apply test14.pp -v
  
info: Applying configuration version '1483693735'
  
notice: /Stage[main]/Httpd/Package[httpd]/ensure: created
  
notice: /Stage[main]/Httpd/Service[httpd]/ensure: ensure changed 'stopped' to 'running'
  
notice: Finished catalog run in 10.27 seconds
  
[root@l-mem-test2 tmp]# rpm -q httpd
  
httpd-2.2.15-55.el6.centos.2.x86_64
  
[root@l-mem-test2 tmp]# netstat -lntup|grep 80
  
tcp        0      0 :::80                       :::*                        LISTEN      23133/httpd
  (3)、类的继承及清单的导入:
class C_NAME inherits PARENG_CALSS_NAME{  
}
  子类的命名方式:nginx::rproxy#父类::子类
  基类:安装nginx
  子类1:提供web配置的配置文件
  子类2:提供反向代理的配置文件
  ###示例:
[root@l-mem-test2 tmp]# cat test15.pp  
class httpd {                 ### 定义基类
  
    package {"httpd":
  
        ensure => present,
  
    }
  
}
  
class httpd::rproxy inherits httpd{              ## 定义子类 httpd::rproxy inherits 父类 #固定格式
  
    file {'/tmp/qw.conf':
  
        ensure => file,
  
        source => "/tmp/xxx.conf",
  
        notify => Service['httpd'],
  
    }
  
    service {'httpd':
  
        ensure => true,
  
    }
  
}
  
class httpd::web inherits httpd{
  
    file {'/tmp/qw.conf':
  
        ensure => file,
  
        source => "/tmp/xxxweb.conf",
  
        notify => Service['httpd'],
  
    }
  
    service {'httpd':
  
        ensure => true,
  
    }
  
}
  清单的导入:
[root@l-mem-test2 tmp]# cat node.pp  
import "/tmp/test15.pp"                   ## 导入清单
  
include httpd::rproxy                     ## 声明
  ------ 执行
[root@l-mem-test2 tmp]# puppet apply node.pp -v  
info: Applying configuration version '1483695028'
  
info: FileBucket adding {md5}2cb3f4eea6c0334eb8bca787e704622b
  
info: /Stage[main]/Httpd::Rproxy/File[/tmp/qw.conf]: Filebucketed /tmp/qw.conf to puppet with sum 2cb3f4eea6c0334eb8bca787e704622b
  
notice: /Stage[main]/Httpd::Rproxy/File[/tmp/qw.conf]/content: content changed '{md5}2cb3f4eea6c0334eb8bca787e704622b' to '{md5}6de9439834c9147569741d3c9c9fc010'
  
info: /Stage[main]/Httpd::Rproxy/File[/tmp/qw.conf]: Scheduling refresh of Service[httpd]
  
notice: /Stage[main]/Httpd::Rproxy/Service[httpd]: Triggered 'refresh' from 1 events
  
notice: Finished catalog run in 0.61 seconds
  
[root@l-mem-test2 tmp]# cat qw.conf
  
xxx
  8、模块
  为了实现某种完备功能而组织成一个独立的,自我包含的目录结构:模块
  总结:模块是目录结构,目录名称即为模块名
  注意:模块名称以小写字母开头,但不能使用main或settings作为模块名。
  目录结构:
/tmp/modules/  
    nginx/
  
    files/           :文件存储目录
  
        nginx.conf
  
    manifests/:清单存储目录
  
        init.pp         #必须有的 必须包含且只能包含与模块同名的类
  
        nginx.pp     # 每个清单通常只包含一个类,其他清单不能包含模块名的类
  
        ...
  
    templates/       :模板存放目录
  
        *.erb
  
    lib/:ruby插件存储目录用于实现自定义功能,一般很少用到

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-544953-1-1.html 上篇帖子: centos6下puppet3.x安装和部署 下篇帖子: 深入浅出Puppet(一)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表