Forum: PC-Programmierung Verschiedene Docker Container mit IP aus lokalem Netz erreich


von Draco (Gast)


Lesenswert?

Ich möchte mehrere Webserver auf Docker Containern aufsetzen. Diese 
möchte in meinem lokalen Netz unter ihrer jeweils eigenen IP erreichen, 
ist dies möglich? Wenn ja wie? Wenn ich im System mehrere NICs zur 
Verfügung habe, kann ich den einzelnen Containern eine eigene Nic 
zuweisen?


System: Ubuntu Server 22.04 LTS
Netzwerk: 192.168.177.0/24
Docker Host: 192.168.177.5
Ip für Webserver: 192.168.177.50-60

Vielen Dank für eure Tipps 😊

von Εrnst B. (ernst)


Lesenswert?

in dem du jedem Dockercontainer nur die Zugriffe von "seiner" IP 
weiterleitest.

also einen Container mit "-p 192.168.177.50:80:80",
den nächsten Container mit "-p 192.168.177.51:80:80"

usw.
Eigene NICs usw. brauchst du nicht. Der Host muss nur alle IP-Adressen 
als Alias bekommen.

von Rolf M. (rmagnus)


Lesenswert?

Draco schrieb:
> Ich möchte mehrere Webserver auf Docker Containern aufsetzen. Diese
> möchte in meinem lokalen Netz unter ihrer jeweils eigenen IP erreichen,
> ist dies möglich? Wenn ja wie? Wenn ich im System mehrere NICs zur
> Verfügung habe, kann ich den einzelnen Containern eine eigene Nic
> zuweisen?

Die Idee von Containerisierung ist eigentlich, dass die Container nicht 
direkt nach draußen kommen. Stattdessen haben Container eigene virtuelle 
Netzwerk-Devices. Man kann aber ein Port-Forwarding einrichten.
Siehe https://docs.docker.com/config/containers/container-networking/
Wenn du mehrere Container auf einmal verwalten willst, ist Docker 
Compose zu empfehlen. Da hast du dann ein Config-File, wo die 
Konfigruation aller Container zusammengefasst ist, inklusive 
Netzwerk-Konfiguration. Die kann man dann alle auf einmal starten. Siehe 
https://docs.docker.com/compose/

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Rolf M. schrieb:

> Die Idee von Containerisierung ist eigentlich, dass die Container nicht
> direkt nach draußen kommen.

Nein. Das kann Designziel sein, muss es aber nicht sein.

> Stattdessen haben Container eigene virtuelle
> Netzwerk-Devices.

Das in jedem Fall. Aber diese Netzwerkinterfaces können vollkomen 
verschieden konfiguriert sein.

> Man kann aber ein Port-Forwarding einrichten.

Es gibt sowohl Konfigurationen, wo das nicht nötig ist als auch 
Konfigurationen, wo das nicht zielführend ist. Hängt eben von der 
Konfiguration des Containers und seiner Umgebung an.

von 🐧 DPA 🐧 (Gast)


Lesenswert?

Ich hab bei mir libvirt LXC Container. Dort habe ich diverse Bridges für 
unterschiedliche Netze, mit den Containern drin, und eine pfSense VM als 
Firewall & Router, mit denen ich die verbinde. Sowas könnte man auch mit 
Docker machen.
Man kann auch z.B. das Lan Interface in die docker Netzwerk Bridge mit 
rein nehmen, dann ist das alles im selben Netz. Aber Docker macht glaub 
ich auch irgend was mit DHCP, das dürfte sich mit bestehenden DHCP 
Servern in die Quere kommen, wenn man das so macht. Naja, wenn man die 
Ranges so einstellt, dass die nicht überlappen, vielleicht geht es ja.

Ich würde in diesem fall aber eher den Docker Containern / ihrer Bridge, 
ein komplett eigenes Netz spendieren, so wie das normal auch ist, und 
einfach ip forwarding einschalten. Dann im Router (und eventuell auch 
noch DHCP), die statische Route zum Netz und PC mit den Containern 
angeben. Der PC mit Docker Drauf ist dann das Gataway zu dem Docker 
Subnet.

Ich glaube es gibt auch noch Wege, die Container per Name per DNS 
erreichbar zu machen. Hatte ich vor langer zeit mal. Weiss aber nicht, 
wie man das heute umsetzen würde, das war schon lange her.

von Rolf M. (rmagnus)


Lesenswert?

c-hater schrieb:
> Rolf M. schrieb:
>
>> Die Idee von Containerisierung ist eigentlich, dass die Container nicht
>> direkt nach draußen kommen.
>
> Nein. Das kann Designziel sein, muss es aber nicht sein.

