StatefulSet:
在1.3以前K8s中StatefulSet叫PetSet(宠物集),由此也可看出StatefulSet是关注个体,而非群体。
StatefulSet要满足以下几点:

  • 稳定且唯一的网络标识符;
  • 如: Redis集群, 在Redis集群中,它是通过槽位来存储数据的,假如:第一个节点是0~1000,第二个节点是1001~2000,第三个节点2001~3000...等等,这就使得Redis集群中每个节点要通过ID来标识自己,如: 第二个节点宕机了,重建后它必须还叫第二个节点,或者说第二个节点叫R2,它必须还叫R2,这样在获取1001~2000槽位的数据时,才能找到数据,否则Redis集群将无法找到这段数据。
  • 稳定且持久的存储
  • 有序、平滑的部署和扩展;如 MySQL集群,要先启动主节点, 若从节点没有要求,则可一起启动,若从节点有启动顺序要求,可先启动第一个从节点,接着第二从节点等;这个过程就是有顺序,平滑安全的启动。
  • 有序、平滑的终止和删除;即: 我们先终止从节点,若从节点是有启动顺序的,那么关闭时,也要按照逆序终止,即启动时是从S1~S4以此启动,则关闭时,则是先关闭S4,然后时S3,依次关闭,最后在关闭主节点。
  • 有序的滚动更新;如: MySQL在更新时,应该先更新从节点,全部的从节点都更新完了,最后在更新主节点,因为新版本一般可兼容老版本,但是一定要注意,若新版本不兼容老版本就很很麻烦!
创建一个StatefulSet控制器的示例:
vim pod-statefulset.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
labels:
app: myapp
spec:
ports:
- port:
name: web
clusterIP: None
selector:
app: myapp-pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: myapp
spec:
serviceName: myapp
replicas:
selector:
matchLabels:
app: myapp-pod
template:
metadata:
labels:
app: myapp-pod
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- containerPort:
name: web
volumeMounts:
- name: myappdata
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
#注意: 它是statefulset.spec.volumeClaimTemplates.
- metadata:
name: myappdata
spec:
accessModes: ["ReadWriteOnce"]
#storageClassName: “gluster-dynamic” #这是定义存储类的。
resources:
requests:
storage: 2Gi

#实验中问题总结:
accessModes: [ “ReadWriteOnce” ]
  #这里需要注意: 你指定模式为RWO,那么你使用kubectl get pv时,必须有RWO权限的pv,因为本例是要创建3个StatefulSet的Pod,因此就需要3个RWO权限的pv,但我测试时,就只有一个pv是RWO的,因此导致创建Pod一直处于Pending状态,而且只有一个! 使用kubectl describe pvc PVC_NAME 查看时提示: no persistent volumes available for this claim and no storage class is set(此声明没有可用持久卷,也没有存储类),其实问题已经说的很白了,但没有经验,所以这点要特别注意!!
  #第二个问题: 我后来新增了3个RWO权限的pv,但在NFS上,忘记创建对应的目录了,使用exportfs -avr 也提示了,目录没有找到,但我没仔细看,结果导致我创建Pod时,一直处于ContainerCreating,查看kubectl describe pod myapp-0 看到mount.nfs: mounting 192.168.111.83:/data/volumes/v6 failed, reason given by server: No such file or directory 这样的错误,最后才想到可能是目录没有创建。
  #第三个问题:我在创建PV时,使用的是k8s集群外部的域名nfs.zcf.com 来指定NFS Server是谁,但我K8s集群内还不能解析集群外域名,也导致了访问超时的问题。
  #第四个问题:创建serive时总提示ClusterIP是无效值:
  解决步骤:
    1. 检查配置清单中clusterIP是否有写错.
    2. 检查是否有service同名冲突:
      kubectl get svc

