<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>LXD on zefanjas.de - Open Source &amp; Education</title>
    <link>https://zefanjas.de/tags/lxd/</link>
    <description>Recent content in LXD on zefanjas.de - Open Source &amp; Education</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>de-DE</language>
    <lastBuildDate>Fri, 03 Apr 2020 07:25:21 +0000</lastBuildDate><atom:link href="https://zefanjas.de/tags/lxd/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Wekan – eine Open Source Trello Alternative</title>
      <link>https://zefanjas.de/wekan-open-source-trello-alternative/</link>
      <pubDate>Fri, 03 Apr 2020 07:25:21 +0000</pubDate>
      
      <guid>https://zefanjas.de/wekan-open-source-trello-alternative/</guid>
      <description>&lt;p&gt;In den letzten Wochen habe ich eine Software ausprobiert, die schon lange auf meiner Liste stand: &lt;a href=&#34;https://wekan.github.io/&#34;&gt;Wekan&lt;/a&gt;. Wekan ist eine Open Source Alternative für Trello, einer &lt;a href=&#34;https://de.wikipedia.org/wiki/Kanban-Tafel&#34;&gt;Kanban-Software&lt;/a&gt;. Mit ihr lassen sich mit der Kanban-Methode Projekte oder Abläufe managen. Manche verwenden es auch als Aufgabenmanagementsystem. Es gibt verschiedene Open Source Alternativen zu Trello – Wekan ist eine, die dem Original am nächsten kommt. Ich möchte heute zeigen, wie man Wekan installiert und einrichtet.&lt;/p&gt;
