Kubernetes ist ein hervorragendes Werkzeug zum Starten von Docker-Containern in einer clusterbasierten Produktionsumgebung. Es gibt jedoch Aufgaben, die Kubernetes nicht bewältigen kann. Bei häufigen Bereitstellungen in der Produktionsumgebung benötigen wir ein vollständig automatisiertes Blue/Green-Deployment, um Ausfallzeiten in diesem Prozess zu vermeiden, bei dem auch externe HTTP-Anfragen bearbeitet und SSL-Entladungen durchgeführt werden müssen. Dies erfordert die Integration mit einem Lastenausgleich, wie zum Beispiel ha-proxy. Eine weitere Herausforderung ist das halbautomatische Skalieren des Kubernetes-Clusters in einer Cloud-Umgebung, beispielsweise das teilweises Reduzieren des Clusters zu Nachtzeiten.
Obwohl Kubernetes diese Funktionen nicht „out of the box“ bietet, stellt es eine API zur Verfügung, die für die Lösung solcher Aufgaben genutzt werden kann. Werkzeuge für automatisierte Blue/Green-Bereitstellungen und das Skalieren des Kubernetes-Clusters wurden im Rahmen des Cloud RTI-Projekts entwickelt, das auf Open-Source basiert.
In diesem Artikel, einer Video-Transkription, wird erklärt, wie man Kubernetes zusammen mit anderen Open-Source-Komponenten für eine produktionsbereite Umgebung einrichtet, die ohne Ausfallzeiten in der Produktion den Code aus einem git commit aufnimmt.

Nachdem Sie also Zugriff auf Ihre Anwendungen aus der Außenwelt haben, können Sie mit der vollständigen Automatisierung beginnen, d.h. sie auf den Stand zu bringen, bei dem ein git commit durchgeführt werden kann, und sicherzustellen, dass dieser git commit in der Produktion endet. Natürlich möchten wir bei der Durchführung dieser Schritte, insbesondere beim Deployment, keine Ausfallzeiten erleben. Daher beginnt jede Automatisierung in Kubernetes mit der API.

Kubernetes ist nicht das Werkzeug, das man „directly out of the box“ produktiv nutzen kann. Natürlich können Sie das tun, kubectl verwenden usw., aber die API ist dennoch das interessanteste und nützlichste an dieser Plattform. Wenn Sie die API als Funktionsbündel nutzen, können Sie praktisch auf alles zugreifen, was Sie in Kubernetes tun möchten. Auch kubectl selbst nutzt die REST API.
Dies ist ein REST-API, sodass Sie für die Arbeit mit diesem API beliebige Programmiersprachen und Werkzeuge verwenden können. Benutzerdefinierte Bibliotheken erleichtern Ihnen jedoch das Leben erheblich. Mein Team hat zwei solche Bibliotheken geschrieben: eine für Java / OSGi und eine für Go. Letztere wird nicht häufig verwendet, aber in jedem Fall stehen Ihnen diese nützlichen Tools zur Verfügung. Sie sind Teil eines teilweise lizenzierten Open-Source-Projekts. Es gibt viele solcher Bibliotheken für verschiedene Sprachen, sodass Sie die am besten geeigneten auswählen können.

