从 docker 容器到 kubernetes pod 的端口发布如何工作?
Posted
技术标签:
【中文标题】从 docker 容器到 kubernetes pod 的端口发布如何工作?【英文标题】:How does port publishing from a docker container to a kubernetes pod work? 【发布时间】:2020-02-08 03:22:34 【问题描述】:在学习Get Started, Part 3: Deploying to Kubernetes 教程时,我偶然发现了清单文件的部署定义中的 Pod 模板。 pod 和容器部分都没有指定端口。
这让我想到了最初的问题:从 docker 容器到 pod 的端口发布如何工作?
下面的引用听起来像是 kubernetes 一旦启动就可以洞察正在运行的容器,并从侦听 0.0.0.0:PORT 的服务中获取端口,并将其映射到 pod 环境中的相同端口(网络命名空间)。
在此处不指定端口不会阻止该端口被暴露。任何侦听容器内默认“0.0.0.0”地址的端口都可以从网络访问。 Source
如果我的假设是正确的,这对于具有多个容器的 pod 意味着什么? kubernetes 是否只允许具有内部服务的容器在不同的端口上侦听?或者是否可以将容器内部端口映射到 pod 环境(网络命名空间)中的不同端口?
根据以下引用,我假设从容器到 pod 的端口映射是不可能的。 实际上,在具有相同端口的两个容器中指定两个服务并没有太大意义,只需通过紧随其后的映射来更改它们。
在此处公开端口可为系统提供有关容器使用的网络连接的附加信息,但主要是信息性的。 Source
2019 年 10 月 15 日更新
正如以下引用所述,默认情况下,docker 容器不会向外界发布任何端口。
默认情况下,当您创建一个容器时,它不会向外界发布任何端口。要使端口可用于 Docker 外部的服务或未连接到容器网络的 Docker 容器,请使用 --publish 或 -p 标志。 Source
这意味着 kubernetes 必须以某种方式配置在 pod 中运行的 docker 容器,以便将容器的端口发布到 pod。
关于下面的引用,kubernetes 是否可以使用 --network host 配置运行 docker 容器?假设 pod 是 Kubernetes 中的 docker 主机。
如果您对容器使用主机网络模式,则该容器的网络堆栈不会与 Docker 主机隔离 [...] 例如,如果您运行绑定到端口 80 的容器并使用主机网络,则容器的应用程序在主机 IP 地址的端口 80 上可用。 Source
【问题讨论】:
【参考方案1】:在 pod 中运行的容器类似于在连接到网络的节点上运行的进程。 Pod 获得一个网络地址,所有容器共享同一个网络地址。他们可以使用localhost
相互交谈。
在 pod 中运行的容器可以监听该地址上的任何端口。如果一个 pod 中运行多个容器,它们不能绑定到同一个端口,只能绑定一个。请注意,不需要发布这些端口。容器可以监听任何端口,如果客户端连接到 Pod 的该端口,则流量将传递给它。
因此,从容器到 pod 的端口映射是不可能的。
容器/pod 暴露的端口主要是信息性的,工具使用它们来创建资源。
【讨论】:
感谢您的回复。您加强了我对 Pod 中发生的事情以及 Pod-Conteiner-Interaction 工作原理的理解。但是从纯粹的 Docker 容器的角度来看,需要发布端口来解决容器中运行的服务,仍然不清楚 kubernetes 如何使容器内部服务(相对于其端口)可以从 Pod 内部(相对于 Pod 的外部)访问)。 @Chris,如果我在这里错了,请纠正我,但据我所知,您根本不需要公开端口。一个 pod 可以有多个容器,它们都共享同一个命名空间,因此当外部进程连接到 pod 上的端口时,该流量被传递到侦听该端口的相关容器。一个 pod 有自己的 IP,每个容器都绑定到该 IP 上一组不同的端口。即使未公开,您仍然可以使用 pod ip:pod 连接到该 pod 上的任何端口。这与 k8s 无关,它是容器和命名空间的工作方式。 据我所知,您必须明确发布 docker 容器的端口(例如 docker run -p 80:80 ... )。否则您将无法访问内部服务。我的问题是,在启动 pod 时,kubernetes 的后台发生了什么。 @Chris -p 将容器端口映射到主机端口。如果没有 -p 标志,您仍然可以使用 containerip:port 连接到容器端口。 -p 将允许您使用 localhost:port 进行访问。 我使用Get Started, Part 2: Containerizing an Application 的图像/容器对此进行了测试。我首先尝试了按给定的方式发布端口的容器。然后我删除了 --publish 8000:8080 部分并尝试使用 CONTAINER_IP:PORT 访问内部服务。那没有用。以上是关于从 docker 容器到 kubernetes pod 的端口发布如何工作?的主要内容,如果未能解决你的问题,请参考以下文章
Kubernetes:如何从 Docker 容器 A 在 Docker 容器 B 上运行 Bash 命令
下一代分布式架构的王者Kubernetes权威指南:从Docker到Kubernetes实践全接触(第4版)PDF文档下载