Best Practices für Kubernetes. Erstellung kleiner Container

Best Practices für Kubernetes. Erstellung kleiner Container

Der erste Schritt beim Bereitstellen in Kubernetes besteht darin, Ihre Anwendung in einem Container zu hosten. In dieser Reihe werden wir untersuchen, wie Sie ein kleines und sicheres Container-Image erstellen können.
Dank Docker war es noch nie so einfach, Container-Images zu erstellen. Geben Sie das Basis-Image an, fügen Sie Ihre Änderungen hinzu und erstellen Sie den Container.

Best Practices für Kubernetes. Erstellung kleiner Container

Obwohl diese Methode ideal ist, um zu beginnen, kann die Verwendung von Standard-Basis-Images zu unsicherer Verwendung führen, wenn große Images mit Sicherheitsanfälligkeiten gefüllt sind.

Darüber hinaus verwenden die meisten Docker-Images Debian oder Ubuntu als Basis-Image, und obwohl dies eine hervorragende Kompatibilität und leichte Anpassung ermöglicht (die Docker-Datei besteht aus nur zwei Codezeilen), können Basis-Images Hunderte von Megabyte an zusätzlichem Overhead in Ihren Container hinzufügen. Zum Beispiel benötigt eine einfache node.js-Anwendung namens Go 'hello-world' etwa 700 Megabyte, während die Größe Ihrer eigentlichen Anwendung nur wenige Megabyte beträgt.

Best Practices für Kubernetes. Erstellung kleiner Container

Daher stellt die gesamte zusätzliche Last eine reine Verschwendung digitaler Ressourcen dar und ist ein hervorragendes Versteck für Sicherheitsanfälligkeiten und Fehler. Lassen Sie uns also zwei Möglichkeiten betrachten, um die Größe des Container-Images zu reduzieren.

Die erste Möglichkeit besteht darin, Basis-Images kleiner Größe zu verwenden, die zweite darin, das Builder Pattern zu verwenden. Die Verwendung kleinerer Basis-Images ist wahrscheinlich der einfachste Weg, die Größe Ihres Containers zu reduzieren. Höchstwahrscheinlich bietet die Programmiersprache oder der Technologie-Stack, den Sie verwenden, ein Original-Image der Anwendung, das wesentlich kleiner ist als das Standard-Image. Lassen Sie uns unseren node.js-Container genauer ansehen.

Best Practices für Kubernetes. Erstellung kleiner Container

Standardmäßig beträgt die Größe des Basis-Images node:8 in Docker 670 MB, während die Größe von node:8-alpine nur 65 MB beträgt, was bedeutet, dass es zehnmal kleiner ist. Mit dem kleineren Basisbild Alpine reduzieren Sie erheblich die Größe Ihres Containers. Alpine ist eine kleine und leichtgewichtige Linux-Distribution, die bei Docker-Nutzern sehr beliebt ist, weil sie mit vielen Anwendungen kompatibel ist und gleichzeitig die Containergröße gering hält. Im Gegensatz zum Standard-Docker-Image "node" entfernt "node:alpine" viele Hilfsdateien und Programme und lässt nur das, was zum Ausführen Ihrer Anwendung erforderlich ist.

Um zu einem kleineren Basis-Image zu wechseln, aktualisieren Sie einfach die Docker-Datei, um mit dem neuen Basis-Image zu beginnen:

Best Practices für Kubernetes. Erstellung kleiner Container

Jetzt müssen Sie im Gegensatz zum alten onbuild-Image Ihren Code in den Container kopieren und alle Abhängigkeiten installieren. Im neuen Docker-File beginnt der Container mit dem Image node:alpine, dann wird ein Verzeichnis für den Code erstellt, die Abhängigkeiten werden mit dem Paketmanager NPM installiert und schließlich wird server.js gestartet.

Best Practices für Kubernetes. Erstellung kleiner Container

