Pambuka Wayang

Wayang minangka sistem manajemen konfigurasi. Iki digunakake kanggo nggawa host menyang negara sing dikarepake lan njaga negara kasebut.

Aku wis nggarap Wayang luwih saka limang taun saiki. Tèks iki ateges kompilasi sing diterjemahaké lan disusun ulang saka dhokumèntasi resmi, sing bakal ngidini para pamula ngerti kanthi cepet inti saka Wayang.

Pambuka Wayang

Informasi dhasar

Sistem operasi Wayang iku klien-server, sanajan uga ndhukung operasi tanpa server kanthi fungsi sing winates.

Model tarik operasi digunakake: kanthi standar, saben setengah jam, klien hubungi server kanggo konfigurasi lan aplikasi. Yen sampeyan wis kerjo karo Ansible, banjur padha nggunakake model push beda: administrator miwiti proses nglamar konfigurasi, klien dhewe ora bakal aplikasi apa-apa.

Sajrone komunikasi jaringan, enkripsi TLS rong arah digunakake: server lan klien duwe kunci pribadi lan sertifikat sing cocog. Biasane server ngetokake sertifikat kanggo klien, nanging ing prinsip bisa nggunakake CA eksternal.

Pambuka kanggo manifesto

Ing terminologi Wayang menyang server wayang nyambung simpul (node). Konfigurasi kanggo simpul ditulis ing manifesto ing basa pamrograman khusus - Wayang DSL.

DSL Wayang iku basa deklaratif. Iki nggambarake kahanan simpul sing dikarepake ing bentuk deklarasi sumber daya individu, contone:

  • File kasebut ana lan nduweni isi tartamtu.
  • Paket wis diinstal.
  • Layanan wis diwiwiti.

Sumber daya bisa disambungake:

  • Ana dependensi, padha mengaruhi urutan sumber daya digunakake.
    Contone, "instal paket dhisik, banjur owahi file konfigurasi, banjur miwiti layanan."
  • Ana kabar - yen sumber wis diganti, iku ngirim kabar menyang sumber daya langganan kanggo.
    Contone, yen file konfigurasi diganti, sampeyan bisa miwiti maneh layanan kanthi otomatis.

Kajaba iku, DSL Wayang nduweni fungsi lan variabel, uga pernyataan kondisional lan pamilih. Macem-macem mekanisme templating uga didhukung - EPP lan ERB.

Wayang ditulis nganggo Ruby, mula akeh konstruksi lan istilah sing dijupuk saka kono. Ruby ngidini sampeyan nggedhekake Wayang - nambah logika kompleks, jinis sumber daya anyar, fungsi.

Nalika Wayang lagi mlaku, manifests kanggo saben simpul tartamtu ing server dikompilasi menyang direktori. Direktori minangka dhaptar sumber daya lan hubungane sawise ngitung nilai fungsi, variabel lan ekspansi pernyataan kondisional.

Sintaksis lan gaya kode

Ing ngisor iki bagean saka dokumentasi resmi sing bakal mbantu sampeyan ngerti sintaks yen conto sing diwenehake ora cukup:

Mangkene conto tampilan manifes kasebut:

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

Indentation lan line break ora bagean sing dibutuhake saka manifest, nanging ana dianjurake pandhuan gaya. Ringkesan:

  • Indentasi rong spasi, tab ora digunakake.
  • Kurung kriting dipisahake dening spasi;
  • Koma sawise saben parameter, kalebu sing pungkasan. Saben parameter ana ing baris sing kapisah. Pangecualian digawe kanggo kasus tanpa parameter lan siji parameter: sampeyan bisa nulis ing siji baris lan tanpa koma (i.e. resource { 'title': } и resource { 'title': param => value }).
  • Panah ing paramèter kudu ing tingkat sing padha.
  • Panah hubungan sumber daya ditulis ing ngarepe.

Lokasi file ing pappetserver

Kanggo panjelasan luwih lengkap, aku bakal ngenalake konsep "direktori root". Direktori root yaiku direktori sing ngemot konfigurasi Wayang kanggo simpul tartamtu.

Direktori root beda-beda gumantung saka versi Wayang lan lingkungan sing digunakake. Lingkungan minangka set konfigurasi independen sing disimpen ing direktori sing kapisah. Biasane digunakake ing kombinasi karo git, ing ngendi lingkungan digawe saka cabang git. Mulane, saben simpul dumunung ing siji lingkungan utawa liyane. Iki bisa dikonfigurasi ing simpul dhewe, utawa ing ENC, sing bakal dakkandhakake ing artikel sabanjure.

  • Ing versi katelu ("Wayang lawas") direktori dhasar ana /etc/puppet. Panggunaan lingkungan iku opsional - contone, kita ora digunakake karo Wayang lawas. Yen lingkungan digunakake, biasane disimpen ing /etc/puppet/environments, direktori root bakal dadi direktori lingkungan. Yen lingkungan ora digunakake, direktori root bakal dadi direktori dhasar.
  • Wiwit saka versi kaping papat ("Wayang anyar"), panggunaan lingkungan dadi wajib, lan direktori dhasar dipindhah menyang /etc/puppetlabs/code. Mulane, lingkungan disimpen ing /etc/puppetlabs/code/environments, direktori root yaiku direktori lingkungan.

