StatefulSet介绍
从1.9 GA版本开始,StatefulSet成为kubernetes的稳定特性。StatefulSet是一种副本控制器,管理pod的部署、缩放等。与ReplicaSet、Deployment不同的是,它对集合中的pod提供顺序、唯一性保证。StatefulSet为集合中的每个pod分配唯一、持久的pod名称、DNS解析、持久化存储,并且负责将这些标识粘在pod上,无论pod调度到任何节点上。
什么时候需要使用StatefulSet
当应用的需求,与下述中的一条或者多条相符时,使用StatefulSet就会有价值:
-
唯一、稳定的网络标识(pod原本没有网络标识,service有)。
-
稳定、持久化存储。
-
多个副本有序、优雅的部署与缩放。
-
多个副本有序、优雅的部署与缩放。
-
多个副本有序、优雅的自动滚动升级。
StatefulSe限制
-
StatefulSet特性,1.5之前的版本不可用,1.9之前的版本不稳定。
-
必需为pod提供持久化存储。
-
删除或者缩容StatefulSet时,出于数据安全的目的,不会自动删除与pod相关的持久化存储,需要手动处理。
-
当前StatefulSet需要通过无头服务为其所管理的pod提供网络标识,或者说DNS条目,用户需手动创建无头服务。
唯一、稳定pod名称
StatefulSet中的pod名称由StatefulSet配置中的name加上表示序号的整数,整数从0开始取值,最大值为副本数量减1.
唯一、稳定网络ID
StatefulSet通过与其相关的无头服务为每个pod提供DNS解析条目。假如无头服务的DNS条目为:
"$(service name).$(namespace).svc.cluster.local",
那么pod的解析条目就是"$(pod name).$(service name).$(namespace).svc.cluster.local",每个pod name也是唯一的。
稳定持久存储
通过
PersistentVolume
提供持久化存储。
创建StatefulSet
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
上述文件包含两个对象,前边名为nginx的service,其clusterIP为None,所以它是无头服务。下边为名web的StatefulSet,其.spec.serviceName的值为nginx,指明通过上边的nginx无头服务提供DNS解析功能功。.spec.volumeClaimTemplates表示持久化存储。将以上内容保存在web.yaml文件中。
执行创建命令:
kubectl create -f web.yaml
service "nginx" created
statefulset "web" created
确认结果:
kubectl get service nginx
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx None <none> 80/TCP 12s
kubectl get statefulset web
NAME DESIRED CURRENT AGE
web 2 1 20s
如果从另一个终端监控StatefulSet创建过程,会看到如下内容:
kubectl get pods -w -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 0/1 Pending 0 0s
web-0 0/1 Pending 0 0s
web-0 0/1 ContainerCreating 0 0s
web-0 1/1 Running 0 19s
web-1 0/1 Pending 0 0s
web-1 0/1 Pending 0 0s
web-1 0/1 ContainerCreating 0 0s
web-1 1/1 Running 0 18s
两个pod,web-0与web-1按序创建,web-0必须先创建并且处于就绪状态后才可以创建web-1。
创建完成后,执行如下命令确认pod名称:
kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 1m
web-1 1/1 Running 0 1m
运行如下命令检查pod的名称在集群内是否可以解析:
kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh
nslookup web-0.nginx
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-0.nginx
Address 1: 10.244.1.6
nslookup web-1.nginx
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-1.nginx
Address 1: 10.244.2.6
测试pod名称、DNS解析条目的粘性。先将pod删除,然后StatefulSet自动恢复缺失副本,再对比新pod与已删除pod的标识是否一致。
kubectl delete pod -l app=nginx
pod "web-0" deleted
pod "web-1" deleted
在另一个终端中监控StatefulSet自动恢复过程:
kubectl get pod -w -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 0/1 ContainerCreating 0 0s
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 2s
web-1 0/1 Pending 0 0s
web-1 0/1 Pending 0 0s
web-1 0/1 ContainerCreating 0 0s
web-1 1/1 Running 0 34s
运行如下命令:
for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done
web-0
web-1
kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh
nslookup web-0.nginx
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-0.nginx
Address 1: 10.244.1.7
nslookup web-1.nginx
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-1.nginx
Address 1: 10.244.2.8
可以看到新pod的名称、主机名称、DNS解析条目都没有变,这些标识被粘在新pod上。但是pod的IP地址变了,所以当在集群中访问pod时,不要直接通过不稳定的IP。
运行如下命令查看持久化存储:
kubectl get pvc -l app=nginx
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
www-web-0 Bound pvc-15c268c7-b507-11e6-932f-42010a800002 1Gi RWO 48s
www-web-1 Bound pvc-15c79307-b507-11e6-932f-42010a800002 1Gi RWO 48s
首先需要配置好集群内的持久化存储功能,以上几个volume在创建 StatefulSet时自动创建、命名、绑定到pod。默认情况下nginx的"/usr/share/nginx/html/index.html"位于以上的持久存储中。运行如下代码修改index.html文件:
for i in 0 1; do kubectl exec web-$i -- sh -c 'echo $(hostname) > /usr/share/nginx/html/index.html'; done
for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done
web-0
web-1
再一次删除pod,确认持久存储是否生效,在旧pod中写入index.html的内容是否被保留到新pod中。删除、监控过程不表,直接确认结果:
for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done
web-0
web-1
结果证明文件内容没有丢失。
StatefulSet的扩容、缩容、滚动升级、删除操作与Deployment、ReplicaSet相似,不同之处是StatefulSet保证pod被按顺序操作。
参考:
https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/
StatefulSet介绍从1.9 GA版本开始,StatefulSet成为kubernetes的稳定特性。StatefulSet是一种副本控制器,管理pod的部署、缩放等。与ReplicaSet、Deployment不同的是,它对集合中的pod提供顺序、唯一性保证。StatefulSet为集合中的每个pod分配唯一、持久的pod名称、DNS解析、持久化存储,并且负责将这些标识粘在pod上,无...
文章目录一:
k8s
的五种控制器1.1:
k8s
的控制器类型1.2:Deployment控制器1.2.1:测试deployment控制器1.3:Satef
ulSe
t控制器1.3.1:创建无头服务的service资源和dns资源1.3.2:创建
state
f
ulse
t资源1.4:DaemonSet控制器1.4.1:测试1.5:job控制器1.5.1:测试1.6:cronjob控制器1.6.1:测试如有疑问可评论区交流!
一:
k8s
的五种控制器
1.1:
k8s
的控制器类型
Kubernetes
中内建了很多contr
State
f
ulSe
t(一)
Deployment 假设了一个应用的所有Pod都是一样的,他们之间没有顺序。但在实际场景中,多个实例之间通常会存在依赖关系,例如分布式应用中存在主从、主备关系;数据存储类应用,它的多个实例,往往都会在本地磁盘上保存一份数据。而这些实例一旦被杀掉,即便重建出来,实例与数据之间的对应关系也已经丢失,从而导致应用失败。
当实例之间有不对等关系时,以及实例对外部数据有依赖关系时,被称为“有
状态
应用”(
State
ful Application)
State
f
ulSe
t将应用
大家可能已知道,
所谓无
状态
:“每一次请求都不依赖历史数据,也无数据持久化需求,扩容简单,即扩即用”。 说人话就是“只是个传声筒,左耳进右耳出,不往脑子里去。 就算复制N个传声筒,其工作内容也是完全一致的”。
所谓有
状态
:“依赖历史数据,且具有数据持久化需求,扩容后续工作复杂”。 数据库为有
状态
的典型,若复制出N个数据库,就涉及master/slave角色分担,底层数据同步的工作。
那么在
k8s
中,在2种工作负载的调度有何异同?
均以con
State
f
ulSe
t
前几篇讲解的都是关于无
状态
的应用, 今天这篇介绍
Kubernetes
中的另一种应用, 有
状态
应用, 而 有
状态
的应用是由
State
f
ulSe
t 来进行管理部署 , **
State
f
ulSe
t 也是
kubernetes
中的一种资源类型, 作用类似于无
状态
应用的 Deployment **.
操作的基础
最近的文章都是基于 minikube 进行.
文章目录
State
f
ulSe
t使用场景限制创建
State
f
ulSe
tPod标识稳定的网络标识稳定的持久化存储有序的部署和扩缩更新策略
State
f
ulSe
t
Deployment是面向无
状态
的服务,它们所管理的Pod的IP、名字,启停顺序等都是随机的。
但是在部署像MySQL、MongoDB这类的集群时,Deployment明显就有些不合适了。因此
kubernetes
提供了Seatef
ulSe
t,它是Deployment的一种变体,在v1.9版本中已成为GA版本,它为了解决有
状态
服务的问题,它所管理的Pod
podApi对象概览
apiVersion + kind 一个是版本 一个是资源组 共同确定当前yaml由谁来管理
metadata元数据 用来唯一标识 该资源 在
k8s
中一个对象 是通过标签选择另外一个对象的
spec 标示容器期望的
状态
status
状态
只读的
RC、Deployment、DaemonSet都是面向无
状态
的服务,它们所管理的Pod的IP、名字,启停顺序等都是随机的,而
State
f
ulSe
t是什么?顾名思义,有
状态
的
集合
,管理所有有
状态
的服务,比如MySQL、MongoDB集群等。
State
f
ulSe
t本质上是Deployment的一种变体,在v1.9版本中已成为GA版本,它为了解决有
状态
服务的问题,它所管理的Pod拥有固定的Pod名称,启停顺序,在
State
f
ulSe
t中,Pod名字称为网络标识
在
Kubernetes
的世界中,ReplicaSet和Deployment主要用于处理无
状态
的服务,无
状态
服务的需求往往非常简单并且轻量,每一个无
状态
节点存储的数据在重启之后就会被删除,虽然这种服务虽然常见,但是我们仍然需要有
状态
的服务来实现一些特殊的需求,
State
f
ulSe
t 就是
Kubernetes
为了运行有
状态
服务引入的资源,例如 Zookeeper、Kafka 等。
这篇文章会介绍
Kubernetes
如何在集群中运行有
状态
服务,同时会分析这些有
状态
服务
State
f
ulSe
t ...