在回答你的问题之前,我必须添加免责声明:有不同的方式来完成同样的任务。由于我们正在讨论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
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
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