Jac*_*cob 75 service port kubernetes
我正在尝试探索kubernetes服务.当我读取服务定义时,我发现有targetPort和port在服务定义中指定.
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
Run Code Online (Sandbox Code Playgroud)
这里kubernetes服务定义中port和targetPort的区别是什么?谁有人澄清这种困惑?
jul*_*256 87
它帮助我从服务的角度思考问题。
nodePort:外部流量将进入的节点上的端口port:这个服务的端口targetPort Pod 上要将流量转发到的目标端口流量进来nodePort,转发到port服务,然后路由到targetPortpod(s)。
更值得强调的nodePort是外部流量。集群中可能需要访问服务的其他 pod 将只使用port,而不是nodePort因为它是对服务的内部访问。
另外值得注意的是,如果targetPort未设置,它将默认为与port. 例如80:80,80针对容器端口的服务端口80。
小智 24
如果容器侦听端口 9376,则\n targetPort : 9376
\n如果服务侦听端口 80,则\n端口: 80
\n然后服务端口配置如下所示
\nports:\n - protocol: TCP\n port: 80\n targetPort: 9376\nRun Code Online (Sandbox Code Playgroud)\n最后,请求收到到 service\xe2\x80\x99s port,并转发到targetPortpod 的
\nMan*_*a P 21
服务:这会将流量引导到吊舱。
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
Run Code Online (Sandbox Code Playgroud)
如果您点击my-service:8089,则流量将路由到容器(targetPort)的8080。同样,如果您命中my-service:8443,则它将重定向到容器(targetPort)的8085。
但是,此myservice:8089是kubernetes集群的内部组件,可以在一个应用程序想要与另一个应用程序通信时使用。因此,要从群集外部访问服务,需要有人公开运行kubernetes的主机上的端口,以便将流量重定向到容器的端口。在那可以使用nodePort。
在上面的示例中,您可以通过host_ip:Nodeport从群集外部(邮递员或任何restclient)访问服务
假设您的主机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注释进行编辑。
Sau*_*abh 13
由于人们已经在 Kubernetes 服务定义中进行了解释port,targetPort我将添加有关DockerfileKubernetes 部署和 Kubernetes Ingress 如何出现的信息,因为它们是通用工作流程的一部分。
Dockerfile假设您在端口 3000 上运行 Flask 服务器,在端口 4000 上运行 Golang 服务器。当您使用 Docker 容器化这些应用程序时,您必须在它们的Dockerfiles 中公开端口 3000 和 4000:
应用
...
...
if __name__ == "__main__":
app.run(host='0.0.0.0', port=3000)
Run Code Online (Sandbox Code Playgroud)
Dockerfile
FROM python:3.10-alpine
...
...
EXPOSE 3000
CMD ...
Run Code Online (Sandbox Code Playgroud)
应用
FROM python:3.10-alpine
...
...
EXPOSE 3000
CMD ...
Run Code Online (Sandbox Code Playgroud)
Dockerfile
FROM golang:1.18-alpine
...
...
EXPOSE 4000
CMD ...
Run Code Online (Sandbox Code Playgroud)
Dockerfiles 和 Kubernetes 部署s中公开的端口Dockerfile必须containerPort与部署清单中的端口相匹配。
Python 部署清单
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: python-flask-api
spec:
...
...
app: flask-api
template:
metadata:
labels:
app: flask-api
spec:
containers:
- name: flask-api
image: ...
ports:
- containerPort: 3000
...
...
Run Code Online (Sandbox Code Playgroud)
Golang 部署清单
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-backend-api
spec:
...
...
app: go-api
template:
metadata:
labels:
app: go-api
spec:
containers:
- name: go-api
image: ...
ports:
- containerPort: 4000
...
...
Run Code Online (Sandbox Code Playgroud)
部署清单中的内容containerPort必须与targetPort服务清单中的内容相匹配
Python 服务清单
apiVersion: v1
kind: Service
metadata:
name: flask-api-service
spec:
type: NodePort
selector:
app: flask-api
ports:
- port: 80
targetPort: 3000
Run Code Online (Sandbox Code Playgroud)
Golang 服务清单
apiVersion: v1
kind: Service
metadata:
name: go-api-service
spec:
type: NodePort
selector:
app: go-api
ports:
- port: 443
targetPort: 4000
Run Code Online (Sandbox Code Playgroud)
服务清单port中的端口必须与number入口中的端口相匹配
适用于 Python 和 Golang 应用程序的 AWS Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: microservice-app-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
rules:
- host: foo.biz.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: go-api-service
port:
number: 443
- host: bar.biz.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: flask-api-service
port:
number: 80
Run Code Online (Sandbox Code Playgroud)
传入请求到达端口上的入口number
Ingress将此请求转发给服务port
服务端口映射port到targetPort
请求从服务targetPort转到部署containerPort
部署containerPort是应用程序的 Docker 映像,该映像在其中公开了相应的端口Dockerfile
最后,暴露的端口将Dockerfile请求发送给应用程序
小智 12
@Manikanta P 上面给出的答案是正确的。然而,“端口”的解释初读时可能有点不清楚。我会用一个例子来解释:
考虑一个 Web 应用程序,其静态内容(首页、图像等)由 httpd 托管,动态内容(例如,对请求的响应等)由 tomcat 托管。Webserver(或静态内容)由 httpd 在 port 提供,80而 Appserver(或动态内容)由 tomcat 在 port 提供8080。
开发人员想要什么:用户应该能够从外部访问 Webserver,但不能从外部访问 Appserver。
解决方案:webserver在service.yml中的service-type为NodePort,在service.yml中Appserver的service-type为ClusterIP。
网络服务器 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.
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
另请注意,在httpd.confWeb 服务器的文件中,我们将编写将用户请求重定向到应用服务器的 IP。该 IP 将是:host_IP:5050.
这里到底发生了什么?用户编写hostIP:30475并查看 Web 服务器的页面。这是因为它由 httpd 在端口80(目标端口)提供服务。当用户单击按钮时,会发出请求。此请求被重定向到 Appserver,因为在httpd.conf文件中,5050提到了端口,这是 Appserver 的容器和 Webserver 的容器内部通信的端口。当 appserver 收到请求时,它能够为请求提供服务,因为 tomcat 在它的内部运行在 port 8080。
Lor*_*ord 10
情况1:
假设没有 nodPort 或端口,现在您想要运行您的应用程序并将其暴露给外部,您将需要什么:
因此,为了从外部访问,我们发现需要三个端口。
使一切正常工作:servicePort === targetPort === networkPort
情况 2: 现在假设一个服务与集群中的另一个服务进行通信,或者假设一个服务接收到来自外部的请求,并且它发出一个事件,该事件触发了集群内的另一个服务。
假设服务X通过nodePort服务对外暴露,在收到请求后,X服务想要与Y服务进行通信。
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]);
});
Run Code Online (Sandbox Code Playgroud)
服务Y的配置和内部
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
Run Code Online (Sandbox Code Playgroud)
app.listen(4009, () => {
console.log('Listening on 4009');
});
Run Code Online (Sandbox Code Playgroud)
简而言之
nodeport: 在 nodeip:port 上的所有工作节点上侦听外部请求并将请求转发到端口。
port: 容器的内部集群服务端口,侦听来自节点端口的传入请求并转发到目标端口。
targetPort:从端口接收请求并转发到它正在侦听的容器 pod(port)。即使您没有指定,默认情况下也会分配与 port 相同的端口号。
除了其他答案之外,这个答案是参考 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 中的端口定义有名称,您可以在
targetPortService的属性中引用这些名称。即使服务中混合了使用单个配置名称的 Pod,并且通过不同的端口号使用相同的网络协议,这也能正常工作。
targetport:容器在 pod 内侦听的一个或多个端口。
nodeport:主要用于接受消费者请求。(例如:从消费者到容器中运行的 Web 服务器的 HTTP 请求)
nodeport 在所有接口上的所有节点上侦听,即 0.0.0.0:nodeport。发送到nodeport的消费者服务请求将被路由到容器的targetport,以便容器可以满足请求。
port:kubernetes pod 网络内使用的端口,主要用于在 pod 之间交换请求。在这里,来自另一个 Pod 的请求也会被路由到相应 Pod 的容器目标端口。
摘要:所有请求最终都到达目标端口。如果请求来自外部 k8s 网络,则使用nodeport ;如果来自内部,则使用端口。
| 归档时间: |
|
| 查看次数: |
26106 次 |
| 最近记录: |