Labor-Umgebung mit Ansible in KVM erstellen

Inspiriert durch die Artikel von Ricardo Geradi [1] und Alex Callejas [3] schreibe ich diesen, um zu erklären, wie mithilfe von Ansible eine Labor-Umgebung bestehend aus einer oder mehreren virtuellen Maschinen (VMs) auf einem KVM-Hypervisor provisioniert werden kann.

Dabei handelt es sich weniger um ein Tutorial, sondern mehr um eine exemplarische Beschreibung einer möglichen Vorgehensweise, die euch als Vorlage für die eigene Umgebung dienen kann.

Ich gehe nicht darauf ein, wie KVM oder Ansible installiert werden. Hierzu verweise ich auf die Dokumentation der jeweiligen Projekte und der verwendeten Linux-Distributionen.

Motivation

Um Anwendungen zu testen, benötigt man in der Regel ein Betriebssystem, auf welchem diese ausgeführt werden können. Ein Betriebssystem läuft dieser Tage meist innerhalb einer virtuellen Maschine (VM). Um bei Tests stets gleiche Rahmenbedingungen zu haben, wird empfohlen, für jeden Test eine neue VM mit einer definierten Konfiguration zu provisionieren, die geplanten Tests durchzuführen, die Ergebnisse zu sichern und die VM zu dekommissionieren.

Möchte man Infrastrukturdienste testen, werden häufig gleich mehrere VMs benötigt. Diese werden auch als Labor-Umgebung bezeichnet.

Um nicht unnötig Zeit mit der Provisionierung der VMs zu verlieren — immerhin möchte man ja seine Anwendungen bzw. Dienste testen — bietet es sich an, diesen Prozess zu automatisieren.

Doch warum mit Ansible und nicht mit [hier Lieblings-Werkzeug eurer Wahl einsetzen]?

Viele Wege führen nach Rom. Und es gibt vermutlich ähnlich viele Werkzeuge, um eine Labor-Umgebung in KVM zu provisionieren. Ich habe mich in diesem Fall für Ansible entschieden, da:

Umgebung

KVM-Hypervisor: Debian 11 Bullseye

Die .qcow2-Image-Dateien für die VMs werden auf dem KVM-Hypervisor im Verzeichnis /var/lib/libvirt/images/ vorgehalten.

Getestete Ansible Versionen:

Die Verzeichnisstruktur für meine Ansible-Umgebung entspricht der aus dem Artikel Linux-Benutzerkonten mit Ansible verwalten, wie sie im dortigen Abschnitt Vorbereitung beschrieben ist.

Die im Laufe dieses Artikels provisionierte Labor-Umgebung wird aus einer RHEL-7 und einer RHEL-8-VM bestehen. Selbstverständlich ist es möglich, durch einfache Anpassungen weitere VMs sowie andere Linux-Distributionen zu provisionieren.

Vorarbeit

Ricardo Geradi [1] und Alex Callejas [3] beziehen in ihren Artikeln die qcow2-Images, welche sie als Vorlage (engl. Template) für weitere VMs verwenden, aus diversen Internet-Quellen. Ich bin kein Freund davon, mir Images aus dem Netz zu laden und zu nutzen, für die es keine ordentliche Dokumentation gibt, mit welchen Paketen und Einstellungen diese erzeugt wurden.

Wer kauft schon gern die Katze im Sack? Daher erstelle ich mir meine Vorlagen selbst. Dazu führe ich für jede Distribution, für die ich eine Vorlage erstellen möchte, eine manuelle Installation durch. Um die Vorlagen unter all den anderen VMs leicht identifizieren zu können, gebe ich ihnen Namen wie z.B.:

Dabei hinterlege ich beim User root bereits den SSH-Public-Key, den ich später mit Ansible verwenden möchte, um diese Systeme weiter zu konfigurieren. Dies tue ich zwar bisher. Es ist für die Verwendung der hier beschriebenen Rolle nicht erforderlich.

Möchte ich eine Vorlage aktualisieren, fahre ich die dazugehörige VM hoch, führe ein Paket-Update durch, fahre die VM wieder herunter und bin fertig. Dies mache ich in der Regel alle paar Monate, wenn mir das Paket-Update bei neu provisionierten VMs zu lange dauert und spätestens nach Erscheinen eines neuen Minor-Release.

Die Ansible-Rolle

Eine Ansible-Rolle wird mit dem Befehl ansible-galaxy role init role_name initialisiert. In meinem Fall sieht dies wie folgt aus:

$ ansible-galaxy role init kvm_provision_lab
- Role kvm_provision_lab was created successfully
$ tree kvm_provision_lab
kvm_provision_lab
├── defaults
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
└── vars
    └── main.yml

In obiger Ausgabe fehlen die Verzeichnisse Files und Handlers. Diese hatte ich bereits gelöscht, da sie nicht benötigt werden. Die erstellte Verzeichnisstruktur kann, je nach verwendeter Version von ansible-galaxy, leicht unterschiedlich aussehen. Benötigt werden in diesem Beispiel nur die oben dargestellten Verzeichnisse und Dateien. Streng genommen können das Verzeichnis meta und die Datei README.md ebenfalls entfernt werden, wenn man nicht vorhat, die Rolle zu veröffentlichen. Ich behalte beide bei und nutze die Dateien zur Dokumentation der Rolle.

Variablen

Es ist gute Praxis alle Variablen, die von einer Ansible-Rolle verarbeitet werden, in der Datei defaults/main.yml zu dokumentieren und mit Standardwerten zu versehen. Genannte Datei hat hier folgenden Inhalt:

$ cat -n defaults/main.yml 
     1	---
     2	libvirt_pool_dir: "/var/lib/libvirt/images"
     3	vm_root_pass: "123456"
     4	ssh_key: "/path/to/ssh-pub-key"
     5	
     6	guests:
     7	  test:
     8	    vm_ram_mb: 512
     9	    vm_vcpus: 1
    10	    vm_net: default
    11	    os_type: rhel7
    12	    file_type: qcow2
    13	    base_image_name: rhel7-template
    14	    vm_template: "rhel7-template"
    15	    second_hdd: false
    16	    second_hdd_size: ""
    17	  test2:
    18	    vm_ram_mb: 512
    19	    vm_vcpus: 1
    20	    vm_net: default
    21	    os_type: rhel8
    22	    file_type: qcow2
    23	    base_image_name: rhel8-template
    24	    vm_template: "rhel8-template"
    25	    second_hdd: true
    26	    second_hdd_size: "100M"

In Zeile 2-4 werden Variablen definiert, die unabhängig von einzelnen VMs für die gesamte Rolle gelten. Dies sind der Speicherort für Image-Dateien, das Passwort für den Root-Benutzer der VMs, sowie der Pfad zu dem SSH-Public-Key, welcher beim Root-Benutzer hinterlegt werden soll.

In Zeile 6 beginnt ein sogenanntes Ansible-Dictionary (siehe [6]) namens guests. Es enthält als Keys die Namen der VMs (hier test und test2) und ordnet diesen diverse Variablen als Werte zu (z.B. vm_ram_mb). Die hierfür gewählten Strings müssen gültige Ansible-Variablen sein (siehe [7]).

Die einzelnen Variablen kurz erklärt:

Führt man diese Rolle mit einem Playbook aus, ohne eigene Variablen zu definieren, werden also zwei VMs mit den Namen test und test2 sowie den obigen Parametern erstellt.

