Drift/Salt

From Programvareverkstedet

Salt er et system for å distribuere filer og sørge for at maskiner har samme oppsett. Etter at vi satte opp versjonskontroll via git lokalt på lommel er det nødvenidg å gå gjennom oppsettet beskrevet i Gjøre endringer-avsnittet før man kan bidra til å endre salt-oppsettet til PVV.

Sette opp ny salt minion

Installasjon

ny-minion# wget -O - https://www.pvv.ntnu.no/salt/salt-setup.sh | bash
ny-minion# rediger /etc/salt/grains og legg til gruppene maskinen er i, se dokumentasjonen for [[Drift/Salt#Grains|grains (grupper)]]
ny-minion# service salt-minion restart
ny-minion$# ssh root@salt.pvv.ntnu.no
salt-master$ sudo salt-key -L
salt-master$ sudo salt-key -a ny-minion.pvv.ntnu.no
ny-minion# salt-call saltutil.sync_grains
ny-minion# salt-call state.highstate saltenv=base pillarenv=base

Hvis alt har har gått bra, vil pingtesten gi true for maskinen din nå. Hvis ikke, kjør service salt-minion status som root på din nye minion for å få hint om hva som er galt. Konfigurasjonsfilen til salt ligger i /etc/salt/minion.

I tilfellet man endrer hostname på en minion, gjør følgende for å få det oppdatert i salt: Stop salt-minion på den berørte maskinen. Slett nøkkelen til maskinen fra salt-master ved å kjøre salt-key -d minion_id på salt-masteren. Slett /etc/salt/minion/minion_id. Start salt-minion service-en. Autoriser den nye nøkkelen med det nye navnet i salt-master.

Husk å legge nyoppsatte maskiner til i riktige grains (grupper).

For montering av hjemmeområdene (autofs) skal bli tillat av filtjeneren må maskinen ha en IP addresse med gydlig DNS revers-oppslag. Legg den nye maskinen inn i DNS.

Gjøre endringer

Endringer gjøres på salt-masteren (salt.pvv.ntnu.no, som for tiden peker på sleipner.pvv.ntnu.no). Alle endringer gjøres som din personlige bruker.

Opprette bruker på salt-masteren

Om du ikke har en bruker, logg inn som root på serveren og lag en. Adduser vil spørre deg om «Current Kerberos password», men du kan bare trykke enter og si nei til å prøve igjen, så fungerer det fint. Legg også brukeren til i sudo-gruppen.

lommel ~ # adduser johndoe && adduser johndoe sudo
Adding user `johndoe' ...
Adding new group `johndoe' (1000) ...
Adding new user `johndoe' (1000) with group `johndoe' ...
Current Kerberos password: 
Current Kerberos password: 
passwd: Authentication token manipulation error
passwd: password unchanged
Try again? [y/N] n
Changing the user information for johndoe
Enter the new value, or press ENTER for the default
	Full Name []: John Doe
	Room Number []: 
	Work Phone []: 
	Home Phone []: 
	Other []: 
Is the information correct? [Y/n] 

Passordet du bruker vil være det samme som admin-principalen din i Kerberos har, altså johndoe/admin i eksempelet over. Om du ikke har en admin-principal, se Drift/Kerberos#Lage_admin-principal.

Gjøre endringer

Når du logger inn første gang vil du automatisk få sjekket ut salt-treet i ~/salt. Gjør endringene dine der inne, og push master til origin for å aktivere endringene.

Det kan være lurt å teste med en maskin først, ved å logge inn på den og gjøre en dry-run (du kan kjøre kommandoer rett fra salt-masteren også, men det er uansett en fordel å ha et skall på maskinen i tilfelle noe går galt):

salt-call state.highstate test=True

Teste endringer før commit

PVV har et lite triks som oppretter et salt-environment [1] for hver bruker. Dette gjør at du kan teste koden din på en minion uten å committe. Det gjør du slik:

salt-call state.highstate saltenv="$LOGNAME" test=True

Grains

Salt kan bruke grains for å gjøre noe på en gruppe med maskiner. salt 'hostname*' grains.items viser alle grains hostname er med i. For eksempel kan man si salt -G 'os_familt:Debian' test.ping for å pinge maskiner som er basert på Debian.

For å legge en minion til en gruppe gjør følgende på minion-en:

Konfigurasjon

$ vim /etc/salt/grains

