Docker-Microservices stabil bekommen?

Pummeluff

Lt. Commander
Registriert
März 2021
Beiträge
1.120
Guten Morgen,

Kurzer Hintergrund:
In meiner Abteilung bin ich mehr oder weniger der Hauptadmin für die VM-Verwaltung. Als OS wird zum großen Teil aktuell Debian 12 eingesetzt. Die Konfiguration erfolgt über Ansible. Als lokale Firewall nutze ich nftables. Das ist mit Ansible ganz hübsch konfigurierbar.

Docker wurde bei uns bisher eher sporadisch verwendet. Meine Kenntnisse mit Docker beschränken sich auch auf die Basisfunktionalitäten. Ist auch schon länger her, dass ich mal einen Container selbst erstellt und eingesetzt hab. Eine spezielle Infrastruktur für Docker (Kubernetes, Ranger, OpenShift) existiert bei uns nicht und ist auch mittelfristig erst mal nicht geplant mangels Ressourcen (personell und Infrastruktur).

Jetzt haben wir die Situation, dass eine externe Entwicklungsfirma ein Projekt mit Docker Microservices umsetzt. Betrieben wird das auf einer Debian-VM. Und da laufen dann ca. 20 Container, von denen einige über das VM-Netzwerk erreichbar sind und der Rest im Docker-Netzwerk miteinander kommuniziert. Dabei sind auch Standardservices wie Grafana, Prometheus usw.

Und jetzt kommen meine Probleme damit:

1. Firewall
Wie oben geschrieben, konfiguriere ich die lokale Firewall per Ansible. Ich nutze ein NFTables-Template, was dann über die Host-Konfiguration leicht erweiterbar ist.

Jetzt kommt Docker daher und erstellt beim Start des Dienstes seine eigenen Regeln über iptables. Per iptables-nft (bei Redhat inzwischen depcrecated) wird das Ganze nach nftables übersetzt, was allerdings nicht zufriedenstellend funktioniert. Statt inet wird ip4 und ip6 erstellt. Und per iptables wird versucht, die Input-Chain zu erstellen, die es in nftables schon gibt.

Eine Idee wäre, Docker durch podman abzulösen. Das scheint wohl zumindest einen initialen NFTables-Support zu haben.

Alternativ schreib analog zum obigen Link ein Skript, was mir iptables-nft bereinigt und bei jedem Docker-Start auch die NFTables mit einbindet.

Da im nichtprofessionellen Teil des Computerbase-Forums gerne so ziemlich jedes Problem mit Docker erschlagen wird, gehe ich mal davon aus, dass die lokale Firewall da keine Rolle spielt.

Gibt's noch andere Möglichkeiten, wie ich Docker dazu bewegen kann, mit NFTables zusammenzuarbeiten?

2. Reinstallation von Docker
Durch ein Missgeschick meinerseits wurde Docker deinstalliert und anschließend neu installiert. Der Docker-Daemon startete problemlos. Die Container waren alle noch vorhanden. Allerdings beendeten sich fast alle Container gleich nach dem Start (Status: Exited). Das ist natürlich blöd.

Sofern die Container eine Reinstallation von Docker generell nicht überleben, hab ich ein Problem. Falls doch, wie kann ich mir das Problem erklären? Und wie bekomme ich es hin, dass nach einer De- und Re-Installation von Docker auch die Container wieder normal starten und laufen?

Im aktuellen Zustand hab ich ziemliche Bauchschmerzen damit, da ich nicht davon ausgehen kann, dass nach einem Reboot oder Systemupdate die Container auch weiterhin zuverlässig laufen. Mit erscheint das ganze Microservices-Konzept bisher extrem fragil.

3. Rechte in Standardcontainer
Docker nutzt einen internen DNS, damit die Container untereinander per Containername kommunizieren können. Bei einigen Containern hatten wir den Fall, dass auf der Test-VM der Entwickler außerhalb unseres Unternehmens das problemlos geklappt hat, auf der firmeninternen VM jedoch nicht.

Ein Blick in den Container offenbarte dann, dass die /etc/resolv.conf die Rechte 0640 (root:root) hatte. Entsprechend konnte ein Nicht-Root-Nutzer im Container keine DNS-Server abfragen. Als ich die Rechte auf 0644 manuell änderte, was Linux-Standard ist, klappte auch die Kommunikation.

