Sử dụng Puppet Modules để tạo một LAMP Stack

Các mô-đun Puppet là các khối xây dựng của máy chủ do Puppet quản lý của bạn. Các mô-đun cài đặt và cấu hình các gói, tạo thư mục và tạo bất kỳ thay đổi máy chủ nào khác mà người dùng đưa vào mô-đun. Một mô-đun Puppet nhằm mục đích thực hiện tất cả các phần của một tác vụ nhất định, chẳng hạn như tải xuống gói Apache, cấu hình tất cả các tệp, thay đổi dữ liệu MPM và thiết lập máy chủ ảo. Các mô-đun, đến lượt mình, được chia thành các lớp là .ppcác tệp nhằm đơn giản hóa mô-đun thành nhiều tác vụ khác nhau và cải thiện khả năng đọc của mô-đun cho bất kỳ người dùng nào trong tương lai.

Trong hướng dẫn này, bạn sẽ tạo một mô-đun Apache và một mô-đun PHP. Một mô-đun MySQL sẽ được điều chỉnh từ mô-đun MySQL của Puppet Lab có trên Puppet Forge . Các bước này sẽ tạo một ngăn xếp LAMP đầy đủ trên máy chủ của bạn và cung cấp tổng quan về các cách khác nhau để sử dụng các mô-đun.

Trước khi bạn bắt đầu

Thiết lập một Puppet Master (Ubuntu 18.04) và hai tác nhân Puppet (Ubuntu 18.04 và CentOS 7) bằng cách làm theo các bước trong hướng dẫn Bắt đầu với Puppet – Cài đặt và thiết lập cơ bản .

Tạo mô-đun Apache

1.Từ Puppet Master, điều hướng đến thư mục mô-đun của Puppet và tạo thư apachemục:

cd /etc/puppetlabs/code/environments/production/modules/ sudo mkdir apache

2.Từ bên trong apachethư mục, tạo các thư mục manifeststemplatesfiles, và examples:

cd apache sudo mkdir {manifests,templates,files,examples}

3.Điều hướng đến thư manifestsmục:

cd manifests

Từ đây, mô-đun sẽ được tách thành các lớp, dựa trên mục tiêu của phần mã cụ thể đó. Trong trường hợp này, sẽ có một init.pplớp để tải xuống gói Apache, một params.pptệp để xác định bất kỳ biến và tham số nào, config.ppđể quản lý bất kỳ tệp cấu hình nào cho chính dịch vụ Apache và một vhosts.pptệp để xác định máy chủ ảo. Mô-đun này cũng sẽ sử dụng dữ liệu Hiera để lưu trữ các biến cho mỗi nút.

Tạo lớp Apache ban đầu và các tham số

1.Từ bên trong manifeststhư mục, tạo một init.pptệp để chứa apachelớp. Lớp này sẽ chia sẻ tên của nó với tên mô-đun. Tệp này sẽ được sử dụng để cài đặt gói Apache. Vì Ubuntu 18.04 và CentOS 7 sử dụng các tên gói khác nhau cho Apache, nên một biến sẽ được sử dụng:

class apache {

  package { 'apache':
    name    => $apachename,
    ensure  => present,
  }

}

Tài packagenguyên cho phép quản lý một gói. Điều này được sử dụng để thêm, xóa hoặc đảm bảo một gói hiện diện. Trong hầu hết các trường hợp, tên của tài nguyên ( apache, ở trên) phải là tên của gói đang được quản lý. Tuy nhiên, do sự khác biệt trong quy ước đặt tên, tài nguyên này chỉ được gọi là , trong khi tênapache thực tế của gói được gọi bằng tham chiếu. , trong trường hợp này, gọi đến biến chưa xác định . Tham chiếu đảm bảo rằng gói là .namename$apachenameensurepresent

Tạo params.ppvà thêm đoạn mã sau:

class apache::params {