Um die Rolle möglichst flexibel einsetzen und wiederverwenden zu können, werden die gewünschten Labor-Umgebungen in separaten Dateien definiert. Für mein RHEL-Lab habe ich die benötigten Variablen in die Datei vars/rhel_lab.yml geschrieben, welche ich mit ansible-vault create vars/rhel_lab.yml erstellt habe. So bleiben mein gewähltes Passwort sowie Pfad zu und Name von meinem SSH-Public-Key vor neugierigen Blicken geschützt. Der Inhalt der Datei entspricht vom Aufbau her jedoch dem aus obigem Code-Block der defaults/main.yml. Wie die Datei rhel_lab.yml genutzt wird, wird in Abschnitt „Das Playbook“ erläutert.

Templates

In der KVM-Terminologie wird eine VM auch als Gast-Domain (engl. guest domain) bezeichnet. Die Definition der Gast-Domain kann in Form einer XML-Datei erfolgen. In diesem Abschnitt werde ich zeigen, wie man die Konfiguration einer bestehenden VM in eine XML-Datei schreibt, um diese anschließend als Template für neue VMs zu benutzen.

Im Vorfeld habe ich die VMs rhel7-template und rhel8-template manuell installiert. Diese werde ich nun nutzen, um daraus Jinja2-Templates abzuleiten, welche ich innerhalb der Rollen-Verzeichnisstruktur im Verzeichnis templates ablege. Der folgende Codeblock zeigt den Befehl exemplarisch für das rhel7-template:

$ sudo virsh dumpxml rhel7-template >templates/rhel7-template.xml.j2

Das rhel8-template.xml.j2 wird auf die gleiche Weise erzeugt. Der Inhalt wird im Folgenden auszugsweise dargestellt:

<domain type='kvm'>
  <name>rhel8-template</name>
  <uuid>cb010068-fe32-4725-81e8-ec24ce237dcb</uuid>
  <metadata>
    <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
      <libosinfo:os id="http://redhat.com/rhel/8-unknown"/>
    </libosinfo:libosinfo>
  </metadata>
  <memory unit='KiB'>2097152</memory>
  <currentMemory unit='KiB'>2097152</currentMemory>
  <vcpu placement='static'>1</vcpu>
[...]
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/rhel8-template.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <target dev='hdb' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>
[...]
    <interface type='network'>
      <mac address='52:54:00:0c:8d:05'/>
      <source network='default'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
[...]
  </devices>
</domain>

Die Template-Dateien sind zu bearbeiten, um aktuell statisch konfigurierte Werte durch Variablen zu ersetzen. Die zu bearbeitenden Zeilen sehen anschließend wie folgt aus:

Darüber hinaus sind weitere Zeilen, welche für jede VM einmalig sind, aus den Template-Dateien zu löschen:

In der fertigen rhel8-template.xml.j2-Datei sieht es dann wie folgt aus:

<domain type='kvm'>
  <name>{{ item.key }}</name>
  <metadata>
    <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
      <libosinfo:os id="http://redhat.com/rhel/8-unknown"/>
    </libosinfo:libosinfo>
  </metadata>
  <memory unit='MiB'>{{ item.value.vm_ram_mb }}</memory>
  <vcpu placement='static'>{{ item.value.vm_vcpus }}</vcpu>
[...]
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='{{ libvirt_pool_dir }}/{{ item.key }}.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </disk>
[...]
    <interface type='network'>
      <source network='{{ item.value.vm_net }}'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
[...]
  </devices>
</domain>

Solltet ihr zu diesem Abschnitt noch Fragen haben, weil z.B. etwas unverständlich ist, stellt diese bitte in den Kommentaren oder meldet euch per E-Mail. Ich werde den Abschnitt dann je nach Bedarf ergänzen.

Tasks

Als Nächstes stelle ich die Tasks vor, welche von dieser Rolle ausgeführt werden. Dabei beginne ich mit dem Inhalt der Datei tasks/main.yml, deren Inhalt ich nach dem folgenden Codeblock erläutern werde.

$ cat -n tasks/main.yml 
     1	---
     2	# tasks file for kvm_provision_lab
     3	- name: Ensure requirements are in place
     4	  apt:
     5	    name:
     6	      - libguestfs-tools
     7	      - python3-libvirt
     8	    state: present
     9	  become: yes
    10	
    11	- name: Get VMs list
    12	  community.libvirt.virt:
    13	    command: list_vms
    14	  register: existing_vms
    15	  changed_when: no
    16	
    17	- name: Copy base image
    18	  copy:
    19	    dest: "{{ libvirt_pool_dir }}/{{ item.key }}.{{ item.value.file_type }}"
    20	    src: "{{ libvirt_pool_dir }}/{{ item.value.base_image_name }}.{{ item.value.file_type }}"
    21	    force: no
    22	    remote_src: yes
    23	    mode: 0660
    24	    group: libvirt-qemu
    25	  register: copy_results
    26	  with_dict: "{{ guests }}"
    27	
    28	- name: Create VMs if not exist
    29	  include_tasks: create_vms.yml
    30	  when: "item.key not in existing_vms.list_vms"
    31	  with_dict: "{{ guests }}"

Der Task in Zeile 3-9 stellt sicher, dass die notwendigen Voraussetzungen erfüllt sind, um sich mit libvirt verbinden zu können. Der Paketname libguestfs-tools existiert unter CentOS Stream, Debian und RHEL. Unter Fedora heißt das Paket guestfs-tools. Der Name muss an die entsprechende Distribution angepasst werden.

In Zeile 11-15 wird das Modul community.libvirt.virt verwendet, um die Liste der bereits existierenden VMs abzurufen und in der Variablen existing_vms zu speichern. Diese wird später genutzt, um nur dann eine VM zu provisionieren, wenn nicht bereits eine VM mit dem gleichen Namen existiert. Es ist quasi ein schmutziger Trick, um der Rolle ein wenig Idempotenz einzuhauchen. Da mit diesem Task nur Informationen abgefragt werden, jedoch keinerlei Änderungen vorgenommen werden, setzt man changed_when: no.

Das Copy-Modul in Zeile 17-26 kopiert die qcow2-Image-Dateien an den vorgesehenen Zielort und setzt Zugriffsrechte entsprechend. Zeile 19 sorgt dafür, dass die Zieldatei den Namen der neuen VM beinhaltet. Da das Copy-Modul bereits idempotent arbeitet, werden die Dateien nur kopiert, wenn das Ziel nicht bereits existiert. Das Ergebnis des Kopiervorgangs wird in copy_results gespeichert.

Der letzte Task führt die Task-Datei create_vms.yml für die VMs aus, die nicht bereits existieren. Dafür sorgt die Bedingung when: "item.key not in existing_vms.list_vms", die diesem Task zu Idempotenz verhilft. Das Playbook selbst hat folgenden Inhalt:

$ cat -n tasks/create_vms.yml 
     1	---
     2	- name: Configure the image
     3	  command: |
     4	    virt-customize -a {{ libvirt_pool_dir }}/{{ item.key }}.qcow2 \
     5	    --hostname {{ item.key }} \
     6	    --root-password password:{{ vm_root_pass }} \
     7	    --ssh-inject 'root:file:{{ ssh_key }}' \
     8	    --uninstall cloud-init --selinux-relabel
     9	  when: copy_results is changed
    10	
    11	- name: Define VMs
    12	  community.libvirt.virt:
    13	    command: define
    14	    xml: "{{ lookup('template', '{{ item.value.vm_template }}.xml.j2') }}"
    15	
    16	- name: Create second disk images if needed
    17	  command: |
    18	    qemu-img create -f {{ item.value.file_type }} \
    19	    {{ libvirt_pool_dir }}/{{ item.key }}-vdb.{{ item.value.file_type }} {{ item.value.second_hdd_size }}
    20	  become: yes
    21	  when: item.value.second_hdd|bool == true
    22	
    23	- name : Attach second disk image to domain
    24	  command: |
    25	    virsh attach-disk {{ item.key }} \
    26	    --source "{{ libvirt_pool_dir }}/{{ item.key }}-vdb.{{ item.value.file_type }}" \
    27	    --target vdb \
    28	    --persistent
    29	  become: yes
    30	  when: item.value.second_hdd|bool == true
    31	
    32	- name: Ensure VMs are startet
    33	  community.libvirt.virt:
    34	    name: "{{ item.key }}"
    35	    state: running
    36	  register: vm_start_results
    37	  until: "vm_start_results is success"
    38	  retries: 15
    39	  delay: 2

