Introductio ad PUPUS

Puppet est systema administrationis configurationis. Ad configurandos hospites adhibetur ut statum desideratum attingant et conservent.

Plus quam quinque annos cum Puppet laboro. Hic textus est essentialiter collectio punctorum praecipuorum ex documentis officialibus conversa et reordinata, destinata ad adiuvandos novos ut celeriter essentiam Puppet comprehendant.

Introductio ad PUPUS

Notitiae fundamentales

Puppet in basi clientis et servitoris operatur, quamquam versio sine servitore cum functionibus limitatis etiam sustinetur.

Exemplar "pull" (vel "extraction") adhibetur: clientes configurationem a servo singulis semihoris petunt eamque applicant. Si cum Ansible laboravisti, exemplar diversum, "push" (vel "push"), adhibet: administrator processum applicationis configurationis initiat; clientes nihil per se applicant.

Communicatio interretialis encryptionem TLS bidirectionalem utitur: et servus et cliens suas claves privatas et certificata correspondentes habent. Typice, servus certificata clientibus emittit, sed usus CA externi etiam possibilis est.

Introductio ad Manifesta

In terminologia marionettarum ad servum pupae coniungere nodi (nodi). Configuratio nodorum scribitur in manifestis in lingua programmandi speciali - Puppet DSL.

Puppet DSL est lingua declarativa. Statum desideratum nodi describit per declarationem singularum opum, exempli gratia:

  • Fasciculus exstat et contenta certa habet.
  • Fasciculus installatus est.
  • Servitium inceptum est.

Opes inter se conexae esse possunt:

  • Sunt dependentiae quae ordinem quo opes adhibentur afficiunt.
    Exempli gratia, "primum fasciculum instala, deinde fasciculum configurationis muta, et tum servitium incipe."
  • Sunt notificationes - si res mutatur, notificationes ad res ei subscriptas mittit.
    Exempli gratia, si fasciculus configurationis mutatur, ministerium sponte denuo incipi potest.

Praeterea, Puppet DSL functiones et variabiles, necnon operatores conditionales et selectores, continet. Etiam varias machinas exemplarium, ut EPP et ERB, sustinet.

Puppet lingua Ruby scriptum est, ita multae structurae et terminologia inde mutuantur. Ruby permittit Puppet extendi, permittens additionem logicae complexae, novarum generum opum, et functionum.

Cum Puppet currit, manifesta pro singulis nodis in servo in directorium componuntur. Directory — est index opum et earum nexuum post computationem valoris functionum, variabilium, et expansionem conditionalium.

Syntaxis et stilus codicis

Hic sunt nonnullae partes documentorum officialium quae te adiuvare possunt ad syntaxin intellegendam si exempla data non sufficiunt:

Exemplum manifesti hic est:

# Комментарии пишутся, как и много где, после решётки.
#
# Описание конфигурации ноды начинается с ключевого слова node,
# за которым следует селектор ноды — хостнейм (с доменом или без)
# или регулярное выражение для хостнеймов, или ключевое слово default.
#
# После этого в фигурных скобках описывается собственно конфигурация ноды.
#
# Одна и та же нода может попасть под несколько селекторов. Про приоритет
# селекторов написано в статье про синтаксис описания нод.
node 'hostname', 'f.q.d.n', /regexp/ {
  # Конфигурация по сути является перечислением ресурсов и их параметров.
  #
  # У каждого ресурса есть тип и название.
  #
  # Внимание: не может быть двух ресурсов одного типа с одинаковыми названиями!
  #
  # Описание ресурса начинается с его типа. Тип пишется в нижнем регистре.
  # Про разные типы ресурсов написано ниже.
  #
  # После типа в фигурных скобках пишется название ресурса, потом двоеточие,
  # дальше идёт опциональное перечисление параметров ресурса и их значений.
  # Значения параметров указываются через т.н. hash rocket (=>).
  resource { 'title':
    param1 => value1,
    param2 => value2,
    param3 => value3,
  }
}

Indentatio et saltus linearum non sunt pars necessaria manifesti, sed commendatur. dux styleSummarium:

  • Spatia duplicia indentata, tabulae non adhibentur.
  • Uncinis crispis spatio separantur, duo puncta spatio non separantur.
  • Commata post singulos parametros, incluso ultimo. Quisque parametrus in linea separata est. Exceptio fit in casu ubi nulli parametri et unus parametri sunt: ​​eos in una linea et sine commate scribere potes (i.e. resource { 'title': } и resource { 'title': param => value }).
  • Sagittae in parametris eodem plano esse debent.
  • Sagittae relationum opum ante eas scriptae sunt.

Loca fasciculorum in PuppetServer

Ad ulteriorem explicationem, notionem "directorii radicis" introducam. Directorium radicis est directorium quod configurationem Puppet pro nodo specifico continet.

Directorium principale variat secundum versionem Puppet et utrum ambitus adhibeantur. Ambitus sunt configurationum series independentes in directoriis separatis repositae. Typice una cum git adhibentur, quo in casu ambitus ex ramis git creantur. Proinde, quisque nodus in ambitu specifico residet. Hoc in ipso nodo vel in ENC configuratur, quod in proximo articulo tractabo.

  • In tertia versione ("vetus Puppet") directorium basicum erat /etc/puppetUsus ambituum est facultativus—exempli gratia, eos non utimur cum vetere Puppet. Si ambitus adhibentur, plerumque servantur in /etc/puppet/environments, directorium principale erit directorium ambitus. Si ambitus non adhibentur, directorium principale erit directorium basis.
  • A quarta versione ("nova Puppet") incipiens, usus ambituum necessarius factus est, et directorium basicum translatum est ad... /etc/puppetlabs/codeProinde, ambitus servantur in /etc/puppetlabs/code/environments, directorium radicis - directorium ambitus.

