当前位置: 首页 > news >正文

Kubernetes中StatefulSet介绍

StatefulSet 是Kubernetes1.9版本中稳定的特性,本文使用的环境为 Kubernetes 1.11。如何搭建环境可以参考kubeadm安装kubernetes V1.11.1 集群

0. 介绍

使用Kubernetes来调度无状态的应用非常简单,那Kubernetes如何来管理调度有状态的应用呢?Kubernetes中提供了一个StatefulSet控制器来管理有状态的应用,本文就介绍StatefulSet的应用,解决以下几个问题:

  • 如何创建StatefulSet
  • StatefulSet如何管理Pods
  • 如何删除StatefulSet
  • 如何对StatefulSet进行扩容
  • 如何更新StatefulSet中的Pods

1. StatefulSet 是什么

StatefulSet是Kubernetes提供的管理有状态应用的负载管理控制器API。在Pods管理的基础上,保证Pods的顺序和一致性。与Deployment一样,StatefulSet也是使用容器的Spec来创建Pod,与之不同StatefulSet创建的Pods在生命周期中会保持持久的标记(例如Pod Name)。

StatefulSet适用于具有以下特点的应用:

  • 具有固定的网络标记(主机名)
  • 具有持久化存储
  • 需要按顺序部署和扩展
  • 需要按顺序终止及删除
  • 需要按顺序滚动更新

2. 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: docker.io/nginx
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: ["ReadWriteOnce"]
      volumeMode: Filesystem
      resources:
        requests:
          storage: 50Mi
      storageClassName: local-storage

StatefulSet创建顺序是从0到N-1,终止顺序则是相反。如果需要对StatefulSet扩容,则之前的N个Pod必须已经存在。如果要终止一个Pod,则它的后序Pod必须全部终止。

If web-0 should fail, after web-1 is Running and Ready, but before web-2 is launched, web-2 will not be launched until web-0 is successfully relaunched and becomes Running and Ready.

在Kubernetes 1.7版本后,放松了顺序的保证策略,对应的参数为 .spec.podManagementPolicy

执行创建命令,并且观察对象是否正常创建。