#创建statefulset:
#执行创建statefulSet前,需要先手动创建出符合条件的PV,若你已经实现了动态供给存储卷,
#则可不用手动事先创建好PV。
  kubectl apply -f pod-statefulset.yaml

#查看:
  kubectl get svc
  kubectl get [statefulset |sts]
  kubectl get pvc    #volumeClaimTemplates可动态创建Pod内部的PVC,然后再创建名称空间级的PVC
注:
    Pod内容器挂载PV的过程 或 层级是这样的:
  容器要挂载网络磁盘---->Pod中要有对应的PVC---->Pod所在的名称空间中要有对于的PVC----->
  K8s集群中要有对应的PV---->要有输出共享存储的后端服务器上的共享空间
  而volumeClaimTemplates它可自动创建Pod 和 名称空间中的PVC。
  kubectl get pv
  kubectl get pods

  

终端2:
kubectl get pods -w 终端1:
kubectl delete -f pod-statefulset.yaml #删除后,查看终端2上,删除Pod的顺序是否为先删除2,,
#在k8s 1.13.5中测试时,发现:
# 删除时,似乎没有顺序:
kubect get pod -w -l app=myapp-pod
myapp- / Terminating 31s
myapp- / Terminating 34s
myapp- / Terminating 28s
myapp- / Terminating 33s
myapp- / Terminating 31s
myapp- / Terminating 37s
myapp- / Terminating 41s
myapp- / Terminating 41s
myapp- / Terminating 47s
myapp- / Terminating 47s
myapp- / Terminating 41s
myapp- / Terminating 41s 终端1:
kubectl apply -f pod-statefulset.yaml #查看创建Pod的过程是否为先0,,
#此测试是正常的:
myapp- / Pending 0s
myapp- / Pending 0s
myapp- / ContainerCreating 0s
myapp- / Running 3s
myapp- / Pending 0s
myapp- / Pending 0s
myapp- / ContainerCreating 0s
myapp- / Running 3s
myapp- / Pending 0s
myapp- / Pending 0s
myapp- / ContainerCreating 0s
myapp- / Running 2s kubectl describe pods myapp- #查看myapp-2是否依然绑定PV-,而且当你删除pod后,kubectl get pv,也会发现,Retain策略是不会释放绑定关系的. #statefulSet的域名结构为:
pod_name.service_name.namespace_name.svc.cluster.local
如:
上例中创建了三个Pod,其中一个叫myapp-
myapp-.myapp.default.svc.cluster.local #对statefulSet做扩缩容:
#扩容:
kubectl scale sts myapp --replicas=
#注意:
# 在定义StatefulSet时,Pod的模板中指定自动创建pvc,并关联可用PV时,选择可用大小为1Gi,我期望时,它自动关联时,选择最匹配的,但事实似乎并非如此。
# 查看
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv01 1Gi RWO,RWX Retain Available 87m
pv02 2Gi ROX,RWX Retain Bound default/myappdata-myapp- 87m
pv03 5Gi ROX,RWX Retain Bound default/myappdata-myapp- 87m #明明有一个1Gi的,它没有选择,而是选择了5Gi的
pv04 10Gi ROX,RWX Retain Available 87m
pv05 20Gi ROX,RWX Retain Available 87m
pv06 1Gi ROX,RWX Retain Bound default/myappdata-myapp- 87m
pv07 1Gi ROX,RWX Retain Bound default/myappdata-myapp- 87m
pv08 2Gi ROX,RWX Retain Bound default/myappdata-myapp- 87m 终端2:
kubectl get pods -w #当执行扩容Pod后, 会看到先创建myapp-,然后是myapp- #缩容:
kubectl patch sts myapp -p ‘{"spec":{"replicas":}}’ 终端2:
kubectl get pods -w #依然查看其缩容的过程,在缩容时,竟然是按顺序的,,,
myapp- / Terminating 5m41s
myapp- / Terminating 5m43s
myapp- / Terminating 5m53s
myapp- / Terminating 5m53s
myapp- / Terminating 5m56s
myapp- / Terminating 5m57s
myapp- / Terminating 5m58s
myapp- / Terminating 5m58s
myapp- / Terminating 8m41s
myapp- / Terminating 8m43s
myapp- / Terminating 8m49s

