Eindeutige Machine ID für den SUSE Manager

Wenn man den SUSE Manager für die Verwaltung seiner Linux Clients einsetzt, dann ist es notwendig beim Hinzufügen neuer Clients auf eine eindeutige machine.id zu achten. Diese machine.id wird bei der Installation von SLES automatisch generiert und ist einmalig. Wenn jedoch die neuen Server aus VM Templates erstellt werden, dann haben alle neuen Server die id des Templates. Im normalen Betrieb stört das nicht weiter, wenn man jedoch die Server mit dem SUSE Manager verwalten möchte dann führt das zu erstmal überraschenden Phänomenen. Der SUSE Manager erwartet eindeutige machine.ids und überschreibt bereits registrierte Server mit der gleichen ID ohne Warnung. Das führt dazu, dass bereits registrierte Server aus dem SUSE Manager verschwinden.

Eine eindeutigen machine.id erfordert die folgenden Schritte:

rm /etc/machine-id
rm /var/lib/dbus/machine-id
service salt-minion stop
rm -rf /var/cache/salt
rm /etc/salt/minion_id
dbus-uuidgen --ensure
systemd-machine-id-setup

re-run the bootstrap script

Damit es nicht versehentlich zu doppelten machine.ids kommt, kann man bereits im Template Vorkehrungen treffen. Das lässt sich zum Beispiel so lösen: Man legt ein File an und prüft nach dem Start, ob dieses File existiert. Wenn ja, dann wird eine neue machine.id generiert und das File gelöscht.

touch /var/log/need_unique_machine_id.txt

Das folgende shell Script speichert man z.B. unter /root/bin/machine_id.sh und macht es ausführbar.

#!/bin/sh
# Michael Lohmann
# 07.08.18
# check if new machine id nescessary
# if /var/log/need_unique_machine_id.txt exists then generate new id and register client


if [  -f /var/log/need_unique_machine_id.txt ]; then
	echo "Generate new machine id"
	rm /etc/machine-id
	rm /var/lib/dbus/machine-id
	service salt-minion stop
	rm -rf /var/cache/salt
	rm /etc/salt/minion_id
	dbus-uuidgen --ensure
	systemd-machine-id-setup
	echo Registering Server at Suse Manager
	if curl -k https://susemanager/pub/bootstrap/bootstrap.sh >/tmp/bootstrap.sh; then
		sh /tmp/bootstrap.sh
		rm /var/log/need_unique_machine_id.txt
	else
		echo Registering not successful
	fi
fi

Jetzt muss man nur noch dafür sorgen, dass das script beim Start ausgeführt wird. Das kann man entweder über die crontab machen oder aber durch den Start in einem der Runlevel.

crontab Eintrag

# Generate new machine_id if /var/log/need_unique_machine_id.txt exists
# delete after first reboot
@reboot /root/bin/machine_id.sh

Startscript für systemd z.B. nach /usr/lib/systemd/system/machine_id.service

# Systemd unit file for default unique machine_id
#
# To create clones of this service:
# DO NOTHING, use tomcat@.service instead.

[Unit]
Description=Create a unique machine_id
After=syslog.target network.target

[Service]
Type=simple
EnvironmentFile=/e
Environment="NAME="
EnvironmentFile=
ExecStart=/root/bin/machine_id.sh start
ExecStop=/root/bin/machine_id.sh stop
SuccessExitStatus=143
User=root
Group=root


[Install]
WantedBy=multi-user.target

Anschließend muss das script noch enabled werden:

# systemctl enable  machine_id
Created symlink from /etc/systemd/system/multi-user.target.wants/machine_id.service
to /usr/lib/systemd/system/machine_id.service.

Adressing salt Clients mit cmd.run und pillars

Mehrere Minions können mit -C ‘MinionA or MinionB’ angesprochen werden.

salt -C 'server1 or server2' test.ping

Grains kann man ebenfalls nutzen um nur einen Teil seiner Minions anzusprechen.

Alle SLES12 Systeme

