statefulset详解及为何结合headless service部署有状态应用
1.1 有状态应用管理statefulset
StatefulSet(有状态集,缩写为sts)常用于部署有状态的且需要有序启动的应用程序,比如在进行SpringCloud项目容器化时,Eureka的部署是比较适合用StatefulSet部署方式的,可以给每个Eureka实例创建一个唯一且固定的标识符,并且每个Eureka实例无需配置多余的Service,其余Spring Boot应用可以直接通过Eureka的Headless Service即可进行注册。
1.1.1 statefulset基本概念
- StatefulSet主要用于管理有状态应用程序的工作负载API对象。比如在生产环境中,可以部署ElasticSearch集群、MongoDB集群或者需要持久化的RabbitMQ集群、Redis集群、Kafka集群和ZooKeeper集群等。
- 和Deployment类似,一个StatefulSet也同样管理着基于相同容器规范的Pod。不同的是,StatefulSet为每个Pod维护了一个粘性标识。这些Pod是根据相同的规范创建的,但是不可互换,每个Pod都有一个持久的标识符,在重新调度时也会保留,一般格式为StatefulSetName-Number。
- 比如定义一个名字是Redis-Sentinel的StatefulSet,指定创建三个Pod,那么创建出来的Pod名字就为Redis-Sentinel-0、Redis-Sentinel-1、Redis-Sentinel-2。
- 而StatefulSet创建的Pod一般使用Headless Service(无头服务)进行通信,和普通的Service的区别在于Headless Service没有ClusterIP,它使用的是Endpoint进行互相通信,Headless一般的格式为:
- statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local。
说明:
serviceName为Headless Service的名字,创建StatefulSet时,必须指定Headless Service名称;
0..N-1为Pod所在的序号,从0开始到N-1;
statefulSetName为StatefulSet的名字;
namespace为服务所在的命名空间;
.cluster.local为Cluster Domain(集群域)
假如公司某个项目需要在Kubernetes中部署一个主从模式的Redis,此时使用StatefulSet部署就极为合适,因为StatefulSet启动时,只有当前一个容器完全启动时,后一个容器才会被调度,并且每个容器的标识符是固定的,那么就可以通过标识符来断定当前Pod的角色


1.1.2 StatefulSet注意事项
一般StatefulSet用于有以下一个或者多个需求的应用程序:
需要稳定的独一无二的网络标识符。
需要持久化数据。
需要有序的、优雅的部署和扩展。
需要有序的自动滚动更新。
如果应用程序不需要任何稳定的标识符或者有序的部署、删除或者扩展,应该使用无状态的控制器部署应用程序,比如Deployment或者ReplicaSet。
StatefulSet是Kubernetes 1.9版本之前的beta资源,在1.5版本之前的任何Kubernetes版本都没有。
Pod所用的存储必须由PersistentVolume Provisioner(持久化卷配置器)根据请求配置StorageClass,或者由管理员预先配置,当然也可以不配置存储。
为了确保数据安全,删除和缩放StatefulSet不会删除与StatefulSet关联的卷,可以手动选择性地删除PVC和PV)。
StatefulSet目前使用Headless Service(无头服务)负责Pod的网络身份和通信,需要提前创建此服务。
删除一个StatefulSet时,不保证对Pod的终止,要在StatefulSet中实现Pod的有序和正常终止,可以在删除之前将StatefulSet的副本缩减为0
为什么要用headless service+statefulSet部署有状态应用?
Headless Services介绍
Headless Services是一种特殊的service,其spec:clusterIP表示为None,这样在实际运行时就不会被分配ClusterIP。也被称为无头服务。
1、headless Service和普通Service的区别
headless不分配clusterIP
headless service可以通过解析service的DNS,返回所有Pod的地址和域名(statefulSet部署的Pod才有域名)
headless service会为关联的Pod分配一个域:
service-name.namespace-name.svc.cluster.local
普通的service,只能通过解析service的DNS返回service的ClusterIP
2、statefulSet和Deployment控制器的区别
statefulSet下的Pod有DNS地址,通过解析Pod的DNS可以返回Pod的IP
StatefulSet会为关联的Pod保持一个不变的Pod Name
statefulset中Pod的hostname格式为
statefulsetname-(pod序号)
而deployment下的Pod没有具体的域名,想访问Pod都是通过普通service来负载均衡到后端pod,无法指定访问具体哪个Pod
3、普通Service解析service的DNS结果
Service的ClusterIP工作原理:一个service可能对应一组endpoints(所有pod的地址+端口),client访问ClusterIP,通过iptables或者ipvs转发到Real Server(Pod)。
StatefulSet+headless service会为关联的每个Pod都分配一个具体的域名:
Pod-Name.service-name.namespace-name.svc.cluster.local
实操部分
1.1.3 定义一个StatefulSet资源文件

点击查看代码
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None #这里可以有IP,也可以无IP,推荐无IP,也就是 无头service
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: nginx:1.15.2
ports:
- containerPort: 80
name: web


创建个Busybox演示如何通过无头service名字来进行网络访问


通过nslookup来解析web-0.nginx(sts名称+无头service名称),可以得到这个Pod的ip地址:10.244.32.152


进入集群busybox容器对web-0.nginx进行Ping和wget发现都是通的


1.1.4 缩容扩容StatefulSet
查看sts lable标签

通过标签对指定sts进行监听

对sts进行扩容操作

可以看到sts启动的顺序是严格按照序号来进行启动的,同理缩容的话会严格按照pod的序号倒序进行删除


1.1.4 StatefulSet更新策略
1. RollingUpdate 更新策略
- 默认更新策略RollingUpdate
点击查看代码
updateStrategy:
rollingUpdate:
partition: 0 #不更新小于 N 的副本
type: RollingUpdate
更新镜像版本


