无状态集和无头服务如何工作-K8s

7
我理解:
  • StatefulSet - 管理/维护稳定的主机名、网络 ID 和持久存储。
  • HeadlessService - 稳定的网络 ID,您需要为有状态应用程序定义一个无头服务。

来自 K8s 文档 -> 有时您不需要或不想要负载均衡和单个服务 IP。在这种情况下,可以通过在 .spec.clusterIP 中指定 "None" 来创建“无头”服务。

我对“有状态 vs 无状态”应用/组件的看法

  1. UI 属于无状态应用/组件,因为它不维护任何数据,但从 DB 获取并显示。

  2. DBCache(Redis)是有状态应用/组件,因为它们必须维护数据。

我的问题。

  1. Persistence storage in Apps - 为什么我要考虑将PostgreSQL(例如)部署为StatefulSet?我可以在Deployement中定义PV和PVC,以将数据存储在PV中。即使Pod重启,它也将获取其PV,因此不会丢失数据。

  2. Network - Redis(例如)应该部署为StatefulSet,这样我们每次重启Pod后都可以获得唯一的“网​​络ID”/名称。例如:Redis-0Redis-1都在StatefulSet中,我可以将Redis-0定义为master,所以主name永远不会改变。现在,为什么应该为StatefulSet应用程序考虑使用Headless Service?我可以直接访问/连接POD本身,对吗?Headless Service有什么用处?

  3. 我听说过Operators,这是管理StatefulSet应用程序的最佳方法。下面是一些示例。为什么这些(或其他一些)重要的部署为StatefulSet。例如,PrometheusElasticSearch;我可以定义PVs和PVCs以存储数据而不会失去。

为什么/何时应关注使用StatefulSetHeadless Serivice

1个回答

16
在回答你的问题之前,我必须添加免责声明:有不同的方式来完成同样的任务。由于我们正在讨论StatefulSets,需要注意的是,并非所有方法都适用于所有有状态的应用程序。如果您需要一个单独的数据库pod和单个PV,则可以采用一种方法;如果您的api pod需要一些共享和一些分离的PV,则可以采用另一种方法,依此类推。
持久化存储在应用中-为什么要考虑将postgress(例如)部署为StatefulSet?我可以在Deployement中定义PV和PVC来存储PV中的数据。
如果所有的pod都使用相同的持久卷声明跨所有副本(且供应商允许),则这是正确的。如果您尝试根据Deployment增加副本数,则所有pod都将使用完全相同的PVC。另一方面,在api documentation中定义的StatefulSet具有volumeClaimTemplates,允许每个副本拥有自己生成的PVC,为副本集中的每个pod分别提供已分配的PV。
现在,为什么要考虑Headless Service用于StatefulSet应用程序呢?
因为易于发现。再次强调,您不需要知道在无头服务中有多少副本,检查服务DNS即可获取所有副本(警告-那些此刻正在运行的副本)。您可以手动完成此操作,但在这种情况下,您依赖于不同的副本计数/监视机制(例如,副本会自行注册到主服务器)。这里有一个很好的使用nslookup进行Pod发现的示例,可以解释为什么无头服务可能是个好主意。
为什么这些(或其他一些)重要部署为StatefulSet?
据我了解,列出的大多数运营商都是使用Deployment自己部署的。但是它们确实处理StatefulSets,因此让我们以ElasticSearch为例。如果它没有作为StatefulSet部署,您将最终得到两个指向相同PV的pod(如果提供程序允许),这将严重破坏事情。使用StatefulSet,每个pod都从模板获取其自己的持久卷索赔,并因此与同一StatefulSet中其他ElasticSearch pod分开。这只是冰山一角,因为ElasticSearch的设置/处理更加复杂,运营商有所帮助。
为什么/何时应关注StatefulSet和无头服务?
  • Stateful set you should use in any case where replicated pods need to have separate PV from each other (created from PVC template, and automatically provisioned).

  • Headless Service you should use in any case where you want to automatically discover all pods under the service as opposed to regular Service where you get ClusterIP instead. As an illustration from above mentioned example here is difference between DNS entries for Service (with ClusterIP) and Headless Service (without ClusterIP):

    • Standard service - you will get the clusterIP value:

      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 service - you will get the IP of each Pod:

      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
      

1
一个常规服务也知道它所属的所有Pod和它们的IP,那么为什么不使用与无头服务相同的机制呢? - user1870400

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接