Mesthi ana subdirektori ing direktori root manifests, sing ngemot siji utawa luwih manifests sing njlèntrèhaké simpul. Kajaba iku, kudu ana subdirektori modules, sing ngemot modul. Aku bakal pitutur marang kowe apa modul sethitik mengko. Kajaba iku, Wayang lawas bisa uga duwe subdirektori files, sing ngemot macem-macem file sing disalin menyang simpul. Ing Wayang anyar, kabeh file diselehake ing modul.

File manifest duwe ekstensi .pp.

Saperangan conto pertempuran

Katrangan saka simpul lan sumber daya ing

Ing simpul server1.testdomain file kudu digawe /etc/issue karo isi Debian GNU/Linux n l. Berkas kasebut kudu diduweni dening pangguna lan grup root, hak akses kudu 644.

Kita nulis manifesto:

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

Hubungan antarane sumber daya ing simpul

Ing simpul server2.testdomain nginx kudu mlaku, nggarap konfigurasi sing wis disiapake sadurunge.

Ayo decompose masalah:

  • Paket kasebut kudu diinstal nginx.
  • Sampeyan perlu supaya file konfigurasi disalin saka server.
  • Layanan kasebut kudu mlaku nginx.
  • Yen konfigurasi dianyari, layanan kasebut kudu diwiwiti maneh.

Kita nulis manifesto:

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

Kanggo nindakake iki, sampeyan butuh kira-kira lokasi file ing server wayang:

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

Jinis sumber daya

Dhaptar lengkap jinis sumber daya sing didhukung bisa ditemokake ing kene ing dokumentasi, kene aku bakal njlèntrèhaké limang jinis dhasar, kang ing laku cukup kanggo ngatasi masalah paling.

file

Ngatur file, direktori, symlink, isi, lan hak akses.

Parameter:

  • jeneng sumber - path menyang file (opsional)
  • path - path menyang file (yen ora kasebut ing jeneng)
  • mesthekake - jinis file:
    • absent - mbusak file
    • present - kudu ana file apa wae (yen ora ana file, file biasa bakal digawe)
    • file - file biasa
    • directory - direktori
    • link - symlink
  • isi - isi file (mung cocok kanggo file biasa, ora bisa digunakake bebarengan karo sumber utawa target)
  • sumber — link menyang path saka ngendi sampeyan pengin nyalin isi file (ora bisa digunakake bebarengan karo isi utawa target). Bisa ditemtokake minangka URI kanthi skema puppet: (banjur file saka server wayang bakal digunakake), lan karo skema http: (Muga-muga cetha apa sing bakal kelakon ing kasus iki), lan malah karo diagram file: utawa minangka path absolut tanpa skema (banjur file saka FS lokal ing simpul bakal digunakake)
  • target - ing ngendi symlink kudu dituju (ora bisa digunakake bebarengan karo isi utawa sumber)
  • pemilik — pangguna sing kudu duwe file
  • group - klompok sing kudu dadi file
  • mode - ijin file (minangka string)
  • mbaleni - mbisakake pangolahan direktori rekursif
  • purge - mbisakake mbusak file sing ora diterangake ing Wayang
  • pasukan - mbisakake mbusak direktori sing ora diterangake ing Wayang

paket

Nginstal lan mbusak paket. Bisa nangani kabar - nginstal maneh paket yen parameter kasebut ditemtokake reinstall_on_refresh.

Parameter:

  • jeneng sumber - jeneng paket (opsional)
  • jeneng - jeneng paket (yen ora kasebut ing jeneng)
  • panyedhiya - manager paket kanggo nggunakake
  • mesthekake - status paket sing dikarepake:
    • present, installed - versi apa wae sing diinstal
    • latest - versi paling anyar diinstal
    • absent - dibusak (apt-get remove)
    • purged - dibusak bebarengan karo file konfigurasi (apt-get purge)
    • held - versi paket dikunci (apt-mark hold)
    • любая другая строка - versi sing ditemtokake wis diinstal
  • reinstall_on_refresh - yen a true, banjur sawise nampa kabar paket bakal diinstal maneh. Migunani kanggo distribusi basis sumber, ing ngendi paket mbangun maneh perlu nalika ngganti parameter mbangun. Default false.

layanan

Ngatur layanan. Bisa ngolah kabar - miwiti maneh layanan.