Subdirectorium in directorio principali esse debet. manifests, quod unum vel plura manifesta cum descriptionibus nodorum continet. Praeterea, subdirectorium esse debet. modules, quae modulos continet. Quae sint moduli paulo post explicabo. Praeterea, vetus Puppet fortasse etiam subdirectorium habet. files, quae varia fascicula continet quae ad nodos copiamus. In novo Puppet, omnia fascicula ad modulos moventur.

Fasciculi manifesti extensionem habent .pp.

Exempla pauca pugnae

Descriptio nodi et opis in eo

In nodo server1.testdomain fasciculus creandus est /etc/issue cum contentis Debian GNU/Linux n lFasciculus ab usore et grege possideri debet. root, iura accessus esse debent 644.

Manifestum scribamus:

node 'server1.testdomain' {   # блок конфигурации, относящийся к ноде server1.testdomain
    file { '/etc/issue':   # описываем файл /etc/issue
        ensure  => present,   # этот файл должен существовать
        content => 'Debian GNU/Linux n l',   # у него должно быть такое содержимое
        owner   => root,   # пользователь-владелец
        group   => root,   # группа-владелец
        mode    => '0644',   # права на файл. Они заданы в виде строки (в кавычках), потому что иначе число с 0 в начале будет воспринято как записанное в восьмеричной системе, и всё пойдёт не так, как задумано
    }
}

Relationes opum in nodo

In nodo server2.testdomain `nginx` cum configuratione praeparata currere et operari debet.

Dissolvamus problema:

  • Sarcina instituenda est nginx.
  • Necesse est fasciculos configurationis e servo exscribere.
  • Servitium currere debet. nginx.
  • Si configuratio renovata est, servitium denuo incipiendum est.

Manifestum scribamus:

node 'server2.testdomain' {   # блок конфигурации, относящийся к ноде server2.testdomain
    package { 'nginx':   # описываем пакет nginx
        ensure => installed,   # он должен быть установлен
    }
  # Прямая стрелка (->) говорит о том, что ресурс ниже должен
  # создаваться после ресурса, описанного выше.
  # Такие зависимости транзитивны.
    -> file { '/etc/nginx':   # описываем файл /etc/nginx
        ensure  => directory,   # это должна быть директория
        source  => 'puppet:///modules/example/nginx-conf',   # её содержимое нужно брать с паппет-сервера по указанному адресу
        recurse => true,   # копировать файлы рекурсивно
        purge   => true,   # нужно удалять лишние файлы (те, которых нет в источнике)
        force   => true,   # удалять лишние директории
    }
  # Волнистая стрелка (~>) говорит о том, что ресурс ниже должен
  # подписаться на изменения ресурса, описанного выше.
  # Волнистая стрелка включает в себя прямую (->).
    ~> service { 'nginx':   # описываем сервис nginx
        ensure => running,   # он должен быть запущен
        enable => true,   # его нужно запускать автоматически при старте системы
    }
  # Когда ресурс типа service получает уведомление,
  # соответствующий сервис перезапускается.
}

Ut hoc functionet, necesse est ut fasciculi in servo puppet sic dispositi sint:

/etc/puppetlabs/code/environments/production/ # (это для нового Паппета, для старого корневой директорией будет /etc/puppet)
├── manifests/
│   └── site.pp
└── modules/
    └── example/
        └── files/
            └── nginx-conf/
                ├── nginx.conf
                ├── mime.types
                └── conf.d/
                    └── some.conf

Genera opum

Index completus generum opum sustentatarum inveniri potest in documentisHic quinque typos fundamentales describam, qui in mea praxi sufficiunt ad pleraque problemata solvenda.

file

Fasciculos, directoria, nexus symbolicos, eorum contenta, et iura accessus administrat.

options:

  • nomen opis — semita ad fasciculum (facultativa)
  • semita — semita ad fasciculum (si in nomine non specificatur)
  • ensure — genus fasciculi:
    • absent - lima delere
    • present - fasciculus cuiuslibet generis exsistere debet (si nullus fasciculus est, fasciculus regularis creabitur)
    • file - fasciculus regularis
    • directory — directorium
    • link — nexus symbolicus
  • content — contenta fasciculi (solum fasciculis regularibus apta, cum eis adhiberi non potest) principium aut scopum)
  • principium — indicium semitae unde contenta fasciculi exscribenda sunt (non potest una cum content aut scopum). Ut URI cum schema specificari potest. puppet: (tunc fasciculi e servo pupae utentur), necnon cum schemate http: (Spero perspicuum esse quid in hoc casu futurum sit), et etiam cum diagramma file: vel ut semita absoluta sine schemate (tum fasciculus ex FS locali in nodo adhibebitur)
  • scopum — quo nexus symbolicus monstrare debeat (non potest una cum content aut principium)
  • dominus — usor qui fasciculum possidere debeat
  • Group — coetus cui fasciculus pertinere debet
  • modum — permissiones fasciculorum (ut series litterarum)
  • recursus — recursivam directoriorum tractationem permittit
  • deiectionem - includit remotionem fasciculorum qui in Puppet non describuntur
  • vi, - directoriorum remotionem includit quae in Puppet non describuntur

sarcina

Fasciculos instituit et removet. Notitias tractare potest — fasciculum denuo instituit si parametrus specificatur. reinstallatio_in_renovatione.

