当前位置: 首页 > 知识库问答 >
问题:

库伯内特斯-如何使用NodePort服务从集群外部访问nginx负载平衡

朱雅惠
2023-03-14

我有一个Kubernetes群集,它有一个主节点和两个其他节点:

sudo kubectl get nodes
NAME                STATUS    ROLES     AGE       VERSION
kubernetes-master   Ready     master    4h        v1.10.2
kubernetes-node1    Ready     <none>    4h        v1.10.2
kubernetes-node2    Ready     <none>    34m       v1.10.2

它们中的每一个都在VirtualBox Ubuntu VM上运行,可从来宾计算机访问:

kubernetes-master (192.168.56.3)
kubernetes-node1  (192.168.56.4)
kubernetes-node2 (192.168.56.6)

我部署了一个带有两个副本的nginx服务器,每个kubernetes-node-x有一个pod:

sudo kubectl get pods -o wide
NAME                                READY     STATUS    RESTARTS   AGE       IP               NODE
nginx-deployment-64ff85b579-5k5zh   1/1       Running   0          8s        192.168.129.71   kubernetes-node1
nginx-deployment-64ff85b579-b9zcz   1/1       Running   0          8s        192.168.22.66    kubernetes-node2

接下来,我将nginx部署的服务公开为节点端口,以便从集群外部访问它:

sudo kubectl expose deployment/nginx-deployment --type=NodePort

sudo kubectl get services 
NAME               TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes         ClusterIP   10.96.0.1      <none>        443/TCP        4h
nginx-deployment   NodePort    10.96.194.15   <none>        80:32446/TCP   2m

sudo kubectl describe service nginx-deployment
Name:                     nginx-deployment
Namespace:                default
Labels:                   app=nginx
Annotations:              <none>
Selector:                 app=nginx
Type:                     NodePort
IP:                       10.96.194.15
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  32446/TCP
Endpoints:                192.168.129.72:80,192.168.22.67:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

我可以直接使用节点IP访问节点中的每个pod

kubernetes-node1 http://192.168.56.4:32446/
kubernetes-node2 http://192.168.56.6:32446/

但是,我认为K8s提供了某种外部集群ip来平衡从外部对节点的请求。那个IP是什么??

共有1个答案

李捷
2023-03-14

但是,我认为K8s提供了某种外部集群ip来平衡从外部对节点的请求。那个IP是什么??

