Kubernetes 服务架构

标签 kubernetes kubernetes-service kubernetes-statefulset

在同一个 Kubernetes 集群中,

  • 我可以将多个 StatefulSet 附加到一个 headless 服务,还是每个 StatefulSet 都有自己的 headless 服务?这样做有什么好处和坏处?
  • 我可以在同一个集群中混合标准服务和 headless 服务吗?具体来说,我想使用 LoadBalancer 服务来负载平衡 headless 服务。我可以定义 LoadBalancer 类型的服务并附加 headless 服务(ClusterIP = None)吗?如果是,我怎样才能做到这一点?

  • 这是我的预期架构:
    Load Balancer Service
      - Headless Service (Database-service)
        -  MySql
        - BlazeGraph
      - Headless Service (Web / Tomcat)
        - Web Service (RESTful / GraphQL)
    

    任何建议和见解都值得赞赏。

    我的设置

    我的服务和附加到它的 statefulsets 有不同的标签。
    database-service: app=database
    mysqlset: app=mysql
    

    我的 pod
    khteh@khteh-T580:~ 2007 $ k get pods -l app=mysql -o wide
    NAME      READY   STATUS    RESTARTS   AGE   IP         NODE         NOMINATED NODE
    mysql-0   1/1     Running   1          18h   10.1.1.4   khteh-t580   <none>
    
    khteh@khteh-T580:~ 2008 $ k get pods -l app=blazegraph -o wide
    NAME           READY   STATUS    RESTARTS   AGE   IP           NODE         NOMINATED NODE
    blazegraph-0   1/1     Running   1          18h   10.1.1.254   khteh-t580   <none>
    
    khteh@khteh-T580:~ 2009 $ k describe service database-service
    Name:              database-service
    Namespace:         default
    Labels:            app=database
    Annotations:       kubectl.kubernetes.io/last-applied-configuration:
                     {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"database"},"name":"database-service","namespace":"defaul...
    Selector:          app=database,tier=database
    Type:              ClusterIP
    IP:                None
    Port:              mysql  3306/TCP
    TargetPort:        3306/TCP
    Endpoints:         <none>
    Port:              blazegraph  9999/TCP
    TargetPort:        9999/TCP
    Endpoints:         <none>
    Session Affinity:  None
    Events:            <none>
    

    注意服务端点是<none> .我不确定这是正确的设置。

    最佳答案

    headless 服务在您想要自动发现服务下的所有 pod 的任何情况下都应该使用,而不是使用常规服务来获取 ClusterIP。作为上述示例的说明,这里是服务(使用 ClusterIP)和 headless 服务(没有 ClusterIP)的 DNS 条目之间的区别:

  • 您将获得 clusterIP 值的标准服务:
    kubectl exec zookeeper-0 -- nslookup zookeeper
    Server:        10.0.0.10
    Address:    10.0.0.10#53
    
    Name:    zookeeper.default.svc.cluster.local
    Address: 10.0.0.213
    
  • headless 服务,您将获得每个 pod 的 IP
    kubectl exec zookeeper-0 -- nslookup zookeeper
    Server:        10.0.0.10
    Address:    10.0.0.10#53
    
    Name:    zookeeper.default.svc.cluster.local
    Address: 172.17.0.6
    Name:    zookeeper.default.svc.cluster.local
    Address: 172.17.0.7
    Name:    zookeeper.default.svc.cluster.local
    Address: 172.17.0.8
    

  • 现在,如果您将两个有状态集与单个 headless 服务连接,它将返回两个状态集中每个 pod 的地址。如果您为此创建两个 statefulset 和一个 headless 服务,则无法将 Pod 与两个应用程序区分开来。看下面的文章了解why headless services are used

    headless 服务允许开发人员通过允许他们以自己的方式进行发现来减少与 Kubernetes 系统的耦合。对于此类服务,不分配 clusterIP,kube-proxy 不处理这些服务,也没有平台为它们做负载均衡和代理。所以,如果你定义 clusterIP: None在您的服务中,kubernetes 端不会进行负载平衡。

    希望这可以帮助。

    编辑:

    我做了一个小实验来回答您的查询,创建了两个名为 mysql 和 mysql2 的 mysql 数据库有状态集,每个状态集有 1 个副本。他们有自己的 PV、PVC,但只受单一 headless 服务的约束。
    [root@ip-10-0-1-235 centos]# kubectl get pods -l app=mysql -o wide
    NAME       READY     STATUS    RESTARTS   AGE       IP              NODE
    mysql-0    1/1       Running   0          4m        192.168.13.21   ip-10-0-1-235.ec2.internal
    mysql2-0   1/1       Running   0          3m        192.168.13.22   ip-10-0-1-235.ec2.internal
    

    现在您可以看到连接到两个 pod 的单个 headless 服务
    [root@ip-10-0-1-235 centos]# kubectl describe svc mysql
    Name:              mysql
    Namespace:         default
    Labels:            <none>
    Annotations:       <none>
    Selector:          app=mysql
    Type:              ClusterIP
    IP:                None
    Port:              <unset>  3306/TCP
    TargetPort:        3306/TCP
    Endpoints:         192.168.13.21:3306,192.168.13.22:3306
    Session Affinity:  None
    Events:            <none>
    

    现在,当您从其他 pod 查找服务时,它会返回两个 pod 的 IP 地址:
    [root@rtp-worker-0 /]# nslookup mysql
    Server:     10.96.0.10
    Address:    10.96.0.10#53
    
    Name:   mysql.default.svc.cluster.local
    Address: 192.168.13.21
    Name:   mysql.default.svc.cluster.local
    Address: 192.168.13.22
    

    现在,无法识别哪个地址(pod)属于哪个 statefulset。现在我尝试使用它的元数据名称来识别有状态集,但不能
    [root@rtp-worker-0 /]# nslookup mysql2.mysql.default.svc.cluster.local
    Server:     10.96.0.10
    Address:    10.96.0.10#53
    
    ** server can't find mysql2.mysql.default.svc.cluster.local: NXDOMAIN
    

    希望它澄清。

    关于Kubernetes 服务架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53358976/

    相关文章:

    security - 在kubernetes etcd存储中加密 secret 数据

    kubernetes - 使用 Kubernetes 编排从部署的微服务访问微服务端点

    Kubernetes Ingress Flask 应用程序

    amazon-web-services - Kubernetes状态集,可用区和批量声明:可用区失败时会发生什么

    kubernetes - StatefulSets 中并行 podManagementPolicy 相对于 OrderedReady podManagementPolicy 的优缺点是什么?

    kubernetes - 使用 helm 升级(部署 + PVC)到 Statefulset

    Kubernetes kubectl按类型获取 secret 吗?

    kubernetes - Kubernetes API服务器连接被拒绝

    ssl - 不要在前面加上 http ://to Endpoint Subset IP

    kubernetes - 阻止 namespace 之间的访问,但允许访问外部流量