Puppet เป็น software ที่ผลิตโดย Puppet Labs เพื่อช่วยเพิ่มความสะดวกให้การทำงานของผู้ดูแลระบบในการจัดการ configuration และ software สำหรับ server เครื่องต่างๆ รวมทั้งยังสามารถช่วยลดเวลาการทำงานในส่วนงานที่มีการดำเนินการซ้ำๆ เนื่องจาก puppet สามารถดึงข้อมูลเพื่อดำเนินการโดยอัตโนมัติ

Puppet แบ่งออกเป็น 2 ประเภท คือ Puppet Enterprise และ open source Puppet โดยมีการใช้งานอย่างแพร่หลายบน Linux, UNIX และ Windows สำหรับในบทความนี้ จะนำเสนอการติดตั้ง puppet 4 บน CentOS 7 ซึ่งสามารถติดตั้งบน Cloud ของ HostPacific ได้

โครงสร้างของ puppet ประกอบด้วย

1) Puppet master server

  • ใช้งานจำนวน 1 เครื่อง
  • Spec server ขั้นต่ำที่ต้องการใช้งานคือ CPU 2 core และ Memory 1 GB
  • มีการใช้งานผ่าน port 8140

2) Puppet agent server

  • สามารถเปิดใช้งานได้มากกว่า 1 เครื่อง ซึ่งหากมีการใช้งานจำนวนเครื่องที่เพิ่มมากขึ้น จำเป็นต้องมีการเพิ่ม spec ของ puppet master server เพื่อรองรับการเรียกใช้งานของ puppet agent server ที่เพิ่มขึ้น

ขั้นตอนการเตรียม server

สำหรับตัวอย่างของการติดตั้งครั้งนี้ จะประกอบด้วย Cloud จำนวน 3 เครื่อง คือ

Puppet master จำนวน 1 เครื่อง

  • example.com : 10.0.10.113
  • Spec เครื่องคือ CPU 2 core และ RAM 4 GB

Puppet agents จำนวน 2 เครื่อง

  • example.com : 10.0.10.114
  • example.com : 10.0.10.115
  • Spec เครื่องคือ CPU 2 core และ RAM 2 GB

โดยดำเนินการทั้ง 3 ขั้นตอนดังต่อไปนี้ที่ server ทั้ง 3 เครื่อง

Build Cloud

โดยใช้ CentOS 7 สำหรับ server ทั้ง 3 เครื่อง update package เบื้องต้นต่างๆ ให้เรียบร้อย โดยใช้คำสั่ง

# yum -y update

ติดตั้ง NTP

NTP หรือ network time protocol คือ protocol ที่ใช้สำหรับปรับเทียบเวลา ระหว่างอุปกรณ์ computer ผ่านทางเครือข่าย internet ซึ่งให้บริการผ่าน protocol UDP ที่ port 123 เมื่อลงเซิร์ฟเวอร์ใหม่ ควรปรับเวลาให้ตรงทุกครั้ง เพราะการทำงานบางอย่างอาศัยการอิงเวลามาตรฐาน หากเวลาในเครื่องไม่ตรง การทำงานอาจคลาดเคลื่อนได้

#ตรวจสอบ time zone ที่รองรับ
#timedatectl list-timezones

#กำหนดค่า time zone สำหรับ server
#timedatectl set-timezone Asia/Bangkok

#เริ่มติดตั้ง
#yum -y install ntp

#เทียบเวลา
#ntpdate th.pool.ntp.org

 

กำหนด server สำหรับใช้เทียบเวลา โดยเลือกใช้ server pool ของ Asia (ด้านล่างนี้) แทน server กลุ่มเดิม

#vi /etc/ntd.conf

…

server 0.asia.pool.ntp.org
server 1.asia.pool.ntp.org
server 2.asia.pool.ntp.org
server 3.asia.pool.ntp.org

…

#Restart service เนื่องจากมีการแก้ไขค่า configuration และกำหนดค่า enable เพื่อให้ start 
เมื่อมีการ reboot server #systemctl restart ntpd #systemctl enable ntpd

 

ตรวจสอบ Private FQDN (Fully qualified domain name)