>

  • 集群IP是集群内部的。不对外公开,用于跨集群互通。

    事实上,您有LoadBanacer类型的服务可以实现您所需的技巧,只是它依赖于云提供商或minikube/docker edge才能正常工作。

    我可以直接使用节点IP访问节点中的每个pod

    • 实际上,您不会以这种方式单独访问它们。NodePort有一点不同的技巧,因为它本质上是在任何暴露的节点IP上对来自外部的请求进行负载平衡。简而言之,如果您使用暴露的NodePort访问任何节点的IP,库贝代理将确保所需的服务得到它,然后服务通过活动pod进行循环,因此尽管您访问了特定的节点IP,但您不一定会让pod在该特定节点上运行。更多详细信息,您可以在此处找到:https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0,正如作者所说,技术上不是最准确的表示,但尝试在逻辑层面上展示NodePort暴露发生了什么:

    >

    (outside) -> ingress (nginx) +--> my-service FQDN (running accross nodes):
                 [node-0]        |      [node-1]: my-service-pod-01 with nginx-01
                                 |      [node 2]: my-service-pod-02 with nginx-02
                                 |      ...
                                 +--> my-second-service FQDN
                                 |      [node-1]: my-second-service-pod with apache?
                                 ...
    

    在上面的草图中,节点0(已知IP)上有nginx入口,它接收外部流量,然后将我的服务(在两个节点上的两个pod上运行)和我的第二个服务(单个pod)作为上游处理。您只需在服务上公开FQDN即可使其工作,而无需担心特定节点IP的详细信息。您可以在文档中找到更多信息:https://kubernetes.io/docs/tutorials/kubernetes-basics/expose/expose-intro/

    为什么服务负载不平衡服务中使用的pod?

    • 发生这种情况有几个原因。根据您的活跃度和准备度探测器的配置方式,可能服务部门仍然不会将pod视为停止服务。由于分布式系统(如k8s)中的这种异步性质,当POD在滚动更新等过程中被移除时,我们会遇到临时的请求丢失。其次,根据kube代理的配置方式,有一些选项可以限制它。通过官方文件(https://kubernetes.io/docs/concepts/services-networking/service/#type-节点端口)使用“节点端口地址”,可以更改节点代理行为。结果表明,循环是旧的库贝代理行为,显然新的应该是随机的。最后,为了从浏览器中排除连接和会话问题,您是否也从匿名会话中尝试了此操作?您是否有本地缓存的dns

    另外,我杀死了node1的pod,当调用node1时,它没有使用Node2的pod。

    • 这有点奇怪。可能与上面提到的探针有关。根据官方留档,情况不应该是这样的。我们让NodePort与上面提到的官方留档行为内联:并且每个节点都会将该端口(每个节点上相同的端口号)代理到您的服务中。但是如果这是您的情况,那么可能是LB或入口,甚至可能是具有外部地址的ClusterIP(见下文)也可以为您完成。

    如果服务是内部的(ClusterIP)。。。它是否对节点中的任何吊舱进行负载平衡

    >

    apiVersion: v1
    kind: Service
    metadata:
        namespace: ns-my-namespace
        name: svc-nginx-ingress-example
        labels:
            name: nginx-ingress-example
            role: frontend-example
            application: nginx-example
    spec:
        selector:
            name: nginx-ingress-example
            role: frontend-example
            application: nginx-example
        ports:
        - protocol: TCP
          name: http-port
          port: 80
          targetPort: 80
        - protocol: TCP
          name: ssl-port
          port: 443
          targetPort: 443
        externalIPs:
        - 123.123.123.123
    

    请注意,在上面的示例中,使用externalIPs公开的虚拟123.123.123.123表示一个工作节点的ip地址。运行在svc nginx ingress example(svc nginx入口示例)服务中的POD根本不需要位于该节点上,但当该ip在指定端口上被命中时,它们仍然可以获得路由到它们的流量(以及POD之间的负载平衡)。

  •  类似资料:
    • 如果之前已经回答过,我很抱歉,但我对Ingress Nginx正在与服务合作感到有点困惑。 我正在尝试在我的库伯内特斯环境中实现nginx入口。到目前为止,我有一个ingres-nginx-控制器-部署设置,以及默认后端的部署和服务。我仍然需要创建我的实际入口资源、ingres-nginx-控制器-服务和我的后端。 <代码>卷曲 我的问题是这是怎么可能的,我可以在集群之外的浏览器上为我的节点访问端

    • 我仍然对Kubernetes节点端口服务有疑问。 NodePort:在静态端口(NodePort)上公开每个节点IP上的服务。将自动创建节点端口服务将路由到的ClusterIP服务。您可以从集群外部通过请求来联系NodePort服务:。 如果我有两个节点:nodeA和nodeB,并且如果我只在nodeA上部署应用程序,然后创建NodePort服务,那么我可以同时使用nodeA和nodeB IP访问

    • 我在两个节点上运行 Kubernetes,并在两个节点上部署一个应用程序(两个 pod,每个节点一个)。 这是一个Spring Boot应用程序。它使用OpenFygnd来实现服务可发现性。在应用程序中,我定义了一个一来控制程序,它有几个API和一个从API内部调用的@Autow的@Service。 每当我对其中一个API进行请求时,Kubernetes都会使用某种负载平衡来将流量路由到其中一个p

    • 我有一个包含 3 个节点的 Kubernetes 集群。 示例部署 我没有入口,但我有外部负载均衡器,可以轮询 80.11.12.10、80.11.12.11、 的流量。 所以我这样设置我的服务。 问题在于,由于现有的 kubernetes 服务负载均衡器,流量会获得两次负载均衡。除此之外,这是不必要的,它会破坏连接持久性。有没有办法强制 Kubernetes 在每个节点的本地机器 Pod 上转发

    • 我只是在本地mac上使用mini kube设置kubernetes。 创建了一个类型为NodePort的服务,并且能够使用url

    • 我们在库伯内特斯运行了Spring Boot服务,并且正在使用Spring Cloud库伯内特斯负载均衡器功能和RestTemboard来调用其他Spring Boot服务。我们这样做的主要原因之一是历史上的——因为之前我们使用Eureka在EC2中运行我们的服务进行服务发现,迁移后我们保持了Spring发现客户端/客户端负载平衡(更新依赖项等,以便它与Spring Cloud库伯内特斯项目一起工