options:

  • nomen opis — nomen fasciculi (facultativum)
  • nomine — nomen fasciculi (si in nomine non specificatur)
  • provisor — administrator fasciculorum qui adhibendus est
  • ensure — status desideratus fasciculi:
    • present, installed - quaelibet versio installata
    • latest — recentissima versio installata est
    • absent — deletum (apt-get remove)
    • purged — una cum fasciculis configurationis remota (apt-get purge)
    • held — versio fasciculi clausa est (apt-mark hold)
    • любая другая строка — versio specificata installata est
  • reinstallatio_in_renovatione - Si true, tum fasciculus iterum instituetur post notificationem acceptam. Hoc utile est distributionibus quae in fontibus nituntur, ubi fasciculos reconstruere fortasse necesse erit cum parametri constructionis mutantur. Per default false.

obsequium

Servitia administrat. Notitias tractare potest—servitium denuo incipit.

options:

  • nomen opis — servitium administrandum (facultativum)
  • nomine — servitium administrandum (si in nomine non specificatum est)
  • ensure — status servitii desideratus:
    • running — emissa
    • stopped - substitit
  • enable — facultatem servitium incipiendi moderatur:
    • true — initium automaticum activum est (systemctl enable)
    • mask - dissimulatus (systemctl mask)
    • false — initium automaticum inactivum est (systemctl disable)
  • sileo — mandatum ad servitium denuo incipiendum
  • Status — mandatum ad statum servitii inspiciendum
  • reinitiare — indica utrum initscript ministerii initium iterum incipere sustineat. Si false et parametrus specificatur sileo — valor huius parametri adhibetur. Si false et parametrum sileo non specificatum - ministerium intermittitur et ad iterum incipitur (sed in systemd mandatum adhibetur) systemctl restart).
  • status habet — indica utrum initscript ministerii mandatum sustineat status. si false, tum valor parametri adhibetur StatusPer default true.

exec

Mandata externa exsequitur. Si nulli parametri specificantur. creat,, tantum si, nisi aut renovatio tantum, mandatum quotiescumque Puppet currit curret. Notitias tractare et mandatum exsequitur.

options:

  • nomen opis — mandatum exsequendum (facultativum)
  • mandatum — mandatum exsequendum (si in nomine non specificatum est)
  • semita — semitae in quibus fasciculus executabilis quaeratur
  • tantum si - si mandatum in hoc parametro specificatum cum codice reditus nullo peractum est, mandatum principale exsequetur.
  • nisi - si mandatum in hoc parametro specificatum cum codice reditus non-nullo peractum est, mandatum principale exsequetur.
  • creat, - si fasciculus in hoc parametro specificatus non existit, mandatum principale exsequetur
  • renovatio tantum - Si true, tunc mandatum curretur tantum cum hoc exsecutor notificationem ab aliis opibus accipiet
  • defectio — directorium ex quo mandatum exsequendum est
  • Disputatio — usor a quo mandatum exsequendum est
  • provisor — quomodo mandatum exsequi:
    • posix - processus filius simpliciter creatur, necesse est specificare semita
    • testa — mandatum in testa curritur /bin/sh, omittere potes semita, globbing, pipes, et alias proprietates testae uti potes. Solet sponte detegi si ullae litterae speciales adsint (|, ;, &&, || et cetera).

cron

Munera coronata administrat.

options:

  • nomen opis - tantum identificatorium quoddam
  • ensure — status muneris coronati:
    • present - creare si non exstat
    • absent - dele si exstat
  • mandatum — quod mandatum exsequendum est
  • environment — in quo ambitu mandatum exsequendum sit (index variabilium ambitalium et earum valores per =)
  • Disputatio — quem usorem mandatum exsequi utendum est
  • momentum, hora, Canticum Benedictus, mensis, dies mensis — quando cron currendum est. Si quodlibet horum attributorum non specificatur, eius valor in crontab erit *.

In Puppet 6.0 cron tamquam ex arca remotus in puppetserver, ergo nulla documentatio in situ generali est. Sed... in arca est in puppet-agent, ergo non opus est separatim instituere. Documentationem eius hic invenire potes. in documentis pro quinta versione Pappetuel in GitHub.

De opibus in genere

Requisita singularitatis opum

Error frequentissimus quem offendimus est Declaratio duplicataHic error oritur cum duae pluresve opes eiusdem generis eodem nomine directorio adduntur.

Itaque iterum scribam: Manifesta unius nodi non debent continere opes eiusdem generis cum eodem nomine (titulo)!

Interdum fasciculos cum eodem nomine sed diversis administratoribus fasciculorum instituere necesse est. Hoc in casu, parametro uti debes. namead errorem vitandum:

package { 'ruby-mysql':
  ensure   => installed,
  name     => 'mysql',
  provider => 'gem',
}
package { 'python-mysql':
  ensure   => installed,
  name     => 'mysql',
  provider => 'pip',
}

Alia genera opum similes parametros habent ad duplicationem vitandam, name у obsequium, command у exec, et cetera.

Metaparametri

Cuique generi opum, cuiuscumque naturae sit, quosdam parametros speciales habet.

Index completus metaparametrorum in documentatione Puppet.

Brevis index:

  • require — hic parameter specificat a quibus opibus haec opes pendeant.
  • ante — hic parameter specificat quae opes ab hac ope pendent.
  • scribet — hic parameter specificat a quibus fontibus haec res notificationes accipiat.
  • certiorem — Hic parameter specificat quae opes notificationes ab hac ope accipiant.

Omnes metaparametri enumerati aut unum nexum opis aut seriem nexuum in uncinis quadratis accipiunt.

Nexus ad opes

Referentia ad opes simpliciter est referentia ad opes. Hae praecipue ad dependentias specificandas adhibentur. Referentia ad opes non existentes errorem compilationis causabit.