Bevor Sie mit der Automatisierung der Bereitstellung beginnen, müssen Sie sicherstellen, dass dieser Prozess nicht unterbrochen wird. Zum Beispiel führt unser Team die Produktionsbereitstellung mitten am Tag durch, wenn die Nutzer die Anwendungen am meisten nutzen, daher ist es sehr wichtig, Verzögerungen in diesem Prozess zu vermeiden. Um Ausfallzeiten zu vermeiden, gibt es zwei Methoden: Blue/Green-Deployment oder Rolling Update. Im letzteren Fall, wenn Sie 5 Replikate der Anwendung haben, werden sie nacheinander aktualisiert. Diese Methode funktioniert gut, ist jedoch nicht geeignet, wenn während der Bereitstellung verschiedene Versionen der Anwendung gleichzeitig ausgeführt werden. In diesem Fall können Sie die Benutzeroberfläche aktualisieren, während das Backend mit der alten Version arbeitet, was zu einem Ausfall der Anwendung führt. Daher ist das Arbeiten unter solchen Bedingungen aus programmiertechnischer Sicht ziemlich schwierig.
Das ist einer der Gründe, warum wir es vorziehen, Blue/Green-Deployment für die Automatisierung der Bereitstellung unserer Anwendungen zu verwenden. Bei dieser Methode müssen Sie sicherstellen, dass zu einem bestimmten Zeitpunkt nur eine Version der Anwendung aktiv ist.
Der Blue/Green-Deployment-Mechanismus funktioniert folgendermaßen. Wir erhalten den Datenverkehr für unsere Anwendungen über ha-proxy, der ihn an die laufenden Replikate der Anwendung derselben Version weiterleitet.
Wenn ein neues Deployment erfolgt, verwenden wir Deployer, dem neue Komponenten bereitgestellt werden, und er führt das Deployment der neuen Version durch. Das Deployment der neuen Version der Anwendung bedeutet, dass ein neuer Satz an Replikaten „hochgefahren“ wird, nachdem diese Replikate der neuen Version in einem separaten, neuen Pod gestartet werden. Ha-proxy weiß jedoch nichts darüber und leitet bisher keinen Arbeitsaufwand an sie weiter.
Deshalb ist es zunächst notwendig, die Funktionsfähigkeit der neuen Versionen durch Health Checking zu überprüfen, um sicherzustellen, dass die Replikate bereit sind, die Last zu bedienen.

Alle Deployment-Komponenten müssen irgendeine Form von Health Check unterstützen. Dies kann eine sehr einfache HTTP-Prüfung sein, bei der Sie einen Statuscode 200 erhalten, oder eine tiefere Prüfung, bei der Sie die Verbindung der Replikate zur Datenbank und anderen Diensten überprüfen, die Stabilität der Verbindungen der dynamischen Umgebung, und ob alles richtig gestartet und funktioniert. Dieser Prozess kann ziemlich komplex sein.

Nachdem das System die Funktionsfähigkeit aller aktualisierten Replikate sichergestellt hat, wird Deployer die Konfiguration aktualisieren und das richtige confd übergeben, das ha-proxy neu konfiguriert.

Erst danach wird der Verkehr zu dem Pod mit den Replikaten der neuen Version geleitet, während der alte Pod verschwindet.

Dieser Mechanismus ist kein spezifisches Merkmal von Kubernetes. Das Konzept des Blue/Green Deployments existiert schon eine geraume Zeit und hat immer einen Lastenausgleich verwendet. Zuerst leiten Sie den gesamten Verkehr zur alten Version der Anwendung, und nach dem Update wechseln Sie vollständig zur neuen Version. Dieses Prinzip wird nicht nur in Kubernetes verwendet.
Jetzt möchte ich Ihnen das neue Deployment-Komponente – Deployer – vorstellen, das die Funktionsfähigkeit überprüft, das Proxy neu konfiguriert und so weiter. Dies ist ein Konzept, das sich nicht auf die Außenwelt bezieht und innerhalb von Kubernetes existiert. Ich werde Ihnen zeigen, wie Sie Ihr eigenes Deployer-Konzept mit Open-Source-Tools erstellen können.
Das Erste, was der Deployer macht, ist die Erstellung eines Replication Controller (RC) mit der Kubernetes-API. Diese API erstellt Pods und Dienste für die weitere Bereitstellung, d.h. sie erstellt einen völlig neuen Cluster für unsere Anwendungen. Sobald der RC sicherstellt, dass die Replikate gestartet wurden, führt er einen Health-Check durch. Für dies wird im Deployer der Befehl GET /health verwendet. Dadurch werden die entsprechenden Prüfkomponenten gestartet und alle Elemente überprüft, die den Betrieb des Clusters gewährleisten.

Sobald alle Pods über ihren «Gesundheitszustand» berichtet haben, erstellt der Deployer ein neues Konfigurationselement – das verteilte Speicher etcd, das innerhalb von Kubernetes verwendet wird, einschließlich zur Speicherung der Konfiguration des Load Balancers. Wir schreiben Daten in etcd, und ein kleines Tool namens confd überwacht etcd auf neue Daten.
Wenn es Änderungen an der ursprünglichen Konfiguration entdeckt, generiert es eine neue Einstellungsdatei und übergibt diese an ha-proxy. In diesem Fall wird ha-proxy ohne Verlust von Verbindungen neu gestartet und leitet die Last an neue Dienste weiter, die den Betrieb der neuen Version unserer Anwendungen gewährleisten.