roles:
  - standard
  - desktop

I skrivende stund har vi følgende roller:

standard Alle maskiner med standard-oppsett (det vil si at brukere kan logge inn der)
desktop Desktopmaskiner
file-server Filservere, som f.eks. microbel.
mysql-server MySQL-serveren
postgresql-server PostGreSQL-serveren
web-frontend Web-frontend (ikke den som hoster brukerenes hjemmesider)
web-homes Web-backend for brukeres hjemmesider
fwlogin Maskinen lytter på SSH på port 80 og 443
salt-master salt-masteren (skal ikke ha standardoppsett)

Når minions har blitt lagt til i roller er det viktig å huske på å synkronisere disse med masteren. Den letteste måten å gjøre det på er å kjøre salt '*' saltutil.sync_grains fra salt-masteren.

For å nå maskiner gjennom egendefinerte grains bruk salt -G 'attributt:verdi' kommando. Et eksempel er salt -G 'roles:workstation' test.ping.

Tekniske ting

Litt nyttig info om hvordan ting fungerer under panseret

Templates

For å distribuere en template og fylle inn verdier kan du gjøre noe ala dette:

/etc/ssh/sshd_config:
  file.managed:
    - source: salt://{{ tpldir }}/sshd_config.jinja
    - template: jinja
    - context:
{% if 'fwlogin' in grains['roles'] %}
      ports: [22, 80, 443]
{% else %}
      ports: [22]
{% endif %}

"template: jinja" betyr at filen skal tolkes som en jinja-template, context inneholder alle variablene.

Restart av tjenester

Etter at en fil er endret eller en pakke er installert kan det være kjekt å automatisk reloade tjenester som påvirkes av det. Tjenester kan ha ulike navn på ulike arkitekturer, men det kan man ta høyde for.

{% set sshd_service = {
    'Debian': 'ssh',
    'FreeBSD': 'sshd',
}.get(grains.os_family) %}

sshd-service:
  service.running:
    - name: {{ sshd_service }}
    - watch:
      - file: /etc/ssh/sshd_config

Her er et annet eksempel, som sørger for at en pakke er installert i samme slengen (her antas det at både pakken og servicen heter salt-master alle arkitekturer)

salt-master: 
  pkg.installed: [] 
  service.running: 
    - watch: 
      - file: /etc/salt/master.d/pvv.conf 
    - require: 
      - pkg: salt-master 


Distribuere mapper

Lag en overordnet mappe som inneholder både mappen du ønsker å distribuere og en sls-fil i salt-mappen: /srv/salt/overordnet_mappe. Der legger du mappen du ønsker å distribuere, og lager en fil du kaller for init.sls. Den formateres slik:

/path/til/der/du/vil/at/mappen/skal/ende/opp/på/minions
 file.recurse:
  - source: salt://overornet_mappe/mappen_du_vil_distribuere
#optional felter:
  - include_empty: True #sørger for at tomme undermapper kommer med 
  - dir_mode: 777 #må bruke dir_mode når man dister mapper, bruk mode: hvis du dister filer
  - user: brukernavn #hilken bruker skal mappen, undermapper og filer tilhøre
  - group: eall_s #default-gruppen er root. Skal mappen tilhøre noen andre bruk eall_s eksplisitt

For å så få distribuert mappen kjør følgende kommando: salt '*' state.sls overordnet_mappe

States og håndheving

Salt oppererer med SLS filer (SaLt State) for å holde orden på reglene for distribusjon og hvordan disse skal håndheves. Legg SLS filene i /srv/salt/. En av de viktigste SLS filene er /srv/salt/top.sls da den spesifiserer hvilke SLS filer som skal anvendes på hvilke minions. (Alle sls-filene er på salt-master.)

For eksempel hvis vi har SLS filene:

/srv/salt/top.sls
/srv/salt/common/init.sls
/srv/salt/common/packages.sls
/srv/salt/sl_eksempel.sls

La så filene se slik ut:

#top.sls:
base:
  '*':
    - common
  'roles:desktop':
    - match: grain
    - sl_eksempel
#common/init.sls:
include:
  - common.packages
#common/packages.sls:
vim:
  pkg:
    - installed
grep:
  pkg:
    - installed
#sl_eksempel.sls:
sl:
  pkg:
    - installed