Syntaxis nexus haec est: genus opis littera capitali incipit (si nomen typi duplices duos punctos continet, quaeque pars nominis inter duos punctos capitalis scribitur), deinde nomen opis in uncinis quadratis sequitur (casus nominis non mutatur!). Spatia nulla esse debent, et uncini quadrati statim post nomen typi scribuntur.

exempli gratia:

file { '/file1': ensure => present }
file { '/file2':
  ensure => directory,
  before => File['/file1'],
}
file { '/file3': ensure => absent }
File['/file1'] -> File['/file3']

Dependentiae et Notificationes

Documentatio hic est.

Ut ante dictum est, simplices dependentiae inter opes transitivae sunt. Obiter, cave cum dependentias specificas — dependentias cyclicas creare potes, quae errorem compilationis causabunt.

Notificationes, dissimiles dependentiis, non sunt transitivae. Hae regulae ad notificationes pertinent:

  • Si res notificationem accipit, renovatur. Actiones renovationis a genere rei pendent: exec mandatum exsequitur, obsequium servitium denuo incipit, sarcina Fasciculum iterum instituit. Si fons actionem renovationis definitam non habet, nihil fit.
  • Res non plus quam semel per cursum Puppet renovatur. Hoc fieri potest quia notificationes dependentias includunt, et graphum dependentiarum sine cyclis est.
  • Si Puppet statum alicuius opis mutat, opes omnes opes ei subscriptas notificationes mittit.
  • Si res renovatur, notificationes ad omnes res ei subscriptas mittit.

Tractatio parametrorum non specificatorum

Regula generali est, si parametrus opis valorem implicitum non habet et hic parametrus in manifesto non specificatur, tum Pappet hanc proprietatem pro ope correspondenti in nodo non mutabit. Exempli gratia, si opes generis... file parametrus non specificatus owner, tum Pappet dominum fasciculi correspondentis non mutabit.

Introductio ad classes, variabiles, et definitiones

Dicamus nos habere plures nodos qui eandem partem configurationis habent, sed etiam differentias exstant - alioquin omnia uno blocco describere possemus. node {}Scilicet, easdem partes configurationis simpliciter exscribere potes, sed plerumque haec solutio mala est—configuratio crescit, et cum partem configurationis communem mutas, eandem rem in multis locis mutare debebis. Facile est errores facere, et principium DRY (noli te ipsum repetere) non frustra inventum est.

Ad hanc difficultatem solvendam, consilium exstat qualis est class.

classes

Класс — est segmentum nominatum codicis pupae. Classes necessariae sunt ad codicem iterum adhibendum.

Primum, classis describi debet. Ipsa descriptio nullas opes addit. Classis in manifestis describitur:

# Описание класса начинается с ключевого слова class и его названия.
# Дальше идёт тело класса в фигурных скобках.
class example_class {
    ...
}

Post hoc classis adhiberi potest:

# первый вариант использования — в стиле ресурса с типом class
class { 'example_class': }
# второй вариант использования — с помощью функции include
include example_class
# про отличие этих двух вариантов будет рассказано дальше

Exemplum ex opere praecedenti: institutionem et configurationem nginx in classem transferamus:

class nginx_example {
    package { 'nginx':
        ensure => installed,
    }
    -> file { '/etc/nginx':
        ensure => directory,
        source => 'puppet:///modules/example/nginx-conf',
        recure => true,
        purge  => true,
        force  => true,
    }
    ~> service { 'nginx':
        ensure => running,
        enable => true,
    }
}

node 'server2.testdomain' {
    include nginx_example
}

variables

Classis ex exemplo priori non admodum flexibilis est, quia semper eandem configurationem nginx affert. Faciamus iter configurationis variabile, ut haec classis ad nginx cum quavis configuratione instituendum adhiberi possit.

Fieri potest variabilibus utens.

Nota: variabiles in Puppet immutabiles sunt!

Praeterea, variabilis accedi potest tantum postquam declarata est, alioquin valor variabilis erit undef.

Exemplum operandi cum variabilibus:

# создание переменных
$variable = 'value'
$var2 = 1
$var3 = true
$var4 = undef
# использование переменных
$var5 = $var6
file { '/tmp/text': content => $variable }
# интерполяция переменных — раскрытие значения переменных в строках. Работает только в двойных кавычках!
$var6 = "Variable with name variable has value ${variable}"

Marionetta habet spatia nominum, et variabiles, proinde, habent ambitusVariabilis eodem nomine in diversis spatiis nominum definiri potest. Cum valor variabilis resolvitur, variabilis in spatio nominum currenti quaeritur, deinde in spatio nominum incluso, et sic porro.

Exempla spatii nominum:

  • globales - variabiles extra descriptionem classis vel nodi huc positae sunt;
  • spatium nominum nodi in descriptione nodi;
  • spatium nominum classis in descriptione classis.

Ad ambiguitatem vitandam cum variabili accedendo, spatium nominum in nomine variabilis specificare potes:

# переменная без пространства имён
$var
# переменная в глобальном пространстве имён
$::var
# переменная в пространстве имён класса
$classname::var
$::classname::var

Conveniamus viam ad configurationem nginx in variabili esse $nginx_conf_sourceTum classis hoc modo apparebit:

class nginx_example {
    package { 'nginx':
        ensure => installed,
    }
    -> file { '/etc/nginx':
        ensure => directory,
        source => $nginx_conf_source,   # здесь используем переменную вместо фиксированной строки
        recure => true,
        purge  => true,
        force  => true,
    }
    ~> service { 'nginx':
        ensure => running,
        enable => true,
    }
}

