简体   繁体   中英

How to expose a Docker container port to one specific Docker network only, when a container is connected to multiple networks?

From the Docker documentation:

  • --publish or -p flag. Publish a container's port(s) to the host.
  • --expose. Expose a port or a range of ports.
  • --link. Add link to another container. Is a legacy feature of Docker. It may eventually be removed.

I am using docker-compose with several.networks. I do not want to publish any ports to the host, yet when I use expose, the port is then exposed to all the.networks that container is connected to. It seems that after a lot of testing and reading I cannot figure out how to limit this to a specific.network.

For example in this docker-compose file with where container1 joins the following three.networks: inte.net , email and database .

services:
    container1:
       networks:
           - internet
           - email
           - database

Now what if I have one specific port that I want to expose to ONLY the database .network, so NOT to the host machine and also NOT to the email and inte.net .networks in this example? If I would use ports: on container1 it is exposed to the host or I can bind it to a specific IP address of the host . *I also tried making a custom overlay.network, giving the container a static IPv4 address and trying to set the ports in that format in ports: like - '10.8.0.3:80:80' , but that also did not work because I think the binding can only happen to a HOST IP address. If i use expose: on container1 the port will be exposed to all three.networks: inte.net , email and database .

I am aware I can make custom firewall ruling but it annoys me that I cannot write such simple config in my docker-compose file. Also, maybe something like 80:10.8.0.3:80 (HOST_IP:HOST_PORT:CONTAINER_IP:CONTAINER_PORT) would make perfect sense here (did not test it).*

Am I missing something or is this really not possible in Docker and Docker-compose?

Also posted here: https://github.com/docker/compose/issues/8795

No, container to container.networking in docker is one-size-fits-many. When two containers are on the same.network, and ICC has not been disabled, container-to-container communication is unrestricted. Given Docker's push into the developer workflow, I don't expect much development effort to change this.

This is handled by other projects like Kube.netes by offloading the.networking to a CNI where various vendors support.networking policies. This may be iptables rules, eBPF code, some kind of sidecar proxy, etc to implement it. But it has to be done as the container.networking is setup, and docker doesn't have the hooks for you to implement anything there.

Perhaps you could hook into docker events and run various iptables commands for containers after they've been created. The application could also be configured to listen on the specific IP address for the.network it trusts, but this requires injecting the su.net you trust and then looking up your container IP in your entrypoint, non-trivial to script up, and I'm not even sure it would work. Otherwise, this is solved by either restructuring the application so components that need to be on a less secure.network are minimized, by hardening the sensitive ports, or switching the runtime over to something like Kube.netes with a.network policy.


Things that won't help :

  • Removing exposed ports: this won't help since expose is just documentation. Changing exposed ports doesn't change.networking between containers, or between the container and host.
  • Links: links are a legacy feature that adds entries to the host file when the container is created. This was replaced by creating.networks with DNS resolution of other containers.
  • Removing published ports on the host: This doesn't impact container to container communication. The published port with -p creates a port forward from the host to the container, which you do want to limit, but containers can still communicate over a shared.network without that published port.

The answer to this for me was to remove the -p command as that binds the container to the host and makes it available outside the host.

If you don't specify -p options. The container is available on all the.networks it is connected to. On whichever port or ports the application is listening on.

It seems the -P forces the container on to the host and binds it to the port specified.

In your example if you don't use -p when staring "container1". "container1" would be available to the.networks: inte.net, email, database with all its ports but not outside the host.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM