{"id":111,"date":"2023-04-04T14:00:11","date_gmt":"2023-04-04T12:00:11","guid":{"rendered":"https:\/\/3fu.de\/?p=111"},"modified":"2023-04-04T14:00:11","modified_gmt":"2023-04-04T12:00:11","slug":"wale-bezwingen-ist-nicht-so-einfach-wie-gedacht-proxmox-lxc-und-docker","status":"publish","type":"post","link":"https:\/\/3fu.de\/?p=111","title":{"rendered":"Wale bezwingen ist nicht so einfach wie gedacht &#8211; Proxmox LXC und Docker"},"content":{"rendered":"\n<h4 class=\"wp-block-heading\">Neuer Rootserver &#8211; Zeit f\u00fcr was neues, auch im Techstack<\/h4>\n\n\n\n<p>Lange Zeit hatte ich zusammen mit meinem Kumpel einen Root Server bei Hetzner aus der Serverb\u00f6rse. Mit einem betagten i7-3770k und zwei HDDs war die Leistung sehr Bescheiden. NextCloud war schon nicht mehr m\u00f6glich wegen den Datenbankzugriffen um ein Beispiel zu nennen. So habe ich dann f\u00fcr jeden Dienst einen vServer gemietet. Es wurden dann immer wieder mehr mit Mailarchiv etc. so dass es dann sich doch lohnte auf den gr\u00f6\u00dferen Root Server von Hetzner zu gehen. Wie sorge ich aber daf\u00fcr das die Dienste immer aktuell bleiben? An sehr vielen Stellen wurde auch Docker hoch gelobt, auch viele andere Dienste bieten bei Docker Hub voll automatisch Dienste an. Auf der Arbeit hatte ich dann auch mit Portainer zu tun. Also nahm ich die Chance und wollte all meine Dienste die im Internet verf\u00fcgbar sind \u00fcber Docker bereitstellen, um auch diese besser aktualisieren zu lassen.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Docker im LXC Container &#8211; nicht so einfach wie gedacht<\/h4>\n\n\n\n<p>Docker im LXC Container, also Container im Container, dass kann doch nur schief gehen, oder? Es steht fest, auch Proxmox empfiehlt bei Docker es in einer QEMU VM laufen zu lassen und nicht in LXC. Jedoch ist es m\u00f6glich Docker in einem unpriviligiertem Container laufen zu lassen. Dabei ist es wichtig Nesting aktiviert zu haben. Praktisch ist, dass ab Proxmox PVE 7.1 Nesting automatisch aktiviert ist. Was ich zu dem Zeitpunkt noch nicht wusste, dass auch fuse aktiviert sein muss. Warum erfolgt in einem sp\u00e4terem Kapitel. Wenn man dieses aktiviert hat kann man ohne Probleme \u00fcber die Docker Doku dann die Repos einf\u00fcgen und installieren.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Docker compose &#8211; beim falschen Befehl verliert man die Daten!<\/h4>\n\n\n\n<p>Docker compose kann vieles einfach machen, aber wenn man die Befehle nicht versteht steht man mit Datenverlust da. Die docker-compose.yml ist eine YAML Datei, bei der dann Docker compose voll automatisch den Docker Container zusammenbauen kann. Nat\u00fcrlich gibt es persistente Daten, bleiben wir beim Beispiel der Nextcloud. Da sollen ja die Daten die zur Nextcloud geh\u00f6ren immer aktualisiert werden, aber die persistente Daten wie meine Bilder, Konfigurationsdateien sollen bleiben. Bei Nextcloud wird z. B. folgende docker-compose.yml als Beispiel angegeben:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>version: '2'\n\nvolumes:\n  nextcloud:\n  db:\n\nservices:\n  db:\n    image: mariadb:10.5\n    restart: always\n    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW\n    volumes:\n      - db:\/var\/lib\/mysql\n    environment:\n      - MYSQL_ROOT_PASSWORD=\n      - MYSQL_PASSWORD=\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n\n  app:\n    image: nextcloud\n    restart: always\n    ports:\n      - 8080:80\n    links:\n      - db\n    volumes:\n      - nextcloud:\/var\/www\/html\n    environment:\n      - MYSQL_PASSWORD=\n      - MYSQL_DATABASE=nextcloud\n      - MYSQL_USER=nextcloud\n      - MYSQL_HOST=db<\/code><\/pre>\n\n\n\n<p>Bei dieser Docker Compose wird also erstmal ein MariaDB Container erstellt und eine zweite (app) die dann NextCloud ist. Sehen wir uns Zeile 3 bis 5 an sehen wir die Reiter Volumes. Mit diesen Zeilen \u00fcbergeben wir Docker die Verwaltung der Persistenten Daten. Wird also der Docker Container erstellt, erstellt der Docker Daemon an einem f\u00fcr sich passenden Ort einen Order, bei dem er Daten auch au\u00dferhalb des Container speichert.<br><br>Mit dem simplen Befehl <code>docker compose up -d<\/code> wird dann der Container erstellt und dann lacht einem ein funktionierendes Nextcloud an. Jetzt kann man annehmen, dass man den Befehlt <code>docker compose down<\/code> verwenden soll um den Container zu beenden. Dieses tat ich auch, ich nahm \u00e4nderunden an der .yml Datei vor und startete dann den Container wieder. Was mich dann \u00fcberrascht hatte, all meine Nextcloud Einstellungen waren weg. Was ist passiert? Mit <code>docker compose down<\/code> wird nicht nur der Container beendet, sondern komplett gel\u00f6scht! Dies bedeutet auch dass die Volumes mit gel\u00f6scht werden. Erst sp\u00e4ter stellte ich fest, dass <code>docker compose stop<\/code> einen Container nur beendet und <code>docker compose start -d<\/code> wieder startet. Jedoch war mir das zu gef\u00e4hrlich, ich m\u00f6chte nicht dass ich in einer doofen Minute dann meine Daten l\u00f6sche weil ich down anstatt stop verwendet hatte. Deshalb habe ich in der .yml Datei absolute Pfade angegeben f\u00fcr die persistenden Dateien. Sprich die Zeile<br><br><code>- nextcloud:\/var\/www\/html<\/code><br>habe ich abge\u00e4ndert in<br><code>- \/home\/docker\/nc\/data:\/var\/www\/html<\/code><br><br>Jetzt bleiben auch bei einem compose down die Daten. Also Lessen learned.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Viel Hoffnung in Portainer, leider nicht das was ich dachte<\/h4>\n\n\n\n<p>Als ich bei meiner Arbeit mit Portainer gearbeitet hatte war ich erst begeistert! Durch deren Interface kann man dann wunderbar mit Docker arbeiten, bekommt einfachen Shell Zugriff, logs usw. So dachte ich mir auch dass ich mit Portainer mir ein Monitoring aufbauen konnte um eine Nachricht zu erhalten wenn ein Container down geht usw. Dem ist leider nicht so, auch \u00fcber die API bekomme ich keine Informationen wenn Container down sind. Schade. Am Ende muss ich dann es doch \u00fcber CheckMK l\u00f6sen. Das ist \u00fcber PiggyBack auch machbar. Gl\u00fcck gehabt \ud83d\ude05<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">und nochmal alle LXC Container anfassen &#8211; LXC auf ZFS mit Docker braucht optimierung!<\/h4>\n\n\n\n<p>Nach zwei Tagen war es irgendwie komisch, immer Morgens hatte ich kein DNS mehr &#8230; Ein Login in den LXC Container teilte mir dann mir, dass der docker daemon nicht mehr lief. Dieses passierte auch nach ein paar Tagen. Also frage ich im Docker Forum nach (<a rel=\"noreferrer noopener\" href=\"https:\/\/forums.docker.com\/t\/docker-daemon-stops-from-time-to-time\/134088\" target=\"_blank\">https:\/\/forums.docker.com\/t\/docker-daemon-stops-from-time-to-time\/134088<\/a>). Zu wenig RAM f\u00fcr den Container war ein Problem, aber in den Logs wurde Metin auf was aufmerksam, n\u00e4mlich der Storage Driver von Docker war vfs. <br><br>Kurz nachgesehen steht dick und fett, dass vfs f\u00fcr den Produktiven Betrieb nicht empfohlen wird, das ist auch nur die Fallback L\u00f6sung. Leider kommt der LXC Container nicht damit klar den ZFS Treiber zu verwenden, auch wenn wie in meinem Fall ZFS das Filesystem ist. Jedoch war ich nicht verloren, denn ich konnte overlay-fs zum laufen bekommen!<br><br>Beschrieben in <a rel=\"noreferrer noopener\" href=\"https:\/\/forums.docker.com\/t\/docker-daemon-stops-from-time-to-time\/134088\/13?u=gamienator\" target=\"_blank\">https:\/\/forums.docker.com\/t\/docker-daemon-stops-from-time-to-time\/134088\/13?u=gamienator<\/a> war eine Featureerweiterung im LXC Container notwendig, n\u00e4mlich fuse, und das Paklet <code>fuse-overlayfs<\/code> zu installieren. Nach einer Woche durfte ich wieder jeden Container anfassen, als meine Backups failten.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">PVE UI crashed komplett wegen Snapshot h\u00e4ngern<\/h4>\n\n\n\n<p>Nach ungef\u00e4hr einer Woche bekam ich eine Mail von meinem Proxmox, dass ein Backup nicht erledigt werden konnte. Dachte ich mir prima, dann schauen wir mal nach was da los ist. Anschlie\u00dfend bekam ich einen kleinen Schock bei demn Anblick:<\/p>\n\n\n<div class=\"wp-block-image is-style-default\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"737\" height=\"634\" src=\"https:\/\/3fu.de\/wp-content\/uploads\/2023\/02\/grafik.png\" alt=\"\" class=\"wp-image-119\" srcset=\"https:\/\/3fu.de\/wp-content\/uploads\/2023\/02\/grafik.png 737w, https:\/\/3fu.de\/wp-content\/uploads\/2023\/02\/grafik-300x258.png 300w\" sizes=\"auto, (max-width: 737px) 100vw, 737px\" \/><figcaption class=\"wp-element-caption\">Zu viele Fragezeichen meiner Meinung nach<\/figcaption><\/figure><\/div>\n\n\n<p>\u00dcber SSH war Proxmox noch erreichbar. Ein simpler Reboot hat geholfen, habe den Backupprozess nochmal angesto\u00dfen und es war wieder Container 107 der in diesen Lockup f\u00fchrte. Welche \u00c4nderung war es, ich habe in dem LXC Container Docker laufen. Container 107 habe ich mir dann nochmal genau angesehen und traute meinen Augen nicht, der Storage Driver vom Docker Daemon war ZFS und was dann passierte war einfach nur :troll:&#8230;<br><br>Bei der Backup Methode Snapshot hat es Zugriffsfehler gegeben. Anscheinend m\u00f6gen sie die Kaskadierung nicht von OverlayFS im ZFS usw. Eine sichere Methode LXC Container zu backupen bei denen Docker l\u00e4uft ist leider die STOP Methode.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Backup? Das muss ja auch noch sein. Dank Hetzner Storagebox<\/h4>\n\n\n\n<p>Um das alles zu backupen kann ich schlecht meine Heimleitung nutzen. W\u00e4hrend der Download mit 250 MBit\/s noch human ist wird im falle eines Desasters das Recovern Tage dauern! Deshalb dachte ich mir, man nehme eine 1 TB Hetzner Storage Box und binde diese ein. Leider ist die Performance der StorageBox alles andere als klasse. Schon kurz nach dem Einbdinden gab es diverse Timeouts beim erstellen eines Backups.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Dann doch noch eine VM mieten, wegen Proxmox Backup Server<\/h4>\n\n\n\n<p>Was ich aber dann feststellte, dass der Proxmox Backup Server stabiler ist. Also eine kleine VM bei der Hetzner Cloud gemietet um dann die StorageBox dort per SMB einzubinden. Die erste Einrichtung hat zwar \u00fcber drei Stunden gedauert, aber dann war der Storage erreichbar und ich konnte erfolgreich Backups auf die Storage Box schieben. Projekt gegl\u00fcckt!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Neuer Rootserver &#8211; Zeit f\u00fcr was neues, auch im Techstack Lange Zeit hatte ich zusammen mit meinem Kumpel einen Root Server bei Hetzner aus der Serverb\u00f6rse. Mit einem betagten i7-3770k und zwei HDDs war die Leistung sehr Bescheiden. NextCloud war schon nicht mehr m\u00f6glich wegen den Datenbankzugriffen um ein Beispiel zu nennen. So habe ich [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-111","post","type-post","status-publish","format-standard","hentry","category-allgemein"],"_links":{"self":[{"href":"https:\/\/3fu.de\/index.php?rest_route=\/wp\/v2\/posts\/111","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/3fu.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/3fu.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/3fu.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/3fu.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=111"}],"version-history":[{"count":15,"href":"https:\/\/3fu.de\/index.php?rest_route=\/wp\/v2\/posts\/111\/revisions"}],"predecessor-version":[{"id":128,"href":"https:\/\/3fu.de\/index.php?rest_route=\/wp\/v2\/posts\/111\/revisions\/128"}],"wp:attachment":[{"href":"https:\/\/3fu.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=111"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/3fu.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=111"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/3fu.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=111"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}