#statefulSet的更新策略:
  kubectl explain sts.spec.updateStrategy.rollingUpdate
    partition: 这种更新策略的含义是, 若当前statefulSet的副本数为5个,则Pod名为pod-0~pod-4,那么此时
      定义partition=4, 就意味着我要更新大于等于4的Pod,而只有pod-4的ID 4 是大于等于4的,所以
      只有pod-4会被更新,其它不会,这就是金丝雀更新。若后期发现pod-4更新后,工作一切正常,
      那么就可以调整partition=0,这样只要大于等于0的pod ID都将被更新。

#修改滚动更新策略,查看效果
  kubectl patch sts myapp -p ‘{"spec":{"updateStrategy":{"rollingUpdate":{"partition":4}}}}’
     #注:
        在打补丁时,若对象为list类型,则需要使用"[]",来指明其下标,如: containers[0],就是第一个容器.

kubectl  describe  sts  myapp      #查看其滚动更新策略中partition的值是否修改为4了。
#在k8s 1.13.5中查看如下:
.......
Replicas: desired | total
Update Strategy: RollingUpdate
Partition:
.......
#但通过kubectl get sts myapp -o yaml 查看,就可以看到,已经修改为4了。
.........
updateStrategy:
rollingUpdate:
partition:
type: RollingUpdate
.......

#以上statefulSet的更新策略已经修改好了,接着来修改pod的镜像为新版镜像,来查看其滚动更新的
  kubectl set image sts/myapp myapp=ikubernetes/myapp:v2

#查看:
  kubectl get sts -o wide    #查看statefulSet控制器层面的容器镜像是否修改成功了。

  kubectl get pods myapp-4 -o yaml    #查看statefulSet控制器下myapp-4这个容器的state(当前运行状态信息)中image是否修改成功了.
  kubectl get pods myapp-3 -o yaml    #查看其image应该是没有改变的

终端2:
  kubectl get pods -w    #当修改更新策略后,这里将可以看到滚动更新的效果了。

终端1:
  kubectl patch sts myapp -p ‘{"spec":{"updateStrategy":{"rollingUpdate":{"partition":0}}}}’
  #由于上面已经跟新了镜像,当这里修改了更新策略后,马上就会触发滚动更新!! 需要注意!!
  注意:
    statefulSet在实际使用中还是需要谨慎!

附上一张PVC和PV的关系图:

  

另外,最好的学习平台是githup,它上面有很多别人做好的清单文件,可作为学习的参考。

