Kubernetes:如果 nodePort 是随机的,如何访问服务? [英] Kubernetes: how to access service if nodePort is random?

查看:35
本文介绍了Kubernetes:如果 nodePort 是随机的,如何访问服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm new to K8s and am currently using Minikube to play around with the platform. How do I configure a public (i.e. outside the cluster) port for the service? I followed the nginx example, and K8s service tutorials. In my case, I created the service like so:

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

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

The service's port is 1234 for anyone trying to access it from INSIDE the cluster. The minikube tutorials say I need to access the service directly through it's random nodePort, which works for manual testing purposes:

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

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

But I don't understand how, in a real cluster, the service could have a fixed world-accessible port. The nginx examples describe something about using the LoadBalancer service kind, but they don't even specify ports there...

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

Any ideas how to fix the external port for the entire service?

推荐答案

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

The minikube tutorials say I need to access the service directly through it's random nodePort, which works for manual testing purposes:

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

When you create service object of type NodePort with a $ kubectl expose command you cannot choose your NodePort port. To choose a NodePort port you will need to create a YAML definition of it.

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

You can manually specify the port in service object of type Nodeport with below example:

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

You can apply above YAML definition by invoking command: $ kubectl apply -f FILE_NAME.yaml

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

Above service object will be created only if nodePort port is available to use.

但我不明白,在真正的集群中,该服务如何没有具有固定的全球可访问端口.

But I don't understand how, in a real cluster, the service could not have a fixed world-accessible port.

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

In clusters managed by cloud providers (for example GKE) you can use a service object of type LoadBalancer which will have a fixed external IP and fixed port.

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

Clusters that have nodes with public IP's can use service object of type NodePort to direct traffic into the cluster.

minikube 环境中,您可以使用 LoadBalancer 类型的服务对象,但它会有一些警告,如上一段所述.

In minikube environment you can use a service object of type LoadBalancer but it will have some caveats described in last paragraph.

Nodeport 将每个节点 IP 上的服务暴露在一个静态端口上.它允许外部流量通过 NodePort 端口进入.此端口将自动从 30000 范围分配到 32767.

Nodeport is exposing the service on each node IP at a static port. It allows external traffic to enter with the NodePort port. This port will be automatically assigned from range of 30000 to 32767.

您可以按照 本手册.

You can change the default NodePort port range by following this manual.

您可以通过查看此 answer 来检查在创建 NodePort 类型的服务对象时究竟发生了什么.

You can check what is exactly happening when creating a service object of type NodePort by looking on this answer.