Jetzt kann ich mir schlecht vorstellen, dass ein so offensichtlicher Bug in Standardcontainern, z.B. Grafana konfiguriert ist. In der docker-compose.yaml wurde aber nichts dergleichen konfiguriert. Der temporäre Workaround bestand dann darin, dass die Dienste innerhalb des Containers als Root laufen. Natürlich kann ich auch in der docker-compose.yaml per chmod die Rechte der Datei setzen. Allerdings denke ich nicht, dass ein Standardcontainer sowas nötig hat.

Wie kann ich herausfinden, was hier bei der Konfiguration bzw. beim Container-Deployment schiefläuft?
 
Pummeluff schrieb:
Mit erscheint das ganze Microservices-Konzept bisher extrem fragil.
Microservices sind primär CV-driven development. Normale Anwendungen in normalem Firmen profitieren davon nicht.

Der externe Dienstleister soll deine Probleme lösen, das macht kein Sinn hier irgendwelche Lösungen vorzuschlagen, die müssen exakt auf deine Umgebung zugeschnitten werden.

Zu 1: ich kenne keinen stabilen/produktiven weg docker mit nftables zu verheiraten. Podman hat andere Schwierigkeiten/Herausforderungen

Zu 2: ohne deine docker config zu kennen, ist das kompliziert, aber mögliche Update Strategien sind rolling deployment (gerade bei Microservices) oder Green/blue deployments

Zu 3: keine Ahnung was du da konfigurieren willst, aber bei so Standardanwendungen wie grafana modifiziert man eigentlich nicht den Container.

Ich glaube hier kollidieren dein eigenes wissen, deine eigenen Versuche mit einer ggf komplexen Umgebung. Der externe Dienstleister soll dir das komplette ansible/Terraform Skript Set geben, das ist im Normalfall nicht der Job der IT Administration
 
  • Gefällt mir
Reaktionen: jebeo und andy_0
Also um so etwas stabil zu bekommen brauchst exakt einen Orchestrator wie Kubernetes / Open Shift. Ansonsten musst selbst Skripte schreiben die schauen ob alles läuft (und ggf neu starten).

Damit kannst dann auch routing und DNS konfigurieren (Ingress Container etc.).

Zu Microservices sollte man sich bewusste entscheiden. Auf der anderen Seite wird heute alles Microservice genannt was mit einem Framwork geschrieben ist, mit dem man auch Microservices machen kann. Aber hier würde das Thema den Rahmen sprengen (das ist Arbeit und ich hab grad Urlaub - aber schreib mir ruhig eine PM)

Gute Microservices starten nur dann wenn sie gebraucht werden (in Millisekunden) und verbrauchen keine Resourcen wenn sie nicht gebraucht werden (mit SpringBoot(Java) geht das z.b. nicht).
 
Ich bin kein Experte in Sachen Docker Administration, Tornhoof hat aber in vielen Fällen recht.

Tornhoof schrieb:
rolling deployment (gerade bei Microservices)
Das wäre in der Tat einer der häufigsten Use Cases.

Tornhoof schrieb:
Zu 3: keine Ahnung was du da konfigurieren willst, aber bei so Standardanwendungen wie grafana modifiziert man eigentlich nicht den Container.
Bin ich voll dabei. Das Image kommt so, wie es kommt. Ist da was nicht gewünscht, muss im Schritt der Imageerzeugung eingegriffen werden. Nicht anschließend.

Tornhoof schrieb:
Der externe Dienstleister soll dir das komplette ansible/Terraform Skript Set geben, das ist im Normalfall nicht der Job der IT AAdministration.
Sehe ich auch nicht als Job der Administration. Wichtig finde ich u.U. Die Möglichkeit, die Images selber zu erzeugen. Oder zumindest werden die Images wie gewünscht erzeugt und in einer (euren eigenen) Docker Registry bereitgestellt, damit ihr jederzeit eine Instanz (Container) starten könnt.

dermoritz schrieb:
Also um so etwas stabil zu bekommen brauchst exakt einen Orchestrator
Das ist im Kern korrekt. Bleibt die Frage, was eigentlich das genaue Problem ist

Pummeluff schrieb:
Betrieben wird das auf einer Debian-VM. Und da laufen dann ca. 20 Container
Da haben wir IMHO eines der Probleme. Es muss egal sein, wo die Container laufen. Über "Skripte" muss die Umgebung relativ schnell wieder lauffähig gemacht werden können.

Je nach Szenario Kann dies auch eine Form von manueller Verwaltung z.B. über Portainer sein.
 
Zuletzt bearbeitet:
andy_0 schrieb:
Bin ich voll dabei. Der Container kommt so, wie er kommt. Ist da was nicht gewünscht, muss im Schritt der Containererzeugung eingegriffen werden. Nicht anschließend.