Hva filene sier:

  • top.sls sier at at alle maskiner skal få staten som er spesifisert i 'common'. Siden 'common' er en mappe og ikke en SLS fil vil det implisitt bety at staten som er gitt i common/init.sls brukes istedenfor.
    • Den sier også at alle maskiner som matcher grainen roles:desktop skal ha staten spesifisert i sl_eksempel.sls
  • common/init.sls starter med å ved includen si at alt som er i /srv/salt/common/packages også skal kjøres i tillegg til innholdet den har (som for dette eksempelet er ikke noe mer)
  • packages.sls sier at to pakker, vim og grep, skal være installert på alle maskiner som hører til staten.
  • sl_eksempel.sls sier at pakken sl skal være installert.

For at minionsene skal gå inn å sjekke hvilke states de skal ha, og anvende dem, kjør:
salt '*' state.highstate
på salt-master.

Sørg for at Salt-minion er kjørende og at den jevnlig poller om nye ting fra master

Lag en mappe /srv/salt/minion_configuration som inneholder en init.sls fil og en minion fil. La init.sls se slik ut:

salt-minion: # sier at det er salt-minion servicen vi påvirker
  service:
    # sier at den skal være kjørende:
    - running
    - enable: True
    # sier at servicen skal restartes om man merker en endring i den oppgitte filen:
    - watch:
      - file /etc/salt/minion
/etc/salt/minion: #sier at denne filen skal speile den oppgitte fra master
  file.managed:
    # filen som skal kopieres over til minionen
    - source salt://minion_configuration/minion
    # bruker, gruppe, og premissions for filen når den ender opp på minionen:
    - user: root
    - group: root
    - mode: 644
    # sier at filen er et jinjatemplate, og at variablene i templatet skal byttes ut
    # med verdiene gitt for dem i context-seksjonen:
    - template: jinja
    - context:
      saltmaster: lommel.pvv.ntnu.no
      timer: 4

Kopier så inn en minion-fil til /srv/salt/minion_configuration/minion, og legg til disse linjene:

#sett inn under "#master: salt" eller istedenfor det som måtte stå på på linjen som begynner med "master:"
master: {{saltmaster}}

#sier at highstate skal schedules til å kjøre hver 'timer' time:
schedule:
  highstate:
    function: state.highstate
    hours: {{ timer }}

Behandlig av errors og feilmeldinger som kan dukke opp ofte

No Top file or external nodes data matches found

Om salt sier dette:

          ID: states
    Function: no.None
      Result: False
     Comment: No Top file or external nodes data matches found
     Started: 
    Duration: 
     Changes:   

Betyr det sannsynligvis at du har glemt å sette noen roller i /etc/salt/grains

UnicodeDecodeError

Hvis du får «UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 99: ordinal not in range» eller lignende kommer dette av en kjent feil i Salt: https://github.com/saltstack/salt/issues/16139

Dette skjer mye oftere om du har gammel salt. Prøv dette:

echo deb http://debian.saltstack.com/debian $(lsb_release -c | awk '{print $2}')-saltstack main > /etc/apt/sources.list.d/saltstack.list
aptitude update && aptitude dist-upgrade

No matching sls found

Hvis du får feilen:
No matching sls found for 'sls_file_or_folder_name' in env 'base'
Så har du sannsynligvis skrevet filnavn.sls (må være uten .sls), eller mappenavnet feil.

Nyttige kommandoer og syntax

Viktig om syntax:

  • All indentering er med mellomrom da tabs ser ut til å krasje, to ser ut til å være standard

Hvordan kopiere enkeltfiler ad-hoc fra salt-master til minions:
salt-cp "*" /path/to/file/on/salt/master /path/to/file/on/minions

Hvordan kjøre kode på minions:
salt "*" cmd.run "ps -e | grep salt"

For å kjøre på enkeltmaskiner istedenfor alle eller grains skriv inn navnet istedenfor "*". Eksempel:
salt maskinnavn.pvv.ntnu.no cmd.run "ps -e | grep salt"

For å sjekke om en pakke er installer og hvilken versjon den har:
salt "*" pkg.version "grep"

For å installere eller oppgradere en pakke:
salt maskinnavn.pvv.ntnu.no pkg.install sl

For å avinstallere en pakke:
salt maskinnavn.pvv.ntnu.no pkg.remove sl

For å se salt-pkg kommandoer:
salt maskinnavn.pvv.ntnu.no pkg. og spam tab.