Auf einem Docker-Host, möchte man unter Umständen vom Host aus auf die interne IP eines Docker Containers zugreifen. Wenn man z.B. per Cron einen Webhook im Container aufrufen will, so ändert sich die IP des Containers unter Umständen mit jedem Start des Containers.
Meine erste Lösung war es mit dem Skript von Idalko die hosts-Datei regelmäßig zu aktualisieren:
#!/bin/sh
# https://www.idalko.com/update-host-file-ip-addresses-containers-running-host/
#
# Retrieve the argument and create a name for a tmp file
#
processfile=$1
tmpfile=${1}.tmp
#
# for all running docker containers
#
for service in `docker ps -q`; do
#
# Extract the servicename and ipaddress
#
servicename=`docker inspect --format '{{ .Name }}' $service `
ipaddress=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' $service`
#
# if there is a service name and ipaddress
#
if [ ! -z $ipaddress ] && [ ! -z $servicename ] ;
then
# get rid of the first character - this is '/'
servicename=${servicename:1}
# remove the service name from the process file, and add it again
grep -v $servicename $processfile > $tmpfile
echo -e $ipaddress '\t' $servicename >> $tmpfile
mv $tmpfile $processfile
fi
done
Das funktioniert grundsätzlich und für manuelle Aufrufe auf die Adresse des Containers ist es auch ein guter Weg.
Wenn man jedoch in Python auf die Container zugreifen möchte, dann sollte man sich nicht auf ein asyncron laufendes Skript verlassen sondern am besten direkt in Python die IP ermitteln können.
Mit der Docker Library kann man in Python auf die Docker API zugreifen. Über dieses Skript bekommt man alle IP’s aller laufenden Container:
#!/bin/env python
import docker
for container in docker.from_env().containers.list():
try:
for netz in container.attrs['NetworkSettings']['Networks']:
container_ip = container.attrs['NetworkSettings']['Networks'][netz]['IPAddress']
print("%20s : %10s : %s" % (container.name, netz,container_ip))
except:
pass
Wenn man nun z.B. nur die IP eines bestimmten Containers (CONTAINERNAME) in einem bestimmten Netz (NETZNAME) braucht, dann kann man die APIClient-Funktion der Library nutzen und erhält einen praktischen Einzeiler:
IP = docker.APIClient().inspect_container(CONTAINERNAME)['NetworkSettings']['Networks'][NETZNAME]['IPAddress']