Werken bij Triple | Server management met Saltstack
Overslaan naar content

BLOG

Server management met Saltstack

Saltstack

Deze blog is geschreven door Rogier van der Heide, Engineer bij Triple.

Eén van de afdelingen van Triple is Technology Operations (Techops), waar ik deel van uitmaak. Het doel van deze afdeling is het beheren van servers en cloud-hosting oplossingen voor onze klanten. We behandelen zaken zoals patching, monitoring, change management en incidentafhandeling. Om deze diensten te kunnen leveren, maken we gebruik van verschillende soorten tools. Eén van die tools heet Saltstack. In deze blog zal ik uitleggen wat het is, en hoe en waarom we het gebruiken.

Wat is Saltstack?

Salt, ook bekend als Saltstack, is een Python-applicatie die ongeveer 11 jaar geleden is gemaakt. Het doel ervan is het automatiseren van softwareconfiguratie met behulp van state management. Het ondersteunt Infrastructure-as-code, waardoor je Git kunt gebruiken om je states op te slaan.

Met behulp van YAML-templates verrijkt met Jinja-code kun je specifieke states schrijven die alle aanpassingen maken die je wenst op de specifieke doelen die je opgeeft.

In gewone taal betekent dit dat we kunnen schrijven hoe we software willen installeren op onze virtuele machines en Git gebruiken om deze templates op te slaan, zodat we ze keer op keer kunnen hergebruiken om ervoor te zorgen dat onze servers op dezelfde manier geconfigureerd zijn.

Saltstack is essentieel bij het beheren van al onze virtuele machines en zorgt ervoor dat verschillende omgevingen (DEV/ACC/PRD) voor dezelfde oplossing vergelijkbaar zijn, met alleen de vereiste verschillen.

Er zijn talloze andere software-oplossingen die hetzelfde effect bereiken als Saltstack, zoals Ansible, Puppet of Chef. We hebben voor Saltstack gekozen om twee redenen: De eerste is het netwerkgedrag, waarbij je een Salt master hebt en voor elk doelwit een minion. In het geval van Saltstack is het niet de master die met de minions communiceert, maar juist andersom. De minion vraagt werk aan bij de master.

Dit betekent dat de minions de communicatie initiëren en wordt beschouwd als uitgaand verkeer. Met een groot aantal verschillende klanten stuiten we meestal op problemen met inkomend verkeer als gevolg van het gebruik van firewalls. Echter, gevallen waarin uitgaand verkeer geblokkeerd wordt door firewalls zijn vrij zeldzaam. Daarom hebben we gekozen voor Saltstack, omdat het makkelijker is om aanvankelijk in te stellen.

De tweede reden is dat Saltstack een relatie heeft tussen de Master en de Minion. Dit biedt de mogelijkheid om actief minions te targeten op basis van hun kenmerken. Vanwege onze grote vloot van verschillende soorten servers en klanten, sluit dit perfect aan bij onze wensen.

Onze Saltstack setup

We hebben Saltstack opgezet met behulp van een MongoDB voor pillar-gegevens en deze gekoppeld aan een git-repository waarin we al onze states opslaan.

Saltstack heeft drie gegevensbronnen die je gebruikt om het gedrag ervan te manipuleren. Deze zijn:

  • State-bestanden

  • Pillar-gegevens

  • Grains

State-bestanden zijn de YAML-templates die we opslaan in git en de extensie .sls hebben. Deze bevatten state-modules die een specifiek gedrag specificeren. Bijvoorbeeld file.managed, waarmee een specifiek bestand op een server wordt beheerd en ervoor zorgt dat een specifiek bestand op een virtuele machine gelijk is aan wat in deze state is gespecificeerd. Of pkg.installed, waarmee wordt gecontroleerd of een pakket is geïnstalleerd via de standaardpakketbeheerder (bijv. yum, apt) en ontbrekende pakketten uit de lijst worden geïnstalleerd. Op de Saltstack-documentatiesite zijn talloze state-modules te vinden. Om logica aan deze state-bestanden toe te voegen, kan Jinja worden gebruikt om ze dynamischer te maken en gegevens van Pillar of Grains op te nemen.