Mit diesem Update erhalten Sie einen Container, der zehnmal kleiner ist. Wenn Ihre Programmiersprache oder Ihr Stack keine Funktion zur Reduzierung des Basis-Images bietet, verwenden Sie Alpine Linux. Dies ermöglicht Ihnen auch eine vollständige Kontrolle über den Inhalt des Containers. Die Verwendung von Basis-Images mit kleiner Größe ist eine großartige Möglichkeit, kleine Container schnell zu erstellen. Aber Sie können noch mehr Einsparungen erzielen, indem Sie das Builder Pattern verwenden.

Best Practices für Kubernetes. Erstellung kleiner Container

In interpretativen Sprachen wird der Quellcode zunächst an den Interpreter übergeben und dann direkt ausgeführt. In kompilierbaren Sprachen wird der Quellcode zuvor in kompilierte Code umgewandelt. Dabei werden oft Werkzeuge verwendet, die tatsächlich nicht erforderlich sind, um den Code auszuführen. Das bedeutet, dass Sie diese Werkzeuge vollständig aus dem finalen Container entfernen können. Dazu kann das Builder Pattern verwendet werden.

Best Practices für Kubernetes. Erstellung kleiner Container

Der Code wird im ersten Container erstellt und kompiliert. Anschließend wird der kompilierte Code in den endgültigen Container gepackt, ohne die für die Kompilierung dieses Codes erforderlichen Compiler und Tools. Lassen Sie uns diesen Prozess mit einer Go-Anwendung durchlaufen. Zunächst wechseln wir vom onbuild-Image zu Alpine Linux.

Best Practices für Kubernetes. Erstellung kleiner Container

Im neuen Dockerfile beginnt der Container mit dem Image golang:alpine. Dann erstellt es ein Verzeichnis für den Code, kopiert den Quellcode hinein, kompiliert diesen Quellcode und führt die Anwendung aus. Dieser Container ist deutlich kleiner als der onbuild-Container, enthält jedoch immer noch den Compiler und andere Go-Tools, die wir eigentlich nicht benötigen. Lassen Sie uns daher einfach das kompilierte Programm extrahieren und in unseren eigenen Container verpacken.

Best Practices für Kubernetes. Erstellung kleiner Container

In dieser Docker-Datei können Sie etwas Seltsames bemerken: Sie enthält zwei FROM-Zeilen. Der erste Abschnitt aus vier Zeilen sieht genau so aus wie die vorherige Docker-Datei, außer dass er das Schlüsselwort AS verwendet, um diesem Schritt einen Namen zu geben. Im nächsten Abschnitt gibt es eine neue FROM-Zeile, die es ermöglicht, ein neues Image zu starten, wobei wir statt des Images golang:alpine das Raw alpine Image als Basis verwenden.

Raw Alpine Linux hat keine installierten SSL-Zertifikate, was die meisten API-Aufrufe über HTTPS fehlerhaft macht. Lassen Sie uns also einige Root-Zertifikate der CA installieren.

Und jetzt das Interessanteste: Um den kompilierten Code vom ersten Container in den zweiten zu kopieren, können wir einfach den Befehl COPY in Zeile 5 des zweiten Abschnitts verwenden. Dieser kopiert nur eine Anwendungsdatei und berührt nicht die Dienstprogramme von Go. Die neue mehrstufige Docker-Datei wird ein Container-Image von nur 12 Megabyte enthalten, während das Ausgangs-Container-Image 700 Megabyte groß war – das ist ein großer Unterschied!
Die Verwendung von kompakten Basis-Images und dem Builder Pattern sind hervorragende Möglichkeiten, Container mit deutlich reduzierter Größe mit minimalem Aufwand zu erstellen.
Je nach Anwendungs-Stack könnten weitere Methoden zur Reduzierung der Image- und Containergröße existieren, jedoch, haben kleinere Container tatsächlich einen messbaren Vorteil? Lassen Sie uns zwei Aspekte betrachten, in denen kleine Container besonders effektiv sind – Leistung und Sicherheit.

