我可以 select 本地主机的哪个端口来创建 docker 容器?

Which port of localhost can I select in order to create a docker container?

我目前正在学习 Kurbernetes 和 Docker,尤其是 KinD。首先,我只想 运行 docker run --rm --name <container's name> -p 8080:80 -d <image name> 从图像创建一个容器。

我知道 TCP/IP 协议(或 Internet 协议)中使用端口来寻址特定程序(软件)。端口 80 是 运行 网络服务器的默认端口。

现在,我的问题是为什么是 8080 或 5000?在这种情况下如何确定哪个端口应该是 OUTSIDE 端口?是随机的还是有 rule/restrictions?

端口 8080 通常用于托管您的个人 webserver/service,它是端口 80 的备用端口 您也可以使用其他端口代替 8080。 当有人试图从外部连接到您的网络服务器时,如果您使用端口 8080,他们不需要指定端口号,因为默认情况下它会查找端口 8080。

如果您使用任何其他端口号,当有人尝试从外部连接到您的 webservice/server 时,他们应该指定您指定的自定义端口号以访问您的 webservice/server

对于 docker run -p 选项(和 Compose ports:),对于第一个端口号,您可以选择主机系统上尚未使用的任何端口。正如您所指出的,端口 80 是标准的 HTTP 端口,在 http://hostname/ URL 中使用的端口没有明确的端口号。各种框架默认使用端口 3000 或 5000 或 8000 或 8080,但其中 none 无论如何都是“标准”或“特殊”。

第二个端口号必须是服务器进程正在侦听的端口号。服务器进程必须监听特殊的 0.0.0.0 “所有地址”地址,如果这是一个可配置的选项;如果它在 127.0.0.1 上侦听(默认情况下有许多 developer-oriented 服务器),则无法从其容器外部访问它。此数字通常包含在 Docker 文件的 EXPOSE 行中,但该指令没有其他作用。 (没有理由包含 docker run --expose 选项或 Compose expose: 块,删除它总是安全的。)

没有特别要求两个端口匹配。如果你想使用主机端口 8888 因为它可用,并且你的应用程序是一个使用默认 Express 端口 3000 的 Node 应用程序,它将工作到

docker run -p 8888:3000 ...

如果您真的不在乎,您可以使用仅包含容器端口号的 docker run -p,但这并不常见。 docker port 会告诉你 Docker 选择了哪个端口。

docker run -p 3000 --name my-container ...
docker port my-container 3000

你在这里也提到了Kubernetes。在 Kubernetes 中,Pods 之间的所有通信都通过 Service,实际上是 in-cluster 负载均衡器。我建议始终让服务对您使用的任何协议使用“正常”端口,端口 80 用于未加密的 HTTP。每个服务都有自己的 in-cluster IP 地址,因此服务之间不存在冲突或 Pods 的风险。如果您使用 NodePort-type 服务使其可以从集群外部访问,您通常只能使用端口 30000 到 32767。

apiVersion: v1
kind: Service
metadata: { name: the-service-name }
spec:
  selector: { ... }
  ports:
    - port: 80           # for HTTP, regardless of how the service is implemented
      targetPort: http   # matching the Pod's `containerPorts:` name
      # nodePort: 30080  # if the Service has type: NodePort, optional

现在通过此服务从另一个 Pod 调用可以使用 http://the-service-name/ 作为具有默认端口的 URL。

正如 David 很好地解释的那样,您可以使用 OS 尚未使用的任何 65535 端口。但是还有两个额外的限制:

用户 space 通常无法访问 1023 以下的端口。由于 docker 守护程序以 root 权限运行,您不必担心,但明智的做法是超越。

那么每个操作系统都有一系列的临时端口。这些是操作系统将用于传出 TCP 连接的端口(是的,它们也需要一个端口)。此范围因操作系统而异。如果您想确保能够在某个端口(您认为可用)上启动容器,请确保 OS 不会基于任何其他进程需要连接而开始使用它。因此最好选择 ephemeral port range.

之外的端口

简而言之,在 Linux 系统上,您要选择一个介于 1024 和 32767 之间的值。