Upgrade auf Debian 9 (Stretch)


Am 17. Juni 2017 wurde Debian 9.0 (Codename "Stretch") veröffentlicht. Im folgenden Artikel findet man eine kurze Anleitung zur Durchführung des Upgrades vom vorherigen Stable-Release (Debian 8 "Jessie").

Das Upgrade muss jeder zuständige Administrator selbstständig durchführen. Bei Problemen oder Rückfragen wenden Sie sich bitte an den LRZ-Servicedesk.

Debian 8 "Jessie" wird nach dem Release von Debian 9.0 "Stretch" noch ein Jahr vollständig gepflegt (oldstable). Nach diesem Zeitpunkt geht die Pflege zum LTS-Projekt über, welches die Distribution noch etwa zwei weitere Jahre mit Sicherheitsupdates versieht. Darin werden allerdings nicht mehr alle Pakete unterstützt. Da auch die LRZ-Anpassungen über die Laufzeit des Systems gepflegt werden müssen besteht aktuell keine Unterstützung bei Nutzung des LTS-Supports.

Änderungen

Debian

Die Release-Notes von Stretch sind unter https://www.debian.org/releases/stretch/amd64/release-notes/index.de.html zu finden, insbesondere das Kapitel 5 sollte vor einem Upgrade durchgelesen werden.

Die wichtigsten Änderungen sind:

  • PHP wird auf PHP 7.0 aktualisiert
  • MySQL 5.5 wird ersetzt durch MariaDB 10.1
  • Subversion wird auf Version 1.9 aktualisiert. Wie bei jedem Versionssprung muss in jedem Checkout (Working-Directory) das Kommando "svn upgrade" ausgeführt werden.

Durchführen des Upgrades

Vorabaktualisierung

Ein Upgrade sollte nur von einem vollständig aktualisierten System aus erfolgen, da zum Teil Bugs beim Upgrade auf Stretch nur durch die vorherige Installation eines gefixten Pakets in Jessie gelöst werden können.

apt update
apt dist-upgrade

Dieses Kommando spielt bei Jessie-Systemen auch (sofern noch nicht geschehen) das Paket debian-archive-keyring ein, welches die PGP-Releaseschlüssel von Stretch enthält

Datensicherung

Die Daten auf dem Server müssen vor Beginn der Arbeiten selbstverständlich auf geeignete Weise gesichert werden (TSM und/oder VMware-Snapshot).

Es ist (unabhängig vom Upgrade) empfehlenswert, Änderungen im Verzeichnis /etc zu dokumentieren. Hierzu bietet sich das Paket "etckeeper" an, welches das /etc-Verzeichnis in einem lokalen git-Repository speichert.

Deaktivieren von Systemmanagementtools (Puppet etc)

Da während des Upgrades eine Mischung von Versionen aus Jessie und Stretch auf der Platte ist und Dienste während des Upgrades gestoppt werden, sollten alle Tools, die regelmäßig den Systemstatus checken und unter Umständen Pakete installieren oder Dienste starten, deaktiviert werden. Ein Beispiel dafür ist Puppet, es kann sich aber auch um Ansible oder Cronjobs handeln. Ein Deaktivieren des cron-Daemons ist in solchen Fällen hilfreich.

puppet agent --disable
service cron stop

Ändern der Paketquellen

In den Konfigurationsdateien für APT muss nun der Codename der Distribution von jessie auf stretch geändert werden.