salt -G 'osmajorrelease:12' cmd.run 'cat /etc/os-release'

Alle 12.3 Systeme:

salt -G 'osrelease:12.3' cmd.run 'cat /etc/os-release'

Die im Susemanager zugewiesen Gruppen werden als pillars auf den Systemen gepeichert. (nur bei den salt Clients)

susemanager:~ # salt MINION pillar.get group_ids
minion:
    - 12
    - 7
    - 10
    - 17

#Anzeigen der zypper Locks auf den Systemen in der Gruppe devel:

salt -I 'group_ids:9' cmd.run 'zypper ll'

Welche Statefiles werden auf einen Minion angewandt?

Wenn man saltstack einsetzt kommt manchmal die Frage auf, welche Statefiles werden nun eigentlich auf dem speziellen Minion angewandt? Diese Frage lässt sich relativ einfach klären:

Auf dem Client nachsehen:

Angezeigt werden nicht nur die im top.sls definierten sondern auch die vom Suse Manager automatisch definierten.

SLES saltminion:~ # salt-call state.show_top
local:
----------
  base:
      - states.users.ssh_keys_root
      - custom_groups
      - states.packages.lshw_package
      - states.network.intra.ntp_conf
      - formulas
      - states.network.intra.proxy
      - states.network.intra.resolv_conf
      - states.users.ssh_keys
      - custom
      - channels
      - states.network.ntpd_restart
      - services.salt-minion
      - certs
      - services.docker
      - packages
      - custom_org
      - states.users.m42
      - states.packages.reboot_sh

vom Saltmaster aus

SLES saltmaster:~# salt server state.show_top
server:
    ----------
    base:
	- states.users.ssh_keys_root
	- custom_groups
	- states.packages.lshw_package
	- states.network.intra.ntp_conf
	- formulas
	- states.network.intra.proxy
	- states.network.intra.resolv_conf
	- states.users.ssh_keys
	- custom
	- channels
	- states.network.ntpd_restart
	- services.salt-minion
	- certs
	- services.docker
	- packages
	- custom_org
	- states.users.m42
	- states.packages.reboot_sh

Das Ergebnis sollte in beiden Fällen das gleiche sein.

salt jobs anzeigen und killen

Es kann hin und wieder mal vorkommen, dass man ein salt Kommando mit Ctrl-C beenden möchte. Der Job läuft jedoch weiter und kann wie folgt gekillt werden:

susemanager:/srv/salt # salt minion saltutil.running
minion:
    |_
      ----------
      arg:
      fun:
	  state.apply
      jid:
	  20180122140250113092
      pid:
	  18939
      ret:
      tgt:
	  minion
      tgt_type:
	  glob
      user:
	  root
susemanager:/srv/salt # salt minion saltutil.kill_job 20180122140250113092
minion:
    Signal 9 sent to job 20180122140250113092 at pid 18939

Automatisches ausführen von Highstate

Ein regelmäßiges Highstate kann natürlich über cron getriggert werden ( oder über die minion.conf auf dem client), eleganter ist es jedoch, das über pillars zu machen.

Man legt /srv/pillar an. Dort kommt ein top.sls rein, das sieht im Prinzip so aus wie ein salt top.sls

susemanager:/srv/salt # cat ../pillar/top.sls
base:
   '*':
     - schedule

Dort wird also auf allen Server der pillar schedule ausgeführt.

susemanager:/srv/salt # cat ../pillar/schedule.sls
schedule:
  highstate:
    function: state.highstate
    minutes: 60

Die Änderungen an den Pillars müssen den minions mitgeteilt werden:

salt '*' saltutil.refresh_pillar

Und das wars auch schon, jetzt wird alle 60 Minuten ein highstate gemacht. Mehr Infos unter https://docs.saltstack.com/en/latest/topics/tutorials/pillar.html

Anzeigen lassen kann man sich das mit

susemanager:/srv/salt # salt minion pillar.get schedule
minion:
    ----------
    highstate:
	----------
	function:
	    state.highstate
	minutes:
	    60