Entwodiksyon nan mannken

Puppet se yon sistèm jesyon konfigirasyon. Li itilize pou pote lame nan eta a vle epi kenbe eta sa a.

Mwen te travay ak Puppet pou plis pase senk ane kounye a. Tèks sa a se esansyèlman yon konpilasyon tradui ak reòdone nan pwen kle nan dokiman ofisyèl la, ki pral pèmèt débutan yo byen vit konprann sans nan Puppet.

Entwodiksyon nan mannken

Enfòmasyon de baz yo

Sistèm operasyon Puppet a se kliyan-sèvè, byenke li sipòte tou operasyon san sèvè ak fonksyonalite limite.

Yo itilize yon modèl operasyon rale: pa default, yon fwa chak demi èdtan, kliyan kontakte sèvè a pou yon konfigirasyon epi aplike li. Si ou te travay ak Ansible, Lè sa a, yo sèvi ak yon modèl pouse diferan: administratè a kòmanse pwosesis pou aplike konfigirasyon an, kliyan yo tèt yo pa pral aplike anyen.

Pandan kominikasyon rezo a, yo itilize chifreman TLS de-fason: sèvè a ak kliyan gen pwòp kle prive yo ak sètifika korespondan yo. Tipikman sèvè a bay sètifika pou kliyan, men nan prensip li posib yo sèvi ak yon CA ekstèn.

Entwodiksyon nan manifès yo

Nan tèminoloji mannken nan sèvè mannken an konekte nœuds (nœuds). Konfigirasyon an pou nœuds yo ekri nan manifès yo nan yon langaj pwogram espesyal - Puppet DSL.

Puppet DSL se yon lang deklaratif. Li dekri eta a vle nan ne la nan fòm lan nan deklarasyon resous endividyèl, pou egzanp:

  • Fichye a egziste epi li gen kontni espesifik.
  • Pake a enstale.
  • Sèvis la te kòmanse.

Resous yo ka konekte:

  • Gen depandans, yo afekte lòd resous yo itilize.
    Pou egzanp, "premye enstale pake a, Lè sa a, modifye fichye a konfigirasyon, Lè sa a, kòmanse sèvis la."
  • Gen notifikasyon - si yon resous te chanje, li voye notifikasyon nan resous ki abònman nan li.
    Pou egzanp, si dosye konfigirasyon an chanje, ou ka otomatikman rekòmanse sèvis la.

Anplis de sa, Puppet DSL la gen fonksyon ak varyab, ansanm ak deklarasyon kondisyonèl ak seleksyon. Yo sipòte plizyè mekanis modèl tou - EPP ak ERB.

Puppet ekri an Ruby, se konsa anpil nan konstriksyon yo ak tèm yo pran soti nan la. Ruby pèmèt ou elaji Puppet - ajoute lojik konplèks, nouvo kalite resous, fonksyon.

Pandan Puppet ap kouri, manifest pou chak ne espesifik sou sèvè a yo konpile nan yon anyè. Anyè se yon lis resous ak relasyon yo apre yo fin kalkile valè fonksyon, varyab ak ekspansyon deklarasyon kondisyonèl.

Sentaks ak codestyle

Men seksyon nan dokiman ofisyèl la ki pral ede w konprann sentaks la si egzanp yo bay yo pa ase:

Men yon egzanp sou sa manifest la sanble:

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

Endentasyon ak kase liy yo pa yon pati obligatwa nan manifest la, men gen yon rekòmande gid style. Rezime:

  • Endentasyon de espas, onglè yo pa itilize.
  • Atèl boukle yo separe pa yon espas;
  • Vig apre chak paramèt, ki gen ladan dènye a. Chak paramèt se sou yon liy separe. Yo fè yon eksepsyon pou ka a san paramèt ak yon paramèt: ou ka ekri sou yon liy ak san yon vigil (sa vle di. resource { 'title': } и resource { 'title': param => value }).
  • Flèch yo sou paramèt yo ta dwe nan menm nivo.
  • Flèch relasyon resous yo ekri devan yo.

Kote dosye yo sou pappetserver

Pou plis eksplikasyon, mwen pral prezante konsèp nan "anyè rasin". Anyè rasin lan se anyè ki gen konfigirasyon Puppet pou yon ne espesifik.

Anyè rasin lan varye selon vèsyon Puppet ak anviwònman yo itilize. Anviwònman yo se yon seri konfigirasyon endepandan ki estoke nan anyè separe. Anjeneral yo itilize nan konbinezon ak git, nan ka sa a anviwònman yo kreye nan branch git. An konsekans, chak ne sitiye nan yon anviwònman oswa yon lòt. Sa a ka configuré sou ne nan tèt li, oswa nan ENC, ki mwen pral pale sou nan pwochen atik la.

  • Nan twazyèm vèsyon an ("ansyen mannken") anyè baz la te /etc/puppet. Itilizasyon anviwònman se opsyonèl - pou egzanp, nou pa sèvi ak yo ak mannken an fin vye granmoun. Si anviwònman yo itilize, yo anjeneral estoke nan /etc/puppet/environments, anyè rasin lan pral anyè anviwònman an. Si anviwònman yo pa itilize, anyè rasin lan pral anyè debaz la.
  • Apati katriyèm vèsyon an ("nouvo Puppet"), itilizasyon anviwònman yo te vin obligatwa, epi yo te deplase anyè debaz la nan /etc/puppetlabs/code. An konsekans, anviwònman yo estoke nan /etc/puppetlabs/code/environments, anyè rasin se anyè anviwònman an.

Dwe gen yon sous-anyè nan anyè rasin lan manifests, ki gen youn oswa plis manifeste ki dekri nœuds yo. Anplis de sa, ta dwe gen yon sous-répertoire modules, ki gen modil yo. Mwen pral di w ki modil yo yon ti kras pita. Anplis de sa, mannken an fin vye granmoun ka gen tou yon sou-anyè files, ki gen plizyè dosye ke nou kopye nan nœuds yo. Nan nouvo mannken an, tout dosye yo mete nan modil.

Fichye Manifest yo gen ekstansyon an .pp.

Yon koup nan egzanp konba

Deskripsyon nan ne ak resous sou li

Sou ne la server1.testdomain yon fichye dwe kreye /etc/issue ak kontni Debian GNU/Linux n l. Fichye a dwe posede pa yon itilizatè ak gwoup root, dwa aksè yo dwe 644.

Nou ekri yon manifès:

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 в начале будет воспринято как записанное в восьмеричной системе, и всё пойдёт не так, как задумано
    }
}

Relasyon ant resous sou yon ne

Sou ne la server2.testdomain nginx dwe kouri, travay ak yon konfigirasyon prepare deja.

Ann dekonpoze pwoblèm nan:

  • Pake a bezwen enstale nginx.
  • Li nesesè pou yo kopye fichye konfigirasyon yo nan sèvè a.
  • Sèvis la dwe kouri nginx.
  • Si konfigirasyon an mete ajou, sèvis la dwe rekòmanse.

Nou ekri yon manifès:

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 получает уведомление,
  # соответствующий сервис перезапускается.
}

Pou sa a travay, ou bezwen apeprè kote dosye sa a sou sèvè mannken an:

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

Kalite Resous

Ou ka jwenn yon lis konplè sou kalite resous sipòte isit la nan dokiman an, isit la mwen pral dekri senk kalite debaz, ki nan pratik mwen yo ase yo rezoud pifò pwoblèm.

dosye

Jere fichye, anyè, lyen senbolik, kontni yo ak dwa aksè.

Paramèt:

  • non resous - chemen nan dosye a (si ou vle)
  • chemen - chemen nan dosye a (si li pa espesifye nan non an)
  • asire - Kalite dosye:
    • absent - efase yon fichye
    • present — dwe gen yon fichye nenpòt kalite (si pa gen fichye, yo pral kreye yon fichye regilye)
    • file - dosye regilye
    • directory - anyè
    • link - lyen senbolik
  • kontni — sa ki nan dosye (apwopriye sèlman pou fichye regilye yo, yo pa ka itilize ansanm ak sous oswa sib)
  • sous — yon lyen ki mennen nan chemen kote ou vle kopye sa ki nan dosye a (pa ka itilize ansanm ak kontni oswa sib). Èske yo ka espesifye kòm swa yon URI ak yon konplo puppet: (Lè sa a, yo pral itilize dosye ki soti nan sèvè mannken), ak konplo a http: (Mwen espere ke li klè sa ki pral rive nan ka sa a), e menm ak dyagram nan file: oswa kòm yon chemen absoli san yon chema (Lè sa a, yo pral itilize dosye ki soti nan FS lokal la sou ne a)
  • sib — kote lyen senbolik la ta dwe montre (pa ka itilize ansanm ak kontni oswa sous)
  • mèt kay - itilizatè a ki ta dwe posede dosye a
  • gwoup — gwoup kote dosye a ta dwe fè pati
  • mòd - otorizasyon dosye (tankou yon fisèl)
  • repete - pèmèt pwosesis anyè rekursif
  • épuration - pèmèt efase dosye ki pa dekri nan Puppet
  • fòse - pèmèt efase anyè ki pa dekri nan Puppet

pake

Enstale epi retire pakè yo. Kapab okipe notifikasyon - reinstalle pake a si paramèt la espesifye reinstall_on_refresh.

Paramèt:

  • non resous - non pake (si ou vle)
  • File - non pake (si yo pa espesifye nan non an)
  • founisè - manadjè pake pou itilize
  • asire - eta vle nan pake a:
    • present, installed - nenpòt vèsyon enstale
    • latest - dènye vèsyon enstale
    • absent - efase (apt-get remove)
    • purged - efase ansanm ak dosye konfigirasyon (apt-get purge)
    • held - vèsyon pake a fèmen (apt-mark hold)
    • любая другая строка - se vèsyon an espesifye enstale
  • reinstall_on_refresh - si yon true, Lè sa a, lè yo resevwa notifikasyon an pral re-enstale pake a. Itil pou distribisyon ki baze sou sous, kote rebati pakè ka nesesè lè w ap chanje paramèt konstriksyon yo. Default false.