andy_0 schrieb:
Sehe ich auch nicht als Job der Administration. Wichtig finde ich u.U. Die Möglichkeit, die Container selber zu erzeugen. Oder zumindest werden die Container wie gewünscht erzeugt und in einer (euren eigenen) Docker Registry bereitgestellt, damit ihr jederzeit eine Instanz starten könnt.

Du meinst da sicherlich die Images auf dessen Basis dann ein Container gestartet wird. In einer Registry (Docker Hub oder self-hosted) liegen dann die vorgefertigten Images.

Die zu startenden Container können durchaus noch konfiguriert werden, was meist über entsprechende Umgebungsvariablen passiert, die man beim Starten des Containers angibt. Beispielsweise kann man beim offiziellen Docker-Image für PostgreSQL über Umgebungsvariablen den Datenbanknamen, den DB-Nutzer (Superuser) und dessen Passwort festlegen.
 
  • Gefällt mir
Reaktionen: andy_0
mibbio schrieb:
Du meinst da sicherlich die Images auf dessen Basis dann ein Container gestartet wird.
Korrekt, vielen Dank. Habe ich korrigiert.

mibbio schrieb:
Die zu startenden Container können durchaus noch konfiguriert werden, was meist über entsprechende Umgebungsvariablen passiert,
Das ist korrekt. Die Manipulation von Einstellungen in einem laufenden Container sollte jedoch strikt vermieden werden, da damit der Container nicht mehr immutable ist. Darauf wollte ich hinaus.
 
  • Gefällt mir
Reaktionen: mibbio
Wo speicherst du die Container zwischen? Hast du eine eigene Registry und schaust auch nach CVE?
Habt ihr definiert ob die Container alle als non-root laufen müssen? Es ist sinnvoll Container nicht als root laufen zu lassen, manchmal wird dies aber vom verwendeten Container nicht angeboten. Heißt umbiegen was meistens Probleme verursacht oder selber bauen.

Es gibt Möglichkeiten das Docker Netzwerk auszuschalten und das CNI Plugin zu verwenden
https://www.dasblinkenlichten.com/understanding-cni-container-networking-interface/
https://www.dasblinkenlichten.com/using-cni-docker/

Dann wäre das Thema Iptables von Docker erledigt, heißt aber Konfigurations muss sitzen.

zu deinem Punkt das es nicht stabil ist nutzt du da mount points oder docker volumes oder sogar mischbetrieb? Hört sich so an als er da irgendwie was nicht mehr findet, weil ne Config oder so fehlt.

Läuft das alles auf einer VM? Mußt du etwas skalieren höhe oder breite?
Bei solchen Deployments sind wir ganz schnell in Kubernetes unterwegs. Wer schon mal damit zu tun hatte, das macht niemand mal nebenher .Kubernetes ist eines der Komplexestens Öko Systeme im Linux Bereich dies es zur Zeit gibt. Ich will da keine Panik verbreiten, sondern nur klar machen, nebenher ist nicht.

Wichtig ist hier, ein oder mehrere DEV/Test Systeme um dinge Testen und Planen zu können.
 
andy_0 schrieb:
Das ist korrekt. Die Manipulation von Einstellungen in einem laufenden Container sollte jedoch strikt vermieden werden, da damit der Container nicht mehr immutable ist. Darauf wollte ich hinaus.
Genau, da wäre der korrekte Ansatz dann, sich ein Dockerfile zu schreiben, um ein individuell angepasstes Image zu erstellen. Und dann mit diesem Image einen Container deployen.

Sowas bleibt ja in manchen Szenmarien auch gar nicht aus, wenn man eine eigene Anwendung in einem Container deployen will. Da setzt man bspw. keine Container mit dem Standardimage für NodeJS auf und kopiert dann seine NodeJS-Anwendung in den laufenen Container, sondern baut ein Image auf Basis des NodeJS-Images, das die Anwendnung direkt mit drin hat.
 
mibbio schrieb:
Sowas bleibt ja in manchen Szenmarien auch gar nicht aus, wenn man eine eigene Anwendung in einem Container deployen will.
Ich würde behaupten, dass ist der Standardfall für eigene Software. Standardsoftware, wie z.B. eine Datenbank, kann man aus der Docker Registry nehmen und "einfach so" nutzen, aber das Image für die eigene Software wird individuell erzeugt.