Der Task in Zeile 2-9 konfiguriert den Inhalt der qcow2-Image-Datei. Die Bedingung when: copy_results is changed stellt sicher, dass dies nur passiert, wenn die Image-Datei zuvor an ihren Zielort kopiert wurde. Damit wird sichergestellt, dass nicht eine bereits vorhandene Image-Datei einer existierenden VM nochmals verändert wird. Der Task konfiguriert den Hostnamen, setzt das Root-Passwort und hinterlegt den SSH-Public-Key.

Der nächste Task ab Zeile 11 definiert/erstellt die neue VM aus den XML-Template-Dateien.

Die beiden Tasks in den Zeilen 16-30 fügen einer VM eine zweite Festplatte hinzu, wenn dies in defaults/main.yml bzw. vars/rhel_lab.yml entsprechend definiert wurde.

Der letzte Task sorgt schließlich dafür, dass die neu erstellten VMs eingeschaltet werden.

Das Playbook

Im Vergleich zu den Dateien mit den einzelnen Tasks fällt das Playbook eher kurz aus:

 cat -n kvm_provision_rhel_lab.yml 
     1	---
     2	- name: Provision RHEL lab VMs
     3	  hosts: localhost
     4	  vars_files:
     5	    - roles/kvm_provision_lab/vars/rhel_lab.yml
     6	  tasks:
     7	    - name: Run role kvm_provision_lab
     8	      include_role:
     9	        name: kvm_provision_lab

In Zeile 3 ist der KVM-Hypervisor anzugeben, auf dem die Rolle ausgeführt werden soll. Dies kann, wie in meinem Fall, der gleiche Host wie der Ansible-Control-Node sein.

In Zeile 4 und 5 wird die Datei geladen, welche die Variablen für die zu erstellende Laborumgebung enthält. Ohne diese Anweisung werden die Werte aus defaults/main.yml verwendet.

Abschließend wird die Ansible-Rolle inkludiert. Dies ist auch schon alles.

Zusammenfassung

Das Schreiben dieses Artikels hat deutlich länger gedauert als die Erstellung der eigentlichen Ansible-Rolle zur Erstellung einer Laborumgebung unter KVM.

Die einzelnen Abschnitte beschreiben das Vorgehen und die Bestandteile der Rolle im Detail. Ich hoffe, damit deren Funktionsweise deutlich gemacht zu haben.

Ich kann nun meine Labor-Umgebungen in Dateien wie rhel_lab.yml, debian_lab.yml, etc. definieren und die Rolle dazu verwenden, diese zu provisionieren. So steht mir in kurzer Zeit eine frische Testumgebung bereit. Und zwar jedes Mal aufs neue, wenn ich sie benötige.

Wenn euch dieser Artikel dabei hilft, eigene Labor-Umgebungen mithilfe von Ansible zu provisionieren freut mich dies umso mehr.

Quellen und weiterführende Links

  1. Build a lab in 36 seconds with Ansible. Ricardo Gerardi (Red Hat, Sudoer). Enable Sysadmin. 2021-10-22.
  2. 8 Linux virsh subcommands for managing VMs on the command line. Ricardo Gerardi (Red Hat, Sudoer). Enable Sysadmin. 2021-09.09.
  3. Build a lab in five minutes with three simple commands. Alex Callejas (Red Hat). Enable Sysadmin. 2021-08-20.
  4. Ansible Create KVM Guests
  5. community.libvirt.virt – Manages virtual machines supported by libvirt
  6. Ansible Dictionary Variables. URL: https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#dictionary-variables
  7. Creating valid variable names. URL: https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#creating-valid-variable-names






SSDs, Sektorgrößen, und das Jahr 2022

Ich dachte ja eigentlich, dass ich mich Jahr 2022 mit solchen Details nicht mehr auseinandersetzen müsste, aber da habe ich mich wohl geirrt.

Worum geht's?

Die nicht mehr ganz so jungen Generationen erinnern sich, Festplatten hatten historisch bedingt eine Sektorgröße von 512 Byte. Mit Aufkommen des Advanced Format (AF) hatte man das auf 4096 Byte (4K) geändert. Vorteil war, dass man mit einer Leseoperation die 8-fache Menge an Daten bekam, das Ganze besser zur Größe der Speicherseite („page size“) moderner Prozessoren passt, insgesamt bessere Performance liefert, und generell auch erlaubt mehr Daten bei gleicher Adressierung anzusprechen. Seit ca. 2011 unterstützt so ziemlich jeder Datenträger (ausgenommen microSD-Karten/USB-Sticks und anderes eher Low-Level Flash-Gedöns) dieses Format.

Und wie immer gibt's einen fetten Haken an der Sache: Aufgrund der Abwärtskompatibilität können die meisten (wenn nicht alle) dieser Datenträger auch mit 512 Byte Sektorgröße umgehen, womit auch alle oben genannten Vorteile verschwinden.

Und mein Dateisystem möchte?

Und da wird's jetzt unangenehm. Es ist nämlich so, dass moderne Dateisysteme mit Sektorgrößen von 4K arbeiten, d.h. eine Sektorgröße von 512 Byte auf dem Datenträger, der intern eigentlich auch 4K verwendet, ergibt mal so überhaupt gar keinen Sinn.

Ich hab mal für die IMHO gebräuchlichsten Dateisysteme nachgesehen:

Sektorgrößen auslesen

Mittels parted -l lassen sich Sektorgrößen ausgeben, sieht bei einer SATA-SSD bspw. wie folgt aus:

[root:~] # parted -l
Modell: ATA SK hynix SC311 S (scsi)
Festplatte  /dev/sda:  256GB
Sektorgröße (logisch/physisch): 512B/4096B
Partitionstabelle: gpt
Disk-Flags:
[…]

Bei einer NVMe-SSD sieht's etwas anders aus, diese lassen sich in der Regel intern umformatieren. Heißt: Die Ausgabe von parted -l zeigt bspw. folgendes an:

[root:~] # parted -l
Modell: TOSHIBA-RC100 (nvme)
Festplatte  /dev/nvme0n1:  240GB
Sektorgröße (logisch/physisch): 4096B/4096B
Partitionstabelle: gpt
[…]

In Wahrheit kann das Ding aber viel mehr, je nach Konfiguration. Das bekommt man mittels smartctl -a /dev/<device> heraus:

[root:~] # smartctl -a /dev/nvme0n1
smartctl 7.2 2020-12-30 r5155 [x86_64-linux-5.15.12-200.fc35.x86_64] (local build)
Copyright (C) 2002-20, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
[…]
Namespace 1 Formatted LBA Size:     4096

[…]

Supported LBA Sizes (NSID 0x1)
Id Fmt  Data  Metadt  Rel_Perf
 0 +    4096       0         0
 1 -     512       0         3

[…]

[root:~] # 