Pillar-gegevens bevatten informatie die we toevoegen aan een minion. Deze gegevens komen uit een MongoDB-database. We gebruiken deze gegevens om extra informatie aan de minion te geven, die we vervolgens gebruiken in onze states of om een specifieke groep minions te targeten. Denk aan informatie zoals tot welk project ze behoren, wie hun klant is. Maar ook aan staatsspecifieke informatie, zoals welk statisch IP-adres we willen configureren op de netwerkinterfacekaart (NIC), of de tijdzone waaraan de datum/tijd van de server moet worden geconfigureerd.

De minion zelf genereert voornamelijk grain-gegevens. Dit bevat informatie zoals het besturingssysteem waarop de minion draait, welk type CPU de machine heeft of de hostnaam. Het kan ook worden gebruikt om bepaalde informatie op te slaan. Bijvoorbeeld het instellen van bepaalde vlaggen om aan te geven dat een specifiek softwarepakket is geïnstalleerd, zodat we het niet telkens opnieuw installeren wanneer we dezelfde state uitvoeren (als het niet via de standaardpakketbeheerder is geïnstalleerd).

Een eenvoudig voorbeeld

Laten we een eenvoudig voorbeeld nemen van een state-bestand dat we gebruiken om een vrij standaard softwarepakket te installeren dat wordt gebruikt bij het werken met websites, namelijk Apache.

{% set customer = salt.pillar.get( 'cmdb:customer:label' ).lower() %} {% set project = salt.pillar.get( 'cmdb:project:label' ).lower() %} {% set prefix = 'httpd' %} {{prefix}}-packages: pkg.installed: - names: - httpd - mod_ssl - httpd-itk {{prefix}}-httpd-file: file.managed: - name: /etc/httpd/conf/httpd.conf - source: salt://customer/{{customer}}/{{project}}/web/files/httpd/httpd.conf - user: root - group: root - mode: 644

In het gegeven voorbeeld hebben we een syntaxis van YAML gemengd met Jinja. Dit wordt door Salt weergegeven voordat de YAML wordt toegepast. Laten we zeggen dat we de volgende gegevens in onze pillar hebben:

  • cmdb.customer.label = voorbeeld

  • cmdb.project.label = foo

De resulterende YAML zal er als volgt uitzien:

httpd-packages: pkg.installed: - names: - httpd - mod_ssl - httpd-itk httpd-httpd-file: file.managed: - name: /etc/httpd/conf/httpd.conf - source: salt://customer/example/foo/web/files/httpd/httpd.conf - user: root - group: root - mode: 644

Alleen met behulp van deze twee state-modules bereiken we het volgende:

  • Installeer Apache met mod_ssl en ITK met behulp van de standaardpakketbeheerder (in ons geval yum).

  • Push onze standaard Apache-configuratie.

Dit behandelt de standaardwebserver met uw generieke configuratie. Nu komt het volgende: hoe om te gaan met de configuratie van uw websites. Voor de eenvoud laat ik alleen zien hoe u individuele websiteconfiguraties kunt verwerken. Er is meer nodig, zoals het maken van mappen en het beheren van certificaten, wat te complex is voor dit voorbeeld.

{% for dom in pillar.custom.domains %} {% set domain = pillar['custom']['domains'][dom] %} {{domain.name}}-user: user.present: - name: {{domain.name}} - home: /home/domains/{{domain.name}}/ - createhome: false - usergroup: true - password: {{domain.password}} {{domain.name}}-vhost-file: file.managed: - name: /etc/httpd/conf.d/{{domain.name}}.conf - source: salt://customer/{{customer}}/{{project}}/files/httpd/vhost.conf.jinja - user: root - group: root - mode: 644 - template: jinja - context: domain: {{domain}} - require: - {{domain.name}}-user {% endfor %}

De Pillar-gegevens die bij dit deel horen, zijn als volgt:

"custom" : { "domains" : { "www_example_com" : { "name" : "www.example.com", "password" : "$1$snip" } } },

Door de state te combineren met de pillar-gegevens wordt er een lus gemaakt die voor elke domeindefinitie in de custom.domains pillar een vhost-configuratie maakt. Combineer dit vervolgens met states die de juiste mappen maken, en je kunt een complete configuratie maken voor elke website die je definieert. Elk domein heeft dan zijn eigen home-map om gegevens naartoe te sturen, behorend tot zijn eigen gebruiker, en Apache wordt geconfigureerd met de juiste hostnamen.

Een levende CMDB