เนื่องจาก puppet จะมีการส่งการร้องขอค่าระหว่างเครื่อง master node และ agent node ดังนั้นเครื่องที่ต้องการใช้งานในระบบ จึงต้องสามารติดต่อผ่าน FQDN ได้  สำหรับตัวอย่างนี้ จะเลือกกำหนดที่ไฟล์ hostname ของ server แต่ละเครื่อง ดังนี้

#vi /etc/hosts

127.0.0.1          localhost
10.0.10.113      masterpp.example.com
10.0.10.114      node1pp.example.com
10.0.10.115      node2pp.example.com

หรืออาจสร้าง DNS server เพื่อรองรับการใช้งานในส่วนนี้ได้

ติดตั้ง Puppet master

สำหรับ puppet master server (master node) จะเป็นเครื่องควบคุม configuration ต่างๆ เพื่อให้เครื่อง puppet agent เรียกไปใช้งาน

#ติดตั้ง repository ของ puppet
#rpm -ivh https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm

#ติดตั้ง puppetserver
#yum -y install puppetserver
#systemctl start puppetserver
#systemctl enable puppetserver

ติดตั้ง Puppet agent

puppet agent (agent node) จะสามารถติดตั้งได้บน Linux, Unix และ Windows สำหรับขั้นตอนนี้จะทำการติดตั้งที่ puppet agent จำนวน 2 เครื่อง

#ติดตั้ง repository ของ puppet
3rpm -ivh https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm

#ติดตั้ง puppet-agent
3yum -y install puppet-agent

#เพิ่มค่าของ puppet master ในส่วนของ agent
#vi /etc/puppetlabs/puppet/puppet.conf
..

[agent]
    server = masterpp.example.com
..
#systemctl start  puppet
#systemctl enable  puppet

การยืนยัน certificate ของเครื่อง agent node และ master node

ก่อนเริ่มต้นการใช้งานสำหรับเครื่อง agent node นั้น ขั้นตอนแรกต้องดำเนินการสร้างค่า SSL certificate เพื่อใช้ในการยืนยันการติดต่อ และยืนยันตัวตนกับ master node ก่อนที่จะทำการส่งข้อมูลอื่นๆ ต่อไป โดยขั้นตอนนี้ต้องดำเนินการที่ agent node ทุกเครื่อง

Agent NodeX # /opt/puppetlabs/bin/puppet resource service puppet ensure=running enable=true

Notice: /Service[puppet]/ensure: ensure changed 'stopped' to 'running'
service { 'puppet':
  ensure => 'running',
  enable => 'true',
}

Agent NodeX # /opt/puppetlabs/bin/puppet agent --test --ca_server=masterpp.example.com

Info: Caching certificate for ca
Info: csr_attributes file loading from /etc/puppetlabs/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for node1pp.example.com
Info: Certificate Request fingerprint (SHA256): 05:78:4A:96:10:8E:96:1B:F6:3B:48:52:65:3B:82:
3F:2A:D2:C7:4B:FE:F7:51:5F:0B:14:A5:7E:3F:34:2A:2B Info: Caching certificate for ca Exiting; no certificate found and waitforcert is disabled

เมื่อดำเนินการที่ agent node ทั้ง 2 เครื่องเรียบร้อยแล้ว ให้ตรวจสอบที่ master node โดยสั่งให้แสดงค่าการร้องขอจาก agent node

Master Node # /opt/puppetlabs/bin/puppet cert list
  "node1pp.example.com" (SHA256) 05:78:4A:96:10:8E:96:1B:F6:3B:48:52:65:3B:82:3F:2A:D2:C7:4B
:FE:F7:51:5F:0B:14:A5:7E:3F:34:2A:2B   "node2pp.example.com" (SHA256) 51:83:69:AE:1E:A8:E0:BA:D2:BE:F2:DB:94:29:6C:6A:B9:4E:E6:7A
:A7:09:9C:79:FF:72:1E:01:F1:45:D2:20

ยืนยันการร้องขอ

Master Node # /opt/puppetlabs/bin/puppet cert sign node1pp.example.com