Parameter:

  • jeneng sumber - layanan kanggo dikelola (opsional)
  • jeneng - layanan sing kudu dikelola (yen ora kasebut ing jeneng)
  • mesthekake - status layanan sing dikarepake:
    • running - dibukak
    • stopped - mandegake
  • ngaktifake - ngontrol kemampuan kanggo miwiti layanan:
    • true - autorun diaktifake (systemctl enable)
    • mask - nyamar (systemctl mask)
    • false - autorun dipateni (systemctl disable)
  • baleni meneh - printah kanggo miwiti maneh layanan
  • status — printah kanggo mriksa status layanan
  • wis miwiti maneh — nunjukaké apa layanan initscript ndhukung miwiti maneh. Yen false lan parameter kasebut ditemtokake baleni meneh - Nilai saka parameter iki digunakake. Yen false lan parameter baleni meneh ora ditemtokake - layanan mandheg lan diwiwiti maneh (nanging systemd nggunakake perintah systemctl restart).
  • statuse - nunjukake apa layanan initscript ndhukung printah status. Yen false, banjur nilai parameter digunakake status. Default true.

exec

Mlaku printah external. Yen sampeyan ora nemtokake paramèter nggawe, mung yen, kajaba utawa refreshonly, printah bakal mbukak saben wektu Wayang wis mbukak. Bisa ngolah kabar - nglakokake prentah.

Parameter:

  • jeneng sumber - perintah sing kudu ditindakake (opsional)
  • printah - printah sing bakal ditindakake (yen ora kasebut ing jeneng)
  • path - path kanggo nggoleki file sing bisa dieksekusi
  • mung yen - yen printah kasebut ing parameter iki rampung karo kode bali nul, printah utama bakal kaleksanan
  • kajaba - yen printah sing ditemtokake ing parameter iki rampung karo kode bali non-nol, printah utama bakal dieksekusi
  • nggawe - yen file sing ditemtokake ing parameter iki ora ana, printah utama bakal dieksekusi
  • refreshonly - yen a true, banjur printah mung bakal mbukak nalika exec iki nampa kabar saka sumber daya liyane
  • cwd - direktori saka ngendi kanggo mbukak printah
  • user — pangguna saka kang kanggo mbukak printah
  • panyedhiya - carane mbukak printah:
    • posix - proses anak mung digawe, manawa kanggo nemtokake path
    • Nihan - printah dibukak ing Nihan /bin/sh, bisa uga ora ditemtokake path, sampeyan bisa nggunakake globbing, pipa lan fitur cangkang liyane. Biasane dideteksi kanthi otomatis yen ana karakter khusus (|, ;, &&, || lsp).

cron

Ngontrol cronjob.

Parameter:

  • jeneng sumber - mung sawetara jenis pengenal
  • mesthekake - status crownjob:
    • present - nggawe yen ora ana
    • absent - mbusak yen ana
  • printah - printah apa kanggo mbukak
  • lingkungan - ing lingkungan kanggo mbukak printah (dhaftar variabel lingkungan lan nilai liwat =)
  • user - saka pangguna kanggo mbukak printah
  • menit, jam, dina minggu, sasi, wulan - nalika kanggo mbukak cron. Yen atribut kasebut ora ditemtokake, nilai kasebut ing crontab bakal dadi *.

Ing Wayang 6.0 cron kaya-kaya dibusak saka kothak ing puppetserver, supaya ora ana dokumentasi ing situs umum. Nanging dheweke ana ing kothak ing wayang-agen, supaya ana ora perlu kanggo nginstal dhewe. Sampeyan bisa ndeleng dokumentasi kasebut ing dokumentasi kanggo versi kaping lima Wayang, utawa ing GitHub.

Babagan sumber daya ing umum

Requirements kanggo uniqueness sumber

Kesalahan sing paling umum sing kita temoni yaiku Pranyatan duplikat. Kesalahan iki kedadeyan nalika loro utawa luwih sumber daya saka jinis sing padha karo jeneng sing padha katon ing direktori.

Mulane, aku bakal nulis maneh: manifests kanggo simpul padha ngirim ora ngemot sumber daya saka jinis padha karo judhul padha!

Kadhangkala ana perlu kanggo nginstal paket kanthi jeneng sing padha, nanging karo manajer paket sing beda. Ing kasus iki, sampeyan kudu nggunakake parameter namekanggo nyegah kesalahan:

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

Jinis sumber daya liyane duwe opsi sing padha kanggo nyegah duplikasi − name у layanan, command у exec, lan sapanunggalane.

Metaparameter

Saben jinis sumber duwe sawetara paramèter khusus, preduli saka sifate.

Dhaptar lengkap paramèter meta ing dokumentasi Wayang.

Daftar singkat:

  • mbutuhake - parameter iki nuduhake sumber daya sing gumantung ing sumber daya iki.
  • sadurunge - Parameter iki nemtokake sumber daya sing gumantung marang sumber daya iki.
  • langganan - parameter iki nemtokake saka sumber daya iki nampa kabar.
  • ngabari - Parameter iki nemtokake sumber daya sing nampa kabar saka sumber iki.

Kabeh metaparameter sing kadhaptar nampa link sumber siji utawa sawetara pranala ing kurung kothak.

Pranala menyang sumber

