Kubernetes 的有状态和无状态服务

k8s-LAB

Author:rab


目录

    • 前言
    • 一、无状态服务案例
      • 1.1 yml 案例
      • 1.2 扩容与缩容
        • 1.2.1 扩容
        • 1.2.2 缩容
      • 1.3 暂停与恢复
        • 1.3.1 暂停
        • 1.3.2 恢复
      • 1.4 回滚
    • 二、有状态服务案例
      • 2.1 yml 案例
      • 2.2 扩容与缩容
        • 2.2.1 扩容
        • 2.2.2 缩容
    • 总结


前言

在 Kubernetes(k8s)中,有状态服务和无状态服务是两种不同类型的应用程序部署方式,它们在容器编排和管理方面有一些关键区别。

1、无状态服务(Stateless Services)

  • 无状态服务是指应用程序不依赖于本地状态,并且对于每个请求都能以相同的方式处理。这意味着无状态服务的任何一个实例都可以处理来自客户端的请求,而请求之间没有关联。
  • 无状态服务的典型示例包括 Web 服务器、API 服务、负载均衡器等,这些服务可以水平扩展,即可以通过添加更多的副本来处理更多的请求流量。
  • 无状态服务通常适合使用 Kubernetes 中的 Deployment 进行部署。因为它们的实例可以随意启动和停止,而不会影响应用程序的状态或数据。

2、有状态服务(Stateful Services)

  • 有状态服务是指应用程序依赖于本地状态,通常需要稳定的标识和数据。这意味着每个实例都有唯一的标识,如数据库服务器或消息队列,它们需要在启动、停止或故障转移时保留其数据和状态。
  • 有状态服务的典型示例包括数据库系统(如 MySQL、PostgreSQL)、消息队列(如 RabbitMQ、Kafka)等,这些服务通常需要持久性存储和网络标识的稳定性。
  • Kubernetes 提供 StatefulSet 来部署有状态服务。StatefulSet 具有管理有状态应用程序的能力,为每个 Pod 提供唯一的标识,以及稳定的网络标识,从而支持有状态服务的稳定性。

一、无状态服务案例

1.1 yml 案例

比如我们可以举个 Nginx 负载均衡的例子,那此时这个负载均衡可以归为无状态服务,任何一个 Nginx 实例都可以处理来自客户端的请求。因此我们可以采用 Kubernetes 中的 Deployment 进行部署。

vim Stateless.yml
apiVersion: v1
kind: Namespace
metadata:
  name: myweb
  labels:
    name: ops
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: myweb
  labels:
    app: stateless
spec:
  replicas: 3
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: nginx
        image: nginx:1.21.4
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-srv
  namespace: myweb
spec:
  selector:
    app: demo
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30333
  type: NodePort

注意:Service 的 selector 标签选择器的值一定要和 Deployment 的 selector 标签选择器的值保持一致,否则外部 Client 的请求就无法路由到 Pod 资源。

kubectl apply -f Stateless.yml

本地浏览器访问:

http://192.168.56.160:30333/

image-20231025153300073

1.2 扩容与缩容

1.2.1 扩容

扩容的方式有很多,以下是常见的扩容方式。

1、修改 yml 文件方式

vim Stateless.yml    # 只需修改replicas值即可
...
spec:
  replicas: 5
  ...

修改完成后执行扩展(更新)

kubectl apply -f Stateless.yml

2、Shell 命令行方式

  • 法1

    kubectl scale --replicas=5 deploy nginx -n myweb
    
    # 说明:deploy是deployment的缩写,写deployment也是没问题的
    
  • 法2

    kubectl edit deployment nginx -n myweb
    
    # 这会以交互式的方式进入yml配置文件,进去后修改replicas的值后保存退出即可实现扩容
    

说明:与直接修改 yml 文件不同的是,该命令执行完后即可升级,而无需执行 kubectl apply -f Stateless.yml

1.2.2 缩容

与扩容没有任何区别,操作一模一样,所谓的缩容就是当你设置的 replicas 值小于当前 replicas 值时就是缩容的概念。