sèvis

Jere sèvis yo. Kapab trete notifikasyon - rekòmanse sèvis la.

Paramèt:

  • non resous - sèvis yo dwe jere (si ou vle)
  • File - sèvis la ki bezwen jere (si yo pa espesifye nan non an)
  • asire - eta vle nan sèvis la:
    • running - te lanse
    • stopped - sispann
  • pèmèt — kontwole kapasite pou kòmanse sèvis la:
    • true — Autorun pèmèt (systemctl enable)
    • mask - degize (systemctl mask)
    • false — otorun enfim (systemctl disable)
  • rekòmanse - lòd pou rekòmanse sèvis la
  • sitiyasyon - lòd pou tcheke estati sèvis la
  • rekòmanse — endike si initscript sèvis la sipòte rekòmanse. Si false epi yo espesifye paramèt la rekòmanse - yo itilize valè paramèt sa a. Si false ak paramèt rekòmanse pa espesifye - sèvis la sispann epi yo kòmanse rekòmanse (men systemd sèvi ak lòd la systemctl restart).
  • hasstatus — endike si initscript sèvis la sipòte kòmandman an status. Si false, Lè sa a, se valè paramèt la itilize sitiyasyon. Default true.

Egzekitif

Kouri kòmandman ekstèn. Si ou pa presize paramèt yo kreye, sèlman si, sof si oswa rafrechiman, lòd la pral kouri chak fwa Puppet ap kouri. Kapab trete notifikasyon - kouri yon lòd.

Paramèt:

  • non resous - lòd yo dwe egzekite (si ou vle)
  • lòd - lòd la dwe egzekite (si li pa espesifye nan non an)
  • chemen — chemen pou chèche dosye ègzèkutabl la
  • sèlman si — si kòmandman ki espesifye nan paramèt sa a ranpli ak yon kòd retounen zewo, yo pral egzekite kòmandman prensipal la
  • sof si — si kòmandman ki espesifye nan paramèt sa a ranpli ak yon kòd retounen ki pa zewo, yo pral egzekite kòmandman prensipal la
  • kreye — si dosye ki espesifye nan paramèt sa a pa egziste, yo pral egzekite kòmandman prensipal la
  • rafrechiman - si yon true, Lè sa a, lòd la pral sèlman kouri lè exec sa a resevwa notifikasyon nan men lòt resous
  • cwd - anyè ki soti nan ki kouri lòd la
  • itilizatè - itilizatè a soti nan ki moun yo kouri lòd la
  • founisè - Ki jan yo kouri lòd la:
    • posix — se yon pwosesis timoun tou senpleman kreye, asire w ke ou presize chemen
    • koki - se lòd la te lanse nan koki a /bin/sh, pa ka espesifye chemen, ou ka itilize globbing, tiyo ak lòt karakteristik koki. Anjeneral detekte otomatikman si gen nenpòt karaktè espesyal (|, ;, &&, || ak sou sa).

kron

Kontwole cronjobs.

Paramèt:

  • non resous - jis kèk kalite idantifyan
  • asire - eta kouwòn:
    • present - kreye si pa egziste
    • absent - efase si egziste
  • lòd - ki lòd pou kouri
  • anviwònman - nan ki anviwònman yo kouri lòd la (lis varyab anviwònman ak valè yo atravè =)
  • itilizatè - soti nan ki itilizatè yo kouri lòd la
  • minit, èdtan, pandan lasemèn, mwa, jou mwa — lè pou kouri cron. Si nenpòt nan atribi sa yo pa espesifye, valè li nan crontab la pral *.

Nan Puppet 6.0 kron tankou si retire nan bwat la nan puppetserver, kidonk pa gen okenn dokiman sou sit jeneral la. Men li se nan bwat la nan mannken-ajan, kidonk pa gen okenn bezwen enstale li separeman. Ou ka wè dokiman an pou li nan dokimantasyon an pou senkyèm vèsyon PuppetOswa sou GitHub.

Sou resous an jeneral

Kondisyon pou inik resous yo

Erè ki pi komen nou rankontre se Deklarasyon kopi. Erè sa a rive lè de oswa plis resous nan menm kalite ak menm non parèt nan anyè a.

Se poutèt sa, mwen pral ekri ankò: manifès pou menm ne a pa ta dwe gen resous nan menm kalite ak menm tit la!

Pafwa gen yon bezwen enstale pakè ki gen menm non, men ki gen diferan administratè pake. Nan ka sa a, ou bezwen sèvi ak paramèt la namepou evite erè a:

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

Lòt kalite resous gen opsyon menm jan an pou ede evite repetisyon - name у sèvis, command у Egzekitif, ak sou sa.

Metaparamèt

Chak kalite resous gen kèk paramèt espesyal, kèlkeswa nati li yo.

Lis konplè paramèt meta yo nan dokiman mannken an.

