简体   繁体   English

当容器连接到 multiple.networks 时,如何仅将 Docker 容器端口暴露给一个特定的 Docker.network?

[英]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:来自 Docker 文档:

  • --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.我将 docker-compose 与 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.我不想向主机发布任何端口,但是当我使用 expose 时,该端口会暴露给容器连接到的所有.networks。 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 .例如,在这个docker-compose文件中, container1加入了以下三个网络: inte.netemaildatabase

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?现在,如果我有一个特定端口只想公开给database .network,而不是主机,也不要公开给本示例中的emailinte.net .networks,该怎么办? 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 .如果我要使用ports:container1上它会暴露给主机,或者我可以将它绑定到主机的特定 IP 地址。 *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. *我还尝试制作自定义 overlay.network,为容器提供 static IPv4 地址,并尝试在ports: like - '10.8.0.3:80:80'中设置该格式的端口,但这也没有用,因为我认为绑定只能发生在 HOST IP 地址上。 If i use expose: on container1 the port will be exposed to all three.networks: inte.net , email and database .如果我在container1上使用expose:端口将暴露给所有三个网络: inte.netemaildatabase

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.我知道我可以制定自定义防火墙规则,但令我恼火的是我无法在我的 docker-compose 文件中编写如此简单的配置。 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).*另外,也许像80:10.8.0.3:80 (HOST_IP:HOST_PORT:CONTAINER_IP:CONTAINER_PORT) 这样的东西在这里很有意义(没有测试)。*

Am I missing something or is this really not possible in Docker and Docker-compose?我是不是遗漏了什么,或者这在 Docker 和 Docker-compose 中真的不可能吗?

Also posted here: https://github.com/docker/compose/issues/8795也张贴在这里: https://github.com/docker/compose/issues/8795

No, container to container.networking in docker is one-size-fits-many.不,容器到 docker 中的 container.networking 是一刀切。 When two containers are on the same.network, and ICC has not been disabled, container-to-container communication is unrestricted.当两个容器在同一个网络上,并且 ICC 没有被禁用时,容器到容器的通信是不受限制的。 Given Docker's push into the developer workflow, I don't expect much development effort to change this.考虑到 Docker 对开发人员工作流程的推动,我预计不会有太多的开发工作来改变这一点。

This is handled by other projects like Kube.netes by offloading the.networking to a CNI where various vendors support.networking policies.这是由 Kube.netes 等其他项目通过将网络卸载到各种供应商支持网络策略的 CNI 来处理的。 This may be iptables rules, eBPF code, some kind of sidecar proxy, etc to implement it.这可能是 iptables 规则、eBPF 代码、某种 sidecar 代理等来实现它。 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.但它必须在 container.networking 设置时完成,而 docker 没有钩子让你在那里实现任何东西。

Perhaps you could hook into docker events and run various iptables commands for containers after they've been created.也许您可以挂钩docker events并在创建容器后为容器运行各种 iptables 命令。 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.该应用程序还可以配置为监听它信任的 .network 的特定 IP 地址,但这需要注入你信任的 su.net,然后在你的入口点查找你的容器 IP,编写脚本非常重要,我我什至不确定它会起作用。 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.否则,这可以通过重组应用程序来解决,以便通过加固敏感端口来最小化需要在不太安全的网络上的组件,或者将运行时切换到具有网络策略的 Kube.netes 之类的东西。


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.这被 creating.networks 替换为其他容器的 DNS 分辨率。
  • 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.带有-p的已发布端口创建了一个从主机转发到容器的端口,您确实希望限制该端口,但容器仍然可以在没有该已发布端口的情况下通过 shared.network 进行通信。

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.对我来说,答案是删除 -p 命令,因为它将容器绑定到主机并使其在主机外部可用。

If you don't specify -p options.如果不指定 -p 选项。 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.似乎 -P 强制容器到主机并将其绑定到指定的端口。

In your example if you don't use -p when staring "container1".在您的示例中,如果您在盯着“container1”时不使用 -p。 "container1" would be available to the.networks: inte.net, email, database with all its ports but not outside the host. “container1”将可用于.networks:inte.net,email,数据库及其所有端口但不能在主机外部使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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