Dockerfile EXPOSE与Kubernetes服务/容器端口的关系?



在Kubernetes中,您为应用程序公开端口的方式是首先使用EXPOSE在Dockerfile中公开它,然后在部署yaml文件中设置containerPort设置,最后在服务yaml文件中设置targetPort。我认为这些都必须是相同的值,例如7214

然而,我刚刚注意到,我有一个不正确的端口暴露在我的应用程序Dockerfile作为7124(但有正确的端口在其他两个文件),像这样:

Dockerfile

expose 7124 #This is incorrect

Deployment.yaml

ports:
- containerPort: 7214

Service.yaml

apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
ports:
- port: 7214
targetPort: 7214

然而,我的其他应用程序都很好地击中了服务,请求被转发到端口7214的应用程序,没有问题。

为什么这个工作?我不需要在Dockerfile中暴露端口吗?containerPort优先还是什么?这个用户回答了一个类似的问题,说暴露的端口不必匹配,但没有解释为什么。

当端口绑定在代码中发生时,进程正在侦听的端口只有该进程的开发人员知道。EXPOSEcontainerPort是与外界沟通的方式。

EXPOSE指令在Dockerfile中不做任何事情,除了作为文档的人阅读你的Dockerfile,以了解容器中的进程可能正在监听哪个端口,并为一些UI目的,当你运行docker ps命令。这就像dockerfile的作者和另一个可能正在使用您的图像或修改您的dockerfile的人之间的通信。

甚至是部署中的containerPort部分。Yaml对任何东西都没有影响。它还可以作为文档,让读取您的清单的人员了解您的进程在pod中的哪些端口可能正在侦听。另一种用法是,您可以使用name字段为端口指定一个名称,然后您可以在其他地方(如服务对象)通过名称引用该端口。

唯一重要的是您的进程在容器中侦听的实际端口,并确保端口在服务端口的targetPort字段中使用。

Dockerfile中的EXPOSE选项仅作为文档,它是不暴露官方文档中规定的端口:

EXPOSE指令实际上并不发布端口。它的作用是在构建映像的人和运行容器的人之间作为一种文档,关于打算发布哪些端口。

在Kubernetes中,相当于EXPOSE的是spec.containers.ports.containerPort。您可以将这两个值设置为您想要的任何值,这根本不会改变任何东西。就当是评论吧

对于Service对象,这有点不同,值确实很重要。Service包含spec.ports.portspec.ports.targetPort。如果你没有指定targetPort,那么Kubernetes会将其值设置为与port中指定的值相同(这是必需的)。

然而,targetPort和' port不一定是相同的,事实上它们确实有不同的用途:

  • port指定Service的端口
  • targetPort指定Pod的端口

一般流程是这样的:

call to <service-name>:port->转发到标签为foo: bar->Pod在targetPort上接收呼叫

下面是一个例子:

apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 12345

导致:

curl my-service:80->转发到标签为app: MyApp->Pod在12345上收到请求。

在您的情况下,您在端口7214上与您的服务通信,它将请求转发到Pod也转发到端口7214,这就是为什么无论您为EXPOSEcontainerPort设置什么,它都将继续工作。

相关内容

  • 没有找到相关文章

最新更新