Bei Docker ist es das, auch wenn man das natürlich durch entsprechende 
Konfiguration umgehen kann.

>> Stattdessen haben Container eigene virtuelle
>> Netzwerk-Devices.
>
> Das in jedem Fall. Aber diese Netzwerkinterfaces können vollkomen
> verschieden konfiguriert sein.

Natürlich.

>> Man kann aber ein Port-Forwarding einrichten.
>
> Es gibt sowohl Konfigurationen, wo das nicht nötig ist als auch
> Konfigurationen, wo das nicht zielführend ist. Hängt eben von der
> Konfiguration des Containers und seiner Umgebung an.

Bei dem hier genannten Anwendungsfall klingt es für mich nach der 
geeignetsten und auch einfachsten Variante.

von Draco (Gast)


Lesenswert?

Ich habe das eigentlich nun ohne jegliche Probleme hinbekommen. Ich kann 
die Webserver auf verschiedene IPs des Servers mappen und kann 
problemlos von außerhalb darauf zugreifen. Das funktioniert tadellos.

Was mir nur ein wenig Kopfzerbrechen aktuell bereitet ist der ssh server 
unter im docker image.

Beim erstellen des Images funktioniert er leider nicht "out-of-the-box" 
sondern ich muss erst mit docker exec in den jeweiligen container und 
dort mit "service ssh restart" neu starten, damit ich von außerhalb 
darauf zugreifen kann.

Mein Dockerfile
1
FROM ubuntu:22.04
2
3
RUN apt-get update && apt-get install -y apache2 openssh-server sudo nano && apt-get clean && rm -rf /var/lib/apt/lists/*
4
5
RUN useradd -rm -d /home/ubuntu -s /bin/bash -g root -G sudo -u 1000 test
6
RUN echo 'test:test' | chpasswd
7
8
RUN echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
9
10
ENV APACHE_RUN_USER  www-data
11
ENV APACHE_RUN_GROUP www-data
12
ENV APACHE_LOG_DIR   /var/log/apache2
13
ENV APACHE_PID_FILE  /var/run/apache2/apache2.pid
14
ENV APACHE_RUN_DIR   /var/run/apache2
15
ENV APACHE_LOCK_DIR  /var/lock/apache2
16
ENV APACHE_LOG_DIR   /var/log/apache2
17
18
RUN mkdir -p $APACHE_RUN_DIR
19
RUN mkdir -p $APACHE_LOCK_DIR
20
RUN mkdir -p $APACHE_LOG_DIR
21
22
COPY index.html /var/www/html
23
24
EXPOSE 80
25
EXPOSE 22
26
27
RUN sudo service ssh restart
28
29
CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]

meine docker-compose.yml
1
version: "3"
2
services:
3
  webserver:
4
    build: .
5
    ports:
6
      - "192.168.177.103:80:80"
7
      - "192.168.177.103:25:22"
8
    volumes:
9
      - ./http:/var/www/html

Beim verbinden mit ssh direkt nach dem erstellen bekomme ich ein 
connection refused - wenn ich aber mit docker exec in den container 
wechsele, dort dann den ssh server restarte (er läuft zu diesem 
Zeitpunkt übrigens bereits) - wieder aus dem Container wechsel - dann 
funktioniert dies tadellos.

Aber er macht ja in der Dockerfile bereits einen restart. Warum wird 
dort die Änderung nicht bereits übernommen?

Hat da jemand einen Tipp?

von Εrnst B. (ernst)


Lesenswert?

Draco schrieb:
> Hat da jemand einen Tipp?

das "RUN" im Dockerfile läuft nur beim BAUEN des Images, nicht später, 
wenn du einen Container mit diesem Image startest.

Du musst das "CMD" erweitern (z.B. shell-script), damit das deinen sshd 
startet, und danach den apache.

Ansonsten würde ich empfehlen, das "/var/log/apache2" als "VOLUME" im 
Dockerfile zu deklarieren.

: Bearbeitet durch User
von Draco (Gast)


Lesenswert?

Oh super, danke für diesen Tipp!

Das hat tadellos funktioniert.

Startupscript erstellt:
1
#!/usr/bin/env bash
2
set -e
3
4
## Run startup command
5
service ssh restart
6
/usr/sbin/apache2 -D FOREGROUND

diese im gleiche Ordner wie das Dockerfile gespeichert, mit chmod +x 
ausführbar gemacht und dann über das Dockerfile mit in bin kopiert. 
dieses dann via CMD ausgeführt.
1
....
2
3
COPY index.html /var/www/html
4
COPY startup.sh bin/startup.sh
5
6
EXPOSE 80
7
EXPOSE 22
8
9
CMD ["startup.sh"]

Ich danke vielmals für den Gedankenanstoß!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.