&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;
&lt;p&gt;Wekan kann man auf verschiedene Art und Weise installieren (manuell, Docker, snap, …). Wir werden es heute in einem LXD Container (Ubuntu 18.04) einrichten (&lt;a href=&#34;https://zefanjas.de/tag/lxd/&#34;&gt;LXD Container&lt;/a&gt; waren hier schon mehrmals Thema im Blog). Als erstes erstellen wir einen Container für Wekan:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ lxc launch ubuntu:b wekan
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nachdem der Container erstellt und gestartet ist, loggen wir uns im Container ein:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ lxc exec wekan bash
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Wir werden Wekan als Snap installieren. In den Ubuntu LXD Container ist snapd schon installiert. Wir können also direkt Wekan installieren mit&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ snap install wekan
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nun legen wir die Haupt-URL und den Port für Wekan fest:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ snap set wekan root-url=&amp;#34;http://wekan.example.com&amp;#34;
$ snap set wekan port=&amp;#34;80&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Optional kann man noch einstellen, das Updates automatisch installiert werden:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ snap set core refresh.schedule=02:00-04:00
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Fertig 🙂&lt;/p&gt;
&lt;h2 id=&#34;einrichtung&#34;&gt;Einrichtung&lt;/h2&gt;
&lt;p&gt;Nun können wir unter der IP unseres LXD Containers Wekan aufrufen. Wenn man LXD nicht lokal, sondern auf einem Server betreibt, kann es unter Umständen hilfreich sein eine &lt;a href=&#34;https://zefanjas.de/netzwerkbruecke-fuer-lxd-container-einrichten/&#34;&gt;Netzwerkbrücke für den Container&lt;/a&gt; einzurichten. Alternativ kann man auch Nginx als Reverse Proxy verwenden. Hinweise zur Einrichtung findet man im &lt;a href=&#34;https://github.com/wekan/wekan/wiki/Nginx-Webserver-Config&#34;&gt;Wiki von Wekan&lt;/a&gt;.&lt;/p&gt;
&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;aligncenter wp-image-2956 size-full&#34; src=&#34;https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_394-1.png&#34; alt=&#34;Wekan Login&#34; width=&#34;356&#34; height=&#34;411&#34; srcset=&#34;https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_394-1.png 356w, https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_394-1-260x300.png 260w, https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_394-1-234x270.png 234w&#34; sizes=&#34;(max-width: 356px) 100vw, 356px&#34; /&gt; 
&lt;p&gt;&lt;strong&gt;Hinweis:&lt;/strong&gt; Der erste Benutzer, den wir einrichten, ist Administrator für Wekan.&lt;/p&gt;
&lt;p&gt;Wir klicken als auf Registrieren und legen einen neuen Benutzer an.&lt;/p&gt;
&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;aligncenter size-full wp-image-2955&#34; src=&#34;https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_395.png&#34; alt=&#34;Wekan Registrieren&#34; width=&#34;344&#34; height=&#34;467&#34; srcset=&#34;https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_395.png 344w, https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_395-221x300.png 221w, https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_395-199x270.png 199w&#34; sizes=&#34;(max-width: 344px) 100vw, 344px&#34; /&gt; 
&lt;p&gt;Wenn wir nun auf &lt;strong&gt;Registrieren&lt;/strong&gt; klicken, erscheint eine Fehlermeldung („Internal Server Error“). Das liegt daran, weil wir noch keinen EMail-Server eingerichtet haben.&lt;/p&gt;
&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;aligncenter size-full wp-image-2954&#34; src=&#34;https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_396.png&#34; alt=&#34;Wekan Error&#34; width=&#34;348&#34; height=&#34;108&#34; srcset=&#34;https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_396.png 348w, https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_396-300x93.png 300w&#34; sizes=&#34;(max-width: 348px) 100vw, 348px&#34; /&gt; 
&lt;p&gt;Wekan funktioniert aber auch ohne einen EMail-Server, deswegen öffnen wir einfach wieder unsere Hauptseite (wekan.example.com bzw. die IP des Containers) und können uns mit den eben angelegten Benutzer anmelden.&lt;/p&gt;
&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;aligncenter wp-image-2957 size-full&#34; src=&#34;https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_398.png&#34; alt=&#34;wekan open source&#34; width=&#34;922&#34; height=&#34;251&#34; srcset=&#34;https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_398.png 922w, https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_398-300x82.png 300w, https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_398-768x209.png 768w, https://zefanjas.de/wp-content/uploads/2020/04/Auswahl_398-604x164.png 604w&#34; sizes=&#34;(max-width: 922px) 100vw, 922px&#34; /&gt; 
&lt;p&gt;Nun können wir neue Boards in diesen neue Listen und Karten erstellen. Die Funktionsweise ist dem von Trello sehr ähnlich.&lt;/p&gt;
&lt;h2 id=&#34;fazit&#34;&gt;Fazit&lt;/h2&gt;
&lt;p&gt;Wer nach einer Open Source Alternative für Trello sucht, die man selber hosten kann, findet in Wekan einen guten Ersatz. Ich habe bisher oft Trello verwendet. Mit Wekan habe ich endlich einen Ersatz gefunden, der so ziemlich ein 1:1 Ersatz für Trello ist.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Netzwerkbrücke für LXD Container einrichten</title>
      <link>https://zefanjas.de/netzwerkbruecke-fuer-lxd-container-einrichten/</link>
      <pubDate>Thu, 07 Feb 2019 14:05:12 +0000</pubDate>
      
      <guid>https://zefanjas.de/netzwerkbruecke-fuer-lxd-container-einrichten/</guid>
      <description>&lt;p&gt;Die meisten unserer Webanwendungen laufen in LXD Containern. Nicht ohne Grund ist LXD für mich eines der &lt;a href=&#34;https://zefanjas.de/5-gruende-warum-wir-lxd-verwenden/&#34;&gt;wichtigsten Features&lt;/a&gt; von Ubuntu Server. Es gibt viele Wege um von außen auf eine Webanwendung in einem LXD Container zuzugreifen. So kann man z.B. einen Reverse Proxy nehmen und darüber die Zugriff auf die Container regeln (&lt;a href=&#34;https://zefanjas.de/wie-man-mehrere-webseiten-mit-nginx-und-haproxy-mit-lxd-hosten-kann/&#34;&gt;hier hatte ich schon mal davon berichtet&lt;/a&gt;). Eine andere Möglichkeit ist die Einrichtung einer Netzwerkbrücke, sodass sich die Container im gleichen Netz wie der Containerhost (Ubuntu Server) befinden. In diesem Artikel möchte ich kurz beschreiben, wie man eine Netzwerkbrücke für LXD Container einrichtet.&lt;/p&gt;
&lt;h2 id=&#34;netzwerkbrücke-für-lxd-container&#34;&gt;Netzwerkbrücke für LXD Container&lt;/h2&gt;
&lt;p&gt;Um eine Netzwerkbrücke unter Ubuntu einzurichten, muss man die &lt;em&gt;bridge-utils&lt;/em&gt; installieren:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ apt install bridge-utils
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Danach kann man die Netzwerkbrücke einrichten.&lt;/p&gt;
&lt;h3 id=&#34;bis-ubuntu-1604&#34;&gt;bis Ubuntu 16.04&lt;/h3&gt;
&lt;p&gt;Bis Ubuntu 16.04 nutzt Ubuntu &lt;em&gt;ifupdown&lt;/em&gt; um Einstellungen für die Netzwerkverbindungen festzulegen. Die Konfiguration nimmt man in den Dateien unter &lt;strong&gt;/etc/network/&lt;/strong&gt; vor. Eine einfache Netzwerkbrücke, um die Container in das Host-Netzwerk zu bekommen, könnte so aussehen:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The main Bridge
auto br0
iface br0 inet dhcp
    bridge-ifaces enp4s0
    bridge-ports enp4s0
    up ip link set enp4s0 up

# The primary network interface
iface enp4s0 inet manual
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hier bekommt die Brücke ihre Adresse vom DHCP-Server mitgeteilt. Die reale Netzwerkkarte &lt;em&gt;enp4s0&lt;/em&gt; wird in den manuellen Modus gesetzt und der Brücke zugewiesen.&lt;/p&gt;
&lt;h3 id=&#34;ab-ubuntu-1804&#34;&gt;ab Ubuntu 18.04&lt;/h3&gt;
&lt;p&gt;Ab Ubuntu 18.04 wird &lt;a href=&#34;https://netplan.io/&#34;&gt;Netplan&lt;/a&gt; für die Konfiguration der Netzwerkverbindungen verwendet. Die Konfigurationsdateien befinden sich unter &lt;strong&gt;/etc/netplan/&lt;/strong&gt;. Eine Definition für die Brücke könnte folgendermaßen aussehen:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ cat /etc/netplan/50-cloud-init.yaml
# This file is generated from information provided by
# the datasource.  Changes to it will not persist across an instance.
# To disable cloud-init&amp;#39;s network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp3s0:
            dhcp4: no
    version: 2
    bridges:
        br0:
            dhcp4: no
            addresses:
            - 10.10.10.5/24
            gateway4: 10.10.10.254
            nameservers:
                addresses:
                - 10.10.10.254
            interfaces:
            - enp3s0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Im oberen Teil konfiguriert man die reale Netzwerkkarte (&lt;em&gt;enp3s0&lt;/em&gt;) und weißt ihr keine Adresse zu. Danach folgt die Definition der Netzwerkbrücke. Sie wird wie eine statische Netzwerkverbindung eingerichtet und enthält zusätzlich den Punkt &lt;em&gt;interfaces&lt;/em&gt;. Dort legt man fest, welche reale Netzwerkkarte „überbrückt“ werden soll. &lt;a href=&#34;https://netplan.io/examples#configuring-network-bridges&#34;&gt;Weitere (komplexere) Beispiele&lt;/a&gt; zu Netzwerkbrücken gibt es auf der offiziellen Website.&lt;/p&gt;
&lt;p&gt;Nun werden mit dem folgenden Befehl die Änderungen an den Netzwerkeinstellungen angewendet:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ netplan apply  --debug
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;netzwerkbrücke-zuweisen&#34;&gt;Netzwerkbrücke zuweisen&lt;/h2&gt;
&lt;p&gt;Hat man die Netzwerkbrücke fertig eingerichtet und bekommt sie auch die richtige IP-Adresse, muss man dem LXD Container noch mitteilen, dass er seine IP-Adresse über die Netzwerkbrücke beziehen soll. Das erledigt man mit folgendem Befehl:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ lxc config device add containername eth0 nic nictype=bridged parent=br0 name=eth0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Mit &lt;em&gt;name=eth0&lt;/em&gt; legt man fest, unter welchen Namen man die Netzwerkkarte im Container findet. Nun kann man im Container &lt;em&gt;eth0&lt;/em&gt; nach Belieben konfigurieren. Ab sofort sollte der Container eine IP-Adresse aus dem Host-Netzwerk bekommen.&lt;/p&gt;
&lt;h2 id=&#34;fazit&#34;&gt;Fazit&lt;/h2&gt;
&lt;p&gt;Eine einfache Netzwerkbrücke lässt sich schnell einrichten und man kann sie ohne Probleme einem Container zuweisen. Andere Benutzer im Netzwerk können so ohne die Einrichtungen eines Reverse-Proxys auf eine Webanwendung zugreifen. Auch komplexere Szenarien sind denkbar (VLANs, mehrere Brücken, um die Container in verschiedene Netz zu bekommen etc.), doch das würde den Rahmen dieses kurzen Artikels sprengen.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Backup für LXD-Container</title>
      <link>https://zefanjas.de/backup-fuer-lxd-container/</link>
      <pubDate>Sat, 12 May 2018 02:44:26 +0000</pubDate>
      
      <guid>https://zefanjas.de/backup-fuer-lxd-container/</guid>
      <description>&lt;p&gt;[LXD][1] ist ein Hypervisor für Linuxcontainer, den es seit einigen Versionen in Ubuntu gibt. Ein Linuxcontainer ist im Prinzip wie eine virtuelle Maschine, nur leichtgewichtiger. Wir verwenden LXD / LXC für viele unserer Anwendungen an der Schule. LXD lässt sich leicht bedienen und es gibt so [einige Gründe][2], warum wir es verwenden. Heute möchte ich zeigen, wie man das Backup für LXD-Container machen kann.&lt;/p&gt;
&lt;h3 id=&#34;1-möglichkeit-lxc-copy&#34;&gt;1. Möglichkeit: lxc copy&lt;/h3&gt;
&lt;p&gt;Die einfachste Möglichkeit besteht darin, das man einen LXD-Container einfach auf einen anderen Rechner kopiert. Dazu braucht man einen zweiten LXD-Host, den man auf dem ersten als Remote hinzufügt.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ sudo lxc remote add lxd2 192.168.1.50
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;lxd2&lt;/em&gt; ist dabei der Name, den man dem zweiten LXD-Host geben wollen, gefolgt von der IP. Beim Setup des zweiten LXD-Hosts muss man darauf achten, dass er über das Netzwerk erreichbar ist und man muss auch ein Admin-Passwort vergeben. Dieses Passwort muss man eingeben, wenn man die Remote hinzufügen will.&lt;/p&gt;
&lt;p&gt;Ist alles eingerichtet kann man sich z.B. alle Container auf der Remote anzeigen lassen:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ lxc list lxd2:
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Um nun ein Backup eines Containers zu machen, kopiert man ihn bzw. einen Snapshot auf die eben hinzugefügte Remote:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ lxc snapshot my-container my-snapshot
$ lxc copy my-container/my-snapshot lxd2:my-backup
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In umgekehrter Weise kann man den Container wieder auf dem ursprünglichen Host wiederherstellen.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ lxc copy lxd2:my-backup my-container-restored
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;2-möglichkeit-lxc-export-und-lxc-publish&#34;&gt;2. Möglichkeit: lxc export und lxc publish&lt;/h3&gt;
&lt;p&gt;Mit LXD kann man auch einen Container als komprimiertes Image exportieren und dann auf einem NAS, einem Offsite-Backup oder einem Cloud-Speicher sichern. Später können diese Images dann mit &lt;code&gt;lxc import&lt;/code&gt; wieder importiert bzw. wiederherstellt werden.&lt;/p&gt;
&lt;p&gt;Auf [Github habe ich ein Skript gefunden][3], welches genau unsere Anforderungen erfüllt. Es exportiert den gewünschten Container und sichert ihn dann mit &lt;code&gt;rclone&lt;/code&gt; (tolles Projekt!!!) auf einen Cloud-Speicher/NAS unserer Wahl.&lt;/p&gt;
&lt;p&gt;Dazu muss man sich erst noch &lt;code&gt;rclone&lt;/code&gt; installieren und einrichten. Ein Anleitung für die Installation und Pakete für alle Plattformen gibt auf der [Projektwebseite][4]. &lt;code&gt;rclone&lt;/code&gt; unterstützt so ziemlich jeden Cloud-Speicher und Protokoll (ssh, webdav, …). Wir haben uns für ein Backup auf Google Drive entschieden, da wir da durch GSuite for Education unbegrenzten Speicherplatz haben 🙂&lt;/p&gt;
&lt;p&gt;Ist &lt;code&gt;rclone&lt;/code&gt; eingerichtet lädt man sich das Backup-Skript herunter, macht es ausführbar:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ wget https://raw.githubusercontent.com/cloudrkt/lxdbackup/master/lxdbackup
$ chmod +x lxdbackup
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Damit der Upload des Backups auch funktioniert muss man noch einige Parameter festlegen (v.a. RCLONETARGET).&lt;/p&gt;
&lt;pre class=&#34;&#34;&gt;$ nano lxdbackup
# Settings

# The target bucket or container in your Rclone cloudstorage 
RCLONETARGETDIR=&#34;lxdbackup&#34; 
# Optional Rclone settings.
RCLONEOPTIONS=&#34;&#34;
# Rclone target cloud used in your rlcone.conf
RCLONETARGET=&#34;my-remote&#34;
# Directory were local images are stored before upload
WORKDIR=&#34;/tmp/lxdbackup&#34;
```

Nun kann man das Skript mit folgendem Aufruf testen:

```
$ lxdbackup my-container
```

Wenn alles gut geht, sollten man sein Backup nach einiger Zeit (der Export eines Containers kann etwas dauern, je nach Größe) auf dem Speichern finden, den man in `rclone` konfiguriert hat.

### Fazit

Bisher haben wir einfach den LXD-Host im Gesamten gesichert. Das reicht in der Regel aus, aber man verliert die Möglichkeit einzelne Container getrennt voneinander wiederherstellen zu können. Mit dem lxdbackup-Skript und der Kombination mit `rclone` haben wir nun viel mehr Möglichkeiten und können unsere Container sehr flexibel sichern. Mit Hilfe von Cronjobs haben wir das Backup automatisiert. Manche Container werden z.B. 2x am Tag gesichert, andere nur 1x in der Woche ([und das nur, wenn keine Schulferien sind][5]) &amp;#8211; je nach Anwendungsfall.

 [1]: https://linuxcontainers.org/lxd/
 [2]: https://zefanjas.de/5-gruende-warum-wir-lxd-verwenden/
 [3]: https://github.com/cloudrkt/lxdbackup/
 [4]: https://rclone.org/
 [5]: https://github.com/anschuetz/linuxmuster/tree/master/schultag</description>
    </item>
    
    <item>
      <title>5 Gründe warum wir LXD verwenden</title>
      <link>https://zefanjas.de/5-gruende-warum-wir-lxd-verwenden/</link>
      <pubDate>Mon, 08 Jan 2018 00:27:45 +0000</pubDate>
      
      <guid>https://zefanjas.de/5-gruende-warum-wir-lxd-verwenden/</guid>
      <description>&lt;p&gt;Linuxcontainer und der Container-Hypervisor LXD sind eine meiner Lieblingstechnologien seit Ubuntu 16.04. Wir verwenden [Linuxcontainer][1] bei uns in der Schule für unsere [Webanwendungen oder auch andere Dienste][2]. Es gibt einige Dinge, die ich an LXD sehr mag. Also: Warum LXD?&lt;/p&gt;
&lt;p&gt;Einige Dinge, wie Installation, einen ersten Container erstellen usw. habe ich in [diesem kleinen Screencast][3] zusammengefasst:&lt;/p&gt;
&lt;h3 id=&#34;1-lxc-client-und-rest-api&#34;&gt;1. LXC Client und REST API&lt;/h3&gt;
&lt;p&gt;Neben LXD gibt es noch das Kommandozeilenprogramm &lt;code&gt;lxc&lt;/code&gt;. Es ist sehr einfach zu bedienen und dabei sehr mächtig. Es macht einfach Spaß damit zu arbeiten. &lt;code&gt;lxc&lt;/code&gt; greift dabei auf die Rest API von LXD zurück. Hier ein paar kleine Beispiele:&lt;/p&gt;
&lt;p&gt;Einen neuen Ubuntu Container erstellen und starten (x steht für Xenial):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ lxc launch ubuntu:x mein_container
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Root im Container werden:&lt;/p&gt;
&lt;pre class=&#34;lang:sh decode:true &#34;&gt;$ lxc exec mein_container bash
```

Alle Container anzeigen:

```
$ lxc list
```

Eine Datei in den Container kopieren:

```
lxc file push /mein/lokaler/Pfad mein_container/mein/Pfad/im/Container
```

Das Tolle ist IMHO auch, dass man die API über das Netzwerk verfügbar machen kann. So kann ich an meinem Rechner mehrere Remotes hinzufügen. Wir haben z.B. mehrere LXD Hosts im Einsatz. Möchte ich nun auf diese Hosts zugreifen, ohne mich jedes Mal per SSH anzumelden, füge ich diese einfach als Remote hinzu:

```
$ lxc remote add host1 IP-des-Hosts
```

Nun kann ich die gleichen Befehle wie oben nutzen. Vor dem Containername muss einfach nur der Name des Remote-Hosts angegeben werden:

```
$ lxc launch ubuntu:x host1:container2
$ lxc list hosts1:
$ lxc exec host1:container2 bash
```

### 2. Geschwindigkeit

Linuxcontainer sind schnell erstellt und man kann sie sehr schnell starten und beenden. Das dauert i.d.R. nur wenige Sekunden. Das ist vielleicht kein Alleinstellungsmerkmal für LXD, denn das Gleiche gilt auch für Docker oder andere Containertechnologien.

### 3. Snapshots &amp; Migration

Ein Feature von LXD sind Snapshots. Ich kann von jedem Container einfach ein Abbild erstellen, auf welches ich später wieder zurück kann.

```
$ lxc snapshot mein_container
```

Mit `lxc info mein_container` kann ich mir meine Snapshots anzeigen lassen und mit folgendem Befehl zum letzten Snapshot zurückkehren:

```
$ lxc restore mein_container snap0
```

Ich kann aber auch aus einem Snapshot einen neuen Container (hier _test_) erstellen, um z.B. ein Update oder eine Änderung zu testen.

```
$ lxc copy mein_container/snap0 test
```

Auch hier gilt, dass ich das nicht nur lokal auf einem Host machen kann, sondern so z.B. einen Container von einem Host auf einen anderen (live) migrieren kann. Es gibt dabei zwei Möglichkeiten. Entweder erstelle ich eine Kopie oder ich verschiebe den Container. Ich mache davon manchmal Gebrauch, wenn ich z.B. eine neue Anwendung lokal auf meinem Rechner teste, kann ich sie später einfach auf den Host in der Schule schieben.

```
$ lxc copy mein_container host1:mein_container
$ lxc move mein_container host1:mein_container
```

### 4. Ressourcenschonend

Linuxcontainer verbrauchen sehr wenig Speicherplatz, da sie sich viele Komponenten mit dem Container-Host teilen. Ein frisches Ubuntu-Image z.B. verbraucht nur wenige MB an Speicherplatz. Alle Container teilen sich zudem Arbeitsspeicher und CPU-Ressourcen. So kann eine viel höhere Dichte im Vergleich zu virtuellen Maschinen erreicht werden, die wesentlich mehr Ressourcen brauchen. Canonical spricht davon, dass auf einem Server [10x mehr Container-VMs][4] möglich sind im Vergleich zu klassischen virtuellen Maschinen (z.B. KVM).

### 5. Flexible Netzwerk und Speicherkonfiguration

Mit LXD sind verschiedenste Anwendungsszenarien möglich. Es werden verschiedene Speicher-Backends unterstützt und verschiedene Netzwerktreiber. Man kann auch mehrere Speicher-Backends auf einem Host haben und bei der Erstellung eines Containers entscheiden, auf welchem Speicher er gestartet werden soll. Eine [Übersicht über alle möglichen Speicher][5] findet man in der Dokumentation.

Auch netzwerktechnisch sind unterschiedliche Optionen vorhanden. Standardmäßig erstellt LXD ein eigenes Subnet für die Container. Man kann aber auch Netzwerkbrücken einrichten oder VLANs nutzen, um den Container die gewünschte IP zu geben bzw. die vorhandene Infrastruktur zu nutzen.

### Fazit

Wer viel mit Linux-VMs arbeitet, sollte sich [LXD][6] auf jeden Fall anschauen. LXD ist für mich die perfekte Mischung aus den Vorteilen, die Container bringen und der gewohnten Umgebung, die man von einer Linux-VM gewohnt ist. Es ist wie eine &amp;#8222;richtige&amp;#8220; virtuelle Maschine, nur schneller.

&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;strong&gt;Welche Erfahrungen hast du bereits mit Container allgemein bzw. mit LXD konkret gemacht?&lt;/strong&gt;
&lt;/p&gt;

 [1]: https://zefanjas.de/wie-man-mehrere-webseiten-mit-nginx-und-haproxy-mit-lxd-hosten-kann/
 [2]: https://zefanjas.de/5-grossartige-open-source-programme-die-wir-in-unserer-schule-einsetzen/
 [3]: https://www.youtube.com/watch?v=14MS_NKTKUE
 [4]: https://www.ubuntu.com/containers/lxd
 [5]: https://lxd.readthedocs.io/en/latest/storage/#storage-backends-and-supported-functions
 [6]: https://zefanjas.de/tag/lxd/</description>
    </item>
    
    <item>
      <title>HAProxy, Nginx, LXD und Let’s Encrypt</title>
      <link>https://zefanjas.de/haproxy-nginx-lxd-und-lets-encrypt/</link>
      <pubDate>Mon, 01 Jan 2018 04:55:59 +0000</pubDate>
      
      <guid>https://zefanjas.de/haproxy-nginx-lxd-und-lets-encrypt/</guid>
      <description>&lt;p&gt;In meinem &lt;a href=&#34;https://zefanjas.de/wie-man-mehrere-webseiten-mit-nginx-und-haproxy-mit-lxd-hosten-kann/&#34;&gt;letzten Beitrag habe ich beschrieben&lt;/a&gt;, wie man verschiedene Webserver, die in einem LXD Container laufen, von außen über einen Reverse-Proxy (in unserem Fall HAProxy) erreichbar machen kann. Diese Setup läuft aber nur über HTTP (Port 80) und damit über einen unverschlüsselte Verbindung. Heutzutage ist es unabdingbar, dass man seine Website auch verschlüsselt. Deswegen möchte ich heute das Setup erweitern, sodass die Webserver über eine verschlüsselte Verbindung erreichbar sind. HAProxy wird dabei &lt;a href=&#34;https://en.wikipedia.org/wiki/TLS_termination_proxy&#34;&gt;SSL/TLS Termination Proxy&lt;/a&gt; agieren, d.h. wir müssen nur an einer Stelle alle unsere Zertifikate verwalten und nicht auf jedem einzelnen Webserver selbst. Der Vorteil ist, dass den Webservern Arbeit durch den Proxy abgenommen wird, allerdings muss man wissen, dass die Kommunikation zwischen HAProxy und den Webservern unverschlüsselt erfolgt. Dieses private Netz sollte als sicher angesehen werden. In unserem Fall ist das das Subnet von LXD, in dem sich die Container befinden. Folgende Grafik veranschaulicht den Prozess:&lt;/p&gt;
&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;size-full aligncenter&#34; src=&#34;https://upload.wikimedia.org/wikipedia/commons/thumb/3/34/SSL_termination_proxy.svg/640px-SSL_termination_proxy.svg.png&#34; alt=&#34;TLS / SSL Termination&#34; width=&#34;640&#34; height=&#34;185&#34; /&gt; 
&lt;h3 id=&#34;container-überprüfen&#34;&gt;Container überprüfen&lt;/h3&gt;
&lt;p&gt;Zuerst überprüfen wir, ob alle unsere Container laufen und eine IP haben. Das können wir mit dem bekannten &lt;code&gt;lxc list&lt;/code&gt; Befehl machen:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ lxc list
+---------+---------+-----------------------+------+------------+-----------+
|  NAME   |  STATE  |         IPV4          | IPV6 |    TYPE    | SNAPSHOTS |
+---------+---------+-----------------------+------+------------+-----------+
| haproxy | RUNNING | 10.10.10.10 (eth0)    |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+
| web1    | RUNNING | 10.10.10.100 (eth0)   |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+
| web2    | RUNNING | 10.10.10.200 (eth0)   |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Alle unsere Container sind online und haben eine IP-Adresse bekommen. Weiterhin sollten die DNS-Einträge unserer beiden Webserver auf die öffentliche IP des Servers zeigen. Dies können wir z.B. mit dem &lt;code&gt;host&lt;/code&gt;-Befehl überprüfen:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ host web2.example.com
web1.example.com has address 1.2.3.4
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;weiterleitung-für-https-einrichten&#34;&gt;Weiterleitung für HTTPS einrichten&lt;/h3&gt;
&lt;p&gt;Bisher wird nur Traffic, der auf Port 80 auf unserem Server ankommt an den HAProxy Container weitergeleitet. Für HTTPS brauchen wir aber noch eine Weiterleitung für Port 443. Diese können wir mit einer ähnlichen iptables Regel einrichten:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ sudo iptables -t nat -I PREROUTING -i eth0 -p TCP -d server_ip/32 --dport 443 -j DNAT --to-destination haproxy_ip:443
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Diese Regel ist nach einem Neustart wieder weg. Um sie dauerhaft einzurichten, kann man z.B. das Paket &lt;em&gt;iptables-persistent&lt;/em&gt; installieren.&lt;/p&gt;
&lt;h3 id=&#34;haproxy-anpassen&#34;&gt;HAProxy anpassen&lt;/h3&gt;
&lt;p&gt;Als nächsten müssen wir den HAProxy Konfiguration anpassen. Dazu loggen wir uns als &lt;code&gt;root&lt;/code&gt; in dem Container ein:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ lxc exec haproxy bash
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nun können wir die Konfigurationsdatei (&lt;strong&gt;&lt;em&gt;/etc/haproxy/haproxy.cfg&lt;/em&gt;&lt;/strong&gt;) öffnen (im HAProxy-Container) und anpassen.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ nano /etc/haproxy/haproxy.cfg
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Damit unser SSL Setup möglichst sicher ist, fügen wir folgende Zeilen im &lt;code&gt;global&lt;/code&gt; Abschnitt hinzu. Ich habe Sie mit dem &lt;a href=&#34;https://mozilla.github.io/server-side-tls/ssl-config-generator/&#34;&gt;Mozilla SSL Configuration Generator&lt;/a&gt; erzeugt:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;global
    ...
    # set default parameters to the modern configuration
    ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
    ssl-default-server-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Im &lt;code&gt;defaults&lt;/code&gt; Block fügen wir folgende Zeilen hinzu:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;defaults
     ...
     option forwardfor
     option http-server-close
     ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nun sind einige Anpassungen im &lt;code&gt;frontend www_frontend&lt;/code&gt; Abschnitt notwendig:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;frontend www_frontend
    # Http
    bind *:80
    # Https mit Ordner für Certifikate
    bind *:443 ssl crt /etc/haproxy/certs/
    # allen Traffic nach https weiterleiten
    redirect scheme https if !{ ssl_fc }
    # TLS Termination. HAProxy informiert hier unseren Webserver darüber. 
    reqadd X-Forwarded-Proto:\ https

    # Unterscheide zwischen sicheren und unsicheren Requests (wird in den nächsten zwei Zeilen verwendet).
    acl secure dst_port eq 443
    
    # Markiere alle Cookies als sicher, wenn sie über SSL gesendet werden.
    rsprep ^Set-Cookie:\ (.*) Set-Cookie:\ \1;\ Secure if secure
    # Füge den HSTS-Header mit einem maximalen Alter von 1 Jahr hinzu.
    rspadd Strict-Transport-Security:\ max-age=31536000 if secure
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In in den Backend Abschnitten müssen wir keine Änderungen vornehmen.&lt;/p&gt;
&lt;h3 id=&#34;let8217s-encrypt-zertifikate-einrichten&#34;&gt;Let’s Encrypt Zertifikate einrichten&lt;/h3&gt;
&lt;p&gt;Nun brauchen wir für die verschlüsselte Kommunikation noch ein Zertifikat für unsere Webserver. Let’s Encrypt bietet kostenfreie Zertifikate schon seit einigen Jahren an und ab diesem Jahr sogar Wildcard-Zertifikate.&lt;/p&gt;
&lt;p&gt;Damit wir die Zertifikate einrichten können, brauchen wir den Let’s Encrypt Client, den wir wie folgt installieren (im HAProxy Container):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ sudo apt install letsencrypt
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Wir generieren ein Zertifikat, welches für alle unsere Domains gültig ist:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ letsencrypt certonly -d example.com -d web2.example.com
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Wenn alles geklappt hat, haben wir nun ein gültiges Zertifikat für unsere beiden Webserver. Jetzt müssen wir nur noch HAProxy die richtigen Zertifikate zur Verfügung stellen. Dazu müssen wir die Certificate Chain und den Private Key zusammenfügen, damit HAProxy etwas damit anfangen kann. Wir legen im ersten Schritt das Zielverzeichnis an und fügen dann die Zertifikate und den Key zusammen:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ mkdir -p /etc/haproxy/certs/
$ DOMAIN=&amp;#39;example.com&amp;#39; sudo -E bash -c &amp;#39;cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem &amp;amp;gt; /etc/haproxy/certs/$DOMAIN.pem&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Zum Schluss starten wir den HAProxy neu:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ systemctl restart haproxy
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;testen&#34;&gt;Testen&lt;/h3&gt;
&lt;p&gt;Wir sind fast am Ziel und möchten unsere Domains noch testen, ob auch alles richtig konfiguriert wurde.  Zuerst rufen wir die Seiten in einem Webbrowser auf. Es sollte neben der Adresse ein grünes Schloss erscheinen (im Firefox). Weiterhin sollten wir noch einen &lt;a href=&#34;https://www.ssllabs.com/ssltest/index.html&#34;&gt;SSL Server Test&lt;/a&gt; durchführen. Das Ergebnis lässt sich sehen:&lt;/p&gt;
&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;aligncenter size-full wp-image-2298&#34; src=&#34;https://zefanjas.de/wp-content/uploads/2018/01/Auswahl_149.png&#34; alt=&#34;SSL Test Result&#34; width=&#34;1008&#34; height=&#34;432&#34; srcset=&#34;https://zefanjas.de/wp-content/uploads/2018/01/Auswahl_149.png 1008w, https://zefanjas.de/wp-content/uploads/2018/01/Auswahl_149-300x129.png 300w, https://zefanjas.de/wp-content/uploads/2018/01/Auswahl_149-768x329.png 768w, https://zefanjas.de/wp-content/uploads/2018/01/Auswahl_149-604x259.png 604w&#34; sizes=&#34;(max-width: 1008px) 100vw, 1008px&#34; /&gt; 
&lt;h3 id=&#34;fazit&#34;&gt;Fazit&lt;/h3&gt;
&lt;p&gt;Mit wenigen Schritten haben wir ein Setup geschaffen, in dem wir mehrere Webseiten nach außen hin erreichbar machen können. Das Ganze lässt sich leicht erweitern und skalieren. Besonders angenehm finde ich die Verwaltung der Zertifikate an einer Stelle und nicht auf jedem Webserver einzeln. LXD und Let’s Encrypt, sowie HAProxy sind für mich eine der großen persönlichen Entdeckungen der letzten zwei Jahre.&lt;/p&gt;
&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;strong&gt;Was sind für dich die größten Herausforderung bei der Bereitstellung von Webservern?&lt;/strong&gt;
&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Wie man mehrere Webseiten mit Nginx und HAProxy mit LXD hosten kann</title>
      <link>https://zefanjas.de/wie-man-mehrere-webseiten-mit-nginx-und-haproxy-mit-lxd-hosten-kann/</link>
      <pubDate>Tue, 26 Dec 2017 14:16:50 +0000</pubDate>
      
      <guid>https://zefanjas.de/wie-man-mehrere-webseiten-mit-nginx-und-haproxy-mit-lxd-hosten-kann/</guid>
      <description>&lt;p&gt;LXD und Linuxcontainer sind eine meiner Lieblingstechnologien in Ubuntu. In wenigen Sekunden kann man einen neue virtuelle Maschine in einem Container starten. Wir machen davon in [unserer Schule][1] [stark Gebrauch][2]. Fast alle Webanwendungen laufen in einem solchen Container. So haben wir die einzelnen Anwendungen besser getrennt. Weiterhin kann man sehr schnell einen Snapshot eines Containers machen und vieles mehr. Wenn man nun diese verschiedenen Webseiten öffentlich zugänglich machen möchte, gibt es ein Problem, denn i.d.R. hat man nur eine öffentliche IP zur Verfügung (fest bzw. dynamisch). Eine Lösung wäre, dass die Webanwendungen auf verschiedenen Ports laufen, aber das ist nicht unbedingt benutzerfreundlich. In diesem Beitrag möchte ich zeigen, wie man mehrere Webseiten mit Nginx und HAProxy mit LXD hosten kann.&lt;/p&gt;
&lt;h3 id=&#34;voraussetzungen&#34;&gt;Voraussetzungen&lt;/h3&gt;
&lt;p&gt;Wir brauchen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;einen Server (ab Ubuntu 16.04) mit öffentlicher IP&lt;/li&gt;
&lt;li&gt;Zugang mit Rootrechten (root / sudo)&lt;/li&gt;
&lt;li&gt;eine Domain und Subdomain, die mit je einem DNS A Eintrag auf die öffentliche IP des Servers zeigen&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;schritt-1-8211-benutzer-der-lxd-8211-gruppe-hinzufügen&#34;&gt;Schritt 1 – Benutzer der lxd – Gruppe hinzufügen&lt;/h3&gt;
&lt;p&gt;Damit man mit einem Nicht-Root-Benutzer lxd verwalten kann, müssen wir zuerst den Benutzer der Gruppe hinzufügen:&lt;/p&gt;
&lt;pre class=&#34;code-pre command&#34;&gt;&lt;code&gt;sudo usermod --append --groups lxd username&lt;/code&gt;
```

Damit die Änderungen wirksam werden, müssen wir uns einmal _aus- und wieder einloggen_!

### Schritt 2 &amp;#8211; lxd konfigurieren

lxd ist in Ubuntu 16.04 vorinstalliert. Falls nicht, können wir es mit

```
sudo snap install lxd
```

nachholen. In LXD gibt es verschiedene Möglichkeiten, wie und wo die Container ihren Speicherplatz haben. Man kann verschiedene Dateisysteme auswählen und entscheiden, ob die Container in einer Datei oder extra Partition bzw. Festplatte gespeichert werden. In diesem Tutorial verwenden wir ZFS für Linux mit einen sogenannten &amp;#8222;loop device&amp;#8220;. Das installieren wir mit

&lt;pre class=&#34;code-pre command&#34;&gt;&lt;code&gt;sudo apt-get install zfsutils-linux&lt;/code&gt;
```

Nun können wir mit der Einrichtung von lxd beginnen:

&lt;pre class=&#34;code-pre command&#34;&gt;&lt;code&gt;sudo lxd init&lt;/code&gt;
```

Es werden verschiedene Fragen gestellt, die man wie folgt beantworten kann (Achtung: Die Netzwerkbrücke nur für IPv4 aktivieren! Das Subnet kann frei gewählt werden)

```
Name of the storage backend to use (dir or zfs) [default=zfs]: zfs
Create a new ZFS pool (yes/no) [default=yes]? &amp;lt;span style=&#34;color: yes
Name of the new ZFS pool [default=lxd]: lxd
Would you like to use an existing block device (yes/no) [default=no]? no
Size in GB of the new loop device (1GB minimum) [default=15]: 15
Would you like LXD to be available over the network (yes/no) [default=no]? no
Do you want to configure the LXD bridge (yes/no) [default=yes]? yes
LXD has been successfully configured.
```

Die Netzwerkbrücke ist notwendig, damit jeder Container seine eigene IP bekommt und Zugang zum Internet hat.

&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;aligncenter size-full wp-image-2281&#34; src=&#34;https://zefanjas.de/wp-content/uploads/2017/12/lxdinit.png&#34; alt=&#34;lxd init&#34; width=&#34;722&#34; height=&#34;408&#34; srcset=&#34;https://zefanjas.de/wp-content/uploads/2017/12/lxdinit.png 722w, https://zefanjas.de/wp-content/uploads/2017/12/lxdinit-300x170.png 300w, https://zefanjas.de/wp-content/uploads/2017/12/lxdinit-478x270.png 478w&#34; sizes=&#34;(max-width: 722px) 100vw, 722px&#34; /&gt; 

So, jetzt ist alles eingerichtet und wir können unsere ersten Container erstellen!

### Schritt 3 &amp;#8211; Container erstellen

Um unsere Container zu verwalten, brauchen wir den `lxc` Befehl. Diese feine Programm ist sehr einfach zu verwenden und dabei sehr mächtig. Zuerst wollen wir uns mal alle Container anzeigen lassen. Das geht mit `lxc list`:

&lt;pre class=&#34;code-pre&#34;&gt;&lt;code langs=&#34;&#34;&gt;$ lxc list
+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+&lt;/code&gt;
```

Es werden keine Container angezeigt, weil wir ja noch keine erstellt haben.

Für unser Beispiel brauchen wir drei Container: einen für HAProxy und 2 Webserver mit Nginx (oder Apache, wenn das jemand bevorzugt).

Wir werden den Befehl `lxc launch` verwenden, um einen Ubuntu 16.04 (`ubuntu:x`) Container namens `web1` zu erstellen und zu starten. Das `x` in `ubuntu:x` ist eine Abkürzung für den ersten Buchstaben von Xenial, der Codename von Ubuntu 16.04. `ubuntu:` ist der Bezeichner für das vorkonfigurierte Repository von LXD-Images.

Unsere drei Container können wir also mit folgenden Befehlen erstellen:

```
$ lxc launch ubuntu:x web1
$ lxc launch ubuntu:x web2
$ lxc launch ubuntu:x haproxy

```

Wenn man den ersten Container erstellt, wird zuerst das Image heruntergeladen, dass etwas dauern kann. Die anderen beiden Container werden dann sehr schnell erstellt.

Nun können wir mit lxc list schauen, ob unsere Container auch alle da sind:

```
$ lxc list
+---------+---------+-----------------------+------+------------+-----------+
|  NAME   |  STATE  |         IPV4          | IPV6 |    TYPE    | SNAPSHOTS |
+---------+---------+-----------------------+------+------------+-----------+
| haproxy | RUNNING | 10.10.10.10 (eth0)    |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+
| web1    | RUNNING | 10.10.10.100 (eth0)   |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+
| web2    | RUNNING | 10.10.10.200 (eth0)   |      | PERSISTENT | 0         |
+---------+---------+-----------------------+------+------------+-----------+
```

In dieser Liste sehen wir zuerste den Namen des Containers und seinen Status (RUNNING, STOPPED). Dann die IP Adresse(n) (die hier exemplarisch ist) und der Typ. Zum Schlusso noch die Anzahl der Snapshots / Sicherungspunkte. Die IP-Adressen werden wir gleich brauchen (am besten notieren).

### Schritt 4 &amp;#8211; Nginx-Container einrichten

Um eine Verbindung zum Container herzustellen, verwenden wir den Befehl `lxc exec`, der den Namen des Containers und die auszuführenden Befehle enthält.

```
$ lxc exec web1 -- sudo --login --user ubuntu
```

Die Zeichenkette `--` gibt an, dass die Befehlsparameter für lxc dort zu Ende sind, und der Rest der Zeile wird als der auszuführende Befehl innerhalb des Containers übergeben. Der Befehl ist `sudo --login --user ubuntu`, der eine Login-Shell für das vorkonfigurierte Konto `ubuntu` im Container bereitstellt.

&gt; Hinweis: Wenn man eine Verbindung zu den Containern als _root_ herstellen müssen, kann man stattdessen den Befehl `lxc exec web1 -- /bin/bash` verwenden

Nun sind wir in der Konsole des Containers (_ubuntu@web1_) und können nginx installieren:

```
$ sudo apt update
$ sudo apt install nginx
```

Damit wir später besser erkennen auf welchem Webserver wir uns gerade befinden, ändern wir die Standard-Seite des Webservers:

```
$ sudo nano /var/www/html/index.nginx-debian.html
```

Für die Änderung bieten sich der _title_-Tag und die erste Überschrift (_h1_) an:

```
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Welcome to nginx on LXD container web1!&amp;lt;/title&amp;gt;
&amp;lt;style&amp;gt;
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
&amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1&amp;gt;Welcome to nginx on LXD container web1!&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.&amp;lt;/p&amp;gt;
```

Nachdem wir die Datei an den beiden Stellen geändert haben, können wir mit **Strg+X** und **Y** die Datei speichern. Mit **Strg+D** oder `logout` verlassen wir wieder den Container.

Zurück auf dem Server testen wir, ob der Webserver auch ordnungsgemäß funktioniert. Mit dem folgenden Befehl sollten wir die Willkommenseite sehen, die wir gerade eben angepasst haben:

```
$ curl http://10.10.10.100/
```

Wenn alles geklappt hat, kann der zweite Container nach dem gleichen Muster eingerichtet werden.

### Schritt 5 &amp;#8211; HAProxy konfigurieren

Jetzt, da alle beiden Webserver-Container eingerichtet sind, fehlt nur noch der Reverse Proxy. Er ist dafür verantwortlich, dass die Anfragen von außen vom richtigen Container verarbeitet werden. [HAProxy][3] ist ein sehr leistungsstarker Proxy, der auch von Gihub oder Twitter verwendet wird. Die Möglichkeiten sind auch hier wieder sehr vielfältig. Wir werden deshalb nur ein sehr einfaches Setup machen.

Zuerst loggen wir uns wieder in den Container ein und installieren HAProxy:

```
$ lxc exec haproxy -- sudo --login --user ubuntu
$ sudo apt-get update
$ sudo apt-get install haproxy
```

Nun konfigurieren wir HAProxy. Dazu öffnen wir die Datei _**/etc/haproxy/haproxy.conf**_ mit einem Texteditor:

&lt;pre class=&#34;code-pre custom_prefix fourth-environment&#34;&gt;&lt;code&gt;$ sudo nano /etc/haproxy/haproxy.cfg&lt;/code&gt;
```

Im Abschnitt `defaults` fügen wir die Optionen _forwardfor_ und _http-server-close_ hinzu.

&lt;pre class=&#34;code-pre haproxy fourth-environment&#34;&gt;&lt;code langs=&#34;&#34;&gt;global
...
defaults
    log global
    mode    http
    option  httplog
    option  dontlognull
    &amp;lt;span class=&#34;highlight&#34;&gt;option   forwardfor&amp;lt;/span&gt;
    &amp;lt;span class=&#34;highlight&#34;&gt;option   http-server-close&amp;lt;/span&gt;
    timeout connect 5000
    timeout client  50000
    timeout server  50000
...&lt;/code&gt;
```

#### Frontends

Als nächstes konfigurieren wir das Frontend so, dass es auf unsere beiden Backend-Container zeigt. Wir fügen einen neuen Frontend-Abschnitt mit dem Namen _wwww_frontend_ hinzu, der so aussieht:

```
frontend www_frontend
    bind *:80 # Port 80 (www) an den Container binden

    # Es gibt eine Übereinstimmung sobald das HTTP Host: field einen der Hostnamen enthält (nach dem &#39;-i&#39;).
    acl host_web1 hdr(host) -i example.com www.example.com
    acl host_web2 hdr(host) -i web2.example.com

    # Leite die Verbindung zum richtigen Servercluster um, je nach Übereinstimmung.
    use_backend web1_cluster if host_web1
    use_backend web2_cluster if host_web2
```

Die _acl-Befehle_ stimmen mit den Hostnamen der Webserver überein und leiten die Anfragen an den entsprechenden Backend-Abschnitt weiter.

#### Backends

Dann definieren wir zwei neue Backend-Abschnitte, eine für jeden Webserver, und nennen sie _web1_cluster_ bzw. _web2_cluster_. Wir fügen den folgenden Code zur Datei hinzu, um die Backends zu definieren:

```
backend web1_cluster
    balance leastconn
    # Wir setzen den X-Client-IP HTTP-Header. Dies ist nützlich, wenn wir wollen, dass der Webserver die tatsächliche Client-IP kennt.
    http-request set-header X-Client-IP %[src]
    # Dieses Backend, hier &#34;web1&#34; genannt, verweist auf den Container &#34;web1.lxd&#34; (Hostname).
    server web1 web1.lxd:80 check

backend web2_cluster
    balance leastconn
    http-request set-header X-Client-IP %[src]
    server web2 web2.lxd:80 check

```

Die _balance_-Option bezeichnet die Load-Balancing-Strategie. In diesem Fall entscheiden wir uns für die geringste Anzahl von Verbindungen. Die Option _http-request_ setzt einen HTTP-Header mit der realen Web-Client-IP. Wenn wir diesen Header nicht setzen würden, würde der Webserver die HAProxy-IP-Adresse als Quell-IP für alle Verbindungen aufzeichnen, was die Analyse der Herkunft des Datenverkehrs erschwert. Die Server-Option spezifiziert einen beliebigen Namen für den Server (web1), gefolgt von Hostname und Port des Servers.

LXD stellt einen DNS-Server für die Container zur Verfügung, so dass web1.lxd sich auf die mit dem web1-Container verknüpfte IP auflöst. Die anderen Container haben eigene Hostnamen, wie z.B. web2.lxd und haproxy.lxd.

Der c_heck_-Parameter weist HAPRoxy an, auf dem Webserver Überprüfungen durchzuführen, um sicherzustellen, dass er verfügbar ist.

Um zu testen, ob die Konfiguration gültig ist, führen Sie den folgenden Befehl aus:

```
$ haproxy -f /etc/haproxy/haproxy.cfg -c
Configuration file is valid
```

Nun müssen wir noch den HAProxy neu laden:

```
$ sudo systemctl reload haproxy

```

Damit sind wir im HAProxy-Container fertig und können uns wieder mit **Strg+D** bzw. **logout** abmelden.

Wir haben HAProxy so konfiguriert, dass es als Reverse-Proxy fungiert, der alle Verbindungen, die es auf Port 80 empfängt, an den entsprechenden Webserver in den beiden anderen Containern weiterleitet. Testen wir, ob es Haproxy tatsächlich gelingt, die Anfragen an den richtigen Web-Container weiterzuleiten. Dazu führen wir den folgenden Befehl aus:

```
$ curl --verbose --header &#39;Host: web2.example.com&#39; http://10.10.10.10
```

Dies stellt eine Anfrage an HAProxy und setzt einen HTTP-Host-Header, den HAProxy verwenden soll, um die Verbindung zum entsprechenden Webserver umzuleiten.

Als Ausgabe sollten wir nun die Standarseite des Nginx-Servers vom web2-Container erhalten!

HAProxy hat die Anfrage richtig verstanden und an den web2-Container weitergeleitet. Dort zeigt der Webserver der Standard-Indexseite an, die wir zuvor bearbeitet haben, und zeigt den Text auf dem LXD-Container web2 an.

### Schritt 6 &amp;#8211; Eingehende Verbindungen an den HAProxy weiterleiten

Zum Schluss müssen wir noch dafür sorgen, dass alle externen Anfragen auf Port 80 an HAProxy weitergeleitet werden, damit die Welt auf unsere Websites zugreifen kann.

HAProxy haben wir in einem Container installiert und ist standardmäßig aus dem Internet nicht erreichbar. Um dies zu lösen, erstellen wir eine iptables-Regel, um Verbindungen weiterzuleiten.

Der Befehl iptables benötigt zwei IP-Adressen: die öffentliche IP-Adresse des Servers (server\_ip) und die private IP-Adresse des Haproxy-Containers (haproxy\_ip), die man mit dem Befehl `lxc list` erhält.

Führen Sie diesen Befehl aus, um die Regel zu erstellen:

```
$ sudo iptables -t nat -I PREROUTING -i eth0 -p TCP -d server_ip/32 --dport 80 -j DNAT --to-destination haproxy_ip:80
```

Um diesen iptables-Befehl zu speichern, damit er nach einem Neustart erneut angewendet wird, installieren wir das Paket _iptables-persistent_:

```
$ sudo apt-get install iptables-persistent
```

Bei der Installation des Pakets werden wir aufgefordert, die aktuellen iptables-Regeln zu speichern. Akzeptieren und speichern wir alle aktuellen iptables-Regeln.

### Schritt 7 &amp;#8211; Zugriff von außen testen

Wenn wir die beiden Domains (DNS A Eintrag) eingerichtet haben, sollten wir in der Lage sein, sich mit Ihrem Webbrowser mit jeder Website zu verbinden. Alternativ und nur zum lokalem Test können wir auch einen Eintrag in der **_/etc/hosts_** Datei machen:

```
server_IP example.com
server_IP web2.example.com
```

Um zu testen, ob die beiden Webserver tatsächlich über das Internet erreichbar sind, greifen wir von einem lokalen Computer aus mit einem Browser auf unsere beiden Domains zu (example.com bzw. web2.example.com). In beiden Fällen sollten wir nun die entsprechende Standardseite des Webservers sehen!

### Fazit

Wir haben zwei Websites eingerichtet, jede in einem eigenen Container, wobei HAProxy den Datenverkehr steuert. Diesen Prozess können wir wiederholen, um viele weitere Websites zu konfigurieren, die jeweils auf einen eigenen Container beschränkt sind.

So könnten wir z.B. auch MySQL in einem neuen Container hinzufügen und dann ein CMS wie WordPress installieren, um eine Website zu starten. Weiterhin könnten wir  diese Vorgehensweise auch verwenden, um ältere Softwareversionen zu unterstützen. Zum Beispiel, wenn eine Installation eines CMS eine ältere Version von Software wie PHP5 erfordert, dann können wir Ubuntu 14.04 in den Container installieren (`lxc launch ubuntu:t`), anstatt zu versuchen, die Paketmanager-Versionen, die auf Ubuntu 16.04 verfügbar sind, herabzusetzen.

Schließlich bietet LXD die Möglichkeit, Snapshots des vollen Zustands von Containern zu machen, was die Erstellung von Backups und das Zurückrollen von Containern zu einem späteren Zeitpunkt vereinfacht. Darüber hinaus, wenn wir LXD auf zwei verschiedenen Servern installieren, dann ist es möglich, diese miteinander zu verbinden und Container zwischen Servern über das Internet zu migrieren. Doch darüber berichte ich vielleicht ein andern mal&amp;#8230;

**Update:** [Als nächsten Schritt sollte man das Setup noch mit SSL sicherer machen.][4]

&lt;p style=&#34;text-align: center;&#34;&gt;
  &lt;strong&gt;Setzt du LXD ein und welche Erfahrungen hast du bisher gemacht?&lt;/strong&gt;
&lt;/p&gt;

 [1]: https://zefanjas.de/5-grossartige-open-source-programme-die-wir-in-unserer-schule-einsetzen/
 [2]: https://zefanjas.de/open-source-in-der-schul-it-teil-2/
 [3]: http://www.haproxy.org/
 [4]: https://zefanjas.de/haproxy-nginx-lxd-und-lets-encrypt/</description>
    </item>
    
    <item>
      <title>Virtualisierung – Virtuelle Maschine oder Container?</title>
      <link>https://zefanjas.de/virtualisierung-virtuelle-maschine-oder-container/</link>
      <pubDate>Sat, 09 Apr 2016 07:35:56 +0000</pubDate>
      
      <guid>https://zefanjas.de/virtualisierung-virtuelle-maschine-oder-container/</guid>
      <description>&lt;p&gt;Beim Planen und Nachdenken über die unsere &lt;a href=&#34;http://zefanjas.de/2016/04/06/von-fxos-bis-freeipa/&#34;&gt;zukünftige Schul-IT&lt;/a&gt; begegnete mir unweigerlich auch das Thema Virtualisierung. In den letzten Jahren ist dieses Thema teilweise sehr gehypt worden, wenn man z.B. nur an die Containerlösung &lt;a href=&#34;http://docker.com&#34;&gt;Docker&lt;/a&gt; denkt. Insgesamt kann man wohl sagen, dass heute wesentlich mehr und häufiger virtualisiert wird, als das noch vor 5 Jahren der Fall war, wo man eher noch auf „bare-metal“ gesetzt hat.&lt;/p&gt;
&lt;p&gt;In unserem konkreten Fall wollen wir auch virtualisieren, um die einzelnen Anwendungen auf dem Server besser zu isolieren und zu trennen. Im Opensource-Bereich gibt es einige Lösungen, wie man seine Anwendungen auf dem Server virtualisieren kann. Grundlegend unterscheidet man hier zwischen virtuellen Maschinen (der Hypervisor virtualisiert das ganze OS inkl. Kernel) und Containern (Container nutzen den Kernel des Hosts/Hypervisors). Jede Lösung hat seine Anwendungsszenarien, so kann man z.B. nie ein Windows in einem Container auf einem Linux-Host laufen lassen, da sie unterschiedliche Kernel verwenden. Allerdings kann man CentOS in einem Container auf Ubuntu starten (gleicher Kernel).&lt;/p&gt;
&lt;p&gt;Ich habe mir in den letzten Monaten überblicksweise folgende Virtualisierungs-Lösungen angeschaut:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.linux-kvm.org/page/Main_Page&#34;&gt;KVM&lt;/a&gt; (entwickelt von RedHat)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://virtualbox.org&#34;&gt;Virtualbox&lt;/a&gt; (hauptsächlich um auf dem Desktop verschiedenen Softwarelösungen auszuprobieren)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://linuxcontainers.org/&#34;&gt;LXD&lt;/a&gt; (Canonical) → Container-VMs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Alternativen sind noch Xen oder VMWare, welche auch recht weit verbreitet sind, wobei bei VMWare nicht als Opensource-Lösung gilt und einiges an Lizenzkosten fällig wird.&lt;/p&gt;
&lt;h3 id=&#34;virtualbox&#34;&gt;Virtualbox&lt;/h3&gt;
&lt;p&gt;Virtualbox nutze ich gern auf meinem Rechner, um Software zu testen und auszuprobieren. Es ist recht einfach ein komplettes Netzwerk nachzubilden. So habe ich oft eine kleine Router-VM (vorzugsweise &lt;a href=&#34;http://pfsense.org&#34;&gt;pfSense&lt;/a&gt;), welche ein weiteres (isoliertes) Netz bereitstellt. Dann habe ich meist ein oder zwei Server-VMs und noch ein paar Clients, um z.B. PXE-Boot und/oder andere Dienste zu nutzen. Das funktioniert recht gut, solange der Rechner mit genügend Cores und RAM ausgestattet ist (ist bei mir nur teilweise der Fall…)&lt;/p&gt;
&lt;h3 id=&#34;kvm&#34;&gt;KVM&lt;/h3&gt;
&lt;p&gt;KVM hat mir bisher am meisten zugesagt, wenn es um die Virtualisierung „richtiger“ VMs geht. Ich nutze hauptsächlich den &lt;a href=&#34;http://virt-manager.org/&#34;&gt;virt-manager&lt;/a&gt;, um meine VMs zu verwalten, aber es gibt noch unzählige &lt;a href=&#34;http://www.linux-kvm.org/page/Management_Tools&#34;&gt;andere Frontends&lt;/a&gt; für KVM. &lt;a href=&#34;http://proxmox.com/&#34;&gt;Proxmox&lt;/a&gt; ist noch sehr bekannt oder virsh für die Konsole. KVM ist sicher nicht die einfachste VM-Lösung, aber dafür sehr flexibel einsetzbar. Snapshots der einzelnen VMs sind ohne Probleme mit dem virt-manager oder einem anderen Management-Werkzeug möglich.&lt;/p&gt;
&lt;h3 id=&#34;lxd&#34;&gt;LXD&lt;/h3&gt;
&lt;p&gt;LXD 2.0 ist erst vor kurzem Erschienen und wird in Ubuntu 16.04 am besten anwendbar sein. Es gibt derzeit eine &lt;a href=&#34;http://insights.ubuntu.com/2016/03/14/the-lxd-2-0-story-prologue/&#34;&gt;Blogreihe&lt;/a&gt; von einem der Hauptentwickler, die ich jedem ans Herz lege, der sich damit auseinander setzen möchte. LXD finde ich äußerst spannend – aus verschiedenen Gründen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Container VMs → man kann sehr einfach und schnell (!) ein Linux starten und seine Anwendung drin laufen lassen&lt;/li&gt;
&lt;li&gt;durch den Einsatz von ZFS als Speicherbackend kann man super Snapshots im laufenden Betrieb usw. machen&lt;/li&gt;
&lt;li&gt;man kann wesentlich mehr Container als echte VMs starten (bessere Ausnutzung des Servers)&lt;/li&gt;
&lt;li&gt;Konfiguration und Bedienung von lxd finde ich sehr intuitiv&lt;/li&gt;
&lt;li&gt;sehr geringer Overhead&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Allerdings gibt es auch Sachen, die nicht oder nicht ohne weiteres möglich sind, da es halt Container und keine vollwertigen VMs sind. So kann man keine ISO „booten“ (es gibt aber für alle wichtigen OS Images). Ich wollte z.B. freeIPA / FOG in einem CentOS Container auf Ubuntu 16.04 testen und bin nicht ganz zum Ziel gekommen, da die Installation an manchen Stellen nicht sauber durchlief, da z.B. Ubuntu und CentOS verschiedene Technologien einsetzen (SELinux vs. Appamor). Das schaue ich mir aber noch mal genauer an. Insgesamt könnte ich mir LXD Container sehr gut für reine Webanwendungen vorstellen, sozusagen als Webserver-VMs. Das Anlegen, Starten, Backup und Restore sind einfach super easy mit LXD! Kann ich nur empfehlen sich das mal anzuschauen.&lt;/p&gt;
&lt;p&gt;Derzeit tendiere ich zu KVM für vollwertige VMs für alle Infrastruktur-Dienste (AD, NFS, DHCP, DNS) und zu LXD für zusätzliche Webanwendungen, welche wir hier in der Schule zu einsetzen bzw. einsetzen werden. Dazu folgt noch ein extra Blogeintrag.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