Link sumber daya mung nyebutake sumber daya. Utamane digunakake kanggo nunjukake dependensi. Referensi sumber daya sing ora ana bakal nyebabake kesalahan kompilasi.

Sintaks pranala kasebut kaya ing ngisor iki: jinis sumber kanthi huruf kapital (yen jeneng jinis ngemot titik loro, mula saben bagean jeneng ing antarane titik loro kasebut dikapitalisasi), banjur jeneng sumber ing kurung kothak (kasus jeneng. ora owah!). Ora ana spasi; kurung kothak ditulis langsung sawise jeneng jinis.

Conto:

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

Ketergantungan lan kabar

Dokumentasi kene.

Kaya kasebut sadurunge, dependensi prasaja antarane sumber daya transitif. Miturut cara, ati-ati nalika nambah dependensi - sampeyan bisa nggawe dependensi siklik, sing bakal nyebabake kesalahan kompilasi.

Ora kaya dependensi, kabar ora transitif. Aturan ing ngisor iki ditrapake kanggo kabar:

  • Yen sumber nampa kabar, iku dianyari. Tumindak nganyari gumantung saka jinis sumber daya − exec nindakake perintah, layanan miwiti maneh layanan, paket nginstal maneh paket. Yen sumber daya ora duwe tumindak nganyari sing ditetepake, mula ora ana sing kedadeyan.
  • Sajrone siji mbukak Wayang, sumber daya dianyari ora luwih saka sapisan. Iki bisa uga amarga kabar kalebu dependensi lan grafik dependensi ora ngemot siklus.
  • Yen Wayang ngganti kahanan sumber daya, sumber daya ngirim kabar kanggo kabeh sumber daya langganan kanggo.
  • Yen sumber daya dianyari, iku ngirim kabar kanggo kabeh sumber daya langganan kanggo.

Nangani paramèter sing ora ditemtokake

Minangka aturan, yen sawetara parameter sumber ora duwe nilai standar lan parameter iki ora ditemtokake ing manifest, banjur Wayang ora bakal ngganti properti iki kanggo sumber sing cocog ing simpul. Contone, yen sumber daya saka jinis file parameter ora ditemtokake owner, banjur Wayang ora bakal ngganti pemilik file sing cocog.

Pambuka kanggo kelas, variabel lan definisi

Upaminipun kita duwe sawetara simpul sing duwe bagean konfigurasi sing padha, nanging ana uga beda - yen ora, kita bisa njlèntrèhaké kabeh ing siji blok. node {}. Mesthi, sampeyan mung bisa nyalin bagean sing padha saka konfigurasi, nanging umume iki minangka solusi sing ora becik - konfigurasi bakal tuwuh, lan yen sampeyan ngganti bagean umum konfigurasi, sampeyan kudu ngowahi sing padha ing pirang-pirang panggonan. Ing wektu sing padha, gampang nggawe kesalahan, lan umume, prinsip DRY (ora mbaleni dhewe) diciptakake kanthi alasan.

Kanggo ngatasi masalah iki ana desain kaya kelas.

Kelas

Класс minangka blok kode poppet sing jenenge. Kelas dibutuhake kanggo nggunakake maneh kode.

Kaping pisanan, kelas kudu diterangake. Katrangan dhewe ora nambah sumber daya ing ngendi wae. Kelas kasebut diterangake ing manifests:

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

Sawise kelas iki bisa digunakake:

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

Conto saka tugas sadurunge - ayo mindhah instalasi lan konfigurasi nginx menyang kelas:

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
}

Variabel

Kelas saka conto sadurunge ora fleksibel amarga tansah nggawa konfigurasi nginx sing padha. Ayo nggawe path menyang variabel konfigurasi, banjur kelas iki bisa digunakake kanggo nginstal nginx karo konfigurasi apa wae.

Bisa rampung nggunakake variabel.

Manungsa waé: variabel ing Wayang ora bisa owah!

Kajaba iku, variabel mung bisa diakses sawise diumumake, yen ora, nilai variabel kasebut undef.

Tuladha nggarap variabel:

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

Wayang wis spasi jeneng, lan variabel, miturut, duwe area visibilitas: Variabel kanthi jeneng sing padha bisa ditetepake ing spasi jeneng sing beda. Nalika ngrampungake nilai variabel, variabel kasebut digoleki ing ruang jeneng saiki, banjur ing ruang jeneng sing dilampirake, lan liya-liyane.

Tuladha namespace:

  • global - variabel ing njaba kelas utawa katrangan simpul menyang kana;
  • ruang jeneng simpul ing katrangan simpul;
  • ruang jeneng kelas ing deskripsi kelas.

Kanggo ngindhari ambiguitas nalika ngakses variabel, sampeyan bisa nemtokake spasi jeneng ing jeneng variabel:

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

Ayo dadi setuju yen path menyang konfigurasi nginx dumunung ing variabel $nginx_conf_source. Banjur kelas bakal katon kaya iki:

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
}