Lis kout:

  • mande pou — paramèt sa a endike ki resous resous sa a depann sou.
  • anvan - Paramèt sa a presize ki resous ki depann sou resous sa a.
  • abònman — paramèt sa a presize nan ki resous resous sa a resevwa notifikasyon.
  • avize — Paramèt sa a presize ki resous ki resevwa notifikasyon nan men resous sa a.

Tout metaparamèt ki nan lis yo aksepte swa yon lyen resous sèl oswa yon etalaj de lyen nan parantèz kare.

Lyen ki mennen nan resous yo

Yon lyen resous se tou senpleman yon mansyone nan resous la. Yo sitou itilize pou endike depandans. Referans yon resous ki pa egziste pral lakòz yon erè konpilasyon.

Sentaks lyen an se jan sa a: kalite resous ak yon lèt majiskil (si non kalite a gen doub kolon, Lè sa a, chak pati nan non ki ant pwent yo ap ekri majiskil), Lè sa a, non resous la nan parantèz kare (ka non an). pa chanje!). Pa ta dwe gen espas; parantèz kare yo ekri imedyatman apre non kalite a.

Egzanp:

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

Depandans ak notifikasyon

Dokimantasyon isit la.

Jan sa di pi bonè, depandans senp ant resous yo tranzitif. By wout la, fè atansyon lè w ajoute depandans - ou ka kreye depandans siklik, ki pral lakòz yon erè konpilasyon.

Kontrèman ak depandans, notifikasyon yo pa tranzitif. Règ sa yo aplike pou notifikasyon:

  • Si resous la resevwa yon notifikasyon, li mete ajou. Aksyon aktyalizasyon yo depann de kalite resous - Egzekitif kouri kòmandman an, sèvis rekòmanse sèvis la, pake re-enstale pake a. Si resous la pa gen yon aksyon aktyalizasyon defini, Lè sa a, pa gen anyen k ap pase.
  • Pandan yon sèl kouri nan Puppet, resous la mete ajou pa plis pase yon fwa. Sa posib paske notifikasyon yo gen ladan depandans ak graf depandans la pa gen sik.
  • Si Puppet chanje eta a nan yon resous, resous la voye notifikasyon bay tout resous ki abònman nan li.
  • Si yon resous mete ajou, li voye notifikasyon bay tout resous ki abònman nan li.

Manyen paramèt ki pa espesifye

Kòm yon règ, si kèk paramèt resous pa gen yon valè default epi paramèt sa a pa espesifye nan manifest la, Lè sa a, Puppet pa pral chanje pwopriyete sa a pou resous ki koresponn lan sou ne la. Pou egzanp, si yon resous nan kalite dosye paramèt pa espesifye owner, Lè sa a, Puppet pa pral chanje mèt kay la nan dosye ki koresponn lan.

Entwodiksyon nan klas, varyab ak definisyon

Sipoze nou gen plizyè nœuds ki gen menm pati nan konfigirasyon an, men gen diferans tou - otreman nou ta ka dekri li tout nan yon sèl blòk. node {}. Natirèlman, ou ka tou senpleman kopye pati ki idantik nan konfigirasyon an, men an jeneral sa a se yon move solisyon - konfigirasyon an ap grandi, epi si ou chanje pati jeneral nan konfigirasyon an, ou pral oblije modifye menm bagay la nan anpil kote. An menm tan an, li fasil pou fè yon erè, epi an jeneral, prensip DRY (pa repete tèt ou) te envante pou yon rezon.

Pou rezoud pwoblèm sa a gen yon konsepsyon tankou klas.

Klas yo

Gwoup se yon blòk non kòd poppet. Yo bezwen klas pou reitilize kòd.

Premye klas la bezwen dekri. Deskripsyon nan tèt li pa ajoute okenn resous nenpòt kote. Klas la dekri nan manifès yo:

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

Apre sa, klas la ka itilize:

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

Yon egzanp nan travay anvan an - ann deplase enstalasyon an ak konfigirasyon nginx nan yon klas:

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
}

Varyab

Klas ki soti nan egzanp anvan an pa fleksib ditou paske li toujou pote menm konfigirasyon nginx la. Ann fè chemen an nan varyab konfigirasyon an, Lè sa a, klas sa a ka itilize pou enstale nginx ak nenpòt konfigirasyon.

Li ka fè lè l sèvi avèk varyab yo.

Atansyon: varyab nan Puppet yo imuiabl!

Anplis de sa, yo ka jwenn aksè nan yon varyab sèlman apre li te deklare, otreman valè varyab la pral undef.

Egzanp travay ak varyab:

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

Puppet gen espas non yo, ak varyab yo, kòmsadwa, genyen zòn nan vizibilite: Yon varyab ki gen menm non ka defini nan espas non diferan. Lè w rezoud valè yon varyab, yo chèche varyab la nan espas non aktyèl la, answit nan espas non ki anvlòp la, ak sou sa.

Egzanp espas non:

  • global - varyab deyò klas la oswa deskripsyon ne ale la;
  • espas non node nan deskripsyon ne;
  • espas non klas la nan deskripsyon klas la.

Pou evite anbigwite lè w gen aksè a yon varyab, ou ka presize espas non an nan non varyab la:

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