[root@devops-101 ~]# kubectl create -f ss-nginx.yml 
service "nginx" created
statefulset "web" created
[root@devops-101 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   9d
nginx        ClusterIP   None         <none>        80/TCP    1d
[root@devops-101 ~]# kubectl get statefulset 
NAME      DESIRED   CURRENT   AGE
web       2         2         1d

看一下Pod是否是有顺序的

[root@devops-101 ~]# kubectl get pods -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          11m
web-1     1/1       Running   0          11m

根据Pod的顺序,每个Pod拥有对应的主机名,在Pod中执行hostname命令确认下。

[root@devops-101 ~]# for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done
web-0
web-1

使用带有nslookup命令的busybox镜像启动一个Pod,检查集群内的DNS地址设置。

3. 扩缩容

将Pod实例扩充到5个。

[root@devops-101 ~]# kubectl scale sts web --replicas=5
statefulset.apps/web scaled
[root@devops-101 ~]# kubectl get pods -w
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          5m
web-1     1/1       Running   0          5m
web-2     0/1       Pending   0         1s
web-2     0/1       Pending   0         1s

因为我的集群PV不是动态供给的,所以扩容停留在等待PV的阶段,本文要按照后面的办法手工创建相应的PV。

将实例减少到2个。

[root@devops-101 ~]# kubectl get pod
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          24m
web-1     1/1       Running   0          23m
web-2     1/1       Running   0          18m
web-3     1/1       Running   0          10m
web-4     1/1       Running   0          6m
[root@devops-101 ~]# kubectl patch sts web -p '{"spec":{"replicas":2}}'
statefulset.apps/web patched

4. 更新策略

4.1 滚动更新

默认的更新策略,以相反的顺序依次更新Pod

4.2 Partition

4.3 金丝雀发布 Canary

金丝雀发布。

5. 删除 StatefulSet

StatefulSet支持级连删除和非级连删除,在非级连删除模式下,仅删除StatefulSet不删除Pod,级连删除则全部删除。

非级连删除StatefulSet后,如果删除Pod,就不会重新拉起原来的Pod,而是新建一个Pod。但是如果重新创建StatefulSet,则会对现有的Pod按照规则进行重新整理。

一些分布式系统,并不希望按照顺序来管理启停Pod,因此在1.7版本之后,提供了.spec.podManagementPolicy这个参数,默认为OrderedReady,可以设置为Parallel这样Pod的创建就不必等待,而是会同时创建、同时删除。

X. 坑

官方的文档没有创建PVC对应的PV,按照官方文档操作创建后会遇到下面的错误,需要提前创建PV及PVC。关于存储的更详细的内容,可以参考Kubernetes 存储系统 Storage 介绍。

pod has unbound PersistentVolumeClaims

官方文档里解释了,因为他所用的集群配置为动态提供PV,所以不用手工创建。

As the cluster used in this tutorial is configured to dynamically provision PersistentVolumes, the PersistentVolumes were created and bound automatically.

PV的创建脚本如下:

kind: List
apiVersion: v1
items:
- apiVersion: v1
  kind: PersistentVolume
  metadata:
    name: es-storage-pv-01
  spec:
    capacity:
      storage: 100Mi
    volumeMode: Filesystem
    accessModes: ["ReadWriteOnce"]
    persistentVolumeReclaimPolicy: Delete
    storageClassName: local-storage
    local:
      path: /home/es
    nodeAffinity:
      required:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - devops-102
            - devops-103
- apiVersion: v1
  kind: PersistentVolume
  metadata:
    name: es-storage-pv-02
  spec:
    capacity:
      storage: 100Mi
    volumeMode: Filesystem
    accessModes: ["ReadWriteOnce"]
    persistentVolumeReclaimPolicy: Delete
    storageClassName: local-storage
    local:
      path: /home/es01
    nodeAffinity:
      required:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - devops-102
            - devops-103

39469-20180710163655709-89635310.png

参考资料

  1. StatefulSet Basics
  2. DNS for Services and Pods
  3. Services
  4. Persistent Volumes
  5. PersistentVolume Provisioning
  6. StatefulSet Concept

相关文章:

  • Flutter 中的 Animations(二)
  • Spring Cloud Commons 普通抽象
  • zabbix中文问题汇总
  • join
  • 华为S5300系列交换机V200R001SPH027升级补丁
  • 正则表达式小结
  • sql查询语句
  • [转] 梦里Babel知多少(一)
  • 性能测试 tps持续走低,响应时间持续增加,瓶颈分析
  • BZOJ1497 最大获利
  • 探秘varian:优雅的发布部署程序
  • 论“小猪佩奇如何从营销到吸金一路开挂前行”!
  • 使用mysqldump 备份 恢复从库报错解决方案(ERROR 1872)
  • Jquery mobiscroll 移动设备(手机)wap日期时间选择插件以及滑动、滚动插件
  • 动画小记——点击头像逐渐放大
  • 深入了解以太坊
  • JavaScript-如何实现克隆(clone)函数
  • css选择器
  • js 实现textarea输入字数提示
  • orm2 中文文档 3.1 模型属性
  • spring security oauth2 password授权模式
  • uni-app项目数字滚动
  • windows下mongoDB的环境配置
  • 从setTimeout-setInterval看JS线程
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 基于 Babel 的 npm 包最小化设置
  • 记一次删除Git记录中的大文件的过程
  • 深入浅出Node.js
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 数据仓库的几种建模方法
  • 优秀架构师必须掌握的架构思维
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • 7行Python代码的人脸识别
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • ${factoryList }后面有空格不影响
  • (6)设计一个TimeMap
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (一)kafka实战——kafka源码编译启动
  • (一)RocketMQ初步认识
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • .apk 成为历史!
  • .CSS-hover 的解释
  • .net web项目 调用webService
  • .net 开发怎么实现前后端分离_前后端分离:分离式开发和一体式发布
  • .net 提取注释生成API文档 帮助文档
  • .net开发时的诡异问题,button的onclick事件无效
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件
  • .NET中 MVC 工厂模式浅析
  • [ vulhub漏洞复现篇 ] struts2远程代码执行漏洞 S2-005 (CVE-2010-1870)
  • [].slice.call()将类数组转化为真正的数组