node 'server2.testdomain' {
    $nginx_conf_source = 'puppet:///modules/example/nginx-conf'
    include nginx_example
}

Exemplum autem datum problematicum est, quia quandam "scientiam secretam" de usu variabilis nomine quodam alicubi intra classem implicat. Multo aptius est hanc scientiam publicam facere — classes parametros habere possunt.

Parametri classis Hae sunt variabiles in spatio nominum classis; in capite classis definiuntur et sicut variabiles regulares in corpore classis adhiberi possunt. Valores parametrorum in manifesto specificantur cum classis adhibetur.

Parametro valorem implicitum assignari potest. Si parametro valorem implicitum non habet et valor non specificatur cum adhibetur, error compilationis fiet.

Давайте параметризуем класс из примера выше и добавим два параметра: первый, обязательный — путь к конфигурации, и второй, необязательный — название пакета с nginx (в Debian, например, есть пакеты nginx, nginx-light, nginx-full).

# переменные описываются сразу после имени класса в круглых скобках
class nginx_example (
  $conf_source,
  $package_name = 'nginx-light', # параметр со значением по умолчанию
) {
  package { $package_name:
    ensure => installed,
  }
  -> file { '/etc/nginx':
    ensure  => directory,
    source  => $conf_source,
    recurse => true,
    purge   => true,
    force   => true,
  }
  ~> service { 'nginx':
    ensure => running,
    enable => true,
  }
}

node 'server2.testdomain' {
  # если мы хотим задать параметры класса, функция include не подойдёт* — нужно использовать resource-style declaration
  # *на самом деле подойдёт, но про это расскажу в следующей серии. Ключевое слово "Hiera".
  class { 'nginx_example':
    conf_source => 'puppet:///modules/example/nginx-conf',   # задаём параметры класса точно так же, как параметры для других ресурсов
  }
}

In Puppet, variabiles typis describuntur. Sunt multa genera datorumTypiter genera datorum ad valores parametrorum classibus et definitionibus traditos validandos adhibentur. Si parametrus traditus typo specificato non congruit, error compilationis eveniet.

Typus statim ante nomen parametri scribitur:

class example (
  String $param1,
  Integer $param2,
  Array $param3,
  Hash $param4,
  Hash[String, String] $param5,
) {
  ...
}

Classes: include nomen classis contra classis {'nomen classis':}

Quaeque classis est fons generis genusUt cum quolibet alio genere opum, duae instantiae eiusdem classis in uno nodo esse non possunt.

Si bis classem eidem nodo addere conaris utens class { 'classname':} (sive eosdem sive diversos parametros habeant) errorem compilationis producet. Attamen, si classem in stilo opum uteris, omnes eius parametros ibi in manifesto explicite specificare potes.

Attamen, si uteris include, tum classis addi potest quotiescumque vis. Res est ut include — functio idempotens quae verificat utrum classis catalogo addita sit. Si classis in catalogo non est, eam addit, et si iam est, nihil agit. Sed in casu usus include Parametra classis dum ea declaratur specificare non potes — omnes parametri necessarii in fonte datorum externo, ut Hiera vel ENC, specificandi sunt. De his in proximo articulo disseremus.

Definit

Ut in sectione praecedenti dictum est, eadem classis plus quam semel in nodo adesse non potest. Attamen, interdum, necesse est eundem codicem cum parametris diversis in uno nodo applicare posse. Aliis verbis, genus opum proprium requiritur.

Exempli gratia, ad modulum PHP instituendum, nos apud Avito haec facimus:

  1. Fasciculum cum hoc modulo instituimus.
  2. Fasciculum configurationis pro hoc modulo creemus.
  3. Crea nexum symbolicum ad configurationem php-fpm.
  4. Crea nexum symbolicum ad configurationem pro PHP CLI.

In talibus casibus, consilium ut Definire (define, typus definitus, typus opis definitus). Definitio similis est classi, sed differentiae sunt: ​​primo, quaeque definitio est typus opis, non ops; secundo, quaeque definitio habet parametrum implicitum. $title, ubi nomen opis ponitur cum declaratur. Sicut cum classibus, definitio primum declaranda est antequam adhiberi possit.

Exemplum simplicius cum modulo PHP:

define php74::module (
  $php_module_name = $title,
  $php_package_name = "php7.4-${title}",
  $version = 'installed',
  $priority = '20',
  $data = "extension=${title}.son",
  $php_module_path = '/etc/php/7.4/mods-available',
) {
  package { $php_package_name:
    ensure          => $version,
    install_options => ['-o', 'DPkg::NoTriggers=true'],  # триггеры дебиановских php-пакетов сами создают симлинки и перезапускают сервис php-fpm - нам это не нужно, так как и симлинками, и сервисом мы управляем с помощью Puppet
  }
  -> file { "${php_module_path}/${php_module_name}.ini":
    ensure  => $ensure,
    content => $data,
  }
  file { "/etc/php/7.4/cli/conf.d/${priority}-${php_module_name}.ini":
    ensure  => link,
    target  => "${php_module_path}/${php_module_name}.ini",
  }
  file { "/etc/php/7.4/fpm/conf.d/${priority}-${php_module_name}.ini":
    ensure  => link,
    target  => "${php_module_path}/${php_module_name}.ini",
  }
}

node server3.testdomain {
  php74::module { 'sqlite3': }
  php74::module { 'amqp': php_package_name => 'php-amqp' }
  php74::module { 'msgpack': priority => '10' }
}

In Definitione, facillime error deprehendendus est declaratio duplicata. Hoc fit si res cum nomine constanti in definitione exstat, et duae pluresve instantiae huius definitionis in quodam nodo exstant.

