Im ersten Artikel dieser Blogserie hat mein Kollege Lukas Pustina bereits eine Einführung in RED (Runtime Environment for Developers), unserer Docker basierten Entwicklungsumgebung, gegeben. In diesem Artikel werde ich auf die ersten technischen Details von RED eingehen. Das Projekt ist auf GitHub verfügbar und wird mit jedem nachfolgenden Artikel dieser Serie erweitert.
Im Einführungsartikel wurde bereits erwähnt, dass die Grundlagen VirtualBox , Vagrant und Docker sind. Ziel dieses Artikels ist die Basiskonfiguration dieser 3 Komponenten, um die Folgenden Grundanforderungen erfüllen zu können:
- Docker soll automatisiert installiert werden können
- Docker Container sollen vom Host (PC / Laptop) aus erreichbar sein
- Docker Container sollen statische IP Adressen zugewiesen bekommen können
- Die statischen IP Adressen sollen nicht mit den automatischen von Docker zugewiesenen IP Adressen kollidieren
Vagrant
Mit Hilfe von Vagrant können wir in einer Datei – der Vagrantfile – beschreiben wie unsere virtuelle Maschine konfiguriert werden soll. Wir gehen hier nun auf die wichtigsten Bestandteile unserer Vagrantfile ein:
1config.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box"
Wir nutzen Ubuntu 14.04 als Betriebssystem für unsere virtuelle Maschine, welches unter der angegebenen URL automatisch heruntergeladen und installiert wird.
1config.vm.network "private_network", ip: "10.34.1.10", netmask: "255.255.0.0"
Die virtuelle Maschine bekommt die IP Adresse 10.34.1.10/16 zugewiesen. Diese IP Adresse ist wichtiger Bestandteil für die spätere Docker Konfiguration, da diese im selben Netz liegen muss!
1config.vm.provider :virtualbox
VirtualBox wird als VM-Provider genutzt
1vbox.customize ["modifyvm", :id, "--cpus", "2", "--memory", "2048"]
Hier wird die Anzahl der CPUs und die Größe des Hauptspeichers für die virtuelle Maschine gesetzt.
11.upto(8) do |nic| 2vbox.customize ["modifyvm", :id, "--nicpromisc#{nic}", "allow-all"] 3end
Mit diesem Befehl werden alle NICs auf promiscous mode „allow-all“ gesetzt. Standardmäßig nehmen die NICs nur Datenpakete für die virtuelle Maschine an, weil sie keine weiteren IP Adressen innerhalb der virtuellen Maschine kennen. Da die Docker Container eine andere MAC Adresse als die virtuelle Maschine haben, würden die NICs diese Datenpakete verwerfen. Somit wäre es nicht möglich Datenpakete zwischen Host (Laptop / PC) und den Docker Containern zu routen. Mit dem Parameter promiscous mode „allow-all“ werden jedoch sämtliche Frames anderer MAC Adressen akzeptiert, wodurch der Host später mit den Docker Containern kommunizieren kann.
1config.vm.provision "docker", version: "1.4.0"
Vagrant bietet bereits einen eigenen Docker Provisioner an, der die Installation von Docker übernimmt. Es muss nur die Docker Version, in unserem Fall 1.4.0, angegeben werden.
1config.vm.provision :shell, :path => "provisioning/run.sh"
Hier konfigurieren wir den Docker Daemon auf unsere Bedürfnisse. Wir werden im nächsten Abschnitt detailliert darauf eingehen.
1config.vm.provision :unix_reboot
Nachdem die virtuelle Maschine vollständig konfiguriert wurde, muss diese nun nur noch neu gestartet werden. Hierfür benutzen wir das Folgende Vagrant Plugin .
Docker
Im provisioning Verzeichnis liegt das run.sh Skript, das von Vagrant beim Provisionieren der virtuellen Maschine ausgeführt wird. Das Skript ist dafür verantwortlich 2 Dateien an ihren richtigen Platz zu kopieren und Pipework in das /usr/local/sbin Verzeichnis herunterzuladen.
Docker Daemon mit zusätzlichen Optionen starten
Docker erlaubt es unter “/etc/default” eine Datei mit dem Namen „docker“ abzulegen, die zusätzliche Docker Parameter beinhaltet, welche beim Start von Docker berücksichtigt wird. In unserem Fall sieht die docker Datei wie folgt aus:
1-bip=10.34.1.10/16
Mit diesem Parameter setzen wir die IP Adresse für die Docker Bridge auf 10.34.1.10/16. Die Docker Bridge liegt somit im selben Netz wie die virtuelle Maschine. Dies ist eine Grundvoraussetzung um später vom Host (PC / Laptop) aus mit den Docker Containern kommunizieren zu können.
1--fixed-cidr=10.34.128.0/17"
Hiermit beschränken wir den IP Bereich des Docker Netzwerks und umgehen somit IP Kollisionen wenn Docker Container statische IP Adressen mit Hilfe von Pipework zugewiesen bekommen. Aus der Sicht von Docker bedeutet dies, dass IP Adressen im Bereich von 10.34.128.1 bis 10.34.255.255 vergeben werden können.
VirtualBox und Docker miteinander vereinen
Die rc.local Datei wird bei jedem Systemstart ausgeführt und stellt sicher, dass zum Einen die virtuelle Maschine in das Docker Netzwerk integriert und zum Anderen Pipework installiert wird.
1/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE 2/sbin/iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT 3/sbin/iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
Mit diesen 3 Zeilen aktivieren wir NAT, damit die Docker Container mit der Außenwelt kommunizieren können, denn die IP Adressen der Container gelten nicht im Host Netz (PC / Laptop), da sie dort nicht gehostet werden.
1ip addr del 10.34.1.10/16 dev eth1 2ip link set eth1 master docker0
Hier löschen wir die IP Adresse an eth1 und stecken das Interface in die Dockerbridge wodurch der Host (PC / Laptop), die VM und die Docker Container miteinander verbunden werden.
Fazit
Mit der hier vorgestellten Basiskonfiguration haben wir nun Folgende Ziele erreicht:
1. Docker wird automatisiert installiert
Dies wurde mit Hilfe des Docker Provisioner erzielt.
2. Docker Container sind vom Host (PC / Laptop) aus erreichbar
Dies können wir mit einem einfachen Test beweisen. Hierfür müssen wir uns in die virtuelle Maschine einloggen und einen Docker Container starten:
1docker run -it stackbrew/ubuntu /bin/bash
Wenn der Docker Container gestartet wurde kann mit Hilfe von ifconfig die IP Adresse von eth0 herausgefunden werden. Diese IP Adresse solltet ihr nun von eurem Host (PC / Laptop) aus mit einem einfachen Ping Befehl erreichen können. Falls dies der erste Docker Container war den ihr gestartet habt, sollte die IP Adresse: 10.34.128.1 lauten.
3. Docker Container können statische IP Adressen zugewiesen bekommen
Die Grundlage hierfür haben wir mit der Installation von Pipework geschaffen. Um nun beispielsweise unserem vorher gestarteten Docker Container eine von uns definierte IP Adresse zuzuweisen muss Folgender Befehl ausgeführt werden:
1sudo pipework docker0 <container-id> 10.34.10.11/16
Mit diesem Befehl würde unser Docker Container nun auch unter der IP Adresse 10.34.10.11 erreichbar sein.
4. Die statischen IP Adressen sollen nicht mit den automatischen von Docker zugewiesenen IP Adressen kollidieren
Da wir das Docker Netzwerk auf 10.34.128.0/17 beschränkt haben, können wir IP Adressen von 10.34.0.1 bis 10.34.127.255 an die Docker Container vergeben, ohne dass wir Konflikte mit den von Docker automatisch vergebenen IP Adressen bekommen.
Ausblick
Wir haben nun die Grundkonfiguration für RED fertig gestellt. Der nächste Artikel wird sich dann mit den Automatismen für das Bauen, Starten und Stoppen von unseren eigenen Docker Images/Containern beschäftigen. Also bleibt dran und meldet Euch bei uns, falls Ihr Fragen oder Anregungen habt.
Weitere Beiträge
von Alexander Berresch
Dein Job bei codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Weitere Artikel in diesem Themenbereich
Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog-Autor*in
Alexander Berresch
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.