mibbio schrieb:
Da setzt man bspw. keine Container mit dem Standardimage für NodeJS auf und kopiert dann seine NodeJS-Anwendung in den laufenen Container, sondern baut ein Image auf Basis des NodeJS-Images, das die Anwendnung direkt mit drin hat.
Das muss der Administration aber erst bewusst werden. Ein Image ist final. Alle Änderungen müssen vorher, d.h. in der Entwicklung für die Imageerzeugung, geschehen.
 
Tornhoof schrieb:
Zu 3: keine Ahnung was du da konfigurieren willst, aber bei so Standardanwendungen wie grafana modifiziert man eigentlich nicht den Container.
Ich will da gar nichts modifizieren. Fakt war halt, dass die resolv.conf im Container die falschen Rechte hatte. Wie das zustande gekommen ist, versuche ich gerade zu ergründen. Die docker-compose-Datei hat der Dienstleister erstellt, als er die Container deployt hat.

konkretor schrieb:
Wo speicherst du die Container zwischen? Hast du eine eigene Registry und schaust auch nach CVE?
Tja, schön wär's. Hätte ich die Entscheidungsgewalt gehabt, hätte ich mich gegen Docker für das Projekt entschieden. Das Deployment läuft so ab, dass der externe Dienstleister die Images auf den Rechner kopiert und dann docker compose aufruft. Ich bin davon alles andere als begeistert.

Eine Registry haben wir auch nicht. Das Problem mit den CVEs hab ich mal angesprochen. Ich gehe aber nicht davon aus, dass da irgendwas gefixt wird, wenn sich eine neue Lücke auftut.

konkretor schrieb:
Habt ihr definiert ob die Container alle als non-root laufen müssen? Es ist sinnvoll Container nicht als root laufen zu lassen, manchmal wird dies aber vom verwendeten Container nicht angeboten. Heißt umbiegen was meistens Probleme verursacht oder selber bauen.
Nein, da wurde im Vorfeld nichts definiert.

konkretor schrieb:
Läuft das alles auf einer VM? Mußt du etwas skalieren höhe oder breite?
Nein, da muss nichts skalieren. Den Entwicklern wurde freie Hand gelassen. Und die haben sich dann für Docker entschieden, weil sie vermutlich damit ein ganzes Stück Arbeit sparen. Ich hab im Nachhinein noch versucht, ein paar Sachen zu retten, z.B. dass das Logging nicht nur im Loki-Container geschieht sondern nach /var/log auf dem Host übertragen wird. Das war schon ein kleiner Kampf. Auch konnte ich verhindern, dass die Container im /home deployt werden.

Wie das halt so ist. Bei der Projektplanung im Einklang mit der Chefebene wurden Ziele definiert, was die Software zu leisten hat. Wie das umzusetzen ist, wurde hingegen nicht festgelegt.

Ok, was nehm ich jetzt davon mit:
Ich mach mich in den nächsten Tagen mal ran und versuch über ein Bash-Skript und entsprechender Systemd-Konfiguration Docker mit NFTAbles zu verheiraten. Dem Dienstleister hatte ich schon vor ein paar Tagen eine Mail geschrieben, dass wir uns wegen des ganzen Deploymentprozesses nochmal hinsetzen müssen.

Danke erstmal an alle. Die Beiträge bestätigen im Grunde genommen meine Befürchtungen, die ich bereits im Vorfeld hatte. Und es bestätigt auch wieder, dass die Arbeit durch die Nutzung von Docker nicht weniger wird. Sie verlagert sich nur auf andere Personen.
 
Puh, wie du schon gemerkt hast, ist das ne ganz schöne Baustelle. Also besprich das nochmals mit der Security Abteilung falls es diese gibt. Vielleicht findest du da ein paar Hebel
 
Tja, der Dienstleister hat sich das Leben leicht gemacht. Nimm was du kriegen kannst, im Zweifel aus zweifelhaften Quellen und frickel alles hin damit es halt irgendwie tut.

Das ist halt der Unterschied zwischen echtem Produktiveinsatt der sich mit Compliance beschäftigt und irgendwelches Frickel-Sachen.

Ohne klare Auflagen wie nir rootless Container musst du davon ausgehen, dad im Container immer alles als root läuft und im Zweifel sogar als privileged Container.

Jeder Handschlag der gespart werden kann wird gespart. Hauptsache das Gesamtkonstruckt zuckt und tut erstmal das was verlangt wird. Ob das auch nur irgendwie nachhaltig Betreiber ist ist in der Regal kein Thema.
 
  • Gefällt mir
Reaktionen: konkretor und jebeo
Zurück
Oben