开启另一个窗口,观察Pod更新过程,可以看到他的更新顺序是倒序的

2. Ondelete 更新策略 [适用于灰度发布]
更改更新策略为Ondelete
点击查看代码
修改:
updateStrategy:
rollingUpdate:
partition: 0
type: RollingUpdate
改为:
updateStrategy:
type: OnDelete #修改为OnDelete更新模式并保存,该更新策略是,删除时才会进行更新

更新镜像版本,并观察更新过程

只有进行delete pod删除操作的时候,pod才会被更新


statefulset详解及为何结合headless service部署有状态应用的更多相关文章
- kubernetes之StatefulSet详解
系列目录 概述 RC.Deployment.DaemonSet都是面向无状态的服务,它们所管理的Pod的IP.名字,启停顺序等都是随机的,而StatefulSet是什么?顾名思义,有状态的集合,管理所 ...
- .Neter玩转Linux系列之五:crontab使用详解和Linux的进程管理以及网络状态监控
一.crontab使用详解 概述:任务调度:是指系统在某个时间执行的特定的命令或程序. 任务调度分类: (1)系统工作:有些重要的工作必须周而 复始地执行. (2)个别用户工作:个别用户可能希望执 行 ...
- Spring注解详解@Repository、@Component、@Service 和 @Constroller
概述 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO ...
- 详解Maven项目利用java service wrapper将Java程序生成Windows服务
在项目的开发中,有时候需要将Java应用程序打包成Windows服务,我们就直接可以通过windows的服务来启动和关闭java程序了. 本博文将通过有两种方法实现该功能,手动创建法和Maven自动打 ...
- HTTP协议简介详解 HTTP协议发展 原理 请求方法 响应状态码 请求头 请求首部 java模拟浏览器客户端服务端
协议简介 协议,自然语言里面就是契约,也是双方或者多方经过协商达成的一致意见; 契约也即类似于合同,自然有甲方123...,乙方123...,哪些能做,哪些不能做; 通信协议,也即是双方通过网络通信必 ...
- 《HTTP协议详解》读书笔记---请求篇之响应状态码
在接收和解释请求消息后,服务器返回一个http响应消息.它也分为3个部分:状态行.消息报头.响应正文,格式如下: HTTP-VersionStatus-CodeReason-PhraseCRLF(CR ...
- Kubernetes K8S之Service服务详解与示例
K8S之Service概述与代理说明,并详解所有的service服务类型与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master Cent ...
- Kubernetes K8S之资源控制器StatefulSets详解
Kubernetes的资源控制器StatefulSet详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2 ...
- [RM 状态机详解3]RMContainer状态机详解
摘要 RMContainer是RM内部维护的Container状态.事实上,在RM的调度器中,会维护着一个liveContainers列表,保存着所有存活着的Container信息.图1显示RMCon ...
- GDB scheduler-locking 命令详解
GDB scheduler-locking 命令详解 GDB> show scheduler-locking //显示线程的scheduler-locking状态GDB> set ...
随机推荐
- perl中 use strict会出现“requires explicit package name”错误
转载 perl中use strict的用法 如果你使用 use strict 的话,它会强迫你用 my 声明变量,否则将会报上述错误.
- 2022-11-04 Acwing每日一题
本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我会认真改正的.同时也希望 ...
- 刚哥谈架构(八)- 为你的应用选择合适的API
前言: 架构师的主要活动是做出正确的技术决策.选择合适的API是一项重要的技术决策.那么今天就看看API的选择问题. 应用程序编程接口(API)是一种计算接口,它定义了多个软件中介之间的交互.它定义了 ...
- vue脚手架安装及依赖
一.安装Vue Cil (脚手架) 需要先安装node.js,这是node官网地址: https://nodejs.org/en/download/ ,node有两种版本一种是稳定版一种开发版 安装完 ...
- NLP实践!文本语法纠错模型实战,搭建你的贴身语法修改小助手 ⛵
作者:韩信子@ShowMeAI 深度学习实战系列:https://www.showmeai.tech/tutorials/42 自然语言处理实战系列:https://www.showmeai.tech ...
- [信息抽取]基于ERNIE3.0的多对多信息抽取算法:属性关系抽取
[信息抽取]基于ERNIE3.0的多对多信息抽取算法:属性关系抽取 实体关系,实体属性抽取是信息抽取的关键任务:实体关系抽取是指从一段文本中抽取关系三元组,实体属性抽取是指从一段文本中抽取属性三元组: ...
- 「Docker学习系列教程」9-Docker容器数据卷介绍
通过前面8篇文章的学习,我们已经学会了docker的安装.docker常用的命令已经docker镜像修改后提交的远程镜像仓库及提交到公司的私服仓库中.接下来,我们再来学学Docker另外一个重要的东西 ...
- Qt多线程开发总览,既然用到了就记录一下
多线程 在LBD_VM_Intercom中使用的一个简单的实例 陶工给的dll需要进行异步操作才可以将视频画面附到窗体上,必须得在画面出现之后才可以附加画面,否则就有可能出现意外bug,所以需要在这个 ...
- uniapp 微信小程序自己封装头部标题栏
一.首先要关闭原生导航栏 :在pages.json 中设置 "navigationStyle":"custom" 二.在APP.vue中 onLaunch: ...
- JavaScript:立即执行函数
想象一下,如果我希望某个代码块,只执行一次,就不再执行,应该怎么办? 代码块肯定是用函数来表示,执行肯定是调用函数,但是确保只执行一次,该怎么办? 我们为什么可以多次调用函数,因为函数名指向了函数的内 ...