注意:但要注意的是,我们说动态扩容和缩容不会触发上线(即不会产生新的 replicaset)

1.3 暂停与恢复

注意的是,这个暂停和恢复不是说暂停了我的程序就不对外提供服务了,而是用于当你使用 kubectl set ... 命令来更新时使用。其大概流程就是:当你暂停后,允许你执行多个 kubectl set ... 更新命令,但每条指令执行完后不是立即生效,而是当你恢复 deployment 时你执行的那些 kubectl set ... 才会生效。

1.3.1 暂停

1、暂停服务

kubectl rollout pause deployment nginx -n myweb

2、执行第一条更新指令

kubectl set image deploy nginx nginx=nginx:1.20.0 -n myweb

3、执行第二条更新指令

kubectl set resources deploy nginx -c nginx --limits=cpu=200m,memory=128Mi --requests=cpu=10m,memory=16Mi -n myweb

如下图,以上这两条更新指令都是未生效的,从 nginx 镜像版本没变化就可证明。

image-20231025170727008

1.3.2 恢复

那要如何是我们执行过的 kubectl set ... 指令生效呢?恢复即可。

kubectl rollout resume deploy nginx -n myweb

如下图,恢复后我们在暂停期间执行的 kubectl set ... 指令就生效了。

image-20231025171200713

当然了,如果你想使用 kubectl set 来更新服务,但又不想暂停,你完全可以直接执行 kubectl set 指令即可,执行完后,就会立马更新。

kubectl set image deploy nginx nginx=nginx:1.18.0 -n myweb

image-20231025171428065

1.4 回滚

如果我们以上的一系列更新最终的测试验证出问题了,需要回滚到最初(或更新前)的状态或中间某个版本状态,那此时就需要使用到 K8s 的回滚功能了,具体的操作如下。

1、先查看更新的版本

默认情况下,K8s 只会保留近 10 个的 revision,我们可以在 Deployment 配置文件中使用 revisionHistoryLimit 字段来指定 revision 的保留数量。

kubectl rollout history deploy nginx -n myweb

# 下图中这三个版本编号中,1表示最初版本状态,3表示当前的版本状态

image-20231025172113126

2、再查看每个版本对应的详情(因为上图根本看不出来)

kubectl rollout history deployment nginx --revision=1 -n myweb

# 我们来看看第一个版本详情

image-20231025172640153

3、回滚到我们指定的版本状态

kubectl rollout undo deployment nginx --to-revision=1 -n myweb

image-20231025172836324

4、最后来验证一下是否回滚成功

kubectl get deployment nginx -o wide -n myweb

image-20231025173029086

这个时候我们再来看看历史版本号:

image-20231025173140455

你会发现,历史版本为 1 的编号消失了,为什么呢?因为已经被我们回滚了(此时你就要记住了,如果你又执行了多次更新操作后,又想回到最初的状态的话,只能回到 4 这个版本,因为 4 此时才是我们最初的状态,而 2 并不是)。

二、有状态服务案例

2.1 yml 案例

上面说到,像 MySQL、RabbitMQ 等这类服务实际上就是属于有状态服务,对于这类服务我们一般会要求每个 Pod 具有唯一的标识,以及稳定的网络标识。例如 MySQL 就是一个典型的有状态应用程序,因为每个 MySQL 实例需要唯一的标识,并且通常依赖于稳定的网络标识。

vim Stateful.yml
apiVersion: v1
kind: Namespace
metadata:
  name: myweb-2
  labels:
    name: ops
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx
  namespace: myweb-2
  labels:
    app: stateful
spec:
  serviceName: myweb-2
  replicas: 3
  selector:
    matchLabels:
      app: demo-2
  template:
    metadata:
      labels:
        app: demo-2
    spec:
      containers:
      - name: nginx
        image: nginx:1.21.4
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-srv
  namespace: myweb-2
spec:
  selector:
    app: demo-2
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30334
  type: NodePort
kubectl apply -f Stateful.yml

对于如何查看 deployment 资源,我想你已经会了,那 statefulset 资源如何查看呢?其实都是一样的套路:

kubectl get statefulset -n myweb-2

# 或
kubectl get sts -n myweb-2

image-20231025175454025

本地浏览器访问:

http://192.168.56.160:30334/

image-20231025175657501

2.2 扩容与缩容

2.2.1 扩容
kubectl scale --replicas=5 sts nginx -n myweb-2
2.2.2 缩容
kubectl scale --replicas=2 sts nginx -n myweb-2

说明:暂停、恢复、回滚套路和 deployment 保持一致的,这里就不再重复造轮子了。

总结

  • 无状态服务适用于可以随意扩展并处理请求而不依赖本地状态的应用程序,而有状态服务适用于需要稳定的标识和数据的应用程序。

  • 在 Kubernetes 中,我们可以使用不同的控制器(例如 Deployment 和 StatefulSet)来适应这两种不同类型的服务。

  • 有状态服务通常需要考虑持久性存储和数据备份策略,以确保数据的可靠性和可用性。

说明:以上案例均未配置持久化存储,后面会提到。

—END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/103689.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(Java)中的数据类型和变量

文章目录 一、字面常量二、数据类型三、变量1.变量的概念2.语法的格式3.整型变量4.长整型变量5.短整型变量6.字节型变量 四、浮点型变量1.双精度浮点数2.单精度浮点数 五、字符型常量六、布尔型变量七、类型转换1.自动类型转换(隐式)2.强制类型转换(显式…

SCT52240STDR双路 4A/4A 高速MOSFET/IGBT栅极驱动器, 可并联输出

SCT52240是是一款宽供电电压、双通道、高速、低测栅极驱动器,包括功率MOSFET,IGBT。单个通道能够提供高达4A拉电流和4A灌电流的轨到轨驱动能力,并实现轨到轨输出。高达24V宽电压范围提高功率器件开关瞬间栅极驱动的振铃幅值裕度。13ns输入输出…

Pytorch公共数据集、tensorboard、DataLoader使用

本文将主要介绍torchvision.datasets的使用,并以CIFAR-10为例进行介绍,对可视化工具tensorboard进行介绍,包括安装,使用,可视化过程等,最后介绍DataLoader的使用。希望对你有帮助 Pytorch公共数据集 torc…

如何理解某一个开发框架的意图,从而去写和落代码文件位置不会出错

理解一个开发框架的意图并正确地组织代码和文件位置是一个重要的技能。这不仅需要对框架本身有深入的理解,还需要对框架背后的设计哲学和最佳实践有所了解。以下是一些帮助你达到这一目标的步骤和建议: 1. 学习框架的文档 详细阅读: 开始使用任何框架前…

【数据结构】数组和字符串(四):特殊矩阵的压缩存储:稀疏矩阵——三元组表

文章目录 4.2.1 矩阵的数组表示4.2.2 特殊矩阵的压缩存储a. 对角矩阵的压缩存储b~c. 三角、对称矩阵的压缩存储d. 稀疏矩阵的压缩存储——三元组表结构体初始化元素设置打印矩阵主函数输出结果代码整合 4.2.1 矩阵的数组表示 【数据结构】数组和字符串(一&#xff…

前端请求后台接口失败处理逻辑

前后分离项目,前端为uni-app(vue2),后台为java 后台api设置存在问题,部分公共接口为开放非登录用户访问权限 导致前台打开首页后立即跳转到登录提示页 怀疑是开了uni-app开发代理服务器,导致访问的代理服务…

Kubernetes 通过 Deployment 部署Jupyterlab

概要 在Kubernetes上部署jupyterlab服务,链接Kubernetes集群内的MySQL,实现简单的数据开发功能。 前置条件 镜像准备:自定义Docker镜像--Jupyterlab-CSDN博客 MySQL-Statefulset准备:StatefulSet 简单实践 Kubernetes-CSDN博客…

利用MATLAB创建栅格地图(代码可复制)

先做一个声明:文章是由我的个人公众号中的推送直接复制粘贴而来,因此对智能优化算法感兴趣的朋友,可关注我的个人公众号:启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法,经典的,或者是近几年…

C语言 每日一题 PTA 10.21-10.24日 day3

1.计算分段函数[1] 本题目要求计算下列分段函数f(x)的值: yf(x)1/x x!0 yf(x)0 x0 int main() {double num 0;scanf("%lf", &num);double result 0;if (num 0){result 0;}else{result 1 / num;}printf("f(%.1lf)%.1lf", num, result)…

通俗介绍:什么是 Redis ?

刚接触 Redis 的伙伴们可能会因为不熟悉而感到困惑。本文简述 Redis 是什么、有哪些作用的问题,是一篇短浅而入门级别的文章。 Redis官网:Redis 打开 Redis 官网可以看到,官方对 Redis 的介绍是这样的:The open source, in-memo…

python 之 矩阵相关操作

文章目录 1. **创建矩阵**:2. **矩阵加法**:3. **矩阵乘法**:4. **矩阵转置**:5. **元素级操作**:6. **汇总统计**:7. **逻辑操作**: 理解你的需求,我将为每个功能写一个单独的代码块…

ES在企业项目中的实战总结,彻底掌握ES的使用

通过之前两篇文章 了解了ES的核心概念和基础使用学习进阶的DSL语法处理复杂的查询 这段时间通过在本企业代码中对ES框架的使用,总结了不少经验。主要分为三点 企业封装了ES原生的api,需要使用企业项目提供的接口实现 -------简单使用(本章节目…

论文阅读[51]通过深度学习快速识别荧光组分

【论文基本信息】 标题:Fast identification of fluorescent components in three-dimensional excitation-emission matrix fluorescence spectra via deep learning 标题译名:通过深度学习快速识别 三维激发-发射矩阵荧光光谱中的荧光组分 期刊与年份&…

基于springboot的房产销售系统

基于springbootvue的房产销售系统 角色:用户、管理员、销售经理 管理员:首页、个人中心、用户管理、销售经理管理、房源信息管理、房源类型管理、房子户型管理、交易订单管理、预约看房管理、评价管理、我的收藏管理、系统管理等。 用户:首页、个人中心…

UI 自动化测试框架:PO模式+数据驱动

1. PO 设计模式简介 什么是 PO 模式? PO(PageObject)设计模式将某个页面的所有元素对象定位和对元素对象的操作封装成一个 Page 类,并以页面为单位来写测试用例,实现页面对象和测试用例的分离。 PO 模式的设计思想与…

利用Jpom在线构建Spring Boot项目

1 简介 前面介绍了运用Jpom构建部署Vue项目,最近研究了怎么部署Spring Boot项目,至此,一套简单的前后端项目就搞定了。 2 基本步骤 因为就是一个简单的自研测试项目,所以构建没有使用docker容器,直接用java -jar命令…

xcode15一直显示正在连接iOS17真机问题解决

前言 更新xcode15之后,出现了各种报错问题,可谓是一路打怪啊,解决一个报错问题又来一个。没想到到了最后还能出现一个一直显示正在连接iOS17真机的问题 一直显示正在连接iOS17真机的问题 问题截图如下: 解决方法 1. 打开De…

2018年亚太杯APMCM数学建模大赛B题人才与城市发展求解全过程文档及程序

2018年亚太杯APMCM数学建模大赛 B题 人才与城市发展 原题再现 招贤纳士是过去几年来许多城市的亮点之一。北京、上海、武汉、成都、西安、深圳,实际上都在用各种吸引人的政策来争夺人才。人才代表着城市创新发展的动力,因为他们能够在更短的时间内学习…

Kafka入门04——原理分析

目录 01理解Topic和Partition Topic(主题) Partition(分区) 02理解消息分发 消息发送到分区 消费者订阅和消费指定分区 总结 03再均衡(rebalance) 再均衡的触发 分区分配策略 RangeAssignor(范围分区) RoundRobinAssignor(轮询分区) StickyAssignor(粘性分区) Re…

【多线程】Java如何实现多线程?如何保证线程安全?如何自定义线程池?

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ 多线程 Java多线程1. 进程与线程2. 多线程1&am…