Wie Sie sehen, gibt es trotz der Vielzahl von Komponenten nichts Kompliziertes. Sie müssen nur mehr Aufmerksamkeit der API und etcd schenken. Ich möchte Ihnen von dem Open-Source-Deployer erzählen, den wir selbst verwenden – dem Amdatu Kubernetes Deployer.

Dies ist ein Tool zur Orchestrierung von Kubernetes-Bereitstellungen, das folgende Funktionen bietet:
- Blue/Green Deployment;
- Konfiguration eines externen Load Balancers;
- Verwaltung von Deploymentsbeschreibungen;
- Verwaltung der tatsächlichen Bereitstellung;
- Health Checks während der Bereitstellung;
- Einspeisung von Umgebungsvariablen in die Pods.
Dieser Deployer ist auf der Kubernetes-API aufgebaut und stellt eine REST-API zur Verwaltung von Beschreibungen und Bereitstellungen sowie eine Websocket-API für Streaming-Protokolle während der Bereitstellung bereit.
Er speichert die Konfigurationsdaten des Load Balancers in etcd, sodass Sie ha-proxy nicht unbedingt mit «Out of the Box»-Unterstützung verwenden müssen, sondern problemlos Ihre eigene Load-Balancer-Konfigurationsdatei nutzen können. Amdatu Deployer ist in Go geschrieben, genau wie Kubernetes selbst, und lizenziert unter Apache.
Vor der Verwendung dieser Version des Deployers habe ich den folgenden Deployment-Descriptor verwendet, in dem die benötigten Parameter angegeben sind.

Einer der wichtigen Parameter dieses Codes ist die Aktivierung des Flags „useHealthCheck“. Wir müssen angeben, dass während des Deployments eine Funktionsprüfung durchgeführt werden muss. Dieser Parameter kann deaktiviert werden, wenn im Deployment Container von Drittanbietern verwendet werden, die nicht überprüft werden müssen. In diesem Descriptor sind auch die Anzahl der Replikate und die URL des Frontends angegeben, die für ha-proxy erforderlich ist. Am Ende wird das Flag der Pod-Spezifikation „podspec“ angegeben, das sich an Kubernetes wendet, um Informationen zur Portkonfiguration, zum Image usw. zu erhalten. Dies ist ein recht einfacher Descriptor im JSON-Format.
Ein weiteres Werkzeug, das Teil des Open-Source-Projekts Amdatu ist, ist Deploymentctl. Es verfügt über eine Benutzeroberfläche (UI) zur Konfiguration des Deployments, speichert die Deployment-Historie und enthält Webhooks für Rückrufe durch Drittbenutzer und Entwickler. Sie können die UI nicht verwenden, da der Amdatu Deployer selbst eine REST-API ist, aber diese Schnittstelle kann Ihnen das Deployment erheblich erleichtern, ohne dass eine API verwendet werden muss. Deploymentctl ist in OSGi/Vertx unter Verwendung von Angular 2 geschrieben.
Jetzt werde ich das oben Gesagte auf dem Bildschirm demonstrieren, indem ich eine vorab erstellte Aufnahme verwende, damit Sie nicht warten müssen. Wir werden eine einfache Anwendung in Go bereitstellen. Machen Sie sich keine Sorgen, wenn Sie vorher noch nie mit Go zu tun hatten, dies ist eine sehr einfache Anwendung, also sollte Ihnen alles klar sein.

Hier erstellen wir einen HTTP-Server, der nur auf /health antwortet, sodass diese Anwendung lediglich die Funktionsprüfung überprüft und nichts weiter. Wenn die Prüfung erfolgreich ist, wird die unten angezeigte JSON-Struktur aktiviert. Sie enthält die Version der Anwendung, die vom Deployer bereitgestellt wird, die Nachricht, die Sie oben in der Datei sehen, und den boolean Datentyp – ob unsere Anwendung funktionsfähig ist oder nicht.
Mit der letzten Zeile habe ich etwas geschummelt, da ich am oberen Rand der Datei einen festen boolean Wert platziert habe, der mir später hilft, sogar eine „nicht funktionsfähige“ Anwendung bereitzustellen. Damit werden wir uns später befassen.
Lass uns anfangen. Zuerst überprüfen wir, ob es laufende Pods gibt, indem wir den Befehl ~ kubectl get pods verwenden, und wenn wir keine Antwort von der Frontend-URL erhalten, stellen wir fest, dass derzeit keine Deployments durchgeführt werden.

