1. Headless Service 简述
什么是Service?
Service是kubernetes最核心的概念,通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求进行负载分发到后端的各个容器应用上。
什么是Headless Service?
需要Service不做负载均衡,并且不在意cluster ip。
什么是StatefuleSets?
目前容器里跑的服务有两类,无状态和有状态。无状态服务异常后,可以直接删掉并新建一个,管理起来非常简单。但是对于有状态服务,它要求有更长的生命周期,并且要保持网络、存储的稳定性。在一个集群的情况下,集群成员之间如何能保持稳定的成员关系?这都对容器编排系统提出了新的挑战。
有状态pod特性:
而StatefulSets的目的就是给为数众多的有状态服务提供正确的控制器支持,给有状态Pod提供唯一标志的控制器,可以保证有状态pod集群的部署和扩展
使用StatefulSets的时机
不一定所有的有存储应用都是适合移植到 Kubernetes 上的,在移植存储层和编排框架之前,需要考虑以下几个问题,然后再这几个问题的基础上考虑采用ReplicaSets还是Statefulsets:
3. kubernetes 1.6 版本 StatefulSets 特性
创建副本
StatefulSets按顺序创建副本。例如,StatefulSets创建一个3副本的有状态服务,statefulset描述文件中replicas为 3,如下所示:
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 10
containers:
- name: test
image: gcr.io/google_containers/nginx-slim:0.8
ports:
- containerPort: 80
name: test
volumeMounts:
- name: disk
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: disk
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: my-storage-class
resources:
requests:
storage: 1Gi
创建步骤如下:
1) 先创建pod-0,等pod-0状态为Running and Ready 后,再创建pod-1;
2) 等pod-1 状态为Running and Ready 后,再创建pod-2;
3) 若pod-0创建失败,则创建pod-1,等pod-1状态为Running and Ready后,再重试创建pod-0(而不是创建pod-2);
4)等pod-0重新创建成功,再创建pod-2
删除副本
StatefulSets按倒序删除pod(或者缩容,replicas 变为 1)。例如,StatefulSets删除pod-0、pod-1、pod-2 3副本的有状态服务,步骤如下:
1) 先删除pod-2,等pod-2 完全关机并彻底删除后,再开始删除pod-1;
2) 如果删除pod-2后,发现pod-0状态不健康,则先不删除pod-1,等pod-0重新变成Running and Ready 后,再开始删除pod-1
总之,statefulsets总是按顺序部署服务。
4. kubernetes 1.7 版本 StatefulSets 新增特性
在1.6版本中,StatefulSets只有当前序Pod都运行起来才能创建后面的Pod。虽然一个Pod挂掉不会死锁,但如果是Unhealthy状态会卡住这个过程。尤其是,如果pod-0和pod-4都挂了,当前的实现会试着重启pod-0,而pod-4只有pod-0起来后才能启动。这样的表现很安全,但是对于另外一些有状态应用,不需要考虑已经部署的Pod的顺序,那么上面的规则会带来一些约束,造成不必要的不可用现象。所以需要指定一个注解(annotation)来与StatefulSetController进行通信,让它可以同时处理多个Pod。
在1.7版本中,StatefulSets可以通过定义spec.podManagementPolicy来实现并行控制pod的创建和删除,不用再等待前序pods已部署。(不设置则默认顺序部署)
1.7版本中,还可以通过定义spec.updateStrategy来开启或者禁用自动更新statefulset集群中pod资源对象的配置项,例如 containers,labels,resoruce request/limits,annotations等。
1.7版本中,增加了spec.updateStrategy字段,若定义该字段为OnDelete,则StatefulSet控制器将不会再去自动更新StatefulSet集群中的pod,用户需手动删除非健康状态的pod,如此StatefulSet控制器才能重新部署该pod。
1.7版本中的RollingUpdate更新策略实现了StatefulSet中pods的自动滚动更新。 StatefulSet的.spec.updateStrategy.type设置为RollingUpdate时,StatefulSet控制器将在StatefulSet中删除并重新创建每个Pod。 它将按照Pod终止(从最大序数到最小)的顺序进行,每次更新一个Pod,并且要等待更新的Pod正在运行和就绪后,才能更新后续pod。也可以通过指定spec.updateStrategy.rollingUpdate.partition来对RollingUpdate更新策略进行分区。 如果指定了分区,则当StatefulSet的spec.template更新时,具有大于或等于分区的序数的所有Pod将被更新。具有小于分区的序数的所有Pods将不会更新,即使删除它们也将在以前的版本中重新创建,而不是在更新后的版本中。 如果StatefulSet的spec.updateStrategy.rollingUpdate.partition大于其spec.replicas,则spec.template的更新将不会影响到已经创建的Pods。
本文来自网易实践者社区,经作者张文娟授权发布。