我已经使用docker几个月了,我只是一个开发人员,而不是DevOps或网络人员。但是,我遇到了一个docker-compose,它将一个外部端口映射到一个内部端口。这个撰写文件中的内容如下:

ports:
  - 8080:80


我的问题是为什么?为什么我们需要将外部端口映射到内部端口。我遇到的一些解释是,如果您不想向用户公开特定的端口,而是在内部使用它。那也引出了一个相同的问题:一个人想要这样做的真实例子是什么?为什么?

#1 楼

TL; DR

端口映射有许多用例,但是对于大规模的DevOps,主要的原因通常是将众所周知的服务端口映射到主机上的可用端口。当您运行默认情况下使用相同端口的大量容器,并且您不想手动分配或跟踪备用端口号时,这很重要。

非常短的端口入门

作为一般规则,端口只能映射到每个主机上的单个服务或进程(多路复用端口和多端口服务是一个例外)。只有65,536个端口可用于服务绑定,而最低的1,024个端口通常保留给root用户绑定。服务通常还绑定到众所周知的端口(例如22、53或5432),以使服务易于查找。所有这些问题都很重要,但这通常是最常涉及Docker主机的最后一个问题。

映射容器端口

想象一下,单个主机上有多个PostgreSQL容器。默认情况下,每个用户都希望绑定到端口5432作为其默认值。尽管您当然可以修改每个容器或运行命令以将容器的服务绑定到唯一的主机端口,但这很快就成为了麻烦。

相反,Docker和其他容器管理器使映射变得容易主机操作系统和容器之间的端口。例如:

# launch three PostgreSQL instances
for i in {1..3}; do
    docker run --rm -d -P postgres:alpine
done

# show port mappings for each container
docker container ls -q --filter="ancestor=postgres:alpine" |
    xargs -n1 docker port
5432/tcp -> 0.0.0.0:32773
5432/tcp -> 0.0.0.0:32772
5432/tcp -> 0.0.0.0:32771


这表明您有PostgreSQL的三个实例,所有这些实例都在它们的容器内愉快地侦听默认端口5432。但是,每个实例都在Docker主机上的不同端口(32771、32772和32773)上进行监听!

通常,您通常会使用DNS,自动发现,链接或容器网络来帮助客户端。应用程序会找到合适的PostgreSQL实例进行连接。在仅运行少数几个实例的情况下,解析docker ps可能足以满足您的需求。您的特定用例可能会有所不同。

#2 楼

实例化一个新容器时,它具有与主机隔离的自己的网络。因此,不能直接从其端口访问容器。


端口:
-8080:80



此命令将指定您正在将主机端口转发到容器端口。
在本地主机中,端口8080将调用容器的端口80。

有一些方法可以实现使用traefik在容器内部执行反向代理的示例,您可以将所有容器寻址到网络,仅公开traefik的端口,因此您可以访问执行您指定的路由器规则的所有容器。

简单的答案是:

因为这是从容器访问服务的最简单方法。