Ann dakò ke chemen an nan konfigirasyon nginx la chita nan varyab la $nginx_conf_source. Lè sa a, klas la pral sanble sa a:

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
}

Sepandan, egzanp yo bay la se move paske gen kèk "konesans sekrè" ki yon kote andedan klas la yon varyab ki gen yon non tankou yon non. Li pi kòrèk pou fè konesans sa a jeneral - klas yo ka gen paramèt.

Paramèt klas yo yo se varyab nan espas non klas la, yo espesifye nan header klas la epi yo ka itilize tankou varyab regilye nan kò klas la. Valè paramèt yo espesifye lè w ap itilize klas la nan manifest la.

Ka paramèt la dwe mete nan yon valè default. Si yon paramèt pa gen yon valè default epi valè a pa mete lè yo itilize, li pral lakòz yon erè konpilasyon.

Ann parametrize klas la nan egzanp ki anwo a epi ajoute de paramèt: premye a, obligatwa, se chemen an nan konfigirasyon an, ak dezyèm lan, opsyonèl, se non an nan pake a ak nginx (nan Debian, pou egzanp, gen pakè. 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',   # задаём параметры класса точно так же, как параметры для других ресурсов
  }
}

Nan Puppet, varyab yo tape. Manje anpil kalite done. Kalite done yo anjeneral yo itilize pou valide valè paramèt yo pase nan klas ak definisyon. Si paramèt pase a pa matche ak kalite espesifye a, yon erè konpilasyon ap fèt.

Kalite a ekri imedyatman anvan non paramèt la:

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

Klas: enkli non klas kont klas {'classname':}

Chak klas se yon kalite resous klas. Menm jan ak nenpòt lòt kalite resous, pa ka gen de ka nan menm klas la sou menm ne.

Si ou eseye ajoute yon klas nan menm ne a de fwa lè l sèvi avèk class { 'classname':} (pa gen diferans, ak paramèt diferan oswa idantik), pral gen yon erè konpilasyon. Men, si ou itilize yon klas nan style resous la, ou ka imedyatman klèman mete tout paramèt li yo nan manifest la.

Sepandan, si ou itilize include, Lè sa a, klas la ka ajoute anpil fwa ke ou vle. Reyalite a se ke include se yon fonksyon idempotan ki tcheke si yo te ajoute yon klas nan anyè a. Si klas la pa nan anyè a, li ajoute li, epi si li deja egziste, li pa fè anyen. Men, nan ka itilize include Ou pa ka mete paramèt klas yo pandan deklarasyon klas la - tout paramèt obligatwa yo dwe mete nan yon sous done ekstèn - Hiera oswa ENC. Nou pral pale sou yo nan pwochen atik la.

Defini

Kòm te di nan blòk anvan an, menm klas la pa ka prezan sou yon ne plis pase yon fwa. Sepandan, nan kèk ka ou bezwen kapab sèvi ak blòk la menm nan kòd ak paramèt diferan sou ne nan menm. Nan lòt mo, gen yon bezwen pou yon kalite resous pwòp li yo.

Pou egzanp, yo nan lòd yo enstale modil PHP a, nou fè sa ki annapre yo nan Avito:

  1. Enstale pake a ak modil sa a.
  2. Ann kreye yon fichye konfigirasyon pou modil sa a.
  3. Nou kreye yon lyen senbolik nan konfigirasyon an pou php-fpm.
  4. Nou kreye yon lyen senbolik nan konfigirasyon an pou php cli.

Nan ka sa yo, yon konsepsyon tankou defini (defini, defini kalite, defini kalite resous). Yon Define sanble ak yon klas, men gen diferans: premye, chak Define se yon kalite resous, pa yon resous; dezyèmman, chak definisyon gen yon paramèt implicite $title, kote non resous la ale lè li deklare. Menm jan nan ka klas yo, yon definisyon dwe premye dekri, apre sa li ka itilize.

Yon egzanp senplifye ak yon modil pou 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' }
}

Fason ki pi fasil pou trape erè deklarasyon kopi a se nan Defini. Sa rive si yon definisyon gen yon resous ki gen yon non konstan, epi gen de oswa plis ka definisyon sa a sou kèk ne.

Li fasil pou pwoteje tèt ou kont sa a: tout resous andedan definisyon an dwe gen yon non depann sou $title. Yon altènatif se adisyon idempotan nan resous nan ka ki pi senp, li se ase yo deplase resous yo komen nan tout ka nan definisyon an nan yon klas separe epi enkli klas sa a nan definisyon an - fonksyon; include idempotan.

Gen lòt fason yo reyalize idempotity lè ajoute resous, sètadi lè l sèvi avèk fonksyon defined и ensure_resources, men mwen pral di w sou li nan pwochen Episode la.

Depandans ak notifikasyon pou klas ak definisyon

Klas ak definisyon ajoute règ sa yo nan manyen depandans ak notifikasyon:

  • depandans sou yon klas/defini ajoute depandans sou tout resous nan klas la/defini;
  • yon depandans klas/defini ajoute depandans nan tout resous klas/defini;
  • notifikasyon klas/defini notifye tout resous klas/defini;
  • abònman klas/defini abònman nan tout resous nan klas la/defini.