Auf dem Bildschirm sehen Sie die von mir erwähnte Benutzeroberfläche Deploymentctl, in der die Bereitstellungsparameter festgelegt werden: Namespace, Anwendungsname, Bereitstellungsversion, Anzahl der Replikate, Frontend-URL, Containername, Image, Ressourcengrenzen, Portnummer für den Health Check usw. Die Ressourcengrenzen sind sehr wichtig, da sie die maximal mögliche Nutzung von Hardware ermöglichen. Hier können Sie auch das Bereitstellungsprotokoll ansehen.

Wenn wir jetzt den Befehl ~ kubectl get pods wiederholen, können wir sehen, dass das System für 20 Sekunden „einfriert“, während Ha-Proxy neu konfiguriert wird. Danach wird der Pod gestartet, und unsere Replikat ist im Bereitstellungsprotokoll sichtbar.

Ich habe die 20-sekündige Wartezeit aus dem Video herausgeschnitten, und jetzt sehen Sie auf dem Bildschirm, dass die erste Version der Anwendung bereitgestellt wurde. All dies wurde nur mithilfe der Benutzeroberfläche durchgeführt.

Jetzt versuchen wir die zweite Version. Dazu ändere ich die Nachricht der Anwendung von „Hello, Kubernetes!“ in „Hello, Deployer!“. Das System erstellt dieses Image und speichert es im Docker-Registry. Danach klicken wir einfach erneut auf die Schaltfläche „Deploy“ im Fenster Deploymentctl. Dabei wird automatisch das Bereitstellungsprotokoll gestartet, genau wie es beim Bereitstellen der ersten Version der Anwendung der Fall war.

Der Befehl ~ kubectl get pods zeigt, dass derzeit 2 Versionen der Anwendung ausgeführt werden, die Frontend-URL jedoch anzeigt, dass weiterhin Version 1 aktiv ist.

Der Lastenausgleich wartet, bis der Health Check durchgeführt wurde, bevor er den Datenverkehr auf die neue Version umleitet. Nach 20 Sekunden wechseln wir zu curl und sehen, dass jetzt die Version 2 der Anwendung bereitgestellt wurde und die erste entfernt wurde.

Das war die Bereitstellung einer „gesunden“ Anwendung. Lassen Sie uns sehen, was passiert, wenn ich für die neue Version der Anwendung den Parameter Healthy von true auf false ändere, also versuche, eine ungesunde Anwendung bereitzustellen, die den Leistungstest nicht bestanden hat. Dies kann geschehen, wenn in der Entwicklungsphase Fehler in der Konfiguration aufgetreten sind und die Anwendung in diesem Zustand in die Produktion geschickt wurde.
Wie Sie sehen, durchläuft das Deployment alle oben genannten Phasen, und ~ kubectl get pods zeigt an, dass beide Pods gestartet wurden. Im Gegensatz zum vorherigen Deployment zeigt das Protokoll jedoch einen Timeout-Status an. Das bedeutet, dass die neue Version der Anwendung aufgrund fehlgeschlagener Health-Checks nicht bereitgestellt werden kann. Daher sehen Sie, dass das System zur Nutzung der alten Version der Anwendung zurückgekehrt ist, während die neue Version einfach gelöscht wurde.

Der Vorteil dabei ist, dass selbst wenn Sie eine große Anzahl von gleichzeitigen Anfragen an die Anwendung haben, diese den Ausfall während des Deployment-Vorgangs nicht bemerken werden. Wenn Sie diese Anwendung mit dem Gatling-Framework testen, das die maximal mögliche Anzahl an Anfragen sendet, sind keine dieser Anfragen fehlgeschlagen. Das bedeutet, dass unsere Nutzer die Versionen in Echtzeit nicht einmal bemerken werden. Scheitert das Deployment, läuft die Arbeit mit der alten Version weiter; ist es erfolgreich, wechseln die Nutzer zur neuen Version.
Es gibt nur einen Grund, der zu einem Fehlschlag führen kann: Wenn der Health-Check erfolgreich war, die Anwendung jedoch abstürzt, sobald die Arbeitslast eintrifft, dann tritt der Kollaps nur nach Abschluss des Deployments auf. In diesem Fall müssen Sie manuell auf die alte Version zurückkehren. So haben wir erörtert, wie Kubernetes mit dafür vorgesehenen Open-Source-Tools verwendet werden kann. Der Deployment-Vorgang wird erheblich einfacher, wenn Sie diese Tools in Ihre Build/Deploy-Pipelines integrieren. Dabei können Sie sowohl die Benutzeroberfläche als auch komplett automatisierte Prozesse nutzen, beispielsweise durch einen Commit zum Master.

Unser Build-Server erstellt ein Docker-Image und lädt es in Docker Hub oder ein anderes von Ihnen verwendetes Repository hoch. Docker Hub unterstützt Webhooks, sodass wir das Remote-Deployment über Deployer wie oben gezeigt auslösen können. Dadurch kann das Deployment der Anwendung in eine potenzielle Produktionsumgebung vollständig automatisiert werden.
Kommen wir zur nächsten Thematik – das Skalieren des Kubernetes-Clusters. Ich möchte darauf hinweisen, dass der Befehl kubectl ein Skalierungsbefehl ist. Damit kann die Anzahl der Replikate im vorhandenen Cluster einfach erhöht werden. In der Praxis wollen wir jedoch normalerweise die Anzahl der Nodes und nicht der Pods erhöhen.

Dabei kann es tagsüber notwendig sein, die Anzahl zu erhöhen, während man in der Nacht, um die Kosten für die Amazon-Dienste zu senken, die Anzahl der laufenden Anwendungsinstanzen verringern möchte. Das bedeutet nicht, dass es genug ist, nur die Anzahl der Pods zu skalieren, da man auch dann für einen inaktiven Node bei Amazon bezahlen muss. Das heißt, neben dem Skalieren der Pods müssen wir auch die Anzahl der verwendeten Maschinen skalieren.
Das kann zu Schwierigkeiten führen, denn unabhängig davon, ob wir Amazon oder einen anderen Cloud-Dienst verwenden, weiß Kubernetes nichts über die Anzahl der verwendeten Maschinen. Es fehlt ein Werkzeug, das es ermöglicht, das System auf der Ebene der Nodes zu skalieren.

Daher müssen wir uns sowohl um die Nodes als auch um die Pods kümmern. Wir können das Starten neuer Nodes einfach über die AWS-API und die Auto-Scaling-Gruppe für die Anpassung der Anzahl der Arbeitsknoten in Kubernetes skalieren. Außerdem kann cloud-init oder ein ähnliches Skript verwendet werden, um Nodes im Kubernetes-Cluster zu registrieren.
Ein neues Gerät wird in einer Scaling-Gruppe gestartet, registriert sich als Node, wird im Master-Register eingetragen und beginnt seine Arbeit. Danach kann die Anzahl der Replikate erhöht werden, um die neu entstandenen Nodes zu nutzen. Eine Reduzierung des Maßstabs erfordert mehr Aufwand, da sichergestellt werden muss, dass dieser Schritt nicht zur Zerstörung bereits laufender Anwendungen führt, nachdem die "unnötigen" Maschinen abgeschaltet wurden. Um ein solches Szenario zu vermeiden, müssen die Nodes in den Status "unschedulable" versetzt werden. Das bedeutet, dass der Scheduler bei der Planung von DaemonSet-Pods diese Nodes ignoriert. Der Scheduler wird nichts von diesen Servern löschen, aber auch keine neuen Container dort starten. Der nächste Schritt besteht im Draining des Knoten, das heißt der Verschiebung der laufenden Pods auf eine andere Maschine oder andere Nodes mit ausreichender Kapazität. Nachdem sichergestellt ist, dass auf diesen Nodes keine Container mehr laufen, können sie aus Kubernetes entfernt werden. Danach existieren sie für Kubernetes einfach nicht mehr. Anschließend muss die AWS-API verwendet werden, um die nicht benötigten Nodes oder Maschinen abzuschalten.
Sie können Amdatu Scalerd verwenden – ein weiteres Open-Source-Tool für Skalierung, ähnlich der AWS-API. Es bietet eine CLI zum Hinzufügen oder Entfernen von Nodes im Cluster. Ein interessantes Merkmal ist die Möglichkeit, den Scheduler mittels der folgenden JSON-Datei zu konfigurieren.

Der dargestellte Code reduziert die Kapazität des Clusters während der Nacht um die Hälfte. Dabei wird sowohl die Anzahl der vorhandenen Replikate als auch die gewünschte Kapazität des Amazon-Clusters konfiguriert. Die Verwendung dieses Schedulers verringert automatisch die Anzahl der Nodes nachts und erhöht sie am Morgen, was hilft, die Kosten für die Nutzung solcher Cloud-Dienste wie Amazon zu sparen. Diese Funktion ist nicht in Kubernetes integriert, aber die Nutzung von Scalerd ermöglicht es Ihnen, diese Plattform nach Belieben zu skalieren.
Ich möchte Ihre Aufmerksamkeit darauf lenken, dass viele Leute mir sagen: „Das ist alles gut und schön, aber was ist mit meiner Datenbank, die sich normalerweise im statischen Zustand befindet?“ Wie kann man so etwas in einer dynamischen Umgebung wie Kubernetes umsetzen? Meiner Ansicht nach sollten Sie es nicht versuchen, die Funktionsweise einer Datenbank in Kubernetes zu organisieren. Technisch ist das möglich, und es gibt Anleitungen im Internet dazu, jedoch wird dies Ihr Leben erheblich erschweren.
Ja, in Kubernetes gibt es das Konzept von persistenten Speichern, und Sie können versuchen, solche Datenbanken wie Mongo oder MySQL zu betreiben, aber das ist eine ziemlich aufwendige Aufgabe. Das liegt daran, dass Datenbanken nicht vollständig auf die Interaktion mit einer dynamischen Umgebung ausgelegt sind. Die meisten Datenbanken erfordern eine erhebliche Konfiguration, einschließlich manueller Cluster-Einstellungen, und mögen keine automatische Skalierung und ähnliche Dinge.
Deshalb sollten Sie es sich nicht komplizieren, indem Sie versuchen, eine Datenbank in Kubernetes zu betreiben. Organisieren Sie deren Betrieb auf traditionelle Weise mithilfe bekannter Dienste und geben Sie Kubernetes einfach die Möglichkeit, diese zu nutzen.

Abschließend möchte ich Sie mit der Cloud RTI Plattform auf Basis von Kubernetes vertrautmachen, an der mein Team arbeitet. Sie bietet zentrales Logging, Überwachung von Anwendungen und Clustern und viele andere nützliche Funktionen, die Ihnen von Nutzen sein werden. Dabei kommen verschiedene Open-Source-Tools zum Einsatz, wie Grafana zur Visualisierung der Überwachung.


Es stellte sich die Frage, warum man mit Kubernetes einen Load Balancer wie ha-proxy verwenden sollte. Eine gute Frage, denn derzeit gibt es zwei Ebenen der Lastverteilung. Kubernetes-Dienste befinden sich nach wie vor auf virtuellen IP-Adressen. Sie können diese nicht für die Ports externer Hostmaschinen verwenden, da sich die Adresse ändert, wenn Amazon seinen Cloud-Host überlastet. Deshalb platzieren wir ha-proxy vor den Diensten – um eine statischere Struktur für den unterbrechungsfreien Verkehrsfluss mit Kubernetes zu schaffen.
Eine weitere gute Frage ist, wie man bei einem Blue/Green Deployment auf Änderungen des Datenbankschemas achten kann. Unabhängig davon, ob Kubernetes verwendet wird, ist das Ändern eines Datenbankschemas eine komplexe Aufgabe. Sie müssen sicherstellen, dass das alte und neue Schema kompatibel sind, bevor Sie die Datenbank aktualisieren und anschließend die Anwendungen selbst. Sie können ein "Hot Swapping" der Datenbank durchführen und danach die Anwendungen aktualisieren. Ich kenne Personen, die einen völlig neuen Datenbankcluster mit einem neuen Schema geladen haben. Das ist eine Option, falls Sie eine schemaloose Datenbank wie Mongo haben, aber in jedem Fall ist es keine einfache Aufgabe. Wenn es keine weiteren Fragen gibt, danke für Ihre Aufmerksamkeit!

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 Freunden empfehlen, , ein einzigartiges Äquivalent zu Einsteigerservern, das wir für Sie entwickelt haben: (es sind Optionen mit RAID1 und RAID10 bis zu 24 Kernen und bis zu 40GB DDR4 verfügbar).
Dell R730xd ist im Equinix Tier IV Rechenzentrum in Amsterdam doppelt so günstig? Nur bei uns in den Niederlanden! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — ab $99! Lesen Sie, wie
Quelle: habr.com
