如何通过Docker命令行及Python库实现多容器实例的DNS解析
Great question! When you're using docker-compose to run multiple instances of a service, Docker's internal DNS lets tools like dig resolve the service name to all container IPs. Here's how you can replicate that using the Docker CLI and Python's Docker SDK:
Using Docker Command Line
Method 1: Filter by docker-compose service label
Docker-compose adds a label com.docker.compose.service=<your-service-name> to all containers belonging to a service. You can use this to filter containers and extract their IPs:
First, get the IDs of all containers for your service (replace
my-servicewith your actual service name):docker ps -q -f "label=com.docker.compose.service=my-service"Pipe those IDs into
docker inspectto pull out the IP addresses. Replace<your-network-name>with the name of your docker-compose network (usually<project-name>_default, where<project-name>is your current directory name):docker inspect -f '{{.NetworkSettings.Networks.<your-network-name>.IPAddress}}' $(docker ps -q -f "label=com.docker.compose.service=my-service")If you don't know the network name, you can list all networks with
docker network lsand look for one tied to your project. Alternatively, use a more generic command to output all IPs across any networks the containers are part of:docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}} {{end}}' $(docker ps -q -f "label=com.docker.compose.service=my-service")
Method 2: Use docker-compose directly
If you're in the same directory as your docker-compose.yml, you can use docker-compose commands to simplify this:
docker-compose ps -q my-service | xargs docker inspect -f '{{.NetworkSettings.Networks.${COMPOSE_PROJECT_NAME}_default.IPAddress}}'
The COMPOSE_PROJECT_NAME environment variable automatically uses your current directory name (you can set it manually if needed).
Using Python's Docker SDK
First, install the official Docker SDK for Python:
pip install docker
Option 1: Filter containers by docker-compose service label
This works just like the CLI method, but programmatically:
import docker # Initialize the Docker client (uses local daemon by default) client = docker.from_env() # Replace with your service name TARGET_SERVICE = "my-service" # Get all containers belonging to the target service service_containers = client.containers.list( filters={"label": f"com.docker.compose.service={TARGET_SERVICE}"} ) # Extract IP addresses (assuming containers use the default docker-compose network) container_ips = [] for container in service_containers: # Iterate through the container's networks to find the project's default network for network_name, network_details in container.attrs["NetworkSettings"]["Networks"].items(): if "_default" in network_name: container_ips.append(network_details["IPAddress"]) break print(f"IP addresses for service '{TARGET_SERVICE}':") for ip in container_ips: print(f"- {ip}")
Option 2: Query a specific Docker network
If you're using a custom named network, you can fetch all containers in that network and filter by service name:
import docker client = docker.from_env() # Replace with your custom network name and service container name prefix TARGET_NETWORK = "my-custom-network" SERVICE_NAME_PREFIX = "my-service" # Get the target network object network = client.networks.get(TARGET_NETWORK) # Filter containers in the network that belong to your service service_containers = [ container for container in network.containers if SERVICE_NAME_PREFIX in container.name ] # Extract IP addresses directly from the network context container_ips = [ container.attrs["NetworkSettings"]["Networks"][TARGET_NETWORK]["IPAddress"] for container in service_containers ] print(f"IP addresses for service in network '{TARGET_NETWORK}':") for ip in container_ips: print(f"- {ip}")
Both approaches give you the same list of IPs that dig returns internally, since we're directly querying Docker's container metadata.
内容的提问来源于stack exchange,提问作者JamesP