Nanging, conto sing diwenehake iku ala amarga ana sawetara "kawruh rahasia" sing nang endi wae ing kelas variabel kanthi jeneng kasebut lan kasebut digunakake. Luwih bener kanggo nggawe kawruh iki umum - kelas bisa duwe paramèter.

Paramèter kelas minangka variabel ing ruang jeneng kelas, ditemtokake ing header kelas lan bisa digunakake kaya variabel biasa ing awak kelas. Nilai parameter ditemtokake nalika nggunakake kelas ing manifest.

Parameter bisa disetel menyang nilai standar. Yen parameter ora duwe nilai standar lan nilai kasebut ora disetel nalika digunakake, bakal nyebabake kesalahan kompilasi.

Ayo paramèter kelas saka conto ing ndhuwur lan tambahake rong paramèter: pisanan, dibutuhake, yaiku path menyang konfigurasi, lan kaloro, opsional, yaiku jeneng paket karo nginx (ing Debian, contone, ana paket. 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',   # задаём параметры класса точно так же, как параметры для других ресурсов
  }
}

Ing Wayang, variabel diketik. mangan akeh jinis data. Jinis data biasane digunakake kanggo validasi nilai parameter sing diterusake menyang kelas lan definisi. Yen parameter sing dilewati ora cocog karo jinis sing ditemtokake, kesalahan kompilasi bakal kedadeyan.

Jinis kasebut ditulis langsung sadurunge jeneng parameter:

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

Kelas: kalebu jeneng kelas vs kelas {'classname':}

Saben kelas minangka sumber saka jinis kelas. Kaya karo jinis sumber liyane, ora bisa ana rong conto kelas sing padha ing simpul sing padha.

Yen sampeyan nyoba kanggo nambah kelas kanggo simpul padha kaping pindho nggunakake class { 'classname':} (ora ana bedane, kanthi paramèter sing beda utawa padha), bakal ana kesalahan kompilasi. Nanging yen sampeyan nggunakake kelas ing gaya sumber, sampeyan bisa langsung nyetel kabeh paramèter ing manifest.

Nanging, yen sampeyan nggunakake include, banjur kelas bisa ditambahake kaping pirang-pirang sing dikarepake. Kasunyatan iku include minangka fungsi idempoten sing mriksa apa kelas wis ditambahake menyang direktori. Yen kelas ora ana ing direktori, nambah, lan yen wis ana, ora nindakake apa-apa. Nanging ing kasus nggunakake include Sampeyan ora bisa nyetel paramèter kelas sajrone deklarasi kelas - kabeh parameter sing dibutuhake kudu disetel ing sumber data eksternal - Hiera utawa ENC. Kita bakal ngrembug bab mau ing artikel sabanjure.

Nemtokake

Kaya sing dikandhakake ing blok sadurunge, kelas sing padha ora bisa ana ing simpul luwih saka sepisan. Nanging, ing sawetara kasus, sampeyan kudu bisa nggunakake blok kode sing padha karo paramèter sing beda ing simpul sing padha. Ing tembung liyane, ana perlu kanggo jinis sumber daya dhewe.

Contone, kanggo nginstal modul PHP, kita nindakake ing ngisor iki ing Avito:

  1. Instal paket karo modul iki.
  2. Ayo nggawe file konfigurasi kanggo modul iki.
  3. Kita nggawe symlink menyang config kanggo php-fpm.
  4. Kita nggawe symlink menyang config kanggo php cli.

Ing kasus kaya mengkono, desain kayata netepake (netepake, ditetepake jinis, ditetepake jinis sumber). A Nemtokake padha karo kelas, nanging ana beda: pisanan, saben Nemtokake jinis sumber, ora sumber; kapindho, saben definisi wis parameter implisit $title, ngendi jeneng sumber nalika diumumake. Kaya ing kasus kelas, definisi kudu diterangake dhisik, banjur bisa digunakake.

Conto sing disederhanakake karo modul kanggo 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' }
}

Cara paling gampang kanggo nyekel kesalahan deklarasi Duplikat yaiku ing Define. Iki kedadeyan yen definisi nduweni sumber kanthi jeneng konstan, lan ana loro utawa luwih saka definisi iki ing sawetara simpul.

Iku gampang kanggo nglindhungi dhewe saka iki: kabeh sumber daya nang definisi kudu jeneng gumantung ing $title. Alternatif tambahan idempoten sumber daya ing kasus paling gampang, iku cukup kanggo mindhah sumber daya umum kanggo kabeh kedadean definisi menyang kelas kapisah lan kalebu kelas iki ing definisi - fungsi; include idempoten.

Ana cara liya kanggo entuk idempotensi nalika nambah sumber daya, yaiku nggunakake fungsi defined и ensure_resources, nanging aku bakal pitutur marang kowe bab iku ing episode sabanjuré.

Dependensi lan kabar kanggo kelas lan definisi

