为什么需要为Docker容器进行端口映射

97次阅读
没有评论

问题描述

在使用Docker时,遇到了一个问题:为什么需要将外部端口映射到内部端口?他想知道为什么需要将外部端口映射到内部端口,以及在实际应用中有哪些例子。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

端口映射的用途

端口映射有很多用途,但对于规模化的DevOps来说,主要原因通常是为了将众所周知的服务端口映射到主机上的可用端口。当您运行大量默认使用相同端口的容器时,您不希望手动分配或跟踪备用端口号。

简单的端口介绍

一般来说,每个主机上的端口只能映射到一个服务或进程(多路复用端口和多端口服务是一种例外)。可用于服务绑定的端口只有65,536个,其中最低的1,024个通常保留给root用户进行绑定。服务通常还绑定到众所周知的端口,如22、53或5432,以便易于找到服务。所有这些问题都很重要,但通常最关心Docker主机的是最后一个问题。

映射容器端口

假设您在单个主机上有多个PostgreSQL容器。默认情况下,每个容器都希望将其服务绑定到端口5432。虽然您可以修改每个容器或运行命令,将容器的服务绑定到唯一的主机端口,但在规模化时,这很快变得麻烦。

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

# 启动三个PostgreSQL实例
for i in {1..3}; do
    docker run --rm -d -P postgres:alpine
done

# 显示每个容器的端口映射
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可能已经足够满足您的需求。具体的使用情况可能会有所不同。

其他方法

还有其他一些方法可以实现类似的效果,例如使用反向代理或容器网络。这些方法可以根据您的具体需求和环境选择使用。

总之,端口映射是从容器访问服务的最简单方式之一。

正文完