  if $::osfamily == 'RedHat' {
    $apachename   = 'httpd'
  }
  elsif $::osfamily == 'Debian' {
      $apachename   = 'apache2'
  }
  else {
    fail ( 'this is not a supported distro.')
  }

}

Bên ngoài init.pplớp gốc, mỗi tên lớp cần phải phân nhánh từ apache. Do đó, lớp này được gọi là apache::params. Tên sau dấu hai chấm kép phải chia sẻ tên với tệp.

Một ifcâu lệnh được sử dụng để xác định các tham số, lấy thông tin do Facter cung cấp , đã được cài đặt trên máy chủ Puppet. Trong trường hợp này, Facter sẽ được sử dụng để kéo xuống họ hệ điều hành ( osfamily), để phân biệt xem nó dựa trên Red Hat hay Debian.

Ghi chú: Trong thời gian của hướng dẫn này, khi cần thêm một cái gì đó vào danh sách tham số, các biến cần thiết cho Red Hat và Debian sẽ được cung cấp, nhưng mã mở rộng sẽ không được hiển thị. params.ppCó thể xem bản sao đầy đủ tại đây .

3.Với các tham số cuối cùng được xác định, chúng ta cần gọi tệp params.ppvà các tham số vào init.pp. Để làm điều này, các tham số cần được thêm vào sau tên lớp, nhưng trước dấu ngoặc nhọn mở ( {):

class apache (
  $apachename   = $::apache::params::apachename,
) inherits ::apache::params {

Chuỗi giá trị $::apache::params::valueyêu cầu Puppet lấy các giá trị từ các apachemô-đun, paramslớp, theo sau là tên tham số. Đoạn mã inherits ::apache::paramscho phép init.ppkế thừa các giá trị này.

Quản lý tập tin cấu hình

Tệp cấu hình Apache sẽ khác nhau tùy thuộc vào việc bạn đang làm việc trên hệ thống dựa trên Red Hat hay Debian. Bạn có thể xem các tệp này tại đây: httpd.conf (Red Hat) , apache2.conf (Debian) .

1.Sao chép nội dung của httpd.confvà apache2.confvào các tệp riêng biệt và lưu chúng vào filesthư mục nằm tại /etc/puppetlabs/code/environments/production/modules/apache/files.

2.Cả hai tệp đều cần được chỉnh sửa để vô hiệu hóa keepalive. Bạn sẽ cần thêm dòng vào KeepAlive Offtệp httpd.conf. Nếu bạn không muốn thay đổi cài đặt này, hãy thêm chú thích vào đầu mỗi tệp:

# This file is managed by Puppet

3.Thêm các tệp này vào tệp init.ppđể Puppet biết chúng nằm ở đâu trên cả máy chủ chính và các nút tác nhân. Để thực hiện việc này, tài filenguyên được sử dụng:

file { 'configuration-file':
  path    => $conffile,
  ensure  => file,
  source  => $confsource,
}

Vì tệp cấu hình nằm ở hai vị trí khác nhau nên tài nguyên được đặt tên chung configuration-filevới đường dẫn tệp được xác định là tham số có paththuộc tính . ensuređảm bảo rằng đó là một tệp. sourcecung cấp vị trí trên máy chủ Puppet của các tệp được tạo ở trên.

4.Mở params.pptệp. Các biến $conffilevà $confsourcecần được định nghĩa trong ifcâu lệnh:

if $::osfamily == 'RedHat' {

...

  $conffile     = '/etc/httpd/conf/httpd.conf'
  $confsource   = 'puppet:///modules/apache/httpd.conf'
}
elsif $::osfamily == 'Debian' {

...

  $conffile     = '/etc/apache2/apache2.conf'
  $confsource   = 'puppet:///modules/apache/apache2.conf'
}
else {

...

Các tham số này cũng cần được thêm vào phần đầu của apachekhai báo lớp trong init.pptệp, tương tự như ví dụ trước. init.ppBạn có thể xem bản sao đầy đủ của tệp tại đây để tham khảo.

5.Khi tệp cấu hình được thay đổi, Apache cần phải khởi động lại. Để tự động hóa việc này, tài servicenguyên có thể được sử dụng kết hợp với notifythuộc tính, sẽ gọi tài nguyên để chạy bất cứ khi nào tệp cấu hình được thay đổi:

file { 'configuration-file':
  path    => $conffile,
  ensure  => file,
  source  => $confsource,
  notify  => Service['apache-service'],
}

service { 'apache-service':
  name          => $apachename,
  hasrestart    => true,
}

Tài servicenguyên sử dụng tham số đã tạo sẵn để xác định tên Apache trên hệ thống Red Hat và Debian. Thuộc hasrestarttính sẽ kích hoạt khởi động lại dịch vụ đã xác định.

Tạo các tập tin máy chủ ảo

Tùy thuộc vào bản phân phối hệ thống của bạn, các tệp máy chủ ảo sẽ được quản lý khác nhau. Do đó, mã cho máy chủ ảo sẽ được bao bọc trong một ifcâu lệnh, tương tự như câu lệnh được sử dụng trong params.pplớp nhưng chứa các tài nguyên Puppet thực tế. Điều này sẽ cung cấp một ví dụ về cách sử dụng thay thế ifcác câu lệnh trong mã của Puppet.

1.Từ trong thư apache/manifests/mục, tạo và mở một vhosts.pptệp. Thêm khung của ifcâu lệnh:

class apache::vhosts {

  if $::osfamily == 'RedHat' {

  } elsif $::osfamily == 'Debian' {

  } else {

  }

}

2.Vị trí của tệp virtual hosts trên máy chủ CentOS 7 của chúng tôi là /etc/httpd/conf.d/vhost.conf. Tệp này sẽ cần được tạo dưới dạng mẫu trên Puppet master. Cũng cần thực hiện tương tự đối với tệp virtual hosts của Ubuntu, nằm tại /etc/apache2/sites-available/example.com.conf, thay thế example.combằng FQDN của máy chủ. Điều hướng đến templatestệp trong apachemô-đun, sau đó tạo hai tệp cho máy chủ ảo của bạn:

Đối với hệ thống Red Hat:

<VirtualHost *:80>
    ServerAdmin	<%= @adminemail %>
    ServerName <%= @servername %>
    ServerAlias www.<%= @servername %>
    DocumentRoot /var/www/<%= @servername -%>/public_html/
    ErrorLog /var/www/<%- @servername -%>/logs/error.log
    CustomLog /var/www/<%= @servername -%>/logs/access.log combined
</Virtual Host>

Đối với hệ thống Debian:

<VirtualHost *:80>
    ServerAdmin	<%= @adminemail %>
    ServerName <%= @servername %>
    ServerAlias www.<%= @servername %>
    DocumentRoot /var/www/html/<%= @servername -%>/public_html/
    ErrorLog /var/www/html/<%- @servername -%>/logs/error.log
    CustomLog /var/www/html/<%= @servername -%>/logs/access.log combined
    <Directory /var/www/html/<%= @servername -%>/public_html>
        Require all granted
    </Directory>
</Virtual Host>

Chỉ có hai biến được sử dụng trong các tệp này: adminemailvà servername. Chúng sẽ được định nghĩa theo từng nút trong site.pptệp.

3.Quay lại vhosts.pptệp. Các mẫu đã tạo bây giờ có thể được tham chiếu trong mã:

class apache::vhosts {

  if $::osfamily == 'RedHat' {
    file { '/etc/httpd/conf.d/vhost.conf':
      ensure    => file,
      content   => template('apache/vhosts-rh.conf.erb'),
    }
  } elsif $::osfamily == 'Debian' {
    file { "/etc/apache2/sites-available/$servername.conf":
      ensure  => file,
      content  => template('apache/vhosts-deb.conf.erb'),
    }
  } else {
      fail('This is not a supported distro.')
  }

}

Cả hai họ phân phối đều gọi đến filetài nguyên và lấy tên của vị trí máy chủ ảo trên bản phân phối tương ứng. Đối với Debian, điều này một lần nữa có nghĩa là tham chiếu đến giá $servernametrị. contentThuộc tính gọi đến các mẫu tương ứng.

Ghi chú: Các giá trị chứa biến, chẳng hạn như tên của tài nguyên tệp Debian ở trên, cần được đặt trong dấu ngoặc kép ( "). Bất kỳ biến nào trong dấu ngoặc đơn ( ') đều được phân tích cú pháp chính xác như đã viết và sẽ không kéo vào một biến.

4.Cả hai tệp máy chủ ảo đều tham chiếu đến hai thư mục không có trên hệ thống theo mặc định. Chúng có thể được tạo thông qua việc sử dụng tài filenguyên, mỗi thư mục nằm trong ifcâu lệnh. vhosts.confTệp hoàn chỉnh sẽ giống như sau:

class apache::vhosts {

  if $::osfamily == 'RedHat' {
    file { '/etc/httpd/conf.d/vhost.conf':
      ensure    => file,
      content   => template('apache/vhosts-rh.conf.erb'),
    }
    file { [ '/var/www/$servername',
             '/var/www/$servername/public_html',
             '/var/www/$servername/log', ]:
      ensure    => directory,
    }
  } elsif $::osfamily == 'Debian' {
    file { "/etc/apache2/sites-available/$servername.conf":
      ensure  => file,
      content  => template('apache/vhosts-deb.conf.erb'),
    }
    file { [ '/var/www/$servername',
             '/var/www/$servername/public_html',
             '/var/www/$servername/logs', ]:
      ensure    => directory,
    }
  } else {
    fail ( 'This is not a supported distro.')
  }

}

Kiểm tra và chạy mô-đun

1.Từ trong thư apache/manifests/mục, hãy chạy lệnh puppet parsertrên tất cả các tệp để đảm bảo mã hóa Puppet không có lỗi:

sudo /opt/puppetlabs/bin/puppet parser validate init.pp params.pp vhosts.pp

Kết quả sẽ là rỗng, trừ khi có vấn đề gì xảy ra.

2.Điều hướng đến examplesthư mục trong apachemô-đun. Tạo một init.pptệp và bao gồm các lớp đã tạo. Thay thế các giá trị cho $servernamevà $adminemailbằng giá trị của riêng bạn:

$serveremail = 'webmaster@example.com'
$servername = 'example.com'

include apache
include apache::vhosts

3.Kiểm tra mô-đun bằng cách chạy puppet applyvới --noopthẻ:

sudo /opt/puppetlabs/bin/puppet apply --noop init.pp

Nó sẽ không trả về lỗi nào và đầu ra sẽ kích hoạt làm mới từ các sự kiện. Để cài đặt và cấu hình apache trên Puppet master, có thể chạy lại mà không cần --noop, nếu muốn.

4.Quay lại thư mục Puppet chính rồi đến thư manifestsmục ( không phải thư mục nằm trong mô-đun Apache).

cd /etc/puppetlabs/code/environments/production/manifests

Nếu bạn đang tiếp tục hướng dẫn này từ hướng dẫn Bắt đầu với Puppet – Cài đặt và thiết lập cơ bản , bạn sẽ có một site.pptệp đã được tạo. Nếu chưa, hãy tạo một tệp ngay bây giờ.

5.Mở site.ppvà bao gồm mô-đun Apache cho mỗi nút tác nhân. Cũng nhập các biến cho các tham số adminemailvà servername. Nếu bạn đã làm theo hướng dẫn Bắt đầu với Puppet – Cài đặt và thiết lập cơ bản , cấu hình một nút đơn trong đó site.ppsẽ giống như sau:

node 'ubuntuhost.example.com' {
  $adminemail = 'webmaster@example.com'
  $servername = 'hostname.example.com'

  include accounts
  include apache
  include apache::vhosts

  resources { 'firewall':
    purge => true,
  }

  Firewall {
    before        => Class['firewall::post'],
    require       => Class['firewall::pre'],
  }

  class { ['firewall::pre', 'firewall::post']: }

  }

node 'centoshost.example.com' {
  $adminemail = 'webmaster@example.com'
  $servername = 'hostname.example.com'

  include accounts
  include apache
  include apache::vhosts

  resources { 'firewall':
    purge => true,
  }

  Firewall {
    before        => Class['firewall::post'],
    require       => Class['firewall::pre'],
  }

  class { ['firewall::pre', 'firewall::post']: }

  }

    

Nếu bạn không làm theo hướng dẫn Bắt đầu với Puppet – Cài đặt và thiết lập cơ bản , thì site.pptệp của bạn sẽ giống như ví dụ sau:

node 'ubupuppet.ip.linodeusercontent.com' {
  $adminemail = 'webmaster@example.com'
  $servername = 'hostname.example.com'

  include apache
  include apache::vhosts

  }

node 'centospuppet.ip.linodeusercontent.com' {
  $adminemail = 'webmaster@example.com'
  $servername = 'hostname.example.com'

  include apache
  include apache::vhosts

  }
        

6.Theo mặc định, dịch vụ tác nhân Puppet trên các nút được quản lý của bạn sẽ tự động kiểm tra với máy chủ sau mỗi 30 phút và áp dụng bất kỳ cấu hình mới nào từ máy chủ. Bạn cũng có thể gọi thủ công quy trình tác nhân Puppet giữa các lần chạy tác nhân tự động. Để chạy thủ công mô-đun mới trên các nút tác nhân của bạn, hãy đăng nhập vào các nút và chạy:

sudo /opt/puppetlabs/bin/puppet agent -t

Sử dụng Mô-đun MySQL

Nhiều mô-đun cần thiết để chạy máy chủ đã tồn tại trong Puppet Forge của Puppet Labs . Chúng có thể được cấu hình chi tiết như một mô-đun mà bạn đã tạo và có thể tiết kiệm thời gian vì mô-đun không cần phải được tạo từ đầu.

Đảm bảo bạn đang ở trong /etc/puppetlabs/code/environments/production/modulesthư mục và cài đặt mô-đun MySQL của Puppet Forge của PuppetLabs. Thao tác này cũng sẽ cài đặt bất kỳ mô-đun tiên quyết nào.

cd /etc/puppetlabs/code/environments/production/modules
sudo /opt/puppetlabs/bin/puppet module install puppetlabs-mysql

Sử dụng Hiera để tạo cơ sở dữ liệu

Trước khi bạn bắt đầu tạo các tệp cấu hình cho mô-đun MySQL, hãy cân nhắc rằng bạn có thể không muốn sử dụng cùng một giá trị trên tất cả các nút tác nhân. Để cung cấp cho Puppet dữ liệu chính xác cho mỗi nút, Hiera được sử dụng. Trong trường hợp này, bạn sẽ sử dụng mật khẩu gốc khác nhau cho mỗi nút, do đó tạo ra các cơ sở dữ liệu MySQL khác nhau.

1.Điều hướng đến /etc/puppetvà tạo tệp cấu hình Hiera hiera.yamltrong thư mục chính puppet. Bạn sẽ sử dụng các giá trị mặc định của Hiera:

---
version: 5
hierarchy:
  - name: Common
    path: common.yaml
defaults:
  data_hash: yaml_data
  datadir: data

2.Tạo file common.yaml. File này sẽ được sử dụng để xác định rootmật khẩu mặc định cho MySQL:

mysql::server::root_password: 'password'

Tệp common.yamlđược sử dụng khi một biến không được định nghĩa ở nơi khác. Điều này có nghĩa là tất cả các máy chủ sẽ chia sẻ cùng một mật khẩu gốc MySQL. Những mật khẩu này cũng có thể được băm để tăng tính bảo mật.

3.Để sử dụng các giá trị mặc định của mô-đun MySQL, bạn chỉ cần thêm một include '::mysql::server'dòng vào site.pptệp. Tuy nhiên, trong ví dụ này, bạn sẽ ghi đè một số giá trị mặc định của mô-đun để tạo cơ sở dữ liệu cho từng nút của mình. Chỉnh sửa site.pptệp với các giá trị sau:

node 'ubupuppet.ip.linodeusercontent.com' {
  $adminemail = 'webmaster@example.com'
  $servername = 'hostname.example.com'

  include apache
  include apache::vhosts
  include php

  mysql::db { "mydb_${fqdn}":
    user     => 'myuser',
    password => 'mypass',
    dbname   => 'mydb',
    host     => $::fqdn,
    grant    => ['SELECT', 'UPDATE'],
    tag      => $domain,
  }

}

node 'centospuppet.ip.linodeusercontent.com' {
  $adminemail = 'webmaster@example.com'
  $servername = 'hostname.example.com'

  include apache
  include apache::vhosts
  include mysql::server
  include php

  mysql::db { "mydb_${fqdn}":
    user     => 'myuser',
    password => 'mypass',
    dbname   => 'mydb',
    host     => $::fqdn,
    grant    => ['SELECT', 'UPDATE'],
    tag      => $domain,
  }

 }
    

4.Bạn có thể chạy các bản cập nhật này theo cách thủ công trên từng nút bằng cách SSH vào từng nút và đưa ra lệnh sau:

 sudo /opt/puppetlabs/bin/puppet agent -t

Nếu không, dịch vụ tác nhân Puppet trên các nút được quản lý của bạn sẽ tự động kiểm tra với máy chủ chính sau mỗi 30 phút và áp dụng mọi cấu hình mới từ máy chủ chính.

Tạo Module PHP

1.Tạo phpthư mục trong /etc/puppetlabs/code/environments/production/modulesđường dẫn và tạo các thư mục filesmanifeststemplates, và examplessau đó:

sudo mkdir php
cd php
sudo mkdir {files,manifests,examples,templates}

2.Tạo init.pp. Tệp này sẽ sử dụng packagetài nguyên để cài đặt PHP. Hai gói sẽ được cài đặt: Gói PHP và kho lưu trữ ứng dụng và tiện ích mở rộng PHP. Thêm nội dung sau vào tệp của bạn:

class php {

  package { 'php':
    name: $phpname,
    ensure: present,
  }

  package { 'php-pear':
    ensure: present,
  }

}

3.Thêm include phpvào máy chủ trong sites.pptệp của bạn:

    node 'ubupuppet.ip.linodeusercontent.com' {
      $adminemail = 'webmaster@example.com'
      $servername = 'hostname.example.com'

      include apache
      include apache::vhosts
      include mysql::database
      include php

      }

    node 'centospuppet.ip.linodeusercontent.com' {
      $adminemail = 'webmaster@example.com'
      $servername = 'hostname.example.com'

      include apache
      include apache::vhosts
      include mysql::database
      include php

      }
    

4.Chạy lệnh sau trên các nút tác nhân của bạn để kéo bất kỳ thay đổi nào vào máy chủ của bạn.

sudo /opt/puppetlabs/bin/puppet agent -t

Nếu không, dịch vụ tác nhân Puppet trên các nút được quản lý của bạn sẽ tự động kiểm tra với máy chủ chính sau mỗi 30 phút và áp dụng mọi cấu hình mới từ máy chủ chính.

Bây giờ bạn sẽ có một ngăn xếp LAMP hoạt động đầy đủ trên mỗi nút do Puppet quản lý.

Nguồn: https://www.linode.com/docs/guides/use-puppet-modules-to-create-a-lamp-stack-ubuntu-18-04-master/