Kelas lan definisi nambahake aturan ing ngisor iki kanggo nangani dependensi lan kabar:

  • katergantungan ing kelas / nemtokake nambah dependensi ing kabeh sumber daya saka kelas / nemtokake;
  • kelas / nemtokake katergantungan nambah dependensi kanggo kabeh kelas / nemtokake sumber;
  • kabar kelas / netepake ngabari kabeh sumber daya saka kelas / nemtokake;
  • kelas / nemtokake langganan langganan kabeh sumber daya saka kelas / nemtokake.

Pernyataan kondisional lan pamilih

Dokumentasi kene.

if

Kabeh iku prasaja ing kene:

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

kajaba

kajaba yen ing mbalikke: pemblokiran kode bakal kaleksanan yen expression iku palsu.

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

cilik

Ora ana sing rumit ing kene. Sampeyan bisa nggunakake nilai reguler (string, angka, lsp.), ekspresi reguler, lan jinis data minangka nilai.

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

Pamilih

Pamilih minangka konstruksi basa sing padha karo case, nanging tinimbang nglakokake blok kode, ngasilake nilai.

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

Modul

Nalika konfigurasi cilik, bisa gampang disimpen ing siji manifest. Nanging luwih akeh konfigurasi sing digambarake, luwih akeh kelas lan kelenjar sing ana ing manifest, tuwuh, lan dadi ora trep kanggo nggarap.

Kajaba iku, ana masalah nggunakake maneh kode - nalika kabeh kode ana ing siji manifest, angel nuduhake kode iki karo wong liya. Kanggo ngrampungake rong masalah kasebut, Wayang duwe entitas sing diarani modul.

Modul - iki minangka set kelas, definisi lan entitas Wayang liyane sing diselehake ing direktori sing kapisah. Ing tembung liyane, modul punika Piece independen saka logika Wayang. Contone, bisa uga ana modul kanggo nggarap nginx, lan bakal ngemot apa lan mung apa sing dibutuhake kanggo nggarap nginx, utawa bisa uga ana modul kanggo nggarap PHP, lan liya-liyane.

Modul ana versi, lan dependensi modul ing saben liyane uga didhukung. Ana repositori mbukak modul - Wayang Golek.

Ing server wayang, modul dumunung ing subdirektori modul direktori root. Ing saben modul ana skema direktori standar - manifes, file, template, lib, lan liya-liyane.

Struktur file ing modul

Oyod modul bisa ngemot direktori ing ngisor iki kanthi jeneng deskriptif:

  • manifests - ngandhut manifestos
  • files - isine file
  • templates - iku ngandhut Cithakan
  • lib - ngandhut kode Ruby

Iki dudu dhaptar lengkap direktori lan file, nanging cukup kanggo artikel iki saiki.

Jeneng sumber lan jeneng file ing modul

Dokumentasi kene.

Sumber daya (kelas, definisi) ing modul ora bisa dijenengi apa wae sing disenengi. Kajaba iku, ana korespondensi langsung antarane jeneng sumber lan jeneng file ing ngendi Wayang bakal nggoleki katrangan babagan sumber kasebut. Yen sampeyan nglanggar aturan jeneng, Wayang mung ora bakal nemokake katrangan sumber, lan sampeyan bakal entuk kesalahan kompilasi.

Aturane prasaja:

  • Kabeh sumber daya ing modul kudu ana ing papan jeneng modul. Yen modul diarani foo, banjur kabeh sumber daya kudu dijenengi foo::<anything>, utawa mung foo.
  • Sumber daya kanthi jeneng modul kudu ana ing file kasebut init.pp.
  • Kanggo sumber daya liyane, skema jeneng file kaya ing ngisor iki:
    • ater-ater kanthi jeneng modul dibuwak
    • kabeh titik pindho, yen ana, diganti karo garis miring
    • extension ditambahake .pp

Aku bakal nduduhake karo conto. Ayo ngomong aku nulis modul nginx. Isine sumber daya ing ngisor iki:

  • kelas nginx diterangake ing manifest init.pp;
  • kelas nginx::service diterangake ing manifest service.pp;
  • netepake nginx::server diterangake ing manifest server.pp;
  • netepake nginx::server::location diterangake ing manifest server/location.pp.

Cithakan

Mesthi sampeyan dhewe ngerti apa cithakan sing aku ora bakal njlèntrèhaké ing rinci kene. Nanging aku bakal ninggalake mung ing kasus pranala menyang Wikipedia.

Cara nggunakake cithakan: Makna cithakan bisa ditambahi nggunakake fungsi template, sing dilewati path menyang cithakan. Kanggo sumber daya saka jinis file digunakake bebarengan karo parameter content. Contone, kaya iki:

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

Ndeleng dalan <modulename>/<filename> nuduhake file <rootdir>/modules/<modulename>/templates/<filename>.

Kajaba iku, ana fungsi inline_template - nampa teks cithakan minangka input, dudu jeneng berkas.

Ing cithakan, sampeyan bisa nggunakake kabeh variabel Wayang ing ruang lingkup saiki.

Wayang ndhukung template ing format ERB lan EPP:

