Kubernetes Service定义中targetPort和port的区别
Posted
技术标签:
【中文标题】Kubernetes Service定义中targetPort和port的区别【英文标题】:Difference between targetPort and port in Kubernetes Service definition 【发布时间】:2018-10-03 12:42:53 【问题描述】:Kubernetes Service
可以在服务定义中包含targetPort
和port
:
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
port
和targetPort
有什么区别?
【问题讨论】:
这个问题可以参考***.com/questions/41963433/… 【参考方案1】:targetport:容器在 pod 中侦听的一个或多个端口。
nodeport:主要用于接受消费者请求。 (例如:消费者向容器中运行的网络服务器发出的 HTTP 请求)
nodeport 在所有接口上的所有节点上被监听,即 0.0.0.0:nodeport。发送到 nodeport 的消费者服务请求被路由到容器的目标端口,以便容器可以满足请求。
端口:kubernetes pod 网络中使用的端口,主要用于在 pod 之间交换请求。同样,来自另一个 pod 的请求被路由到相应 pod 的容器目标端口。
摘要:所有请求最终都在目标端口。如果来自外部 k8s 网络的请求,则使用 nodeport,如果来自内部,则使用 port。
【讨论】:
【参考方案2】:这个答案是给绝对初学者的:
案例 1:
假设没有 nodPort 或端口,现在你想运行你的应用程序并将它暴露给外部,你需要什么:
-
一个 Ingress 控制器,它将使用 servicePort 根据路由重定向到我们所需的服务。
一个集群 IP 服务,它为您的应用程序端口(也称为 targetPort)定义了目标
用于标识计算机上运行的应用程序或服务的网络端口(即应用程序端口)。
所以,为了从外部访问,我们发现需要三个端口。
-
servicePort(入口控制器)
targetPort(集群 IP 服务)
networkPort(应用程序端口)
正常工作: servicePort === targetPort === networkPort
案例 2: 现在假设一个服务与我们集群中的另一个服务进行通信,或者假设一个服务接收到来自外部的请求并发出一个事件,该事件触发了我们集群内的另一个服务。
假设服务X通过nodePort服务暴露在外面,在收到请求后,X服务想与Y服务通信。
Y 服务需要以下端口
-
一个 ClusterIP 端口,X 服务将通过该端口转发请求
一个 ClusterIP 目标端口,Y 服务将通过该端口确定应用程序在哪个端口中运行。
应用程序端口
端口 === 任何
targetPort === 应用程序端口
在服务 X 内部:
app.post('/posts/create', async (req, res) =>
const id = randomBytes(4).toString('hex');
const title = req.body;
posts[id] =
id,
title
;
await axios.post('http://event-bus-srv:4010/events',
type: 'PostCreated',
data:
id,
title
);
res.status(201).send(posts[id]);
);
服务内部配置和内部
apiVersion: v1
kind: Service
metadata:
name: event-bus-srv
spec:
selector:
app: event-bus
type: ClusterIP
ports:
- name: event-bus
protocol: TCP
port: 4010
targetPort: 4009
app.listen(4009, () =>
console.log('Listening on 4009');
);
【讨论】:
【参考方案3】:除了其他答案之外,此答案是参考 Kubernetes 的文档:
https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/:
targetPort
: 是容器接受流量的端口,
port
:是抽象出来的Service端口,可以是其他Pod访问Service的任意端口
https://kubernetes.io/docs/concepts/services-networking/service/:
Pod 中的端口定义具有名称,您可以在 Service 的
targetPort
属性中引用这些名称。即使 Service 中的 Pod 混合使用一个配置名称,也可以通过不同的端口号使用相同的网络协议。
【讨论】:
感谢您的简洁回答【参考方案4】:这有助于我从服务的角度思考问题。
nodePort
:节点上外部流量将进入的端口
port
: 此服务的端口
targetPort
pod(s) 上用于转发流量的目标端口
流量从nodePort
进入,转发到服务上的port
,然后路由到吊舱上的targetPort
。
值得更多强调的是nodePort
是针对外部流量的。集群中可能需要访问该服务的其他 pod 将只使用 port
,而不是 nodePort
,因为它只能在内部访问该服务。
另外值得注意的是,如果没有设置targetPort
,它将默认为与port
相同的值。例如。 80:80
服务端口80
目标容器端口80
。
【讨论】:
【参考方案5】:如果容器监听 9376 端口,那么 目标端口:9376
如果服务在端口 80 上侦听,则 端口:80
然后服务端口配置如下所示
ports:
- protocol: TCP
port: 80
targetPort: 9376
最后,请求接收到服务的port,并在pod的targetPort上转发。
【讨论】:
超级简洁,但这实际上帮助我理解了两者之间的区别【参考方案6】:简而言之
nodeport:
在 nodeip:port 上的所有工作节点上监听外部请求并将请求转发到端口。
port:
容器内部集群服务端口,监听来自nodeport的请求并转发到targetPort。
targetPort:
从端口接收请求并转发到它正在侦听的容器 pod(port)。即使您没有指定,默认情况下也会分配与端口相同的端口号。
【讨论】:
这只是这里最好的解释.. 这应该是公认的答案。更多的投票实际上是令人困惑的。【参考方案7】:“目标端口”是运行容器的端口。
端口:端口将流量从服务重定向到容器。
公开部署
master $ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 31s
master $ kubectl expose deployment nginx --name=nginx-svc --port=8080 --target-port=80
service/nginx-svc exposed
master $ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc ClusterIP 10.107.209.151 <none> 8080/TCP 5s
NodePort : 是服务对外访问的端口。
希望这个答案。
【讨论】:
【参考方案8】:@Manikanta P 上面给出的答案是正确的。但是,初读时对“端口”的解释可能有点不清楚。我将举例说明:
考虑一个 Web 应用程序,其静态内容(首页、图像等)由 httpd 托管,动态内容(例如,对请求的响应等)由 tomcat 托管。 Webserver(或静态内容)由 httpd 在端口 80
提供服务,而 Appserver(或动态内容)由 tomcat 在端口 8080
提供服务。
开发人员想要什么:用户应该能够从外部访问 Web 服务器,但不能从外部访问 Appserver。
解决方案:webserver在service.yml中的service-type为NodePort,而Appserver在service.yml中的service-type为ClusterIP。
webserver 的 service.yml 代码:
spec:
selector:
app: Webserver
type: NodePort // written to make this service accessible from outside.
ports:
- nodePort: 30475 // To access from outside, type <host_IP>:30475 in browser.
port: 5050 // (ignore for now, I will explain below).
protocol: TCP
targetPort: 80 // port where httpd runs inside the webserver pod.
Appserver 的 service.yml 代码
spec:
selector:
app: appserver
type: ClusterIP // written to make this service NOT accessible from outside.
ports:
- port: 5050 // port to access this container internally
protocol: TCP
targetPort: 8080 // port where tomcat runs inside the appserver pod.
另外请注意,在Webserver 的httpd.conf
文件中,我们将写入将用户请求重定向到appserver 的IP。此 IP 将是:host_IP:5050
。
这里到底发生了什么?
用户写hostIP:30475
并看到网络服务器的页面。这是因为它由 httpd 在端口 80
(targetport) 提供服务。当用户单击按钮时,会发出请求。此请求被重定向到 Appserver,因为在 httpd.conf
文件中,提到了端口 5050
,这是 Appserver 的容器和 Webserver 的容器内部通信的端口。当应用服务器收到请求时,它能够为请求提供服务,因为它在端口8080
上运行了tomcat。
【讨论】:
为什么网络服务器规范定义“端口:5050”?如果我理解正确,网络服务器调用 appserver:5050,而不是相反......? 除了埃弗顿的问题,如果Tomcat服务于5050端口的内部请求,它需要开放8080端口有什么意义? 这个答案令人困惑。另外“因为在httpd.conf文件中提到了5050端口”中httpd.conf
在哪里
@Polymerase httpd.conf 文件随您在系统上安装的 httpd 软件包一起提供。这是您必须配置的内部文件。路径:/etc/httpd/conf/http.conf
@Stephen 在 tomcat/conf/server.xml 中,我们指定了 tomcat 服务将运行的端口。这与我们写为目标端口的端口号相同,以便 kubernetes 了解它必须在该端口上启动 tomcat 服务。如果我错了,请纠正我。【参考方案9】:
服务:这会将流量导向一个 pod。
TargetPort: 这是您的应用程序在容器内运行的实际端口。
端口: 有时,容器内的应用程序在不同的端口上提供不同的服务。
示例: 实际应用程序可以运行8080
,并且此应用程序的健康检查可以在容器的8089
端口上运行。
因此,如果您在没有端口的情况下访问服务,它不知道应该将请求重定向到容器的哪个端口。服务需要有一个映射,以便它可以访问容器的特定端口。
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
nodePort: 30475
port: 8089
protocol: TCP
targetPort: 8080
- name: metrics
nodePort: 31261
port: 5555
protocol: TCP
targetPort: 5555
- name: health
nodePort: 30013
port: 8443
protocol: TCP
targetPort: 8085
如果您点击my-service:8089
,流量将被路由到容器(targetPort)的8080
。同样,如果您点击my-service:8443
,那么它会被重定向到容器(targetPort)的8085
。但是这个myservice:8089
是kubernetes 集群内部的,可以在一个应用程序想要与另一个应用程序通信时使用。因此,要从集群外部访问服务,需要在运行 kubernetes 的主机上公开端口
以便将流量重定向到容器的端口。这是node port
(主机上暴露的端口)。
从上面的例子中,您可以通过host_ip:nodePort
从集群外部(邮递员或任何休息客户端)访问服务
假设你的主机 ip 是10.10.20.20
,你可以通过10.10.20.20:30475
、10.10.20.20:31261
、10.10.20.20:30013
访问http、metrics、health services。
编辑:根据Raedwald 评论编辑。
【讨论】:
允许port
和targetPort
不同有什么好处?因此,例如查看您的health
示例,为什么要使用port
8443
而不是8085
?基本上,为什么有两个参数而不是仅仅暴露服务上的所有targetPort
s?
嗨,Dan,您可以使用 8443 作为端口和目标端口以确保健康。为了更好地解释,我使用了不同的数字。
感谢您的回复。我的意思是,在什么情况下让它们不同会有用?
“在容器上运行”是什么意思?服务器内部容器使用的端口?或者客户端外部容器使用的端口?
我们可以为云服务中的主机(如 10.10.20.20)假设一个固定 IP 吗?例如,具有多节点部署情况的 Azure AKS?以上是关于Kubernetes Service定义中targetPort和port的区别的主要内容,如果未能解决你的问题,请参考以下文章
4.Kubernetes权威指南 --- 深入掌握Service
4.Kubernetes权威指南 --- 深入掌握Service