Notice: Signed certificate request for node1pp.example.com
Notice: Removing file Puppet::SSL::CertificateRequest node1pp.example.com at 
'/etc/puppetlabs/puppet/ssl/ca/requests/node1pp.example.com.pem' Master Node # /opt/puppetlabs/bin/puppet cert sign node2pp.example.com Notice: Signed certificate request for node2pp.example.com Notice: Removing file Puppet::SSL::CertificateRequest node2pp.example.com at
'/etc/puppetlabs/puppet/ssl/ca/requests/node2pp.example.com.pem'

หากต้องการยกเลิก สามารถดำเนินการได้ด้วยคำสั่ง

Master Node # /opt/puppetlabs/bin/puppet cert clean [HOSTNAME]

จากคำสั่งนี้จะสถานะของ certificate ที่เกี่ยวข้อง

Master Node # /opt/puppetlabs/bin/puppet cert list --all

+ "masterpp.example.com" (SHA256) EA:04:08:C9:2F:EC:FE:18:52:B0:A8:5B:4C:4A:69:8E:F0:18:C5:A0
:7F:4F:3C:57:4F:5B:72:53:CB:AB:23:29 (alt names: "DNS:puppet", "DNS:masterpp.example.com") + "node1pp.example.com"  (SHA256) 7A:A6:B4:96:45:DB:1F:61:92:F0:0F:30:15:71:D0:22:B3:31:37:98
:6A:A8:9C:1E:B9:F9:66:65:C2:48:85:89 + "node2pp.example.com"  (SHA256) D2:88:98:53:A0:95:FA:C8:56:B1:2C:02:4B:DC:C7:99:12:07:2F:0F
:E8:53:C8:99:CF:E2:C8:89:0B:F6:9B:A7

หากมีการยืนยัน certificate เรียบร้อยแล้วจะแสดงค่าขึ้นต้นด้วยเครื่องหมาย ‘+’  แต่หาก certificate ไม่ถูกต้องหรือถูกยกเลิกจะแสดงค่าขึ้นต้นด้วยเครื่องหมาย ‘-’

ส่วนประกอบพื้นฐานสำหรับ puppet

หลังจากที่ได้ติดตั้งส่วนของ software ต่างๆ เรียบร้อยแล้ว สำหรับส่วนต่อไปจะกล่าวถึงส่วนประกอบ สำหรับการเขียนชุดคำสั่ง และการสร้างไฟล์ต่างๆ ที่เครื่อง master node เพื่อกำหนดการทำงานของ agent node

  1. Manifest file

สำหรับส่วนแรกที่จะกล่าวถึงคือ ไฟล์ manifest

Manifest คือ ไฟล์ที่เก็บชุดคำสั่งต่างๆ ของ puppet ที่เครื่อง master node เพื่อให้ agent node อ่านค่าและนำไปดำเนินการจัดการตามคำสั่ง โดยไฟล์ manifest จะเป็นไฟล์ที่มีนามสกุล .pp และมีไฟล์หลักที่เรียกใช้งานที่ /etc/puppetlabs/code/environments/production/manifests/site.pp

  1. Resource type

Resource type คือส่วนของการประกาศค่าตัวแปรและฟังก์ชั่น เพื่อบอกให้ระบบทราบว่าต้องดำเนินการส่วนใด โดยจะเป็นการกำหนดค่าต่างๆ ลงในไฟล์ manifest

รูปแบบของการประกาศค่า เช่น

resource_type { ‘resource_name’
     attribute => value
}

ตัวอย่างเช่น

# resource type คือ cron , resource title คือ logrotate

cron { 'logrotate':     
  command => '/usr/sbin/logrotate',
  user    => 'root',
  hour    => 2,
  minute  => 0,
}

สามารถตรวจสอบค่า resource type เพิ่มเติมได้ด้วยคำสั่ง

# puppet resource --help
  1. Class

Class คือ การรวมกันของกลุ่ม code ต่างๆ ซึ่งสามารถเรียกใช้งานผ่านไฟล์ manifest ทั้งนี้เมื่อต้องการใช้งานบางกลุ่มคำสั่งบ่อยๆ สามารถกำหนดเป็น class และเรียกใช้งานผ่าน class ได้แทนการเขียน code กลุ่มเดิมซ้ำ

