在回答你的一些问题之前,我必须加上免责声明:剥猫皮有不同的方法。既然我们在这里讨论有状态集,请注意并非所有方法都最适合所有有状态应用程序。如果您需要一个带有单个pv的数据库pod,那么您可以使用一种方法,如果您的api pod需要一些共享的和一些分离的pv,那么再使用另一种方法,以此类推。
应用程序中的持久性存储-为什么我应该考虑将postgres(例如)部署为statefulset?我可以在deployment中定义pvs和pvc来将数据存储在pv中。
如果所有pod在所有副本上使用相同的持久卷声明(provisioner允许这样做),则此情况成立。如果您尝试根据部署增加副本的数量,那么所有pod都将使用相同的pvc。另一方面,statefulset定义为
api documentation
有
volumeClaimTemplates
允许每个副本都有自己生成的pvc,为副本集中的每个pod分别设置pv。
现在我为什么要考虑为statefulset应用程序提供无头服务呢?
因为容易被发现。同样,您不需要知道在无头服务中有多少副本,检查服务dns您将得到所有副本(警告-在那一刻正在运行)。您可以手动执行此操作,但在这种情况下,您依赖于对副本计数/保留选项卡的不同机制(例如,副本是自注册到主副本的)。这是一个很好的例子
pod discovery with nslookup
这可以解释为什么无头是个好主意。
为什么这些(或其他)部署为statefulset很重要
据我所知,您列出的操作员都是使用部署本身部署的。不过,它们处理有状态集,所以让我们以elasticsearch为例。如果它没有被部署为statefulset,那么最终会有两个pod瞄准同一个pv(如果provisioner允许的话),这会严重扰乱事情。有了statefulset,每个pod都会得到自己的持久卷声明(来自模板),从而将持久卷与同一statefulset中的其他elasticsearch pod分离。这只是冰山一角,因为ElasticSearch在设置/处理方面更为复杂,而且运营商也在为此提供帮助。
为什么/什么时候我应该关心有状态的无头服务?
-
如果复制的pod需要有彼此独立的pv(从pvc模板创建并自动配置),则应该使用有状态集。
-
在任何情况下,如果您希望自动发现服务下的所有pod,应该使用headless服务,而不是使用clusterip的常规服务。作为上面提到的一个例子
example
以下是服务(使用clusterip)和无头服务(不使用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
-
无头服务-你将得到每个吊舱的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