Facile est hoc defendere: omnes opes intra definitionem nomen habere debent quod a... $titleAliter, additio idempotens opum fieri potest. Simplicissimo casu, satis est opes communes omnibus instantiis definitionis in classem separatam movere et hanc classem in definitione includere - functionem... include idempotens.

Sunt aliae rationes idempotentiam assequendi cum opes adduntur, nempe functionibus utendo. defined и ensure_resources...sed de hoc tibi in proximo episodio narrabo.

Dependentiae et notificationes pro classibus et definitionibus

Classes et definitiones has regulas ad tractationem dependentiarum et notificationum addunt:

  • Dependentia classis/definitionis addit dependentias omnibus opibus classis/definitionis;
  • Dependentia classis/definitionis dependentias omnibus opibus classis/definitionis addit;
  • Notificatio classis/definitionis omnes opes classis/definitionis certiores facit;
  • Subscriptio classi/definitionis omnibus opibus classis/definitionis subscribit.

Operatores conditionales et selectores

Documentatio hic est.

if

Omnia hic simplicia sunt:

if ВЫРАЖЕНИЕ1 {
  ...
} elsif ВЫРАЖЕНИЕ2 {
  ...
} else {
  ...
}

nisi

`nisi` contrarium est `si`: frustum codicis exsequetur si expressio falsa est.

unless ВЫРАЖЕНИЕ {
  ...
}

apud

Nihil hic complicatum est. Valores regulares (litteras, numeros, et cetera), expressiones regulares, et genera datorum ut valores uti potes.

case ВЫРАЖЕНИЕ {
  ЗНАЧЕНИЕ1: { ... }
  ЗНАЧЕНИЕ2, ЗНАЧЕНИЕ3: { ... }
  default: { ... }
}

Selectores

Selector est constructum linguae simile case, nisi quod loco codicis segmenti exsequendi, valorem reddit.

$var = $othervar ? { 'val1' => 1, 'val2' => 2, default => 3 }

modules

Cum configuratio parva est, facile in uno manifesto contineri potest. Sed quo plures configurationes describimus, eo plures classes et nodi in manifesto apparent, ita ut maior et difficilior ad tractandum fiat.

Praeterea, est problema usus reiterati codicis—cum totus codex in uno manifesto est, difficile est eum cum aliis communicare. Ad has duas difficultates solvendas, Puppet modulos introducit.

modules — sunt series classium, definitionum, aliarumque entitatum Puppet, in directorio separato sitae. Aliis verbis, modulus est pars independens logicae Puppet. Exempli gratia, fortasse est modulus ad operandum cum NGINX, et continebit tantum quod necessarium est ad operandum cum NGINX, vel fortasse est modulus ad operandum cum PHP, et sic porro.

Moduli versiones habent, et dependentiae inter modulos sustinentur. Repositorium modulorum apertum est— Officina Marionettarum.

In servo puppet, moduli in subdirectorio modulorum directorii principalis servantur. Quisque modulus structuram directorii normalem habet: manifesta, fasciculos, templates, lib, et cetera.

Structura fasciculorum in modulo

Radix moduli haec directoria cum nominibus per se claris continere potest:

  • manifests — manifesta in eo sunt
  • files — fasciculi in eo sunt
  • templates - in eo sunt exempla
  • lib — codicem Ruby continet

Hic index directoriorum et fasciculorum non est completus, sed sufficit huic articulo.

Nomina opum et nomina fasciculorum in modulo

Documentatio hic est.

Opes (classes, definitiones) in modulo nullo modo nominari possunt. Praeterea, est correspondentia directa inter nomen opis et nomen fasciculi in quo Puppet descriptionem opis quaeret. Si regulas nominandi violas, Puppet simpliciter descriptionem opis non inveniet, quod errorem compilationis efficiet.

Praecepta simplicia sunt;

  • Omnes opes in modulo in spatio nominum moduli esse debent. Si modulus vocatur... foo, omnes opes in eo vocandae sunt foo::<anything>, vel simpliciter foo.
  • Res cum nomine moduli in fasciculo esse debet. init.pp.
  • Pro aliis fontibus, schema nominandi fasciculos hoc modo est:
    • Praefixum cum nomine moduli omittitur
    • Omnia duo puncta dupla, si quae sunt, virgis substituuntur.
    • extensio additur .pp

Exemplo demonstrabo. Finge me modulum scribere. nginxHae res continet:

  • class nginx in manifesto descriptum init.pp;
  • class nginx::service in manifesto descriptum service.pp;
  • Definire nginx::server in manifesto descriptum server.pp;
  • Definire nginx::server::location in manifesto descriptum server/location.pp.

Templates

Probabiliter iam nosti quid sint formulae, itaque hic in singula non ingrediar. Sed hic relinquam, si forte. nexus ad Vicipaediam.

Quomodo exemplaria utenda sunt: ​​Valor exemplaris functione utens extendi potest template, cui via ad exemplar traditur. Pro opibus typi file Utimur eo una cum parametro contentExempli gratia, hoc modo:

file { '/tmp/example': content => template('modulename/templatename.erb')

Via Specierum <modulename>/<filename> implicat fasciculum <rootdir>/modules/<modulename>/templates/<filename>.

Praeterea, functio est inline_template — textus exemplaris ei ut input transmittitur, non nomen fasciculi.

Omnes variabiles Puppet in ambitu currenti intra formulas adhiberi possunt.

Puppet exempla ERB et EPP sustinet:

Breviter de ERB

Structurae moderationis:

  • <%= ВЫРАЖЕНИЕ %> — valorem expressionis inserere
  • <% ВЫРАЖЕНИЕ %> — valorem expressionis aestima (sine ea inserenda). Operatores conditionales (si) et iterationes (singulum) hic plerumque ponuntur.
  • <%# КОММЕНТАРИЙ %>

Expressiones in ERB lingua Ruby scribuntur (re vera, ERB significat Embedded Ruby).

Ad variabiles ex manifesto accedendum, addere debes @ ad nomen variabilis. Ad tollendam rupturam lineae quae post structuram moderationis apparet, notam claudentem uti debes. -%>.

Exemplum usus formae

Dicamus me modulum scribere ad ZooKeeper administrandum. Classis quae configurationem creandi curat hoc modo apparet:

class zookeeper::configure (
  Array[String] $nodes,
  Integer $port_client,
  Integer $port_quorum,
  Integer $port_leader,
  Hash[String, Any] $properties,
  String $datadir,
) {
  file { '/etc/zookeeper/conf/zoo.cfg':
    ensure  => present,
    content => template('zookeeper/zoo.cfg.erb'),
  }
}

Et exemplar correspondens zoo.cfg.erb - Ita:

<% if @nodes.length > 0 -%>
<% @nodes.each do |node, id| -%>
server.<%= id %>=<%= node %>:<%= @port_leader %>:<%= @port_quorum %>;<%= @port_client %>
<% end -%>
<% end -%>

dataDir=<%= @datadir %>

<% @properties.each do |k, v| -%>
<%= k %>=<%= v %>
<% end -%>

Facta et variabiles insitae

Зачастую конкретная часть конфигурации зависит от того, что в данный момент происходит на ноде. Например, в зависимости от того, какой релиз Debian стоит, нужно установить ту или иную версию пакета. Можно следить за этим всем вручную, переписывая манифесты в случае изменения нод. Но это несерьёзный подход, автоматизация гораздо лучше.

Ad informationem de nodis obtinendam, Puppet mechanismum nomine "facts" habet. facta — Haec est informatio de nodo, in manifestis ut variabiles regulares in spatio nominum globali praesto. Exempli gratia, nomen machinae, versio systematis operandi, architectura processoris, index usorum, index interfacierum retialium et inscriptionum earum, et multo, multo plura. Facta in manifestis et formis ut variabiles regulares praesto sunt.

Exemplum operandi cum factis:

notify { "Running OS ${facts['os']['name']} version ${facts['os']['release']['full']}": }
# ресурс типа notify просто выводит сообщение в лог

Formaliter loquendo, factum nomen (sermo litterarum) et valorem habet (varia genera praesto sunt: ​​serta litterarum, ordines, dictionaria). Est... series factorum insitumTua quoque scribere potes. Collectores factorum describuntur. ut functiones in Ruby, vel sicut hoc exsecutabile filesFacta etiam in forma exhiberi possunt fasciculi textuales cum datis in nodis.

Dum operatur, agens pupae primum omnes collectores factorum praesto e servo pupae ad nodum copiat, deinde eos incipit et facta collecta ad servitorem mittit; post hoc, servitor catalogum compilare incipit.

Facta in forma fasciculorum exsecutibilium

Talia facta in modulis in directorio ponuntur. facts.dScilicet, fasciculi exsequibiles esse debent. Cum currunt, informationes in exitum normalem vel in forma YAML vel clavis-valoris imprimere debent.

Memento facta distribui ad omnes nodos a servo pupato administratos, cui modulus tuus collocatur. Quapropter, in scripto tuo, cura ut systema omnia programmata et fasciculos necessarios ad functionem factae tuae habeat.

#!/bin/sh
echo "testfact=success"
#!/bin/sh
echo '{"testyamlfact":"success"}'

Facta Rubina

Talia facta in modulis in directorio ponuntur. lib/facter.

# всё начинается с вызова функции Facter.add с именем факта и блоком кода
Facter.add('ladvd') do
# в блоках confine описываются условия применимости факта — код внутри блока должен вернуть true, иначе значение факта не вычисляется и не возвращается
  confine do
    Facter::Core::Execution.which('ladvdc') # проверим, что в PATH есть такой исполняемый файл
  end
  confine do
    File.socket?('/var/run/ladvd.sock') # проверим, что есть такой UNIX-domain socket
  end
# в блоке setcode происходит собственно вычисление значения факта
  setcode do
    hash = {}
    if (out = Facter::Core::Execution.execute('ladvdc -b'))
      out.split.each do |l|
        line = l.split('=')
        next if line.length != 2
        name, value = line
        hash[name.strip.downcase.tr(' ', '_')] = value.strip.chomp(''').reverse.chomp(''').reverse
      end
    end
    hash  # значение последнего выражения в блоке setcode является значением факта
  end
end

Facta textuali

Talia facta in nodis in directorio ponuntur. /etc/facter/facts.d in Pappet vetere vel /etc/puppetlabs/facts.d in novo Pappet.

examplefact=examplevalue
---
examplefact2: examplevalue2
anotherfact: anothervalue

Appellatio ad facta

Duae sunt viae ad facta accedendi:

  • per dictionarium $facts: $facts['fqdn'];
  • nomine facti ut nomine variabilis utendo: $fqdn.

Optimum est dictionario uti $facts, et melius etiam, spatium nominum globale specifica ($::facts).

Hic est pars documentorum pertinens.

Variabiles incorporatae

Praeter facta, est etiam variabiles quaedam, in spatio nominum globali praesto.

  • facta fide digna — variabiles quae ex certificato clientis sumptae sunt (cum certificatum plerumque in servo pupae edatur, agens non potest simpliciter certificatum suum mutare, quam ob rem variabiles "fidatae" sunt): nomen certificati, nomen hospitis et dominii, extensiones ex certificato.
  • Facta de servitore —variabiles ad informationes de servitore pertinentes — versio, nomen, inscriptio IP servitoris, ambitus.
  • facta agentis — variabiles ab agente pupa directe additae, non per factorem — nomen certificati, versio agentis, versio pupae.
  • variabiles magistrales - Variabiles Puppetmaster (sic!). Similis fere est ac in Facta de servitore, plus valores parametrorum configurationis praesto sunt.
  • variabiles compilatoris — variabiles compilatoris quae in quoque ambitu differunt: nomen moduli currentis et nomen moduli in quo obiectum currens accessum est. Hae adhiberi possunt, exempli gratia, ad curandum ne classes tuae privatae directe ab aliis modulis adhibeantur.

Addendum 1: Quomodo haec omnia currere et corrigere?

Articulus multa exempla codicis Puppet continebat, sed nulla omnino explicatio erat quomodo hunc codicem currere. Bene, id corrigam.

Ad Puppet currendum, agens sufficit, sed plerumque etiam servitore indigebis.

Agent

Saltem ab versione quinta, fasciculi puppet-agent ex... repositorium officiale Puppetlabs содержат в себе все зависимости (ruby и соответствующие gem’ы), поэтому сложностей с установкой никаких нет (говорю про Debian-based дистрибутивы — RPM-based дистрибутивами мы не пользуемся).

Simplicissimo casu, ad configurationem pupae applicandam, satis est agentem in modo sine servo currere: dummodo codex pupae in nodum transcriptus sit, curre... puppet apply <путь к манифесту>:

atikhonov@atikhonov ~/puppet-test $ cat helloworld.pp 
node default {
    notify { 'Hello world!': }
}
atikhonov@atikhonov ~/puppet-test $ puppet apply helloworld.pp 
Notice: Compiled catalog for atikhonov.localdomain in environment production in 0.01 seconds
Notice: Hello world!
Notice: /Stage[main]/Main/Node[default]/Notify[Hello world!]/message: defined 'message' as 'Hello world!'
Notice: Applied catalog in 0.01 seconds

Melius est, scilicet, servum constituere et agentes in nodis in modo daemonis currere—tum configurationem e servo receptam singulis semihoris applicabunt.

Exemplar operis impulsivum simulare potes - ad nodum quem cupis vade et incipe. sudo puppet agent -tClavis -t (--test) revera plures optiones continet quae singillatim activari possunt. Hae optiones sequentes includunt:

  • noli in modo daemonis currere (per default, agens in modo daemonis currit);
  • post applicationem catalogi terminare (praedefinite, agens perget operari et configurationem applicabit singulis semihoris);
  • diarium operis accuratum scribe;
  • Mutationes in fasciculis ostende.

Modum "sine mutationibus" agens habet—eo uti potes si incertus es num configurationem rectam scripseris et vis inspicere quidnam agens mutabit durante operatione. Hic modus per parametrum activatur. --noop in linea mandati: sudo puppet agent -t --noop.

Etiam diarium debug activare potes—Puppet de omnibus actionibus suis in eo scribit: de re quam nunc tractat, de parametris rei, et de programmatibus quae currit. Hoc, scilicet, parametrus est. --debug.

servo

Totam configurationem PuppetServer et codicem ei distribuendum in hoc articulo non tractabo. Dicam tantum servitorem versione plene functionali praeinstallatam habere, quae nullam configurationem additiciam pro paucis nodis (exempli gratia, usque ad 100) requirit. Maior numerus nodorum aliquam adaptationem requiret — PuppetServer, ut ita dicam, non plus quam quattuor operarios operatur. Pro meliore effectu, numerum eorum augere debes et meminisse limites memoriae augere, alioquin servitor plerumque temporis sui inutilia colligendo impendet.

Distributio codicis - si celeriter et facile opus est, vide (in r10k)https://github.com/puppetlabs/r10k], pro parvis installationibus satis satis esse debet.

Appendix II: Consilia de Codificatione

  1. Omnem logicam in classes et definitiones move.
  2. Classes et definitiones in modulis, non in manifestis nodorum, serva.
  3. Utere factis.
  4. Noli IFs secundum nomina hospitum facere.
  5. Libere parametros classibus et definitionibus addere potes — melius est quam logicam implicitam in corpore classis/definitionis celare.

Et cur hoc facere suadeam, in proximo articulo explicabo.

conclusio,

Hoc introductionem concludit. In proximo articulo, Hiera, ENC, et PuppetDB tractabo.

Tantum usores descripserunt in aliquet participare possunt. InscribeTe gratissimum esse.

Re vera, multo plus materiae est—articulos de his argumentis scribere possum. Quaeso suffragium fer de iis quae legere velis:

  • 59,1%Structurae Puppet provectae sunt quaedam res summi ordinis: cycli, mappae et aliae expressiones lambda, collectores opum, opes exportatae et communicatio inter hospites per Puppet, inscriptiones, provisores, typos datorum abstractos.
  • 31,8%"Administrator matris meae sum," vel quomodo nos apud Avito amicitias cum variis versionibus servorum puparum inivimus, et, in principio, partem de administratione servorum puparum.
  • 81,8%Quomodo Codicem Puppet Scribimus: Instrumenta, Documentatio, Probatio, CI/CD.18

22 utentes censuerunt. 9 Utentes abstinuerunt.

Source: www.habr.com

Emptum certos hospites pro locis cum praesidio DDoS, VPS VDS servers 🔥 Eme hospitium interretiale fidum cum praesidio DDoS, servitores VPS VDS | ProHoster