sed -i 's:jessie:stretch:' /etc/apt/sources.list
sed -i 's:jessie:stretch:' /etc/apt/sources.list.d/*.list
apt update

Sollten hier Fehler auftreten, sind meistens Third-Party-Repositories eingebunden (z.B. Percona), von denen noch keine Stretch-Version existiert. Diese sollten vor dem Upgrade zurückgestellt und ein besonderes Augenmerk auf die Ausgabe im nächsten Schritt gelegt werden, da solche Pakete für eine veraltete Distributionsversion gerne aufgrund von Konflikten deinstalliert werden. Im Zweifelsfall sollte das Upgrade abgebrochen und auf eine aktualisierte Version gewartet werden.

Durchführen des Upgrades

Das tatsächliche Upgrade wird durch den Befehl "apt dist-upgrade" durchgeführt (bei einer SSH-Session ist die Verwendung von "screen" förderlich, sollte die Verbindung zwischendurch abbrechen). Die Liste der zu entfernenden Pakete sollte man kurz überfliegen, ob für den Betrieb wichtige Pakete entfernt werden. 

apt update
apt upgrade
apt dist-upgrade

Nach Bestätigung werden nun die Pakete heruntergeladen und installiert. Es werden einige Fragen gestellt, die in den meisten Fällen mit dem Standardwert beantwortet werden können. 

Die Rückfragen bei geänderten Konfigurationsdateien sollten auf Plausibilität geprüft werden. In den meisten Fällen kann aber die alte Version übernommen werden. Leichte Änderungen können auch nachträglich noch beim Aufräumen nachgezogen werden.

Vor dem Reboot sollte zur Sicherheit

sync

ausgeführt werden. Dies ist vermutlich ein Workaround, um den gelegentlichen Kernelpanic beim Reboot zu vermeiden.

Nach Abschluss der Installation muss das System neu gebootet werden.

Überprüfen und aufräumen

Nach Abschluss des Reboots sollte das System korrekt aktualisiert sein. Zwei einfache Prüfungen dafür sind die Version des laufenden Kernels sowie die Version von Debian

ping:~# uname -a
Linux ping 4.9.0-3-amd64 #1 SMP Debian 4.9.30-2+deb9u3 (2017-08-06) x86_64 GNU/Linux
ping:~# cat /etc/debian_version
9.1

Wenn die Systemdienste den Erwartungen entsprechen, sollte das System noch aufgeräumt werden. Wurde Puppet vor dem Upgrade deaktiviert, muss es nach dem Reboot wieder aktiviert werden.

puppet agent --enable

Löschen nicht mehr benötigter Pakete

Beim Aufruf von aptitude sollten schon einige Dutzend Pakete zur Löschung vorgeschlagen sein. Es handelt sich zum größten Teil um veraltete Library-Versionen. Die Auswahl sollte überprüft und mit zweimal "g" bestätigt werden.

Als nächstes sollte man die Pakete in der Liste "Obsolete and Locally Created Packages" ansehen und nicht mehr benötigte Pakete zur Löschung vorgesehen werden (mit "-"). Abschließend sollten die gelöschten Pakete nicht nur gelöscht, sondern auch deren Konfigurationsdateien entfernt werden (purge). Dazu markiert man die Sektion "Not Installed Packages" und drückt "_". 

Es kann sich dabei auch um Pakete handeln, die für den Betrieb notwendig sind und nicht mehr (mit diesem Paketnamen) in Stretch ausgeliefert werden.

Eine nicht vollständige Liste von betroffenen Paketen ist in den Release-Notes (https://www.debian.org/releases/stretch/amd64/release-notes/ch-information.de.html#noteworthy-obsolete-packages) zu finden.

Übersprungene Änderungen an Konfigurationsdateien

Hat man während der Installation das Ersetzen von veränderten Konfigurationsdateien verneint ("keep your currently-installed version", das Default), werden die geänderten Versionen mit der Endung ".dpkg-dist" im Dateisystem abgelegt. Diese können nun bei Bedarf noch überprüft werden.

ping:/etc# find . -name "*.dpkg-dist"
./systemd/system.conf.dpkg-dist
 
ping:/etc# diff -u systemd/system.conf systemd/system.conf.dpkg-dist 
--- systemd/system.conf 2014-10-29 16:57:53.724353272 +0100
+++ systemd/system.conf.dpkg-dist       2015-04-16 17:52:48.000000000 +0200
@@ -17,14 +17,24 @@
 #ShowStatus=yes
 #CrashChVT=1
 #CPUAffinity=1 2
-DefaultControllers=cpu memory
-#DefaultStandardOutput=journal
-#DefaultStandardError=inherit
-#JoinControllers=cpu,cpuacct,cpuset net_cls,net_prio
+#JoinControllers=cpu,cpuacct net_cls,net_prio
 #RuntimeWatchdogSec=0
 #ShutdownWatchdogSec=10min
 #CapabilityBoundingSet=
+#SystemCallArchitectures=
 #TimerSlackNSec=
+#DefaultTimerAccuracySec=1min
+#DefaultStandardOutput=journal
+#DefaultStandardError=inherit
+#DefaultTimeoutStartSec=90s
+#DefaultTimeoutStopSec=90s
+#DefaultRestartSec=100ms
+#DefaultStartLimitInterval=10s
+#DefaultStartLimitBurst=5
+#DefaultEnvironment=
+#DefaultCPUAccounting=no
+#DefaultBlockIOAccounting=no
+#DefaultMemoryAccounting=no
 #DefaultLimitCPU=
 #DefaultLimitFSIZE=
 #DefaultLimitDATA=

Will man die Änderungen mergen, hat sich die Nutzung des Tools sdiff für einen side-by-side merge bewährt.

ping:/etc# sdiff -o systemd/system.conf.new systemd/system.conf systemd/system.conf.dpkg-dist
#  This file is part of systemd.                                #  This file is part of systemd.
[...]
#CPUAffinity=1 2                                                #CPUAffinity=1 2
DefaultControllers=cpu memory                                 | #JoinControllers=cpu,cpuacct net_cls,net_prio
#DefaultStandardOutput=journal                                <
#DefaultStandardError=inherit                                 <
#JoinControllers=cpu,cpuacct,cpuset net_cls,net_prio          <
%?
ed:     Edit then use both versions, each decorated with a header.
eb:     Edit then use both versions.
el or e1:       Edit then use the left version.
er or e2:       Edit then use the right version.
e:      Discard both versions then edit a new one.
l or 1: Use the left version.
r or 2: Use the right version.
s:      Silently include common lines.
v:      Verbosely include common lines.
q:      Quit.
[...]
ping:/etc# mv systemd/system.conf.new systemd/system.conf
ping:/etc# rm systemd/system.conf.dpkg-dist

Bekannte Änderungen und Probleme

Benennung von Netzwerkschnittstellen

Wie bereits bei vielen anderen Distributionen üblich, benennt udev/systemd die Netzwerkschnittstellen bei Neuinstallationen nicht mehr aufsteigend (eth0, eth1, ...), sondern nach der vom BIOS gelieferten Slotinformation (eno*, ens*, ens?p*, wl*). 

Bei Upgrades von bestehenden Servern wird diese Änderung nicht nachgezogen, da

  • bei physischen Maschinen die Schnittstellen in /etc/udev/rules.d/70-persistent-net.rules bereits bekannt sind
  • virtuelle Maschinen in Abwesenheit von /etc/udev/rules.d/70-persistent-net.rules beim Upgrade den gesamten Mechanismus /etc/systemd/network/99-default.link deaktivieren

Bei sehr alten virtuellen Maschinen kann die Datei /etc/udev/rules.d/70-persistent-net.rules mit einer veralteten MAC-Adresse/Treiber existieren. Diese sollte vor dem Upgrade gelöscht werden. Alternativ kann auch die Schnittstellenbezeichnung geändert werden (Achtung: Der Name kann auch noch an anderen Stellen verwendet werden, zum Beispiel in Firewallregeln) oder die Umbenennung auf Kernel-Ebene mit einem Boot-Parameter deaktiviert werden.

/usr/share/doc/udev/README.Debian.gz
Network interface naming
~~~~~~~~~~~~~~~~~~~~~~~~
Since version 197 udev has a builtin persistent name generator which checks
firmware/BIOS provided index numbers or slot names (similar to biosdevname),
falls back to slot names (PCI numbers, etc., in the spirit of
/dev/disks/by-path/), and then optionally falls back to MAC address, and
generates names based on these properties. This provides "location oriented"
names for PCI cards such as "enp0s1" for ethernet, or wlp1s0" for a WIFI card
so that replacing a broken network card does not change the name. As location
based naming does not work well for USB devices, these use a MAC based naming
schema (see /lib/udev/rules.d/73-usb-net-by-mac.rules).

This has been enabled by default since udev 220-7, which affects new
installations/hardware. Existing installations/hardware which already got
covered by the old 75-persistent-net-generator.rules will keep their interface
names, see below.

You can disable these stable names and go back to the kernel-provided ones
(which don't have a stable order) in one of two ways:

  - Put "net.ifnames=0" into the kernel command line (e. g. in
    /etc/default/grub's GRUB_CMDLINE_LINUX_DEFAULT, then run "update-grub").

  - Disable the default *.link rules with
    "ln -s /dev/null /etc/systemd/network/99-default.link"
    and rebuild the initrd with "update-initramfs -u".

See this page for more information:
http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/

Copy&Paste in VIM macht Probleme (Visual-Mode statt Paste)

Mit Debian 9 funktioniert ein Einfügen aus der Zwischenablage nicht mehr per Maus-Rechtsklick in VIM. VIM schaltet stattdessen beim Rechtsklick in einen Visual-Insert-Mode. Das Verhalten hat sich mit der neueren VIM-Version geändert. Problem siehe u.a. auch hier: https://unix.stackexchange.com/questions/318824/vim-cutpaste-not-working-in-stretch-debian-9

Lösung: Die VIM-Mouse-Awareness systemweit ausschalten. Hierzu folgendes nach /etc/vim/vimrc.local schreiben:

/etc/vim/vimrc.local
set mouse=
set ttymouse=

Postgresql: Manueller Schritt zum Upgrade von 9.4 (jessie) auf 9.6 (stretch) notwendig

Postgres macht kein automatisches Upgrade der bestehenden DBs auf die neue Version, sondern aktiviert die neue Version parallel dazu (auf dem nächsten freien Port, i.d.R. 5433). Das Upgrade kann aber ohne Probleme in wenigen Minuten (je nach Größe der bestehenden Datenbanken) durchgeführt werden. Voraussetzung: Keine offenen Datenbank-Verbindungen, im Zweifel postgres stoppen. Die ausführliche Anleitung gibt es hier: https://gist.github.com/dmitrykustov/27c673ec4f7abd716912e4c830910019 , die Kurzfassung hier:

# pg_lsclusters 
Ver Cluster Port Status Owner    Data directory               Log file
9.4 main    5432 online postgres /var/lib/postgresql/9.4/main /var/log/postgresql/postgresql-9.4-main.log
9.6 main    5433 online postgres /var/lib/postgresql/9.6/main /var/log/postgresql/postgresql-9.6-main.log
# pg_dropcluster 9.6 main --stop
# service postgresql stop
# pg_upgradecluster 9.4 main
# pg_lsclusters 
Ver Cluster Port Status Owner    Data directory               Log file
9.4 main    5433 down   postgres /var/lib/postgresql/9.4/main /var/log/postgresql/postgresql-9.4-main.log
9.6 main    5432 online postgres /var/lib/postgresql/9.6/main /var/log/postgresql/postgresql-9.6-main.log
# pg_dropcluster 9.4 main
# apt-get --purge remove postgresql-client-9.4 postgresql-9.4