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

Sag*_*ann 4 kubernetes kubernetes-service

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

kubectl expose deployment/mysrv --type=NodePort --port=1234
Run Code Online (Sandbox Code Playgroud)

该服务的端口是 1234,供任何试图从集群内部访问它的人使用。minikube 教程说我需要通过它的随机 nodePort 直接访问服务,这适用于手动测试目的:

kubectl describe service mysrv | grep NodePort
...
NodePort:                 <unset>  32387/TCP
# curl "http://`minikube ip`:32387/"
Run Code Online (Sandbox Code Playgroud)

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

任何想法如何修复整个服务的外部端口?

Daw*_*ruk 11

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!
Run Code Online (Sandbox Code Playgroud)

您可以YAML通过调用命令来应用上述定义: $ kubectl apply -f FILE_NAME.yaml

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

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

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

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

minikube环境中,您可以使用类型的服务对象,LoadBalancer但它会有上一段中描述的一些注意事项。

稍微解释一下:

节点端口

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

您可以NodePort按照本手册更改默认端口范围。

您可以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
        • 知识产权: 10.96.0.100
        • port7654
        • targetPort50001

关于 的一句话targetPort。它是pod上端口的定义,例如 Web 服务器。

根据上面的例子,你会得到hello回应:

  • NodeIP:NodePort(所有 Pod 都可以响应hello):
    • 192.168.0.100:32222
    • 192.168.0.101:32222
    • 192.168.0.102:32222
  • ClusterIP:port(所有 Pod 都可以响应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
Run Code Online (Sandbox Code Playgroud)

会发生什么:

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

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

进入 a 的流量NodePort将直接路由到 Pod,而不会转到ClusterIP.

minikube角度来看, aNodePort将是您minikube实例上的一个端口。它的 IP 地址将取决于所使用的管理程序。将它暴露在本地机器之外将严重依赖于操作系统。


负载均衡器

类型LoadBalancer(1) 和外部LoadBalancer(2)的服务对象之间存在差异:

  • 类型LoadBalancer(1) 的服务对象允许使用云提供商的LoadBalancer(2)向外部公开服务。它是 Kubernetes 环境中的一项服务,通过服务控制器可以安排外部LoadBalancer(2)的创建。
  • External 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 
Run Code Online (Sandbox Code Playgroud)

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

具体看一下:

  ports:
    - port: 1234 # LOADBALANCER PORT 
Run Code Online (Sandbox Code Playgroud)

该定义将同时:

  • 将外部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
        • 知识产权: 10.96.0.100
        • port7654
        • targetPort50001

根据上面的例子,你会得到hello回应:

  • ExternalIP:(port所有 Pod 都可以用 响应hello):
    • 34.88.255.5:7654
  • NodeIP:NodePort(所有 Pod 都可以响应hello):
    • 192.168.0.100:32222
    • 192.168.0.101:32222
    • 192.168.0.102:32222
  • ClusterIP:port(所有 Pod 都可以响应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

流量流向:Client -> LoadBalancer:port(2) -> NodeIP:NodePort->Pod:targetPort

Minikube:负载均衡器

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

-- Kubernetes.io:创建外部负载均衡器

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

-- Kubernetes.io:你好 minikube

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

ExternalIP命令$ kubectl get services将挂起状态。

为了解决没有外部LoadBalancer(2) 的问题,您可以调用$ minikube tunnel它将创建从主机到minikube环境的路由以直接访问CIDRof ClusterIP