Deklarasyon kondisyonèl ak seleksyon yo

Dokimantasyon isit la.

if

Li senp isit la:

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

sof si

sof si se yon si nan do: blòk kòd la pral egzekite si ekspresyon an se fo.

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

kay

Pa gen anyen konplike isit la tou. Ou ka itilize valè regilye (fisèl, nimewo, elatriye), ekspresyon regilye, ak kalite done kòm valè.

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

Sélecteurs

Yon seleksyon se yon konstriksyon lang ki sanble ak case, men olye pou yo egzekite yon blòk nan kòd, li retounen yon valè.

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

Modil yo

Lè konfigirasyon an piti, li ka fasilman kenbe nan yon sèl manifest. Men, plis konfigirasyon nou dekri, plis klas ak nœuds gen nan manifest la, li ap grandi, epi li vin enkonvenyan pou travay avèk yo.

Anplis de sa, gen pwoblèm nan reutilizasyon kòd - lè tout kòd la nan yon sèl manifest, li difisil pou pataje kòd sa a ak lòt moun. Pou rezoud de pwoblèm sa yo, Puppet gen yon antite ki rele modil.

Modil yo - sa yo se seri klas, definisyon ak lòt antite Puppet yo mete nan yon anyè separe. Nan lòt mo, yon modil se yon moso endepandan nan lojik mannken. Pou egzanp, ka gen yon modil pou travay ak nginx, epi li pral genyen sa ki epi sèlman sa ki nesesè pou travay ak nginx, oswa ka gen yon modil pou travay ak PHP, ak sou sa.

Modil yo vèsyon, epi depandans modil youn sou lòt yo sipòte tou. Gen yon depo modil ouvè - Sou entènèt jwèt Puppet Forge.

Sou sèvè mannken an, modil yo sitiye nan sou-anyè modil nan anyè rasin lan. Anndan chak modil gen yon konplo anyè estanda - manifeste, fichye, modèl, lib, ak sou sa.

Estrikti dosye nan yon modil

Rasin modil la ka genyen anyè sa yo ak non deskriptif:

  • manifests - li genyen manifeste
  • files - li gen dosye
  • templates - li gen modèl
  • lib - li gen kòd Ruby

Sa a se pa yon lis konplè nan repèrtwar ak dosye, men li ase pou atik sa a pou kounye a.

Non resous ak non fichye nan modil la

Dokimantasyon isit la.

Resous (klas, definisyon) nan yon modil pa ka nonmen non ou renmen. Anplis de sa, gen yon korespondans dirèk ant non yon resous ak non dosye kote Puppet ap chèche yon deskripsyon resous sa a. Si ou vyole règ yo nonmen, Lè sa a, Puppet tou senpleman pa pral jwenn deskripsyon an resous, epi ou pral jwenn yon erè konpilasyon.

Règ yo senp:

  • Tout resous ki nan yon modil dwe nan espas non modil la. Si yo rele modil la foo, Lè sa a, tout resous ki nan li yo ta dwe nonmen non foo::<anything>, oswa jis foo.
  • Resous ki gen non modil la dwe nan dosye a init.pp.
  • Pou lòt resous, konplo nonmen fichye a se jan sa a:
    • prefiks ki gen non modil la jete
    • tout kolon doub, si genyen, yo ranplase ak koupe
    • ekstansyon te ajoute .pp

Mwen pral demontre ak yon egzanp. Ann di mwen ekri yon modil nginx. Li gen resous sa yo:

  • klas nginx dekri nan manifest la init.pp;
  • klas nginx::service dekri nan manifest la service.pp;
  • defini nginx::server dekri nan manifest la server.pp;
  • defini nginx::server::location dekri nan manifest la server/location.pp.

Modèl

Se vre wi ou menm ou konnen ki sa modèl yo ye, mwen pa pral dekri yo an detay isit la. Men, mwen pral kite li jis nan ka lyen nan Wikipedia.

Ki jan yo sèvi ak modèl: siyifikasyon an nan yon modèl ka elaji lè l sèvi avèk yon fonksyon template, ki se pase chemen an nan modèl la. Pou resous kalite dosye itilize ansanm ak paramèt la content. Pou egzanp, tankou sa a:

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

Gade chemen <modulename>/<filename> implique dosye <rootdir>/modules/<modulename>/templates/<filename>.

Anplis de sa, gen yon fonksyon inline_template — li resevwa tèks modèl la kòm opinyon, pa non fichye a.

Nan modèl yo, ou ka itilize tout varyab Puppet nan dimansyon aktyèl la.

Puppet sipòte modèl nan fòma ERB ak EPP:

Yon ti tan sou ERB

Estrikti kontwòl:

  • <%= ВЫРАЖЕНИЕ %> — mete valè ekspresyon an
  • <% ВЫРАЖЕНИЕ %> — kalkile valè yon ekspresyon (san yo pa mete l). Deklarasyon kondisyonèl (si) ak bouk (chak) anjeneral ale isit la.
  • <%# КОММЕНТАРИЙ %>