Je hebt zojuist een eenvoudig maar krachtig voorbeeld gezien van wat je kunt doen met Saltstack als het gaat om het installeren en onderhouden van software.

Maar Saltstack biedt nog een andere functie die echt essentieel is bij het onderhouden van een grote, diverse vloot van servers. Vanwege de grains die worden ingesteld op basis van het type server dat je hebt en het feit dat je de status van alle minions kunt opvragen vanuit een enkele master, heb je in feite een levende CMDB.

Met behulp van compounds kun je bijvoorbeeld snel opvragen hoeveel Ubuntu 20-servers je hebt. Of zien welke versie van OpenSSL je hebt geïnstalleerd.

$ salt -C "G@os:Ubuntu and I@cmdb:customer:label:example" cmd.run 'openssl version' acc-server.example.local: OpenSSL 1.1.1f 31 Mar 2020 prd-server.example.local: OpenSSL 1.1.1f 31 Mar 2020 ------------------------------------------- Summary ------------------------------------------- # of minions targeted: 2 # of minions returned: 2 # of minions that did not return: 0 # of minions with errors: 0 -------------------------------------------

Een andere handige functie is het toewijzen van servers aan specifieke onderhoudsgroepen, zodat je al je niet-productie servers overdag kunt patchen en alleen je productieservers 's nachts kunt patchen. Je kunt met één eenvoudige opdracht alle servers tegelijk patchen als je dat wilt.

Tot slot

Zoals je kunt zien in de eenvoudige voorbeelden hierboven, biedt Saltstack een breed scala aan mogelijkheden bij het werken met virtuele machines.

Het gebruik van state-bestanden en git stelt je in staat om ervoor te zorgen dat je omgevingen vergelijkbaar zijn en wijzigingen snel kunnen worden doorgevoerd zonder angst voor afwijkingen.

En de mogelijkheid om al je servers tegelijkertijd bij te werken, zal de tijd die je nodig hebt om een groot aantal servers te patchen aanzienlijk verminderen.

Zodra je meer uitgebreide state-bestanden maakt en je pillar-gegevens standaardiseert, kun je dezelfde sjablonen steeds opnieuw gebruiken, waardoor je minder tijd nodig hebt om een nieuwe virtuele machine in te stellen. En als je de noodzakelijke configuratiecontroles inbouwt, zal het implementeren van wijzigingen nog veiliger zijn.

Al met al heeft Saltstack ons werk veel gemakkelijker en gestandaardiseerder gemaakt, en het aantal incidenten is verminderd sinds we het zijn gaan gebruiken.

Een andere handige functie is het toewijzen van servers aan specifieke onderhoudsgroepen, zodat je al je niet-productie servers overdag kunt patchen en alleen je productieservers 's nachts kunt patchen. Je kunt met één eenvoudige opdracht alle servers tegelijk patchen als je dat wilt.

Tot slot

Zoals je kunt zien in de eenvoudige voorbeelden hierboven, biedt Saltstack een breed scala aan mogelijkheden bij het werken met virtuele machines.

Het gebruik van state-bestanden en git stelt je in staat om ervoor te zorgen dat je omgevingen vergelijkbaar zijn en wijzigingen snel kunnen worden doorgevoerd zonder angst voor afwijkingen.

En de mogelijkheid om al je servers tegelijkertijd bij te werken, zal de tijd die je nodig hebt om een groot aantal servers te patchen aanzienlijk verminderen.

Zodra je meer uitgebreide state-bestanden maakt en je pillar-gegevens standaardiseert, kun je dezelfde sjablonen steeds opnieuw gebruiken, waardoor je minder tijd nodig hebt om een nieuwe virtuele machine in te stellen. En als je de noodzakelijke configuratiecontroles inbouwt, zal het implementeren van wijzigingen nog veiliger zijn.

Al met al heeft Saltstack ons werk veel gemakkelijker en gestandaardiseerder gemaakt, en het aantal incidenten is verminderd sinds we het zijn gaan gebruiken.

Meer verhalen van Tripelaars

SXSW 2023: AI, Interactieve Content en de menselijke maat

Erik van Schalkwijk

Cross-cultureel design: ontwerpen voor andere culturen dan die van jezelf

Anna Koopmans

WWDC 2022: de superkrachten van developers ondersteunen

Jeroen Bakker