K8s StatfulSet使用总结的更多相关文章

  1. 虚拟化原理到K8s实践经验路线总结

    以下这些内容均为自行学习总结的内容,很多内容没有写概括介绍,看起来可能会有些突兀,但并不影响整体性,我自己的学习经验告诉我,这些内容还仅仅是最精简的核心部分,周边还有很多可扩展内容,主要是操作系统生态 ...

  2. [k8s]k8s-ceph-statefulsets-storageclass-nfs 有状态应用布署实践

    k8s stateful sets storageclass 有状态应用布署实践v2 Copyright 2017-05-22 xiaogang(172826370@qq.com) 参考 由于网上的文 ...

  3. k8s控制器资源(五)

    Pod pod在之前说过,pod是kubernetes集群中是最小的调度单元,pod中可以运行多个容器,而node又可以包含多个pod,关系如下图: 在对pod的用法进行说明之前,有必要先对docke ...

  4. 【Kubernetes】K8S网络方案--最近在看的

    K8S网络-最近在看的 Create a Minikube cluster - Kubernetes Kubernetes Documentation - Kubernetes Kubernetes ...

  5. 【Kubernetes】K8S 网络隔离 方案

    参考资料: K8S-网络隔离参考 OpenContrail is an open source network virtualization platform for the cloud. – Kub ...

  6. k8s入门系列之guestbook快速部署

    k8s集群以及一些扩展插件已经安装完毕,本篇文章介绍一下如何在k8s集群上快速部署guestbook应用. •实验环境为集群:master(1)+node(4),详细内容参考<k8s入门系列之集 ...

  7. k8s volume

        只有nfs和rbd的,本人翻译确实很渣         在容器中磁盘文件寿命是短暂的,当在容器中运行一些重要程序时,这会产生一些问题. 首先,当一个容器崩溃后,kubelet将重新启动该容器, ...

  8. k8s pv

    这个文档描述当前在k8s中PersistentVolumes的使用. 我们建议和volume一起进行了解   Introduction     管理存储和管理计算是截然不同的问题. 持久存储子系统对用 ...

  9. k8s DNS 服务发现的一个坑

    按照官当文档,以及大家的实践进行k8s dns 服务发现搭建还是比较简单的,但是会有一个因为系统默认dns 配置造成的一个问题 1. linux  默认dns 配置在 /etc/resolv.conf ...

随机推荐

  1. Portainer容器可视化管理工具使用文档

    本文内容 主要介绍下Portainer的Docker使用方式,基于当前最新版v1.22.1,使用Docker的本地部署,并连接另一台服务器进行测试,更多请参考官网https://www.portain ...

  2. Problem 1059 老师的苦恼

    Bob写文章时喜欢将英文字母的大小写混用,例如Computer Science经常被他写成coMpUtEr scIeNce,这让他的英文老师十分苦恼,现在请你帮Bob的英文老师写一个程序能够将Bob的 ...

  3. 【04】Jenkins:基本功能补充说明

    写在前面的话 在 Jenkins 中有那么一些功能,可能你几乎不会怎么用到,但是某些时候又能够帮助你解决一些很麻烦的事情.我这里单独的把这些小配置抽离出来作为一个单独章节.很多配置不需要记得,但是要知 ...

  4. 官方elasticsearch-certutiledit命令

    地址:https://www.elastic.co/guide/en/elasticsearch/reference/7.5/certutil.html 语法: bin/elasticsearch-c ...

  5. C#操作XML文档

    Note: '=> ' 表示返回值 参考资料:请点击这里! 1:创建Xml文档 2:写Xml文档(必须保证有根元素) XmlDocument Xd (实例化一个对象) CreateXmlDecl ...

  6. java虚拟机JVM基础

    (1)内存模型以及分区,需要详细到每个区放什么. 堆:Java虚拟机管理内存中最大的一块,线程共享区域.所有对象实例和数组都在堆上分配内存空间. 栈:线程私有,每个线程都会创建一个虚拟机栈,生命周期与 ...

  7. 搜索引擎elasticsearch监控利器cat命令

    目录 一.Cat通用参数 二.cat命令 三.示例 查询aurajike索引下的总文档数和有效文档数 查询aurajike各分片的调度情况 一.Cat通用参数 参数名 指令示例 功能 Verbose ...

  8. v-on 事件触发

    1.v-on 绑定事件 2.methods: 事件绑定语法. 3.v-on:click 可以简写成@click 但是在mvc中会有问题 <!DOCTYPE html> <html&g ...

  9. CentOS 7.0 使用yum 安装 Mariadb

    第一步: 使用命令查看是否已经安装: mysql -u root -p 返回 Enter password:  时表示已经安装成功的,需要卸载安装. 第二步: 使用yum直接安装mariadb,注意带 ...

  10. 01. JavaScript基础总结深入

    01. 数据类型 1. 分类(2大类) * 基本(值)类型 * Number: 任意数值 * String: 任意文本 * Boolean: true/false * undefined: undef ...