服务是NodePort类型,并指定port和targetPort是什么意思?

Lai*_*son 43 kubernetes

我白天对Kubernetes越来越熟悉,但我仍处于基本水平.我也不是网络人.

我正盯着服务定义的以下片段,我无法在脑海中形成正确的图片:

spec:
  type: NodePort
  ports:
  - port: 27018
    targetPort: 27017
    protocol: TCP
Run Code Online (Sandbox Code Playgroud)

引用ServicePort文档,其中部分内容如下:

nodePort     The port on each node on which this service is exposed when type=NodePort or LoadBalancer. Usually
integer      assigned by the system. If specified, it will be allocated to the service if unused or else creation of the
             service will fail. Default is to auto-allocate a port if the ServiceType of this Service requires one. More info: 
             http://kubernetes.io/docs/user-guide/services#type--nodeport

port         The port that will be exposed by this service.
integer

targetPort   Number or name of the port to access on the pods targeted by the service. Number must be in the range 1
IntOrString  to 65535. Name must be an IANA_SVC_NAME. If this is a string, it will be looked up as a named port in the
             target Pod's container ports. If this is not specified, the value of the 'port' field is used (an identity map).
             This field is ignored for services with clusterIP=None, and should be omitted or set equal to the 'port' field.
             More info: http://kubernetes.io/docs/user-guide/services#defining-a-service
Run Code Online (Sandbox Code Playgroud)

我的理解是,该集群之外的客户端将"看到"的端口将在范围内的动态分配的一个30000- 32767,所定义的文档中.这将使用我还不了解的一些黑魔法流向给targetPort定节点(27017在这种情况下).

那么port这里使用的是什么?

fis*_*x01 45

nodePort是群集外部的客户端将"看到"的端口.nodePort通过kube-proxy在集群中的每个节点上打开.使用iptables magic Kubernetes(k8s)然后将流量从该端口路由到匹配的服务pod(即使该pod在完全不同的节点上运行).

port是服务在集群内侦听的端口.我们来看这个例子:

---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
  - port: 8080
    targetPort: 8070
    nodePort: 31222
    protocol: TCP 
  selector:
    component: my-service-app
Run Code Online (Sandbox Code Playgroud)

从我的k8s群集内部,可以通过my-service.default.svc.cluster.local:8080(群集内的服务到服务通信)访问此服务,并且到达那里的任何请求都将转发到targetPort8070 上的正在运行的pod .

tagetPort默认情况下也是相同的值,port如果没有另外指定.

  • 来自#kubernetes-users Slack频道:"`nodePort`路由到服务,然后路由到pod /如果直接点击服务,则跳过`nodePort`步骤/'magical routing'由`KUBE-proxy`".这让我说(使用发明的符号):"`nodePort` - >`port` - >`targetPort`,而不是`nodePort` - >`targetPort` &&`port` - >`targetPort`". (9认同)
  • `nodePort`是唯一的,因此2个不同的服务不能分配相同的`nodePort`.声明后,k8s master会为该服务保留`nodePort`.然后在**EVERY**节点(master和worker)上打开`nodePort` - 也就是不运行该服务的pod的节点 - [k8s iptables](https://kubernetes.io/docs/user-guide/services/#virtual-ips-and-service-proxies)magic负责路由.这样,您可以从k8s群集外部向`nodePort`上的任何节点发出服务请求,而无需担心是否在那里安排了pod. (2认同)

Say*_*ald 9

为了更好地解释这个概念,我想象了Service的NodePort概念.

NodePort服务

正如@fishi在他的回答中提到的,NodePort允许将k8s主机端口(也称为nodePort)暴露给外部客户端.客户端可以直接访问nodePort,k8s将流量转发到必要的端口.

K8s保留了nodePort所有节点.运行服务的pod的所有节点都打开了此端口.

Pod不仅可以通过内部集群IP访问,还可以通过节点的IP和保留端口aka HOST_IP:NODE_PORT对访问.

  • 我认为该图像具有误导性。如果 CURL http://10.0.2.15:30230 是外部调用,则它应该指向云 NodePort,并且该请求会发送到 pod。这意味着云部分应该具有节点 IP:10.0.2.15 和 NodePort:30230。此外,“Pod:CURL”pod 应该显示为直接发送到“Pod:Nginx”pod 的请求。您还可以让“Pod: CURL”pod 向节点云部分发出请求,但我认为您不想描述这一点。 (2认同)