Um eine Leistungssteigerung zu bewerten, betrachten wir die Dauer des Containererstellungsprozesses, das Einfügen in das Registry (Push) und das anschließende Abrufen davon (Pull). Sie werden feststellen, dass ein kleinerer Container einen unbestreitbaren Vorteil gegenüber einem größeren Container hat.

Best Practices für Kubernetes. Erstellung kleiner Container

Docker speichert die Schichten im Cache, sodass nachfolgende Builds sehr schnell ausgeführt werden. In vielen CI-Systemen, die zum Erstellen und Testen von Containern verwendet werden, werden jedoch die Schichten nicht im Cache gespeichert, was zu einer erheblichen Zeitersparnis führt. Wie zu sehen ist, liegt die Build-Zeit für einen großen Container, je nach Leistung Ihrer Maschine, zwischen 34 und 54 Sekunden, während sie bei Verwendung eines durch das Builder-Muster optimierten Containers zwischen 23 und 28 Sekunden liegt. Bei solchen Vorgängen liegt der Leistungszuwachs bei 40-50%. Denken Sie also einfach daran, wie oft Sie Ihren Code erstellen und testen.

Nachdem der Container erstellt wurde, müssen Sie dessen Image (Push-Container-Image) in ein Container-Registry einfügen, um es anschließend in Ihrem Kubernetes-Cluster zu verwenden. Ich empfehle, das Container-Registry von Google zu nutzen.

Best Practices für Kubernetes. Erstellung kleiner Container

Mit Google Container Registry (GCR) zahlen Sie nur für den 'rohen' Speicher und die Netzwerknutzung, während keine zusätzlichen Gebühren für die Verwaltung von Containern anfallen. Es ist vertraulich, sicher und sehr schnell. GCR verwendet zahlreiche Tricks, um den Pull-Vorgang zu beschleunigen. Wie Sie sehen, benötigt das Einfügen eines Docker Container Images mit der Verwendung von go:onbuild, je nach Computerleistung, zwischen 15 und 48 Sekunden, während der gleiche Vorgang mit einem kleineren Container zwischen 14 und 16 Sekunden dauert. Bei weniger leistungsfähigen Maschinen erhöht sich der Geschwindigkeitsvorteil dieses Vorgangs um das Dreifache. Bei groß dimensionierten Maschinen bleibt die Zeit ungefähr gleich, da GCR einen globalen Cache für die gemeinsame Bilddatenbank nutzt, sodass Sie diese im Grunde nicht herunterladen müssen. Bei einem Computer mit niedrigem CPU können die kleinen Container hier deutlich vorteilhafter sein.

Wenn Sie GCR verwenden, empfehle ich dringend, Google Container Builder (GCB) als Teil Ihres Build-Systems zu integrieren.

Best Practices für Kubernetes. Erstellung kleiner Container

Wie Sie sehen können, ermöglicht seine Verwendung deutlich bessere Ergebnisse bei der Verkürzung der Build+Push-Dauer, als selbst bei leistungsstarken Maschinen – in diesem Fall wird der Prozess des Erstellens und Sendens von Containern an den Host fast um das Doppelte beschleunigt. Darüber hinaus erhalten Sie jeden Tag 120 Minuten kostenlose Builds, was in den meisten Fällen den Anforderungen an die Erstellung von Containern entspricht.

Als nächstes kommt die wichtigste Leistungskennzahl – die Geschwindigkeit des Pullens oder Herunterladens von Containern. Wenn Sie sich nicht allzu sehr um die Zeit kümmern, die für den Push-Vorgang benötigt wird, hat die Dauer des Pull-Vorgangs einen erheblichen Einfluss auf die Gesamtleistung des Systems. Angenommen, Sie haben einen Cluster aus drei Knoten und einer davon fällt aus. Wenn Sie ein Management-System wie Google Kubernetes Engine verwenden, wird dieser ausgefallene Knoten automatisch durch einen neuen ersetzt. Dieser neue Knoten wird jedoch völlig leer sein, und Sie müssen alle Ihre Container dorthin ziehen, damit er mit der Arbeit beginnen kann. Wenn der Pull-Vorgang zu lange dauert, wird Ihr Cluster während dieser gesamten Zeit mit einer geringeren Leistung arbeiten.

