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

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

端口和targetPort有什么区别?


当前回答

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

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

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

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

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

其他回答

由于人们已经在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中的公开端口将请求发送给应用程序

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

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

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

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

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

@Manikanta P上面给出的答案是正确的。然而,“Port”的解释初读时可能有点不清楚。我将用一个例子来解释:

考虑一个web应用程序,它的静态内容(首页,图像等)由httpd托管,而动态内容(例如。响应请求等)由tomcat托管。Webserver(或静态内容)由httpd在80端口提供,而Appserver(或动态内容)由tomcat在8080端口提供。

开发者想要的:用户应该能够从外部访问web服务器,但不能从外部访问应用服务器。

解决方案:服务中的web服务器的服务类型。yml将是NodePort,而Appserver的service-type在其服务中。yml将是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文件中,我们将写入将用户请求重定向到应用服务器的IP。这个IP将是:host_IP:5050。

What exactly is happening here? A user writes hostIP:30475 and sees the Webserver's page. This is because it is being served by httpd at port 80 (targetport). When a user clicks a button, a request is made. This request is redirected to the Appserver because in httpd.conf file, the port 5050 is mentioned and this is the port where Appserver's container and Webserver's conatainer communicate internally. When the appserver receives the request, it is able to serve the request because of tomcat running inside it at port 8080.

目标器端口说明

# pod file
apiVersion: v1
kind: Pod
metadata: 
  name: pod_name
  labels: 
     name: pod_ref
spec: 
  containers:
  - name: docker-container
    image: python:3:11
    ports: 
    - containerPort: 5000 # this is the target port which we need to access (target) from service file

---
apiVersion: v1
kind: Service
metadata: 
   name: service_config
   labels: 
     name: service_config_ref
spec:
   type: NodePort
   selector:
     name: pod_ref  # same as pod metadata match labels 
     ports:
      - targetPort: 5000 # this is where the pod is listening 
        port: 80 # this is where this service (this file) is going to listen. 
                 # If you call the port 80, it will reach the service, then the service will forward the port to port:5000


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

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

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

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

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