想象一下:

  • 您的节点具有以下 IP:
    • 192.168.0.100
    • 192.168.0.101
    • 192.168.0.102
    • 10.244.1.10
    • 10.244.1.11
    • 10.244.1.12
    • NodePort (port 32222) 与:
      • ClusterIP:
        • IP:10.96.0.100
        • 端口:7654
        • targetPort:50001
        • NodePort (port 32222) with:
          • ClusterIP:
            • IP: 10.96.0.100
            • port:7654
            • targetPort:50001

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

            A word about targetPort. It's a definition for port on the pod that is for example a web server.

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

            According to above example you will get hello response with:

            • NodeIP:NodePort(所有 Pod 都可以用 hello 响应):
              • 192.168.0.100:32222
              • 192.168.0.101:32222
              • 192.168.0.102:32222
              • NodeIP:NodePort (all the pods could respond with hello):
                • 192.168.0.100:32222
                • 192.168.0.101:32222
                • 192.168.0.102:32222
                • 10.0.96.100:7654
                • 10.244.1.10:50001
                • 10.244.1.11:50001
                • 10.244.1.12:50001

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

                You can check access with curl command as below:

                $ curl http://NODE_IP:NODEPORT

                在你提到的例子中:

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

                会发生什么:

                • 它会在您的 minikube 实例上分配一个范围从 3000032767 的随机端口,将进入该端口的流量引导至 Pod.
                • 另外它会创建一个ClusterIP,端口为1234
                • It will assign a random port from range of 30000 to 32767 on your minikube instance directing traffic entering this port to pods.
                • Additionally it will create a ClusterIP with port of 1234

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

                In the example above there was no parameter targetPort. If targetPort is not provided it will be the same as port in the command.

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

                Traffic entering a NodePort will be routed directly to pods and will not go to the ClusterIP.

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

                From the minikube perspective a NodePort will be a port on your minikube instance. It's IP address will be dependent on the hypervisor used. Exposing it outside your local machine will be heavily dependent on operating system.

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

                There is a difference between a service object of type LoadBalancer(1) and an external LoadBalancer(2):

                • LoadBalancer(1) 类型的服务对象允许使用云提供商的 LoadBalancer(2) 向外部公开服务.它是 Kubernetes 环境中的一项服务,通过服务控制器可以安排创建外部 LoadBalancer(2).
                • 外部 LoadBalancer(2) 是云提供商提供的负载均衡器.它将在第 4 层运行.
                • Service object of type LoadBalancer(1) allows to expose a service externally using a cloud provider’s LoadBalancer(2). It's a service within Kubernetes environment that through service controller can schedule a creation of external LoadBalancer(2).
                • External LoadBalancer(2) is a load balancer provided by cloud provider. It will operate at Layer 4.

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

                Example definition of service of type 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)

                Applying above YAML will create a service of type LoadBalancer(1)

                具体看:

                  ports:
                    - port: 1234 # LOADBALANCER PORT 
                

                这个定义将同时:

                • 指定外部LoadBalancer(2) port 为1234
                • 指定ClusterIP port 为1234
                • specify external LoadBalancer(2) port as 1234
                • specify ClusterIP port as 1234

                想象一下:

                • 您的外部 LoadBalancer(2) 具有:
                  • 外部IP:34.88.255.5
                  • 端口:7654
                  • Your external LoadBalancer(2) have:
                    • ExternalIP: 34.88.255.5
                    • port:7654
                    • 192.168.0.100
                    • 192.168.0.101
                    • 192.168.0.102
                    • 10.244.1.10
                    • 10.244.1.11
                    • 10.244.1.12
                    • NodePort (port 32222) 与:
                      • ClusterIP:
                        • IP:10.96.0.100
                        • 端口:7654
                        • targetPort:50001
                        • NodePort (port 32222) with:
                          • ClusterIP:
                            • IP: 10.96.0.100
                            • port:7654
                            • targetPort:50001

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

                            According to above example you will get hello response with:

                            • ExternalIP:port(所有 Pod 都可以用 hello 响应):
                              • 34.88.255.5:7654
                              • ExternalIP:port (all the pods could respond with hello):
                                • 34.88.255.5:7654
                                • 192.168.0.100:32222
                                • 192.168.0.101:32222
                                • 192.168.0.102:32222
                                • 10.0.96.100:7654
                                • 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

                                Flow of the traffic: Client -> LoadBalancer:port(2) -> NodeIP:NodePort -> Pod:targetPort

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

                                Note: This feature is only available for cloud providers or environments which support external load balancers.

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

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

                                On cloud providers that support load balancers, an external IP address would be provisioned to access the Service. On Minikube, the LoadBalancer type makes the Service accessible through the minikube service command.

                                -- Kubernetes.io:你好 minikube

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

                                Minikube can create service object of type LoadBalancer(1) but it will not create an external LoadBalancer(2).

                                命令$ kubectl get services中的ExternalIP将处于pending状态.

                                The ExternalIP in command $ kubectl get services will have pending status.

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

                                To address that there is no external LoadBalancer(2) you can invoke $ minikube tunnel which will create a route from host to minikube environment to access the CIDR of ClusterIP directly.

                                这篇关于Kubernetes:如果 nodePort 是随机的,如何访问服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