Wie man sehen kann, nutzt die NVMe-SSD aktuell eine Sektorgröße von 4K, könnte aber auch 512 Byte. Was man hier nicht sieht: Die 512 Byte waren ursprünglich vorkonfiguriert, aufgrund der AbWäRtSkOmPaTiBiLiTäT, was mal eben die Datenrate von 1,4GB/s auf nicht ganz so schöne 700MB/s halbiert. Kannste dir nicht ausdenken, dass sowas als Standard ausgeliefert wird...

Noch schöner finde ich in der Tabelle hinten den Eintrag Rel_Perf, der gibt nämlich schon an, dass 4K Sektorgröße deutlich schneller sind als 512 Byte Sektorgröße. Warum man dann trotzdem 512 Byte als Standard anbietet, wenn literally jedes Betriebssystem heutzutage mit 4K umgehen kann? Keine Ahnung.

Aber zumindest LUKS nutzt 4K, ja?

Noch lustiger wird's allerdings, weil meine Datenträger alle verschlüsselt sind. Man würde jetzt denken, hey, wenn logisch 512 Byte angegeben sind, und physisch 4K, dann nimmt doch LUKS auf jeden Fall auch 4K Sektorgröße, nicht? Oder noch besser: Standardmäßig einfach immer 4K nehmen, weil insgesamt die bessere Wahl? Vor allem, wenn das Dateisystem, welches sich später innerhalb der LUKS-Partition befindet, mit unglaublich hoher Wahrscheinlichkeit ebenfalls 4K Sektorgrößen verwendet? Denkste.

Aufgrund der oben genannten AbWäRtSkOmPaTiBiLiTäT nutzt LUKS, wenn's die Wahl hat, auch lieber 512 Byte.

Bevor man weitermacht…

Um's nochmal kurz zu umreißen: Wer ein Dateisystem mit 4K Sektorgröße einsetzt, und evtl. auch noch LUKS, auf einer SSD die angibt mit 512 Byte Sektorgröße zu arbeiten, kann durch Umstellung auf 4K etwas mehr Datenrate herausholen.

„etwas mehr“ bedeutet hierbei, soweit ich das ermitteln konnte, zwischen 0 und 100 Prozent. Eine Umstellung bringt im schlechtesten Falle also nichts, im besten Falle verdoppelt sich die Datenrate (wie bei mir geschehen).

Vorher empfiehlt sich wie immer ein Backup zu machen, und natürlich auch zu schauen womit die Hardware und womit die Software wirklich arbeitet (via parted -l, cryptsetup luksDump, und dateisystemspezifischen Tools zum Auslesen der Sektorgröße).

LUKS-Partition auf SATA-SSDs umstellen

Das Gute: LUKS-Partitionen auf SATA-SSDs lassen sich im laufenden Betrieb von 512 Byte auf 4K umstellen. Dazu muss zwar die komplette Partition gelesen und neu verschlüsselt werden, aber LUKS ist in der Hinsicht wirklich durchdacht, denn auch ein Absturz des Rechners richtet hier i.d.R. keinen Schaden an. Man kann den Prozess jederzeit unterbrechen und später fortsetzen.

Zuerst sollte man aber prüfen, ob LUKS nicht doch schon zufälligerweise die richtige Sektorgröße verwendet:

[root:~] # cryptsetup luksDump /dev/sdxY
LUKS header information
Version:       	2
[…]
Data segments:
  0: crypt
	offset: 16777216 [bytes]
	length: (whole device)
	cipher: aes-xts-plain64
	sector: 512 [bytes]
[…]

Wie man sehen kann ist das nicht der Fall. Eine Umstellung kann mittels cryptsetup reencrypt erfolgen:

[root:~] # cryptsetup --type luks2 --sector-size 4096 reencrypt /dev/sdxY

Wichtig: Der Vorgang kann (muss aber nicht) das darin befindliche Dateisystem unbrauchbar machen. Ich hab's bei insgesamt vier Partitionen getestet (mit darin befindlichem btrfs-Dateisystem), und hatte keine Probleme.

NVMe-SSDs neu formatieren auf 4K

Bei NVMe-SSDs sieht die Sache etwas anders aus, hier muss man nämlich erst die interne Sektorgröße umstellen, was bei mir zum Verlust aller Daten geführt hat. Mittels nvme id-ns kann man die unterstützten LBA-Größen auswählen, und dann mittels nvme format die NVMe-SSD entsprechend formatieren:

[root:~] # nvme id-ns /dev/nvme0n1 | grep lbaf
[…]
lbaf  0 : ms:0   lbads:12 rp:0
lbaf  1 : ms:0   lbads:9  rp:0x3 (in use)

[root:~] # nvme format --lbaf 0 /dev/nvme0n1
[…]

[root:~] # nvme id-ns /dev/nvme0n1 | grep lbaf
[…]
lbaf  0 : ms:0   lbads:12 rp:0 (in use)
lbaf  1 : ms:0   lbads:9  rp:0x3

Dann eine neue Partitionstabelle erstellen, eine LUKS-Partition mit Sektorgröße 4K anlegen, und darin dann das gewünschte Dateisystem erstellen. Gut, und Daten zurückspielen, die man vorher natürlich™ gesichert hat.

Wie sieht's bei HDDs aus?

Kann ich ehrlich nicht beantworten. Ich kann mir vorstellen, dass HDDs in der Hinsicht wie SATA-SSDs funktionieren: Intern also 4K verwenden, logisch aber 512 Byte angeben. Tests dazu habe ich aber noch nicht gemacht - ich habe zur Zeit HDDs ausschließlich als Storage im Einsatz, d.h. mit relativ langsamen Datenraten und dafür relativ groß. Diese im laufenden Betrieb neu zu formatieren ist mir dann doch etwas zu heikel - da muss sich erst die Chance ergeben günstig irgendwo eine 4TB-Platte zu erwerben, die ich dann auch gleich meinem RAID hinzufügen kann. Ich kann aber sagen, dass die Ausgabe von parted -l für meine 4TB-Platten 512/4096 ausgibt, und für meine 1TB-Platte aus dem Jahr 2009 512/512 (was logisch ist, da das eingangs erwähnte Advanced Format 2009 noch nicht standardisiert war - hier waren 512 Byte Sektorgrößen noch der Standard).

Fazit

Anregung zu dem Artikel hat übrigens dieser Post auf Reddit gegeben. Ich persönlich ärgere mich ja, dass mir das zum einen nicht früher aufgefallen ist (normalerweise™ teste ich meine Hardware vor Inbetriebnahme, aber bei meinem aktuellen ThinkPad war damals keine Zeit, und dann habe ich einfach alle Defaults übernommen), zum anderen verstehe ich nicht ganz, warum man im Jahr 2022 überhaupt noch Datenträger bekommt die etwas von 512 Byte vorgaukeln. Abgesehen davon hat die Umstellung von 512 Byte auf 4K die Datenrate auf meiner NVMe-SSD verdoppelt.

Nerdige Notiz am Rande: Ich habe selbstverständlich nicht ein extra Backup meiner NVMe-SSD gemacht (generell Backups existieren natürlich schon), diese dann neu formatiert, und alle Daten zurückgespielt. Da ich btrfs verwende habe ich einfach die Daten im laufenden Betrieb auf eine andere SSD geschoben, dann die NVMe-SSD formatiert, und dann wieder zurückgeschoben. Alles im laufenden Betrieb. Zero Downtime 😎

Und die restlichen LUKS-Partitionen auf den SATA-SSDs wurden auch im laufenden Betrieb konvertiert. Alles andere wäre ja langweilig 😉






(x)Ubuntu 22.04 (Jammy Jellyfish) im Ausblick

Im April diesen Jahres ist es wieder soweit. Ubuntu und die offiziellen Derivate veröffentlichen eine neue LTS der beliebten Distribution. Mithin das wichtigste Ereignis im Linux-Kalender. Zeit mal einen kleinen Ausblick zu nehmen.