Ekspresyon nan ERB yo ekri nan Ruby (ERB se aktyèlman Embedded Ruby).

Pou jwenn aksè nan varyab nan manifest la, ou bezwen ajoute @ nan non varyab la. Pou retire yon kase liy ki parèt apre yon konstriksyon kontwòl, ou bezwen sèvi ak yon tag fèmen -%>.

Egzanp itilize modèl la

Ann di m ap ekri yon modil pou kontwole ZooKeeper. Klas ki responsab pou kreye konfigirasyon an sanble yon bagay tankou sa a:

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'),
  }
}

Ak modèl ki koresponn lan zoo.cfg.erb - Kidonk:

<% 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 -%>

Reyalite ak varyab entegre

Souvan pati espesifik nan konfigirasyon an depann de sa k ap pase kounye a sou ne la. Pou egzanp, tou depann de sa Debian lage se, ou bezwen enstale youn oswa yon lòt vèsyon nan pake a. Ou ka kontwole tout bagay sa yo manyèlman, reekri manifest si nœuds chanje. Men, sa a se pa yon apwòch serye automatisation se pi bon.

Pou jwenn enfòmasyon sou nœuds, Puppet gen yon mekanis ki rele reyalite. Facts - sa a se enfòmasyon sou ne la, ki disponib nan manifeste nan fòm varyab òdinè nan espas non mondyal la. Pou egzanp, non lame, vèsyon sistèm opere, achitekti processeur, lis itilizatè, lis koòdone rezo ak adrès yo, ak anpil, plis ankò. Reyalite yo disponib nan manifeste ak modèl kòm varyab regilye.

Yon egzanp travay ak reyalite:

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

Fòmèlman pale, yon reyalite gen yon non (fisèl) ak yon valè (divès kalite ki disponib: fisèl, etalaj, diksyonè). Manje seri reyalite entegre. Ou ka ekri pwòp ou a tou. Pèseptè reyalite yo dekri tankou fonksyon nan Ruby, oswa kòm dosye ègzèkutabl. Reyalite yo ka prezante tou nan fòm lan dosye tèks ak done yo sou nœuds yo.

Pandan operasyon an, ajan mannken an premye kopye tout pèseptè reyalite ki disponib soti nan pappetserver la nan nod la, apre sa li lanse yo epi voye enfòmasyon yo kolekte nan sèvè a; Apre sa, sèvè a kòmanse konpile katalòg la.

Reyalite sou fòm dosye ègzèkutabl

Reyalite sa yo mete nan modil nan anyè a facts.d. Natirèlman, dosye yo dwe ègzèkutabl. Lè yo kouri, yo dwe bay enfòmasyon sou pwodiksyon estanda nan swa fòma YAML oswa kle = valè.

Pa bliye ke reyalite yo aplike nan tout nœuds ki kontwole pa sèvè poppet kote modil ou a deplwaye. Se poutèt sa, nan script la, pran swen yo tcheke ke sistèm nan gen tout pwogram yo ak dosye ki nesesè pou reyalite ou a travay.

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

Ruby reyalite

Reyalite sa yo mete nan modil nan anyè a 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

Tèks reyalite

Reyalite sa yo mete sou nœuds nan anyè a /etc/facter/facts.d nan ansyen mannken oswa /etc/puppetlabs/facts.d nan nouvo mannken an.

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

Lè w rive nan reyalite yo

Gen de fason pou apwoche reyalite yo:

  • atravè diksyonè a $facts: $facts['fqdn'];
  • lè l sèvi avèk non reyalite a kòm non varyab la: $fqdn.

Li pi bon yo sèvi ak yon diksyonè $facts, oswa menm pi bon, endike espas non mondyal la ($::facts).

Isit la se seksyon ki enpòtan nan dokiman an.

Bati-an Varyab

Anplis reyalite yo, gen tou kèk varyab, disponib nan espas non mondyal la.

  • reyalite ou fè konfyans — varyab ke yo pran nan sètifika kliyan an (piske sètifika a anjeneral bay sou yon sèvè poppet, ajan an pa ka jis pran ak chanje sètifika li, kidonk varyab yo "fè konfyans"): non sètifika a, non an nan sètifika a. lame ak domèn, ekstansyon nan sètifika a.
  • reyalite sèvè —varyab ki gen rapò ak enfòmasyon sou sèvè a—vèsyon, non, adrès IP sèvè, anviwònman.
  • reyalite ajan yo — varyab yo te ajoute dirèkteman pa ajan mannken, epi pa faktè — non sètifika, vèsyon ajan, vèsyon mannken.
  • mèt varyab - Pappetmaster varyab (sic!). Li se sou menm jan ak nan reyalite sèvè, plis valè paramèt konfigirasyon yo disponib.
  • varyab konpilatè — varyab konpilatè ki diferan nan chak dimansyon: non modil aktyèl la ak non modil kote yo te jwenn aksè nan objè aktyèl la. Yo ka itilize, pa egzanp, pou tcheke si klas prive w yo pa itilize dirèkteman nan lòt modil.