รูปการกำหนด class

class example_class {
   code
   …
}

เมื่อต้องการเรียกใช้งาน class จะต้องมีการประกาศค่า ซึ่งแบ่งออกเป็น 2 ประเภทคือ

การประกาศ class แบบทั่วไป คือ การประกาศก่อนเรียนใช้งานในไฟล์ manifest การประการเช่นนี้จะส่งผลให้ทุกส่วนในไฟล์ manifest สามารถเรียกใช้งานได้

include example_class

และ การประกาศ class แบบ resource-like คือการประกาศก่อนเรียนใช้งานในไฟล์ manifest ซึ่งจะเป็นการนำส่วนประการวางใน resource ดังนั้นจะส่งผลให้สามารถใช้งานได้เฉพาะบางส่วนเท่านั้น

class { ‘example_class’ : }
  1. Facts

Fact คือ การแสดงค่าข้อมูล global ที่เกี่ยวข้องกับระบบ เช่น operating system, network interface เราสามารถ run คำสั่งนี้ได้ทั้ง master node และ agent node

/opt/puppetlabs/bin/facter
  1. Module

Module คือ การรวบรวมไฟล์ manifest และ ข้อมูลไฟล์อื่นๆ ที่เกี่ยวข้อง เพื่อนำไปใช้งาน เช่น puppetlabs-apache, puppetlabs-mysql เป็นต้น โดยข้อมูล model ของ puppet จะอยู่ที่ path : /etc/puppetlabs/code/environments/production/modules

 

เริ่มต้นการใช้งาน Puppet

ตัวอย่างที่ 1 เริ่มต้นการสร้างไฟล์ manifest เพื่อทดสอบการทำงานระหว่างเครื่อง master node และ agent node

#ตรวจสอบไฟล์

[node1pp]# ls -ld /tmp/testfile
ls: cannot access /tmp/testfile: No such file or directory

[node2pp]# ls -ld /tmp/testfile
ls: cannot access /tmp/testfile: No such file or directory

#เพิ่มคำสั่งด้านล่างนี้เข้าไปที่ไฟล์ /etc/puppetlabs/code/environments/production/manifests/site.pp