Das Release der neuen LTS von Ubuntu hat sicherlich die größte Breitenwirkung aller Linux-Distributionen. Die große Mehrheit der Linux-Anwender nutzt Ubuntu, eines der offiziellen Derivate oder eines jener inoffiziellen Derivate wie beispielsweise Linux Mint oder elementary OS. Hier treffen zwei Jahre Entwicklung am Linux-Desktop auf den Anwender und damit die Wirklichkeit.

Noch ist einiges im Fluss, denn der Feature Freeze steht erst am 24. Februar an, aber einige Aussagen lassen sich bereits jetzt treffen. Große Umbrüche sind dieses Jahr nicht zu erwarten, aber einige Änderung an der Oberfläche der jeweiligen Derivate und unter der Haube stehen an.

Die größte und wichtigste Neuerung. Es wird nach Jahren einen neuen Installer geben. Unter der Haube lässt man es hingegen eher bedächtig angehen und wird den Linux Kernel 5.15 nutzen, der bereits jetzt bei vielen Rolling Release-Distributionen zum Einsatz kommt. Allerdings ist das wenig dramatisch, weil Ubuntu traditionell im Laufe des Lebenszyklus der Distribution neuere Kernel-Versionen an die Anwender verteilt.

Das Hauptderviat Ubuntu wird standardmäßig Wayland nutzen und damit die endgültige Abkehr von X.org einleiten. Es dürfte sicherlich spannend werden, ob Wayland wirklich schon reif für den produktiven Einsatz bei Massen von normalen Anwendern ist. Bei der Desktopumgebung fährt man eine Zwischenmethode, die bereits bei früheren Releases zum Einsatz kam. Eine aktuelle GNOME Shell (vermutlich 42) wird mit älteren Apps kombiniert, da Ubuntu noch nicht auf Gtk4-Apps umsteigen möchte. Optisch gestaltet man die Shell weiterhin im Stil von Unity. Anwender müssen sich also nicht umorientieren. Firefox ist standardmäßig als Snap enthalten. In den Paketquellen ist aber immer noch ein normales Firefox-Paket im Bereich main enthalten. Die Anwender haben also die Wahl. Ansonsten gibt es nur wenige Änderungen gegenüber Ubuntu 21.10 – was aber für ein LTS-Release nicht unüblich ist.

Kubuntu aktualisiert wie üblich KDE Frameworks, KDE Plasma und die Programmsammlung KDE Gear. KDE Gear wird vermutlich in der Version 21.12 aus dem vergangenen Dezember ausgeliefert werden. KDE Plasma ist bereits in einer Vorschauversion von 5.24 enthalten. Diese Version wird es somit mit Sicherheit ins Release schaffen. Diese Version könnte möglicherweise wieder eine LTS-Version mit Upstream-Unterstützung werden. Mit Sicherheit ist Kubuntu 22.04 die letzte LTS-Version mit einer Qt 5-Basis. Anwender dürfte dies freuen, da KDE gegen Ende eines Releasezyklus meist die besten Produkte ausliefert, bevor man wieder von vorne anfängt. Kubuntu liefert ebenso Firefox als Snap aus und bleibt bei der Abkehr von KDEPIM zugunsten von Thunderbird.

Ubuntu MATE modernisiert leicht sein Design verglichen mit der Version 20.04. Dabei orientiert man sich am Yaru-Theme des Hauptderivats, das in das charakteristische Grün gefärbt wird. Ubuntu MATE unterscheidet sich hierdurch stark von anderen Distributionen, die MATE ausliefern. Auffällig ist die stärkere Bezugnahme auf GNOME-Programme wie Rhythmbox oder Shotwell. Firefox liegt noch nicht in der Snap-Version bei, aber vermutlich sind die Arbeiten hier nur noch nicht abgeschlossen, da Ubuntu MATE traditionell bereits Snaps ausliefert.

Wenig Neues zu berichten gibt es bei den Derivaten Xubuntu, Lubuntu und Ubuntu Budgie. Das liegt schlicht daran, dass die entsprechenden Desktopumgebungen kaum Veränderungen erfahren haben. Hier integriert man lediglich die neuen Versionen der Desktopumgebungen, welche so aber auch schon in beispielsweise 21.10 enthalten waren. Auffällig ist der vollständige Verzicht auf Snaps bei Xubuntu und Lubuntu. Ubuntu Budgie nutzt gegenwärtig Snaps nur Testweise für den Welcome-Screen.

Insgesamt hat die kommende Version 22.04 das Potenzial wieder ein stabiles und unaufgeregtes LTS-Release zu werden. Bei keinem Derivat sind momentan schwierige Strukturen oder potenziell problematische technische Umbrüche zu erwarten. Allerdings ist bis zum Feature Freeze noch ein wenig Zeit und somit kann das nur als erster Ausblick gewertet werden.

Der Artikel (x)Ubuntu 22.04 (Jammy Jellyfish) im Ausblick erschien zuerst auf [Mer]Curius






Riesen Logfile inotify.log

Vor ein paar Wochen hatte ich einen langsam steigenden Load auf dem Server entdeckt.

Was auffiel, war ein schlechtes Antwortverhalten verschiedener CMS Systeme.

Scheinbar besonders betroffen waren Sites mit relativ vielen Redirects.

Es hat eine Weile gedauert, bis ich den Übeltäter fand.

Die inotify Log-Datei war riesige 27GB groß!

Da die Partition voll lief, hat mich mein Monitoring freundlich darauf hingewiesen und ein ncdu -x / hat mir den Übeltäter offenbart.

Sobald die Logdatei gelöscht war, lief alles wieder mit voller Geschwindigkeit.  Maldet und inotify war nicht in den Log-Rotationsprozess eingebunden, also habe ich dies getan, um die inotify Logdatei rotieren zu lassen.

Dazu habe ich den  Vorschlag verwendet. War zu faul mir selbst etwas auszudenken :-)

Auch  Load ist wieder Prima.

 

 

 






Pi Hole auf dem Raspberry Pi + Kubernetes Hosten

Pi-Hole ist eine nette Software um Tracking und Werbung zu blockieren. Das Prinzip ist einfach. Pi Hole wird als Standard DNS Server im lokalen Netzwerk konfiguriert und liefert für Werbedomains eine unbrauchbare IP. Die Domainlisten werden von freundlichen Internet Personen gepflegt und das System updated diese regelmäßig. Ich habe die Software seit Jahren ohne Probleme auf einem alten RaspberryPi gehostet bis die SD Karte vor 4 Stunden kaputt ging.

Inzwischen können RaspberryPi’s Container ausführen und es gibt Kubernetes Distributionen die wunderbar auf darauf laufen. Ich nutze MicroK8S auf einem einzelnen 4GB Raspberry Pi4.

Eine komplette Anleitung zu schreiben macht wenig Sinn und sprengt jegliche Rahmen, ich möchte Dir grob erklären, wo man die Dokumentationen findet und was ungefähr im Hintergrund passiert. Schreib mir gerne einen Kommentar wenn Du mehr über Kubernetes und Container Images wissen möchtest.

Setup

System + Kubernetes

Installier erst Ubuntu auf dem Raspberry und dann nach dieser Anleitung MicroK8s.

Helm, MetalLB und Pi-Hole

Helm

Helm ist ein Package Manager für Kubernetes. Er besteht nur aus einem Binary, welches sich gegen einen Cluster verbindet und dort Konfigurationsdateien ablegt. Kubernetes erzeugt aus diesen Konfigurationen Ressourcen in denen am Ende die Container und damit Anwendungen laufen. Helm zieht diese Konfigurationen (Helm Charts) aus Repos im Internet. Helm managed Installation, Updates und Deinstallationen über Annotationen in Kubernetes Resourcen:

kubectl get deployments.apps -n pihole -oyaml |head
apiVersion: v1
items:
- apiVersion: apps/v1
  kind: Deployment
  metadata:
    annotations:
      deployment.kubernetes.io/revision: "4"
      meta.helm.sh/release-name: pihole
      meta.helm.sh/release-namespace: pihole
    creationTimestamp: "2022-01-15T17:51:07Z"

Wenn Du direkt auf dem Pi arbeitest kannst Du das Binary via Snap installieren. Doku

MetalLB

MetalLB ist ein LoadBalancer für Kubernetes. Ich nutze den OSI Layer 2 Mode um IPs im lokalen Netzwerk zu erzeugen auf denen die Kubernetes Services dann verfügbar sind.

Installation

# actually apply the changes, returns nonzero returncode on errors only
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.3/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.3/manifests/metallb.yaml

Konfiguration

Hier müßt Ihr selbst Hand anlegen. Mein Netz zu Hause hat die Range 192.168.178/24 und MetalLB soll in der Range 1192.168.178.240-192.168.178.250 erzeugen.

192.168.178.240-192.168.178.250

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.178.240-192.168.178.250
EOF

Pi Hole

Ich nutze das Helm Chart von mojo2600.

Diese 3 Befehle reichen auführen:

cat <<EOT >> pihole-values.yaml 
serviceWeb:
	type: LoadBalancer
serviceDns:
	type: LoadBalancer
EOT

helm repo add mojo2600 https://mojo2600.github.io/pihole-kubernetes/

helm upgrade --install pihole  mojo2600/pihole -n pihole -f pihole-values.yaml 

Was passiert hier?

  1. Wir fügen analog zu apt-add-repository für APT einen neuen Kanal für Software hinzu.
  2. Wir legen eine Konfigurationsdatei an welche die Default Values für ServiceWeb & ServiceDns des Charts überschreibt.
  3. Wir installieren mojo2600/pihole in den Namespace (-n) pihole und nennen die Installation auch PißHole und referenzieren die erzeugte Values Datei.

Wir können die Installation überprüfen indem wir schauen ob der Container läuft und was es so an Logs gibt:

kubectl get pods -n pihole
NAME                      READY   STATUS    RESTARTS   AGE
pihole-545cb64d94-zsgxn   1/1     Running   0          4h17m
kubectl logs -n pihole pihole-545cb64d94-zsgxn  |head
[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[s6-init] ensuring user provided files have correct perms...exited 0.
[fix-attrs.d] applying ownership & permissions fixes...
[fix-attrs.d] 01-resolver-resolv: applying... 
[fix-attrs.d] 01-resolver-resolv: exited 0.
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts...
[cont-init.d] 20-start.sh: executing... 
 ::: Starting docker specific checks & setup for docker pihole/pihole

sieht gut aus. Nun brauchen wir noch die IP des Pi Hole DNS Service um unseren Router zu konfigurieren:

kubectl get service -n pihole
NAME             TYPE           CLUSTER-IP       EXTERNAL-IP       PORT(S)                      AGE
pihole-dhcp      NodePort       10.105.187.249   <none>            67:30482/UDP                 4h54m
pihole-dns-tcp   LoadBalancer   10.105.227.20    192.168.178.243   53:31115/TCP                 4h54m
pihole-dns-udp   LoadBalancer   10.103.205.155   192.168.178.244   53:31516/UDP                 4h54m
pihole-web       LoadBalancer   10.106.223.39    192.168.178.245   80:30713/TCP,443:32113/TCP   4h54m

In meinem Fall muß ich den DNS im Router auf die 192.168.178.244 konfigurieren – DNS läuft Traditionell auf Port 53 und ich mag UDP.

Router Setup

Das ist der Punkt an dem Ihr euch selbst schlau machen müßt. Für AVM Geräte ist hier eine nette Anleitung https://docs.pi-hole.net/routers/fritzbox-de/

Warum der ganze Overhead? Das hätte ich auch schnell mit dem SH Installer machen können!

Guter Punkt. So habe ich meine letzte Installation von Pi-hole vor ein paar Jahren auch gemacht und man spart sich die Installation von viel Software. Die Vorteile merkt man wenn auf dem Kubernetes Cluster weitere Software läuft. Upgrades sind standardisiert ( helm upgrade –install) und wenn man GitOps mit z.B. ArgoCD macht hat man direkt ein Backup aller Softwareinstallationen und Konfigurationen in einem Git Repository. Ich muß mir nicht merken wie der Upgrade Prozess für Software XY läuft sondern aktualisiere Charts oder ändere das Tag eines Images – ich verwende gerne die Metapher „Leg einfach die Floppydisk mit der neuesten Version ein. Wenn Dein Kubernetes Cluster aus mehreren Rechnern besteht läuft Pi-hole auch noch wenn einer ausfällt – Kubernetes sorgt automatisch dafür, dass die Container umgezogen werden und wenn Du einen Monitoring / Alerting Stack installiert hast bekommst Du eine nette Nachricht. Natürlich verbraucht der Kubernetes Stack mehr Ressourcen als eine triviale Pi-hole Installation aber mittel- langfristig überwiegen meiner Meinung nach die Vorteile.

Der Beitrag Pi Hole auf dem Raspberry Pi + Kubernetes Hosten erschien zuerst auf Unerklärliches am Rande.






KDE – Eine kleine Niedergangsgeschichte

Das Kool Desktop Environment war mal gestartet als Versuch „den“ Linux-Desktop zu erschaffen. Nach Jahren des schleichenden Niedergangs kann man sich nun hinter GNOME in der zweiten Reihe neben Xfce, MATE und anderen einreihen.

KDE konnte letztes Jahr sein 25-jähriges Jubiläum feiern und sieht sich natürlich selbst auf der Erfolgsspur. Das kann man auch anders sehen und wo, wenn nicht in diesem Blog, wo bekanntermaßen immer alles schlecht gemacht wird – vor allem Linux und hier insbesondere KDE und Debian – sollte man so eine Geschichte schreiben.

Bei der Recherche bin ich auf die Meldung zum 10-Jährigen Jubiläum von KDE gestoßen. Das deckt sich fast mit meinem persönlichen Linux-Einstieg, deshalb lassen wir diese Geschichte 2006 beginnen.

Wir schreiben das Jahr 2006. Smartphones brauchen noch ein paar Jahre und Microsoft hat gerade mit Windows Vista ein richtiges Fiasko erlebt. Im Linux-Land wittert man Morgenluft und tatsächlich wechseln merkbar enttäuschte Windows-Nutzer ins Linux-Lager. Passenderweise hatte sich kurz zuvor ein ambitionierter Unternehmer namens Mark Shuttleworth aufgemacht, eine Linux-Distribution zu erschaffen, die für normale Anwender benutzbar sein soll. Leider mit GNOME und hier gehts los.

Im Jahr 2006 gibt es im wesentlichen drei Linux-Desktops. KDE, GNOME und für Anwender mit geringeren Ressourcen und Anforderungen Xfce. Dazu natürlich noch eine Menge Windowmanager und andere Lösungen, aber die machen zusammen nicht nennenswert Marktanteile aus. GNOME und KDE haben sich bereits in den 1990ern parallel entwickelt, weil Qt nicht frei war und Alternativen schön sind. Mal so ganz stark verkürzt ausgedrückt.

2006 ist die Sache aber nicht entschieden. Die berühmten Desktopwars bestimmen die Diskussion und KDE und GNOME dürften in etwa gleich viele Nutzer auf sich vereinen. Es gibt regionale Schwerpunkte, auch abhängig von regionalen Schwerpunkten entsprechender Distributionen. KDE ist auf dem Höhepunkt des Entwicklungszweiges der Version 3.5. Bis heute eine der Versionen, an die sich viele Anwender gerne zurückerinnern. KDE ist so wichtig, dass Canonical nicht umhinkommt mit Version 6.06 KDE bzw. Kubuntu den gleichen Status wie dem Hauptderivat Ubuntu zuzusprechen und mit Jonathan Riddell einen Entwickler dafür hauptamtlich anzustellen.

Danach beginnt der Niedergang. Im Jahr 2008 veröffentlicht KDE die Version 4. Ein Debakel sondergleichen in der öffentlichen Wahrnehmung. Obwohl nur als Vorschauversion gedacht, kommuniziert man derart schlecht, dass der Ruf nachhaltig leidet. Denn die Software ist funktional nicht ausgereift und strotzt nur so vor Fehlern. Wohlmeinende Anwender bleiben bei 3.5, andere wenden sich enttäuscht ab.

Ewig können die Distributoren aber nicht an KDE 3.5 festhalten. In den Folgejahren stellen nach und nach die Distributionen um. Der Support von Kubuntu 8.04 endet beispielsweise bereits im Oktober 2009, weil Kubuntu angesichts der Entwicklung auf LTS-Support verzichten musste – gewissermaßen das erste KDE-Opfer, bei dem man hinter der offiziellen Hauptvariante zurückstecken musste. Nahezu zeitgleich erscheint openSUSE 11.2 ohne KDE 3.5. Die Nutze können nun nur noch migrieren, aber KDE SC 4 ist zu diesem Zeitpunkt immer noch von Alltagstauglichkeit weit entfernt. Entsprechend verschieben sich die Nutzerzahlen bei den Anwender und Distributionen.

Weil KDE es nicht hinbekommt, die Destopumgebung und die zugehörigen Programme ausreichend zu stabilisieren und die Nachfrage sinkt, ziehen die Distributoren Konsequenzen. War KDE bei SUSE Linux Enterprise bereits im Jahr 2009 mit Version 11 optional geworden, fliegt es in Version 12 im Jahr 2014 komplett aus der Distribution. 2012 degradiert Canonical Kubuntu zu einem normalen Derivat, in der Folge verlässt Jonathan Riddel Canonical. Mandriva und seine diversen Nachfolgelösungen als KDE-Hochburg gerät ebenso in Schwierigkeiten und verliert nachhaltig an Bedeutung. Zuletzt gab im Jahr 2018 Red Hat bekannt, dass KDE nicht mehr in der Enterprise-Distribution RHEL enthalten sein würde. Linux-Desktops im professionellen bzw. Enteprise-Umfeld sind nun durchweg GNOME-Desktops. Wer hätte das 2006 gedacht.

Die KDE-Entwickler sehen diese katastrophale Entwicklung. Man startet man eine beispiellose Kampagne, um die letzte Hochburg von KDE als Standarddesktop zu bewahren: openSUSE. Es gelingt KDE als Standarddesktop durchzudrücken. Ein kurzer Erfolg, denn nach einigen Umstrukturierungen hat openSUSE von vielen unbemerkt wieder den Verzicht auf einen Standarddesktop beschlossen.

Im Zuge der Querelen zwischen Kubuntu und Canonical kommt man 2016 auf die Idee, mit KDE neon eine eigene Distribution zu erschaffen. Die letzten verblieben Distributoren mit KDE-Schwerpunkt sind nachhaltig irritiert durch diese Aktion. Ein großer Erfolg wird KDE neon nicht, sondern dient eher als Anschauungsbeispiel für die aktuelle KDE-Version.

2022 gibt es keine verbreitete Distribution mit KDE als Standarddesktop. Wichtige Linux-Distributionen wie Debian, Ubuntu oder Fedora setzen standardmäßig auf GNOME oder haben von GNOME abgeleitete Alternativen entwickelt, wie z. B. Mint oder Pop OS!. KDE-Software spielt vor allem bei Rolling Release Distributionen noch eine nennenswerte Rolle und erfreut sich bei Arch Linux und Manjaro einiger Beliebtheit. Zudem kann es natürlich optional bei vielen Distributionen genutzt werden. Hiermit steht es aber auf einer ähnlichen Stufe wie die Xfce, MATE, LXQt und andere kleinere Lösungen.

Für einen solchen Niedergang gibt es keine einfachen Erklärungen. Dahinter stehen sicherlich auch Entwicklungen außerhalb der Reichweite der KDE-Entwickler und Verschiebungen im Distributonssegment. Aber einige Punkte kann man dennoch feststellen:

Im Grunde genommen ist das schade, weil KDE Plasma gegenwärtig eine sehr stabil und funktional gut zu benutzende Desktopumgebung ist. Viele der Programme aus dem KDE-Umfeld sind funktional allen anderen Alternativen im Linux-Bereich überlegen. Sofern man von einer manchmal irrlichternden VDG und ihren Missetaten absieht, liefert KDE heute eine tolle Desktopumgebung aus und diese wird natürlich weiter eine Zukunft haben.

Aber Entwicklungen lassen sich nicht umkehren und KDE wird nicht mehr die Bedeutung von 2006 erreichen. Als man sich am Ende des 4er-Releasezyklus hinsichtlich Funktionen und Qualität gefangen hatte, waren die Distributoren als wichtige Mittler zwischen Upstream und den Nutzern bereits umgeschwenkt oder die Anwender hatten sich andere Distributionen gesucht. Einmal verlorene Marktanteile zurückzugewinnen, ist ein sehr hartes Unterfangen. Zu viele im Open Source-Segment unterschätzen dies.

Zu viele Fehler, zu viele schlechte Entscheidungen und ein auf GNOME ausgerichtetes Gesamtökosystem haben sich zementiert. KDE wird es weiter geben, das Projekt liefert gute Software. In einem Atemzug mit GNOME muss man es aber vermutlich nicht mehr nennen.

Der Artikel KDE – Eine kleine Niedergangsgeschichte erschien zuerst auf [Mer]Curius






Mehrere Befehle mit einem Shortcut unter VS Code ausführen

Wenn ich einen Artikel erstelle, in dem ich ein oder mehrere Code-Beispiele zeige, wandle ich erst einmal diverse Zeichen des Codes in Entitäten um, sodass der Browser nicht versucht den Code auszuführen. Dies hat sonst oft ungewollte Nebenwirkungen. Somit wird das Zeichen < beispielsweise in &lt; umgewandelt. Danach packe ich den Code in einen pre und einen code Tag der für das Hervorheben des Codes zuständig ist. Dies sieht dann beispielsweise wie folgt aus.

<pre class="line-numbers language-bash" style="white-space:pre-wrap;">
<code class="language-bash">#!/bin/bash

if [ $# -eq 0 ]
  then
    echo &quot;Usage: $0 &lt;user_name&gt; &quot;
    exit;
fi

USER=$1

for repo in $(curl -s https://api.github.com/users/&quot;$USER&quot;/repos?per_page=1000 |grep git_url |awk &apos;{print $2}&apos;| sed &apos;s/&quot;\(.*\)&quot;,/\1/&apos;);do
git clone &quot;$repo&quot;;
done;</code>
</pre>

Hierfür nutze ich jeweils einen extra Shortcut der dies automatisiert. Für das Umwandeln der Zeichen wäre es dieser Shortcut.

{
    "key": "shift+f3",
    "command": "extension.htmlEntities"
}

Mittels Shift + F3 wird die Erweiterung html-entities ausgeführt. Und genau das vergesse ich ab und zu.

Nützlich wäre daher ein Shortcut der automatisch beide Aktionen durchführt. Das unterstützt VS Code aber leider aktuell nicht. Da ich derzeit keinen anderen Editor nutzen möchte, habe ich mir die Erweiterung multi-command installiert. Damit ist es möglich mehrere Befehle nacheinander auszuführen. Herausgekommen ist schlussendlich folgender Shortcut.

{
    "key":"shift+f5",
    "command":"extension.multiCommand.execute",
    "args":{
        "sequence":[
            "extension.htmlEntities",
            {
                "command":"editor.action.insertSnippet",
                "args":{
                    "name":"wrap_highlight"
                }
            }
        ]
    }
}

Der Shortcut Shift + F5 ruft die Erweiterung multi-command auf welche als Erstes die Erweiterung html-entities und danach das Snippet wrap_highlight ausführt. Letzteres hebt in meinem Fall den Code entsprechend hervor. Zukünftig werde ich also nicht mehr vergessen, Code-Beispiele vor der Veröffentlichung eines Artikels umzuwandeln.






Mozilla veröffentlicht Firefox 96.0.1

Mozilla hat mit Firefox 96.0.1 ein Update außer der Reihe für seinen Desktop-Browser veröffentlicht.

Download Mozilla Firefox 96.0.1

Am gestrigen Morgen kam es zu einem zeitweisen Ausfall von Firefox für zahlreiche Nutzer. Grund hierfür war ein bereits länger existierender, aber bislang nicht bekannter Fehler in der HTTP/3-Implementierung von Firefox, der durch eine Konfigurationsänderung eines externen Hosting-Dienstleisters ausgelöst worden war. Da Mozilla diesen Dienstleister für das Load Balancing einer seiner Dienste nutzt, konnte das Problem bei potentiell jedem Nutzer auftreten, sobald Firefox eine Verbindung zu diesem hergestellt hat. Aber auch der Aufruf einer entsprechenden Website konnte das Problem auslösen, in dessen Folge Firefox in eine Endlosschleife geriet und nicht länger in der Lage war, Website-Anfragen zu beantworten.

Die Konfigurationsänderung des externen Dienstleisters wurde ca. eine Stunde nach der ersten Meldung bei Mozilla rückgängig gemacht, denn gestern um ca. 10.20 Uhr war das Problem genauso plötzlich wieder verschwunden, wie es gekommen war. Spätestens nach einem Neustart von Firefox funktionierte Mozillas Browser wieder für betroffene Nutzer.

Mit Firefox 96.0.1 hat Mozilla den Fehler im Firefox-Code behoben, der dieses Problem verursachte. An einer weiteren Verbesserung, damit Firefox selbst bei einem solchen Fehler nicht erneut in eine Endlosschleife gerät, arbeitet Mozilla bereits für ein kommendes Update.

Außerdem hat Mozilla mit Firefox 96.0.1 das Problem behoben, dass der Browser unter Windows bei Verwendung der Option, die Proxy-Einstellungen des Systems zu verwenden, die Ausnahmen nicht mehr berücksichtigte.

Der Beitrag Mozilla veröffentlicht Firefox 96.0.1 erschien zuerst auf soeren-hentzschel.at.






KDE-Nutzer bei Debian aufgepasst!

Debian verliert einen wichtigen Leistungsträger und ist daran nicht unschuldig. KDE-Nutzer sollten zur Kenntnis nehmen, dass sich Norbert Preining zurückzieht.

Debian hat Probleme. Nicht nur die Sicherheit, nicht nur in den verknöchterten Strukturen, es knirscht an vielen Stellen. Seit Jahren treten jedes Jahr Projektleiter an mit großen Agenden und nichts passiert. Die Strukturen, die das Projekt stabilisieren sollten, scheinen jede Bewegung zu verhindern, oft dienen sie nur noch der Blockade durch Minderheiten, die irgendetwas aufhalten wollen und dann in mühsamen Prozessen überstimmt werden müssen.

Norbert Preining ist seit einiger Zeit die Säule der Paketierung von KDE in Debian. Ohne ihn hätte man die aktuelle Stable-Version nicht mit halbwegs aktuellen KDE-Paketen ausgeliefert worden. Nun hat Norbert Preining seinen Rückzug angekündigt. Zwischen ihm und dem Debian-Projekt bzw. Menschen im Debian-Projekt knirscht es ja seit Längerem, deshalb musste er auch bereits in der Vergangenheit viel seiner Arbeit in OBS auslagern.

Der Verlust für Debian ist gewaltig. Die Liste der Pakete und die sachliche Analyse von Norbert Preining machen das deutlich. Einiges hat sicher eine Zukunft, aber vor allem für alles, was mit KDE zu tun hat und für Cinnamon in Debian sieht es nun düster aus. Norbert Preining legt zudem den Finger in eine Wunde, die viele ignorieren. Die vielen „Gruppen“ bei der Paketbetreuung sind oft nur eine Illusion und letztlich steht dahinter oft nur ein aktiver Betreuer – wie bei vielen „Teamarbeiten“ eben sonst auch.

Die Geschichte erinnert mich an Michael Stapelberg und seinen Rückzug aus Debian 2019. Dieser ist übrigens genau wie Norbert Preining zu Arch Linux gewechselt, aber das nur am Rande.

Debian brüstet sich immer mit seinen vielen Maintainern und Entwicklern, aber die Zahl der Leistungsträger im Desktop-Bereich ist überschaubar und große Weggänge gehen unweigerlich zulasten der Aktualität und Qualität. Darunter leiden übrigens auch abgeleitete Distributionen, wenn sie die Pakete nur übernehmen und die betroffenen Bereiche nicht selbst paketieren. Das Problem reicht deshalb über Debian hinaus.

Debian hat ein Problem, auch wenn nun wieder alle Debian-Nutzer standhaft leugnen und böse Kommentare im Stil von „Ach, der Gerrit mag Debian nicht“ schreiben werden. Vor allem Anwender von KDE Plasma und Cinnamon sollten die Entwicklung von Debian Testing im Auge behalten und sich mental darauf vorbereiten, beim nächsten Stable-Release eine neue Heimat zu suchen und bis dahin hoffen, dass nichts sicherheitsrelevantes für die Versionen in Stable passiert. Denn mir ist nicht klar, wer dort nun noch verantwortlich zeichnet.

Nachtrag 14.01.2022:

Nun hat auch Ferdinand bei Linuxnews berichtet, der ja ein guter Kenner der Debian-Gemeinschaft ist. Dort finden sich auch die Informationen zum Ablauf der Degradierung vor einiger Zeit und was für Mechanismen bei Debian hinter den Kulissen laufen.

Der Artikel KDE-Nutzer bei Debian aufgepasst! erschien zuerst auf [Mer]Curius






Thunderbird 91.5 veröffentlicht

Die MZLA Technologies Corporation hat mit Thunderbird 91.5 ein planmäßige Update für seinen Open Source E-Mail-Client veröffentlicht.

Neuerungen von Thunderbird 91.5

Mit dem Update auf Thunderbird 91.5 hat die MZLA Technologies Corporation ein planmäßiges Update für seinen Open Source E-Mail-Client veröffentlicht und behebt damit aktuelle Sicherheitslücken. Darüber hinaus bringt das Update diverse Fehlerbehebungen der Versionsreihe 91, welche sich in den Release Notes (engl.) nachlesen lassen.

Der Beitrag Thunderbird 91.5 veröffentlicht erschien zuerst auf soeren-hentzschel.at.