简介
StatefulSet是为了解决有状态服务的问题设置的之中资源(Deployment,RepliacSet是为无状态服务设计的)
但是这里可能有能说mysql是有状态服务吧,但是我使用的资源是deployment类型,mysql的data数据通过pv的凡事存储第三方文件系统中,能解决mysql数据存储的问题。
是的,如果你的mysql是单节点使用deployment类型确实可以解决数据存储问题但是如果你的有状态服务是集群,节点之间有主备或者主从之分,但是每个节点分片存储的情况下deployment则不适合这种场景,因为deployment不是在保证pod的有序性,集群通常需要主节点先启动,从节点咋加入集群,StatefulSet则可以保证,其次deployment资源的pod内的pvc是共享存储的。而statefulset下的pod内的pvc不是共享存储的,每个pod拥有独立的存储空间,可以满足分片存储需求,实现分片存储的需求的前提是statefulset可以保证pod重新调度后哈时候能访问到相同的持久化数据
一般使用与statefulset的常用服务:redis es mogodb 这些集群
statefulset适用场景
稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
有序收缩,有序删除(即从N-1到0)
statefulset由以下几部分组成:
用于定义网络标志(DNS domain)的Headless Service
用于创建PersistentVolumes的volumeClaimTemplates
定义具体应用的StatefulSet
创建StatefullSet
创建statefulset需要自己准备好创建的pv
[root@k8s-master ~]# cat statefulset.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
labels:
app: myapp
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: myapp
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "myapp"
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/myapp/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 2Gi
查看sts
[root@k8s-master ~]# kubectl get sts
NAME READY AGE
web 3/3 5m26s
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 5m38s
web-1 1/1 Running 0 5m34s
web-2 1/1 Running 0 5m32s
[root@k8s-master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-web-0 Bound pv002 2Gi RWO,RWX 5m49s
www-web-1 Bound pv001 2Gi RWO,RWX 5m45s
www-web-2 Bound pv004 2Gi RWO,RWX 5m43s
[root@k8s-master ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv001 2Gi RWO,RWX Retain Bound default/www-web-1 5m59s
pv002 2Gi RWO,RWX Retain Bound default/www-web-0 5m59s
pv003 10Gi RWO,RWX Retain Available 5m59s
pv004 2Gi RWO,RWX Retain Bound default/www-web-2 5m59s
pv005 20Gi RWO,RWX Retain Available 5m59s
扩容
[root@k8s-master ~]# kubectl scale statefulset web --replicas=5
查看
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 10m
web-1 1/1 Running 0 10m
web-2 1/1 Running 0 10m
web-3 1/1 Running 0 11s
web-4 1/1 Running 0 7s
[root@k8s-master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-web-0 Bound pv002 2Gi RWO,RWX 12m
www-web-1 Bound pv001 2Gi RWO,RWX 12m
www-web-2 Bound pv004 2Gi RWO,RWX 12m
www-web-3 Bound pv003 10Gi RWO,RWX 99s
www-web-4 Bound pv005 20Gi RWO,RWX 95s
缩容
[root@k8s-master ~]# kubectl patch sts web -p '{"spec":{"replicas": 2}}'
statefulset.apps/web patched
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 30m
web-1 1/1 Running 0 30m
更新策略
Kubernetes 1.7 版本的 StatefulSet 控制器支持自动更新。更新策略由 StatefulSet API Object 的spec.updateStrategy 字段决定。这个特性能够用来更新一个 StatefulSet 中的 Pod 的 container images,resource requests,以及 limits,labels 和 annotations。RollingUpdate滚动更新是 StatefulSets 默认策略。
使用RollingUpdate中的partition进行分段更新
你可以使用 RollingUpdate 更新策略的 partition 参数来分段更新一个 StatefulSet
分段的更新将会使 StatefulSet 中的其余所有 Pod 保持当前版本的同时仅允许改变 StatefulSet 的 .spec.template
默认partition是0
[root@k8s-master ~]# kubectl patch sts web -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":4}}}}'
statefulset.apps/web patched
使用set image 修改镜像也可以使用patch
[root@k8s-master ~]# kubectl set image sts/web myapp=ikubernetes/myapp:v2
statefulset.apps/web image updated
查看镜像版本
#控制器层
[root@k8s-master ~]# kubectl get sts -o wide
NAME READY AGE CONTAINERS IMAGES
web 5/5 93m myapp ikubernetes/myapp:v2
#pod层
[root@k8s-master ~]# kubectl get pods web-4 -oyaml|grep image
f:image: {}
f:imagePullPolicy: {}
- image: ikubernetes/myapp:v2
imagePullPolicy: IfNotPresent
image: ikubernetes/myapp:v2
imageID: docker-pullable://ikubernetes/myapp@sha256:85a2b81a62f09a414ea33b74fb8aa686ed9b168294b26b4c819df0be0712d358
#最后一个pod的镜像版本已经升级
#前面的pod都还升级
[root@k8s-master ~]# kubectl get pods web-3 -oyaml|grep image
f:image: {}
f:imagePullPolicy: {}
- image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
image: ikubernetes/myapp:v1
imageID: docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513
升级余下的pod,只需要把刚刚的partition字段改回即可
[root@k8s-master ~]# kubectl patch sts web -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":0}}}}'
查看所有pod的镜像版本
[root@k8s-master ~]# for p in 0 1 2 3 4; do kubectl get po web-$p --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
ikubernetes/myapp:v2
ikubernetes/myapp:v2
ikubernetes/myapp:v2
ikubernetes/myapp:v2
ikubernetes/myapp:v2
使用RollingUpdate策略更新
默认statefulset就是RollingUpdate策略
[root@k8s-master ~]# kubectl set image sts web myapp=ikubernetes/myapp:v2
statefulset.apps/web image updated
[root@k8s-master ~]# kubectl get sts -o wide
NAME READY AGE CONTAINERS IMAGES
web 5/5 117m myapp ikubernetes/myapp:v2
查看镜像版本
[root@k8s-master ~]# for p in 0 1 2 3 4; do kubectl get po web-$p --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
ikubernetes/myapp:v2
ikubernetes/myapp:v2
ikubernetes/myapp:v2
ikubernetes/myapp:v2
ikubernetes/myapp:v2
网友评论