[masterpp]# vi /etc/puppetlabs/code/environments/production/manifests/site.pp
file {'/tmp/testfile':
       ensure => present,
       mode => '0644',
       content => "This is test file created using puppet.\nHere is my public IP: 
${ipaddress_eth0}.\n", }

การทำงานของเครื่อง agent node นั้นจะมีการเรียกมาที่ master node ทุกๆ 30 นาที เพื่อตรวจสอบค่า configuration หรือชุดคำสั่งว่ามีการเปลี่ยนแปลงหรือแก้ไขเพิ่มเติมหรือไม่ เพื่อนำคำสั่งต่างๆ ไปดำเนินการที่เครื่อง agent node ต่อไป

กรณีที่ต้องการตรวจสอบการทำงานทันทีโดยไม่ต้องรอให้ครบรอบ 30 นาที สามารถทำได้โดยการ run คำสั่งด้านล่างนี้ที่เครื่อง agent node ทั้ง 2 เครื่อง

ตัวอย่างการ run ที่ node1pp

[node1pp]# /opt/puppetlabs/bin/puppet agent --test
Info: Using configured environment 'production'
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Loading facts
Info: Caching catalog for node1pp.example.com
Info: Applying configuration version '1464841755'
Notice: /Stage[main]/Main/File[/tmp/testfile]/ensure: defined content as 
'{md5}adcc53938018b0b082b8a8c7522da693' Notice: Applied catalog in 0.05 seconds # ตรวจสอบผลการทำงานหลังจากที่มีการ run คำสั่งทั้ง 2 เครื่องแล้ว [node1pp]# cat /tmp/testfile This is test file created using puppet. Here is my public IP: 10.0.10.114. [node2pp]# cat /tmp/testfile This is test file created using puppet. Here is my public IP: 10.0.10.115.

จากตัวอย่างนี้แสดงว่า node1pp และ node2pp agent node สามารถติดต่อ masterpp mode เพื่อนำชุดคำสั่งจากไฟล์ manifest มาทำงานที่เครื่อง agent node ได้เรียบร้อย

ตัวอย่างที่ 2 ทดสอบสร้างไฟล์ manifest โดยกำหนดให้สามารถเรียกใช้งานได้เฉพาะ node1pp เท่านั้น

โดยกำหนดไฟล์ site.php ตามคำสั่งด้านล่างนี้

[masterpp]# vi /etc/puppetlabs/code/environments/production/manifests/site.pp

node 'node1pp' {
    file {'/tmp/testnode':
        ensure => present,
        mode => '0644',
        content => "This is test file created using puppet for node1pp.\n 
Here is my public IP: ${ipaddress_eth0}.\n",     } } node default {} # เมื่อบันทึกไฟล์เรียบร้อย สามารถทดสอบการทำงานได้ดังนี้ [node1pp]# /opt/puppetlabs/bin/puppet agent --test Info: Using configured environment 'production' Info: Retrieving pluginfacts Info: Retrieving plugin Info: Loading facts Info: Caching catalog for node1pp.example.com Info: Applying configuration version '1464843823' Notice: /Stage[main]/Main/Node[node1pp]/File[/tmp/testnode]/ensure: defined content as
'{md5}8ee89dd791228c84d05c16a42d609862' Notice: Applied catalog in 0.05 seconds [node1pp]# cat  /tmp/testnode This is test file created using puppet for node1pp.
Here is my public IP: 10.0.10.114. # พบว่า node1pp มีการสร้างไฟล์ตามที่กำหนด [node2pp]# /opt/puppetlabs/bin/puppet agent --test Info: Using configured environment 'production' Info: Retrieving pluginfacts Info: Retrieving plugin Info: Loading facts Info: Caching catalog for node2pp.example.com Info: Applying configuration version '1464843913' Notice: Applied catalog in 0.03 seconds [node2pp ~]#  ls -ld /tmp/testnode ls: cannot access /tmp/testnode: No such file or directory # และ node2pp ไม่มีการสร้างไฟล์

ตัวอย่างที่ 3 เนื่องจาก puppet community มี module มากมายเพื่อให้เลือกใช้งาน สำหรับตัวอย่างนี้จะเป็นติดตั้ง module และสร้างไฟล์ manifest เพื่อติดตั้ง apache, mariadb, php และสร้างไฟล์ php สำหรับ agent node

ติดตั้ง module apache

[masterpp]# /opt/puppetlabs/bin/puppet module install puppetlabs-apache

ติดตั้ง module สำหรับ mariadb (ผู้ติดตั้งสามารถเลือกติดตั้ง module อื่นๆ เพื่อใช้งาน mariadb ได้)

[masterpp]# /opt/puppetlabs/bin/puppet puppet module install yguenane-mariadbrepo

สร้างไฟล์ php.conf ตามด้านล่างนี้ เพื่อให้ agent node นำไฟล์ configuration ไปใช้งาน

[masterpp]# vi /etc/puppetlabs/code/environments/production/modules/apache/files/php.conf
LoadModule php5_module modules/libphp5.so

<FilesMatch \.php
gt;     SetHandler application/x-httpd-php </FilesMatch> AddType text/html.php 
DirectoryIndex index.php

บันทึกไฟล์ให้เรียบร้อย

กำหนดไฟล์ site.php ตามคำสั่งด้านล่างนี้

[masterpp]# vi /etc/puppetlabs/code/environments/production/manifests/site.pp
## สั่งให้ทำการ 'yum update'
exec { 'yum':                                    
   command => '/usr/bin/yum -y update'  
}

## ติดตั้ง httpd สำหรับ node1pp
node 'node1pp' {  
    class { 'apache': }                                    
        apache::vhost { 'node1pp.example.com':  
        port    => '80',
        docroot => '/var/www/html'
    }
}

## ติดตั้ง httpd สำหรับ node2pp
node 'node2pp' {
   # install httpd package
   class { 'apache': }                                        
        apache::vhost { 'node2pp.example.com':  
        port    => '80',
        docroot => '/var/www/html'
    }
}

###########################

## ติดตั้ง MariaDB

class {'mariadbrepo':
   version => '10.0',
}

include mariadb

class mariadb {
   ## ติดตั้ง
   package {'MariaDB-server':
        ensure => installed,
   }
   ## กำหนดให้ start service
   service { 'mysql':
        ensure => running,
        enable => true,
   }
}

## กำหนดให้มีการใช้งาน password : StorangPassword

exec { "mysqlpasswd":
   command => "/usr/bin/mysqladmin -u root password StorangPassword",
   require => Package["MariaDB-server"],
}

###########################

exec { 'httpd':
   command => '/usr/bin/systemctl restart httpd', 
   require => Package['php'],
}

# ติดตั้ง php5

package { 'php':
   ensure => installed,
   require => Package['httpd'],
}

# นำไฟล์ /etc/puppetlabs/code/environments/production/modules/apache/files/php.conf ไปใช้งาน

file { "/etc/httpd/conf.d/php.conf":
   notify => Service['httpd'],
   ensure => present,
   source => 'puppet:///modules/apache/php.conf',
   owner => 'root',
   group => 'root',
}

# ทดสอบสร้างไฟล์

file { '/var/www/html/index.php':
   ensure => file,
   content => '<?php echo "<p align=\'center\'> <font size=\'6pt\'>node2pp.example.com 
</font>"; ?>',       owner => 'apache',    group => 'apache',    require => Package['httpd'], } file { '/var/www/html/info.php':    ensure => file,    content => '<?php  phpinfo(); ?>',    # phpinfo code    owner => 'apache',    group => 'apache',    require => Package['httpd'], }

เมื่อบันทึกไฟล์เรียบร้อย สามารถทดสอบการทำงานได้ดังนี้ (จะแสดงตัวอย่างผลการทดสอบเฉพาะเครื่อง node2pp เท่านั้น เนื่องจาก ได้ผลการทำงานเช่นเดียวกัน)

ตรวจสอบการทำงาน

[node2pp]# /opt/puppetlabs/bin/puppet agent --test

จะพบว่าเครื่อง node2pp มีการติดตั้ง httpd เรียบร้อย

[node2pp]#  httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built:   May 12 2016 10:27:23

[node2pp]# head -12 /etc/httpd/conf/httpd.conf
# Security
ServerTokens OS
ServerSignature On
TraceEnable On
ServerName "node2pp.example.com"
ServerRoot "/etc/httpd"
PidFile run/httpd.pid
Timeout 120
KeepAlive Off
MaxKeepAliveRequests 100
KeepAliveTimeout 15
…

ทดสอบใช้งาน mariadb ด้วย password ที่มีการกำหนดในไฟล์ manifest ก่อนหน้า

[node2pp]# mysql -V
mysql  Ver 15.1 Distrib 10.0.25-MariaDB, for Linux (x86_64) using readline 5.1

[node2pp]# mysql --password= StorangPassword
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 11
Server version: 10.0.25-MariaDB MariaDB Server
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

ทดสอบการใช้งาน web โดยการลองเรียก http://node2pp.example.com

หรือ http://node2pp.example.com/info.php

 

ข้อสรุป

จากการทดสอบใช้งาน puppet เบื้องต้น ผ่าน master และ agent node ด้วย puppet code ทั้งจากไฟล์ manifest และการใช้งาน module จะเห็นได้ว่า puppet สามารถนำไปประยุกต์ เพื่อเพิ่มความสะดวกให้กับผู้ดูแลระบบในการดำเนินการกับ server ต่างๆ ในความดูแลได้เพิ่มมากขึ้น เนื่องจากผู้ดูแลระบบสามารถปรับ หรือแก้ไขไฟล์ configuration ที่เครื่อง puppet master node ก็จะสามารถกระจายการงานที่ต้องการส่งไปยังเครื่อง puppet agent node ต่างๆ ได้

ข้อมูลเพิ่มเติม