Es gibt viele Fälle, in denen so etwas passieren kann: das Hinzufügen eines neuen Knotens zum Cluster, das Aktualisieren von Knoten oder sogar der Wechsel zu einem neuen Container für das Deployment. Daher wird die Minimierung der Pull-Zeit zu einem entscheidenden Faktor. Unbestreitbar wird ein kleiner Container viel schneller heruntergeladen als ein großer. Wenn Sie mehrere Container in einem Kubernetes-Cluster verwenden, kann die Zeitersparnis erheblich sein.

Best Practices für Kubernetes. Erstellung kleiner Container

Sehen Sie sich den folgenden Vergleich an: Der Pull-Vorgang bei der Arbeit mit kleinen Containern benötigt je nach Leistung des Geräts 4-9 mal weniger Zeit als derselbe Vorgang mit go:onbuild. Die Verwendung gemeinsamer Basis-Images kleiner Container beschleunigt erheblich die Zeit und Geschwindigkeit, mit der neue Kubernetes-Knoten bereitgestellt und ins Internet können.

Lassen Sie uns das Thema Sicherheit betrachten. Man glaubt, dass kleinere Container viel sicherer sind als große, da sie eine geringere Angriffsfläche bieten. Ist das wirklich so? Eine der nützlichsten Funktionen des Google Container Registry ist die Möglichkeit, Ihre Container automatisch auf Sicherheitsanfälligkeiten zu scannen. Vor einigen Monaten habe ich sowohl Onbuild- als auch mehrstufige Container erstellt, also schauen wir mal, ob es dort verwundbare Stellen gibt.

Best Practices für Kubernetes. Erstellung kleiner Container

Das Ergebnis ist beeindruckend: In einem kleinen Container wurden nur 3 mittlere Sicherheitsanfälligkeiten entdeckt, während im großen Container 16 kritische und 376 weitere Sicherheitsanfälligkeiten gefunden wurden. Wenn wir die Inhalte des großen Containers betrachten, sehen wir, dass die meisten Sicherheitsprobleme nichts mit unserer Anwendung zu tun haben, sondern mit Programmen, die wir nicht einmal verwenden. Wenn also Leute von einer großen Angriffsfläche sprechen, meinen sie genau das.

Best Practices für Kubernetes. Erstellung kleiner Container

Die Aussage ist klar: Erstellen Sie kleine Container, denn sie bieten echte Vorteile in Bezug auf die Leistung und Sicherheit Ihres Systems.

Best Practices für Kubernetes. Organisation von Kubernetes mit Namespaces

Video abspielen

Ein wenig Werbung 🙂

Danke, dass Sie bei uns bleiben. Gefallen Ihnen unsere Artikel? Möchten Sie mehr interessante Inhalte sehen? Unterstützen Sie uns, indem Sie eine Bestellung aufgeben oder uns Ihren Freunden empfehlen. Cloud-VPS für Entwickler ab 4,99 $, eine einzigartige Alternative zu Einsteiger-Servern, die wir für Sie entwickelt haben: Alles über VPS (KVM) E5-2697 v3 (6 Kerne) 10GB DDR4 480GB SSD 1Gbps ab 19 $ oder wie man einen Server richtig teilt? (Verfügbar sind Optionen mit RAID1 und RAID10, bis zu 24 Kerne und bis zu 40GB DDR4).

Dell R730xd im Equinix Tier IV Rechenzentrum in Amsterdam zum halben Preis? Nur bei uns 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TB ab 199 $ in den Niederlanden! Dell R420 — 2x E5-2430 2.2GHz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — ab 99 $! Lesen Sie darüber Wie man eine Unternehmenskosten-Infrastruktur mit Dell R730xd E5-2650 v4-Servern für ein paar Euro aufbaut?

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster