Kubernetes:如果nodePort是随机的,如何访问服务?

时间:2020-02-01 12:47:17

标签: kubernetes kubernetes-service

我是K8的新手,目前正在使用Minikube体验该平台。如何为服务配置公共(即群集外部)端口?我遵循了nginx example和K8s服务教程。就我而言,我是这样创建服务的:

kubectl expose deployment/mysrv --type=NodePort --port=1234

对于尝试从INSIDE群集访问它的任何人,该服务的端口为1234。 minikube教程说,我需要直接通过随机的nodePort访问该服务,该服务可用于手动测试:

kubectl describe service mysrv | grep NodePort
...
NodePort:                 <unset>  32387/TCP
# curl "http://`minikube ip`:32387/"

但是我不明白在一个真正的集群中,该服务如何具有固定的世界可访问端口。 Nginx示例描述了有关使用LoadBalancer服务类型的一些内容,但它们甚至没有在其中指定端口...

有什么想法如何为整个服务修复外部端口吗?

2 个答案:

答案 0 :(得分:2)

minikube教程说,我需要通过它的随机nodePort直接访问该服务,该服务可用于手动测试:

使用NodePort命令创建类型$ kubectl expose的服务对象时,无法选择NodePort端口。要选择一个NodePort端口,您需要为其创建一个YAML定义。

您可以使用以下示例在类型为Nodeport的服务对象中手动指定端口:

apiVersion: v1
kind: Service
metadata:
  name: example-nodeport
spec:
  type: NodePort
  selector:
    app: hello # selector for deployment
  ports:
  - name: example-port
    protocol: TCP
    port: 1234 # CLUSTERIP PORT
    targetPort: 50001 # POD PORT WHICH APPLICATION IS RUNNING ON 
    nodePort: 32222 # HERE!

您可以通过调用以下命令来应用高于YAML的定义: $ kubectl apply -f FILE_NAME.yaml

仅当nodePort端口可用时,以上服务对象才会创建。

但是我不明白,在一个真实的集群中,该服务如何具有固定的世界可访问端口。

在由云提供商(例如GKE)管理的群集中,您可以使用类型为LoadBalancer的服务对象,该服务对象将具有固定的外部IP和固定的端口。

具有带有公共IP的节点的集群可以使用类型NodePort的服务对象将流量引导到群集中。

minikube环境中,您可以使用类型LoadBalancer的服务对象,但是在上一段中将有一些警告。

一些解释:

NodePort

Nodeport在静态端口的每个节点IP上公开服务。它允许外部流量通过NodePort端口进入。该端口将自动从3000032767的范围内分配。

您可以按照this manual更改默认的NodePort端口范围。

通过查看answer,可以检查创建NodePort 类型的服务对象时到底发生了什么。

想象一下:

  • 您的节点具有IP:
    • 192.168.0.100
    • 192.168.0.101
    • 192.168.0.102
  • 您的Pod在端口50001上以hello进行响应,并且它们具有IP:
    • 10.244.1.10
    • 10.244.1.11
    • 10.244.1.12
  • 您的服务是:
    • NodePort(端口32222)具有:
      • ClusterIP
        • IP:10.96.0.100
        • port7654
        • targetPort50001

关于targetPort的字词。这是 pod 上端口的定义,例如Web服务器。

根据上面的示例,您将收到hello的回复:

  • NodeIP:NodePort(所有广告连播都可以回复hello):
    • 192.168.0.100:32222
    • 192.168.0.101:32222
    • 192.168.0.102:32222
  • ClusterIP:port(所有广告连播都可以回复hello):
    • 10.0.96.100:7654
  • PodIP:targetPort(仅发送请求的Pod可以回复hello
    • 10.244.1.10:50001
    • 10.244.1.11:50001
    • 10.244.1.12:50001

您可以使用curl命令检查访问权限,如下所示:

$ curl http://NODE_IP:NODEPORT


在您提到的示例中:

$ kubectl expose deployment/mysrv --type=NodePort --port=1234

会发生什么:

  • 它将在您的30000实例上的32767minikube范围内分配一个随机端口,将进入该端口的流量引导到Pod。
  • 此外,它将创建一个ClusterIP端口的1234

在上面的示例中,没有参数targetPort。如果未提供targetPort,则它将与命令中的port相同。

输入NodePort的流量将直接路由到广告连播,而不会转到ClusterIP

minikube角度来看,NodePort将是您的minikube实例上的端口。它的IP地址将取决于所使用的管理程序。将其暴露在本地计算机之外将在很大程度上取决于操作系统。


LoadBalancer

类型LoadBalancer(1)的服务对象和外部LoadBalancer(2)的服务对象之间是有区别的:

    类型为LoadBalancer(1)的
  • 服务对象允许使用云提供商的LoadBalancer(2)在外部公开服务。这是Kubernetes环境中的一项服务,通过服务控制器可以安排外部LoadBalancer(2)的创建。
  • 外部LoadBalancer(2)是云提供商提供的负载均衡器。它将在第4层运行。

类型LoadBalancer(1)的服务的示例定义:

apiVersion: v1
kind: Service
metadata:
  name: example-loadbalancer
spec:
  type: LoadBalancer
  selector:
    app: hello
  ports:
    - port: 1234 # LOADBALANCER PORT 
      targetPort: 50001  # POD PORT WHICH APPLICATION IS RUNNING ON 
      nodePort: 32222 # PORT ON THE NODE 

YAML上应用将创建LoadBalancer(1)类型的服务

具体看一下:

  ports:
    - port: 1234 # LOADBALANCER PORT 

此定义将同时:

  • 将外部LoadBalancer(2)port指定为1234
  • ClusterIP port指定为1234

想象一下:

  • 您的外部LoadBalancer(2)具有:
    • ExternalIP34.88.255.5
    • port7654
  • 您的节点具有IP:
    • 192.168.0.100
    • 192.168.0.101
    • 192.168.0.102
  • 您的Pod在端口50001上以hello进行响应,并且它们具有IP:
    • 10.244.1.10
    • 10.244.1.11
    • 10.244.1.12
  • 您的服务是:
    • NodePort(端口32222)具有:
      • ClusterIP
        • IP:10.96.0.100
        • port7654
        • targetPort50001

根据上面的示例,您将收到hello的回复:

  • ExternalIPport(所有广告连播都可以回复hello):
    • 34.88.255.5:7654
  • NodeIP:NodePort(所有广告连播都可以回复hello):
    • 192.168.0.100:32222
    • 192.168.0.101:32222
    • 192.168.0.102:32222
  • ClusterIP:port(所有广告连播都可以回复hello):
    • 10.0.96.100:7654
  • PodIP:targetPort(仅发送请求的Pod可以回复hello
    • 10.244.1.10:50001
    • 10.244.1.11:50001
    • 10.244.1.12:50001

ExternalIP可以通过以下命令进行检查:$ kubectl get services

流量: 客户端-> LoadBalancer:port(2)-> NodeIP:NodePort-> Pod:targetPort

Minikube: LoadBalancer

注意:该功能仅适用于支持外部负载平衡器的云提供商或环境。

- Kubernetes.io: Create external LoadBalancer

在支持负载平衡器的云提供商上,将提供一个外部IP地址来访问服务。在Minikube上,通过LoadBalancer命令可以访问minikube service类型的服务。

- Kubernetes.io: Hello minikube

Minikube可以创建类型LoadBalancer(1)的服务对象,但不会创建外部LoadBalancer(2)。

命令ExternalIP中的$ kubectl get services将处于待处理状态。

要解决没有外部LoadBalancer(2)的问题,您可以调用$ minikube tunnel,这将创建从主机到minikube环境的路由,以访问{的CIDR} {1}}。

答案 1 :(得分:-1)

根据问题:

  • 但是我不明白在一个真正的集群中,该服务如何具有固定的世界可访问端口。
  • 从没有minikube的整个群集外部访问服务时(例如在GKE上),nodePort甚至有什么意义?

在云中提供的Kubernetes集群LoadBalancer服务类型将具有由云提供商分配的外部IP。所需的服务将通过提供的外部IP进行访问。 LoadBalancer还将自动创建一种NodePort类型的服务,以在内部路由流量。 NodePort端口将无法与具有外部流量的节点IP地址直接连接。

创建的LoadBalancer将允许您指定一个端口,它将在该端口上响应流量。

通过链接查看以下参考:

声明类型为LoadBalancer的服务会使用云提供商的负载平衡器在外部公开它。云提供商将为Service设置负载平衡器,并将其映射到自动分配的NodePort

--- Ovh.com: getting-external-traffic-into-kubernetes