Sedhela babagan ERB

Struktur kontrol:

  • <%= ВЫРАЖЕНИЕ %> - masang Nilai saka expression
  • <% ВЫРАЖЕНИЕ %> - ngitung nilai ekspresi (tanpa nglebokake). Pernyataan kondisional (yen) lan puteran (saben) biasane ana ing kene.
  • <%# КОММЕНТАРИЙ %>

Ekspresi ing ERB ditulis ing Ruby (ERB bener-bener Embedded Ruby).

Kanggo ngakses variabel saka manifest, sampeyan kudu nambah @ menyang jeneng variabel. Kanggo mbusak break baris sing katon sawise mbangun kontrol, sampeyan kudu nggunakake tag nutup -%>.

Conto nggunakake cithakan

Ayo dadi ngomong aku nulis modul kontrol ZooKeeper. Kelas sing tanggung jawab kanggo nggawe konfigurasi katon kaya iki:

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

Lan cithakan sing cocog zoo.cfg.erb - Dadi:

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

Fakta lan Variabel Dibangun

Asring bagean tartamtu saka konfigurasi gumantung apa sing saiki kedadeyan ing simpul. Contone, gumantung saka release Debian, sampeyan kudu nginstal siji utawa versi paket liyane. Sampeyan bisa ngawasi kabeh iki kanthi manual, rewriting manifests yen simpul diganti. Nanging iki ora pendekatan serius;

Kanggo njupuk informasi babagan node, Wayang duwe mekanisme sing diarani fakta. Fakta - iki minangka informasi babagan simpul, kasedhiya ing manifests ing wangun variabel biasa ing namespace global. Contone, jeneng host, versi sistem operasi, arsitektur prosesor, dhaptar pangguna, dhaptar antarmuka jaringan lan alamat, lan liya-liyane. Kasunyatan kasedhiya ing manifests lan template minangka variabel biasa.

Conto nggarap fakta:

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

Sacara resmi, kasunyatan nduweni jeneng (string) lan nilai (macem-macem jinis kasedhiya: strings, arrays, dictionaries). mangan set saka dibangun ing kasunyatan. Sampeyan uga bisa nulis dhewe. Fact collectors diterangake kaya fungsi ing Ruby, utawa minangka file eksekusi. Kasunyatan uga bisa ditampilake ing wangun file teks karo data ing simpul.

Sajrone operasi, agen wayang pisanan nyalin kabeh kolektor fakta sing kasedhiya saka pappetserver menyang simpul, sawise iku diluncurake lan ngirim fakta sing diklumpukake menyang server; Sawise iki, server wiwit nyusun katalog.

Kasunyatan ing wangun file eksekusi

Kasunyatan kasebut diselehake ing modul ing direktori facts.d. Mesthine, file kasebut kudu bisa dieksekusi. Nalika mbukak, dheweke kudu ngasilake informasi menyang output standar ing format YAML utawa key = value.

Aja lali manawa kasunyatan kasebut ditrapake kanggo kabeh kelenjar sing dikontrol dening server poppet sing dipasang ing modul sampeyan. Mulane, ing skrip, priksa manawa sistem kasebut duwe kabeh program lan file sing dibutuhake supaya bisa digunakake.

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

Fakta Ruby

Kasunyatan kasebut diselehake ing modul ing direktori 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

Fakta teks

Kasunyatan kasebut diselehake ing simpul ing direktori /etc/facter/facts.d ing Wayang lawas utawa /etc/puppetlabs/facts.d ing Wayang anyar.

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

Njupuk Fakta

Ana rong cara kanggo nyedhaki kasunyatan:

  • liwat kamus $facts: $facts['fqdn'];
  • nggunakake jeneng kasunyatan minangka jeneng variabel: $fqdn.

Luwih becik nggunakake kamus $facts, utawa luwih apik, nuduhake spasi jeneng global ($::facts).

Mangkene bagean dokumentasi sing cocog.

Dibangun ing Variabel

Saliyane kasunyatan, ana uga sawetara variabel, kasedhiya ing ruang jeneng global.

  • kanyatan dipercaya - variabel sing dijupuk saka sertifikat klien (amarga sertifikat biasane ditanggepi ing server poppet, agen kasebut ora bisa njupuk lan ngganti sertifikat, mula variabel kasebut "dipercaya"): jeneng sertifikat, jeneng inang lan domain, ekstensi saka sertifikat.
  • kasunyatan server —variabel sing ana gandhengane karo informasi babagan server—versi, jeneng, alamat IP server, lingkungan.
  • kasunyatan agen - variabel ditambahake langsung dening wayang-agen, lan ora dening facter - jeneng sertifikat, versi agen, versi wayang.
  • variabel master - Variabel Pappetmaster (sic!). Kira-kira padha karo ing kasunyatan server, plus nilai parameter konfigurasi kasedhiya.
  • variabel kompiler - variabel compiler sing beda-beda ing saben ruang lingkup: jeneng modul saiki lan jeneng modul sing diakses obyek saiki. Bisa digunakake, contone, kanggo mriksa yen kelas pribadi sampeyan ora digunakake langsung saka modul liyane.

