Kubernetes服务可以在服务定义中有一个targetPort和port:

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

端口和targetPort有什么区别?


当前回答

如果容器监听端口9376,那么 发送:9376

如果服务在端口80上侦听,则 端口:80

然后服务端口配置如下所示

ports:
 - protocol: TCP
   port: 80
   targetPort: 9376

最后,请求接收到服务的端口,并在pod的targetPort上转发。

其他回答

这个答案是参考Kubernetes的文档以及其他答案:

https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/:

targetPort:容器接收流量的端口,

port:是抽象的服务端口,它可以是其他pod用来访问服务的任何端口

https://kubernetes.io/docs/concepts/services-networking/service/:

Pods中的端口定义有名称,您可以在服务的targetPort属性中引用这些名称。即使服务中有使用单一配置名称的pod的混合物,通过不同的端口号使用相同的网络协议,这种方法也有效。

它帮助我从服务的角度考虑问题。

nodePort:节点上外部流量进入的端口 port:该服务的端口 targetPort pod上转发流量的目标端口

流量从nodePort进入,转发到服务上的port,然后路由到pod上的targetPort。

值得强调的是,nodePort用于外部流量。集群中其他可能需要访问服务的pod将只使用port,而不是nodePort,因为它只在内部访问服务。

另外值得注意的是,如果没有设置targetPort,它将默认为与port相同的值。例如,80:80服务端口80针对集装箱端口80。

targetport: pod中容器侦听的一个或多个端口。

nodeport:主要用于接受使用者请求。(例如:从消费者到运行在容器中的web服务器的HTTP请求)

Nodeport在所有接口上的所有节点上侦听,即0.0.0.0:Nodeport。发送到nodeport的使用者服务请求被路由到容器的targetport,以便容器能够满足该请求。

port: kubernetes pod网络中使用的端口,主要用于在pod之间交换请求。在这里,来自另一个pod的请求也被路由到腐蚀pod的容器targetport。

Summary:所有请求最终都到达targetport。如果请求来自k8s网络外部,则使用Nodeport;如果来自k8s网络内部,则使用port。

由于人们已经在Kubernetes Service定义中解释了port和targetPort,我将添加关于Dockerfile、Kubernetes Deployment和Kubernetes Ingress的信息,因为它们是公共工作流的一部分。

第1部分-应用程序及其Dockerfile

假设您在端口3000上运行Flask服务器,在端口4000上运行Golang服务器。当你使用Docker容器化这些应用程序时,你必须在dockerfile中公开端口3000和4000:

Python

应用程序

...
...
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=3000)

Dockerfile

FROM python:3.10-alpine

...

...

EXPOSE 3000

CMD ...

戈朗

应用程序

...
...
func main() {
    ...
    log.Fatal(http.ListenAndServe(":4000", nil))
}

Dockerfile

FROM golang:1.18-alpine

...

...

EXPOSE 4000

CMD ...

第2部分- Dockerfiles和Kubernetes部署

Dockerfiles中的公开端口必须与部署清单中的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
...
...

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
...
...

第3部分- Kubernetes部署和服务

部署清单中的containerPort必须与服务清单中的targetPort匹配

Python服务清单

apiVersion: v1
kind: Service
metadata:
  name: flask-api-service
spec:
  type: NodePort
  selector:
    app: flask-api
  ports:
    - port: 80
      targetPort: 3000

Golang服务舱单

apiVersion: v1
kind: Service
metadata:
  name: go-api-service
spec:
  type: NodePort
  selector:
    app: go-api
  ports:
    - port: 443
      targetPort: 4000

第4部分- Kubernetes服务和入口

服务清单中的端口必须与入口中的端口号匹配

适用于Python和Golang应用程序的AWS入口

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

Flow

传入请求命中端口号上的入节点 入口将此请求转发到服务端口 服务端口将该端口映射到targetPort 从服务targetPort请求到部署containerPort 部署containerPort是应用程序的Docker映像,它在Dockerfile中公开了相应的端口 最后,Dockerfile中的公开端口将请求发送给应用程序

我认为形象是最好的描述。