Adisyon 1: ki jan yo kouri ak debogaj tout bagay sa a?

Atik la te genyen anpil egzanp nan kòd mannken, men li pa t 'di nou ditou ki jan yo kouri kòd sa a. Bon, mwen korije tèt mwen.

Yon ajan se ase pou kouri Puppet, men pou pifò ka w ap bezwen tou yon sèvè.

Ajan

Omwen depi vèsyon 5, pakè mannken-ajan soti nan depo ofisyèl Puppetlabs genyen tout depandans yo (Ruby ak gems korespondan yo), kidonk pa gen okenn difikilte pou enstalasyon (m ap pale de distribisyon ki baze sou Debian - nou pa sèvi ak distribisyon ki baze sou RPM).

Nan ka ki pi senp, pou itilize konfigirasyon mannken an, li ase pou lanse ajan an nan mòd san sèvè: depi kòd mannken an kopye nan ne, lanse. 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

Li pi bon, nan kou, yo mete kanpe sèvè a epi kouri ajan sou nœuds yo nan mòd daemon - Lè sa a, yon fwa chak demi èdtan yo pral aplike konfigirasyon an telechaje nan sèvè a.

Ou ka imite modèl pouse nan travay - ale nan ne ou enterese nan epi kòmanse sudo puppet agent -t. Kle -t (--test) aktyèlman gen ladan plizyè opsyon ki ka pèmèt endividyèlman. Opsyon sa yo enkli bagay sa yo:

  • pa kouri nan mòd daemon (pa default ajan an kòmanse nan mòd daemon);
  • fèmen apre ou fin aplike katalòg la (pa default, ajan an ap kontinye travay epi aplike konfigirasyon an yon fwa chak demi èdtan);
  • ekri yon jounal travay detaye;
  • montre chanjman nan dosye yo.

Ajan an gen yon mòd opere san chanjman - ou ka itilize li lè ou pa sèten ke ou te ekri konfigirasyon ki kòrèk la epi ou vle tcheke ki sa egzakteman ajan an pral chanje pandan operasyon an. Mòd sa a pèmèt paramèt la --noop sou liy lòd la: sudo puppet agent -t --noop.

Anplis de sa, ou ka pèmèt jounal debogaj nan travay la - nan li, mannken ekri sou tout aksyon li fè: sou resous ke li ap trete kounye a, sou paramèt yo nan resous sa a, sou ki pwogram li lanse. Natirèlman, sa a se yon paramèt --debug.

Sèvè

Mwen pa pral konsidere konfigirasyon an konplè nan pappetserver la ak deplwaye kòd nan li nan atik sa a mwen pral sèlman di ke soti nan bwat la gen yon vèsyon konplètman fonksyonèl nan sèvè a ki pa bezwen konfigirasyon adisyonèl pou travay ak yon ti kantite; nœuds (di, jiska yon santèn). Yon pi gwo kantite nœuds yo pral mande pou akor - pa default, puppetserver lanse pa plis pase kat travayè, pou pi gwo pèfòmans ou bezwen ogmante kantite yo epi yo pa bliye ogmante limit yo memwa, otreman sèvè a pral kolekte fatra pi fò nan tan an.

Deplwaman Kòd - si ou bezwen li byen vit ak fasil, gade (nan r10k)[https://github.com/puppetlabs/r10k], pou ti enstalasyon li ta dwe ase.

Addendum 2: Gid kodaj

  1. Mete tout lojik nan klas ak definisyon.
  2. Kenbe klas ak definisyon nan modil, pa nan manifès ki dekri nœuds.
  3. Sèvi ak reyalite yo.
  4. Pa fè si yo baze sou non host.
  5. Ezite ajoute paramèt pou klas ak definisyon - sa a se pi bon pase lojik implicite kache nan kò a nan klas la / defini.

Mwen pral eksplike poukisa mwen rekòmande fè sa nan pwochen atik la.

Konklizyon

Ann fini ak entwodiksyon an. Nan pwochen atik la mwen pral di w sou Hiera, ENC ak PuppetDB.

Se sèlman itilizatè ki anrejistre ki ka patisipe nan sondaj la. Enskri, tanpri.

An reyalite, gen anpil plis materyèl - mwen ka ekri atik sou sijè sa yo, vote sou sa ou ta enterese nan li sou:

  • 59,1%Konstriksyon mannken avanse - kèk kaka pwochen nivo: bouk, kat ak lòt ekspresyon lambda, pèseptè resous, resous ekspòte ak kominikasyon ant lame atravè Puppet, tags, founisè, kalite done abstrè.13
  • 31,8%"Mwen se admin manman m" oswa ki jan nou nan Avito te fè zanmi ak plizyè sèvè poppet nan diferan vèsyon, epi, an prensip, pati sou administrasyon sèvè poppet la.7
  • 81,8%Ki jan nou ekri kòd mannken: instrumentation, documentation, testing, CI/CD.18

22 itilizatè yo te vote. 9 itilizatè te absteni.

Sous: www.habr.com