Tambahan 1: carane mbukak lan debug kabeh iki?

Artikel kasebut duwe akeh conto kode wayang, nanging ora ngandhani babagan cara mbukak kode iki. Inggih, kula mbenerake dhewe.

Agen cukup kanggo mbukak Wayang, nanging umume sampeyan uga butuh server.

Agen

Paling wiwit versi 5, paket wayang-agen saka gudang resmi Puppetlabs ngemot kabeh dependensi (ruby lan permata sing cocog), supaya ora ana alangan instalasi (Aku ngomong babagan distribusi basis Debian - kita ora nggunakake distribusi adhedhasar RPM).

Ing kasus sing paling gampang, kanggo nggunakake konfigurasi wayang, cukup kanggo miwiti agen ing mode tanpa server: yen kode wayang disalin menyang simpul, bukak 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

Mesthi, luwih apik kanggo nyiyapake server lan mbukak agen ing simpul ing mode daemon - banjur saben setengah jam bakal ngetrapake konfigurasi sing diundhuh saka server.

Sampeyan bisa niru model push karya - pindhah menyang simpul sing kasengsem lan miwiti sudo puppet agent -t. kunci -t (--test) bener kalebu sawetara opsi sing bisa diaktifake kanthi individu. Opsi kasebut kalebu ing ngisor iki:

  • aja mbukak ing mode daemon (kanthi standar agen diwiwiti ing mode daemon);
  • mati sawise nglamar katalog (kanthi standar, agen bakal terus bisa lan aplikasi konfigurasi sapisan saben setengah jam);
  • nulis log karya sing rinci;
  • nuduhake owah-owahan ing file.

Agen kasebut duwe mode operasi tanpa owah-owahan - sampeyan bisa nggunakake nalika sampeyan ora yakin yen sampeyan wis nulis konfigurasi sing bener lan pengin mriksa apa sing bakal diganti agen sajrone operasi. Mode iki diaktifake dening parameter --noop ing baris perintah: sudo puppet agent -t --noop.

Kajaba iku, sampeyan bisa ngaktifake log debugging karya - ing kono, wayang nulis babagan kabeh tumindak sing ditindakake: babagan sumber daya sing lagi diproses, babagan paramèter sumber daya iki, babagan program apa sing diluncurake. Mesthi iki parameter --debug.

Server

Aku ora bakal nimbang persiyapan lengkap pappetserver lan deploying kode ing artikel iki Aku mung bakal ngomong sing metu saka kothak ana versi fungsi kebak server sing ora mbutuhake konfigurasi tambahan kanggo bisa karo nomer cilik; simpul (ngomong, nganti satus). A nomer luwih saka kelenjar bakal mbutuhake tuning - minangka standar, puppetserver mbukak ora luwih saka papat buruh, kanggo kinerja luwih sampeyan kudu nambah nomer lan aja lali kanggo nambah watesan memori, digunakake server bakal uwuh ngumpulake paling wektu.

Panyebaran kode - yen sampeyan butuh kanthi cepet lan gampang, banjur deleng (ing r10k)[https://github.com/puppetlabs/r10k], kanggo instalasi cilik kudu cukup.

Adendum 2: Pedoman Coding

  1. Selehake kabeh logika ing kelas lan definisi.
  2. Tansah kelas lan definisi ing modul, ora ing manifests njlèntrèhaké simpul.
  3. Gunakake kanyatan.
  4. Aja nggawe yen adhedhasar jeneng host.
  5. Bebas bae kanggo nambah paramèter kanggo kelas lan definisi - iki luwih apik tinimbang logika implisit sing didhelikake ing awak kelas / nemtokake.

Aku bakal nerangake kenapa aku nyaranake nindakake iki ing artikel sabanjure.

kesimpulan

Ayo rampung karo pambuka. Ing artikel sabanjure aku bakal ngandhani babagan Hiera, ENC lan PuppetDB.

Mung pangguna pangguna sing bisa melu survey. mlebunggih.

Nyatane, ana luwih akeh materi - Aku bisa nulis artikel babagan topik ing ngisor iki, milih apa sing bakal sampeyan kasengsem maca babagan:

  • 59,1%Konstruksi wayang canggih - sawetara telek tingkat sabanjure: puteran, pemetaan lan ekspresi lambda liyane, kolektor sumber daya, sumber daya sing diekspor lan komunikasi antar host liwat Wayang, tag, panyedhiya, jinis data abstrak.13
  • 31,8%"Aku admin ibuku" utawa carane kita ing Avito kekancan karo sawetara server poppet saka macem-macem versi, lan, ing asas, bagean babagan administering server poppet.7
  • 81,8%Carane nulis kode wayang: instrumentasi, dokumentasi, testing, CI/CD.18

22 pangguna milih. 9 pangguna abstain.

Source: www.habr.com