Kubectl 部署有状态应用(上)

前面介绍了Deployment以及如何部署无状态应用。

  • Kubectl 部署无状态应用
  • Deployment Controller详解(上)
  • Deployment Controller详解(下)

本文将继续介绍如何在k8s上部署有状态应用。

有状态和无状态服务的区别

  • 无状态:
    • 上面所说的deployment 认为所有的pod都是一样的
    • 不用考虑顺序的要求
    • 不用考虑在哪个node节点上运行
    • 可以随意扩容和缩容
  • 有状态
    • 实例之间有差别,每个实例都有自己的独特性,元数据不同,例如etcd,zookeeper
      实例之间不对等的关系,以及依靠外部存储的应用

StatefulSet

Deployments和ReplicaSets是为无状态服务而设计,StatefulSet则是为了解决有状态服务的问题。StatefulSet 作为 Controller 为 Pod 提供唯一的标识。它可以保证部署和 scale 的顺序,其应用场景包括:

  • 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
  • 稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
  • 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
  • 有序收缩,有序删除(即从N-1到0)

好像不太懂?简单来说,部署的无状态应用,每一次的更新部署、都会更新IP以及存储等等。对于业务来说,后端频繁更换ip和存储是一件非常不友好的事情,但有状态服务部署后每次更新都会拥有稳定的存储以及网络标志。

本文目标

  • 如何创建 StatefulSet
  • StatefulSet 如何管理其 Pod
  • 如何删除 StatefulSet
  • 如何扩展 StatefulSet
  • 如何更新 StatefulSet 的 Pod

1. 创建 StatefulSet

首先创建一个nginx service以及两个web StatefulSet

vim statefulset.yaml

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: registry.k8s.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

 statefulset.yaml

接下来我们打开两个终端,其中一个用于部署,另一个观察部署情况。

第一个终端运行kubectl get pods --watch -l app=nginx观察 StatefulSet Pod 的创建。

第二个终端执行kubectl apply -f statefulset.yaml创建Service 和 StatefulSet。

有以下输出:

service/nginx created
statefulset.apps/web created

上面的命令创建两个 Pod,每个 Pod 运行一个 nginx Web 服务器。

插曲

当执行完 kubectl apply -f statefulset.yaml后,发现另一个终端出现以下输出:


排查思路:

  1. 查看pods


2. 查看pod详细信息
执行kubectl describe pod web-1


发现Events中确实创建并且run起来了,但是pod重启失败。

造成Back-off restarting failed container nginx in pod 的原因主要是因为容器内PID为1的进程退出导致(通常用户在构建镜像执行CMD时,启动的程序,均是PID为1)。一般遇到此问题,使用者需自行排查原因,可从如下几个方向入手:

    1. 镜像封装是否有问题,如是否有PID为1的常驻进程
    • 举例1:在容器dockerfile中,最后的CMD执行的是nginx start,执行后,nginx服务一直在前台打印日志,服务常驻,进程持续存在,则不会有问题
    • 举例2:在容器dockerfile中,最后的CMD执行的是nohup nginx start &,执行后,该命令就结束了,对应的进程也就没了,容器back-off重启
    1. 常驻进程是否异常退出
    • 服务启动后,会尝试连接一个第三方服务,重试10次连接失败,则程序终止退出,本地环境和这个三方环境通,换了个k8s之后,这个服务不通了,则会出现服务退出,进程结束,容器back-off
    1. 镜像使用方式不对
  • 例如镜像封装的时候,并没有指定启动参数,需要使用者在使用该镜像的时候,自己添加启动命令及参数(command,args),如果不添加,容器内可能没有正确的执行命令,运行即退出

解决方式

容器没有任务的时候会处于非running状态,要保持running状态大家推荐的方法是在容器起来之后去循环访问一个系统自带的文件/dev/null,默认情况下里面是空的,tail -f就是实时打印日志的命令。
在yaml 文件中加入

command: ["/bin/bash", "-ce", "tail -f /dev/null"]

此时,执行kubectl delete statefulset web。删掉旧服务,并重新执行kubectl apply -f statefulset.yaml部署。发现:

kubectl get pods
-----
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          6s
web-1   1/1     Running   0          5s

回到原文。

经过小插曲的修改后,执行kubectl get statefulset web

kubectl get statefulset web
------
NAME   READY   AGE
web    2/2     13m

发现两个pod都已经ready了。

有序 Pod 创建过程

对于具有n个副本的StatefulSet ,当部署 Pod 时,它们是按顺序创建的,从{0…n-1}排序。从第一个终端中命令的输出将如下例所示:

web-0   0/1     Pending             0                0s
web-0   0/1     Pending             0                0s
web-0   0/1     ContainerCreating   0                0s
web-0   1/1     Running             0                1s
web-1   0/1     Pending             0                0s
web-1   0/1     Pending             0                0s
web-1   0/1     ContainerCreating   0                0s
web-1   1/1     Running             0                1s

未完,待续…

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

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

相关文章

数组元素反序

和前面的字符串逆向输出有异曲同工之妙 第一位和最后一位交换位置,然后用比大小循环 那么接下来修改一下这个程序,我们接下来解释一下p的概念 画图解释: 在最前面的 定义的时候,我们将p(0)定义在了1上&…

四、Spring IoC实践和应用(基于配置类方式管理 Bean)

本章概要 基于配置类方式管理 Bean 完全注解开发理解实验一:配置类和扫描注解实验二:Bean定义组件实验三:高级特性:Bean注解细节实验四:高级特性:Import扩展实验五:基于注解配置类方式整合三层…

抓包工具Fiddler的常用操作

文章目录 Fiddler概述Fiddler页面介绍常用功能介绍端口号的修改设置抓HTTPS数据Fillder过滤请求数据 接口相关Fiddler中查看请求信息Fiddler中查看响应信息 Fiddler模拟弱网测试Fiddler模拟mock数据Fillder篡改数据 Fiddler概述 fiddler是一款http协议调试代理工具,…

redis的那些事(二)——布隆过滤器

什么是布隆过滤器? 布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。 布隆过滤器实现原理 布隆过滤器是一个bit向量或者说是一个b…

【linux提权】利用setuid进行简单提权

首先先来了解一下setuid漏洞: SUID (Set UID)是Linux中的一种特殊权限,其功能为用户运行某个程序时,如果该程序有SUID权限,那么程序运行为进程时,进程的属主不是发起者,而是程序文件所属的属主。但是SUID权限的设置只…

构建深度学习模型:原理与实践

构建深度学习模型:原理与实践 引言 随着人工智能技术的飞速发展,深度学习已经成为当今最为炙手可热的研究领域之一。深度学习通过模拟人脑神经网络的工作原理,使得计算机能够具备更强大的学习和识别能力。本文将深入探讨深度学习的基本原理…

【模式识别】探秘分类奥秘:K-近邻算法解密与实战

​🌈个人主页:Sarapines Programmer🔥 系列专栏:《模式之谜 | 数据奇迹解码》⏰诗赋清音:云生高巅梦远游, 星光点缀碧海愁。 山川深邃情难晤, 剑气凌云志自修。 目录 🌌1 初识模式识…

Unity网格篇Mesh(二)

Unity网格篇Mesh(二) 介绍4.生成额外的顶点数据未计算法线计算法线没有法线vs有法线错误的UV坐标Clamping vs warpping正确的UV纹理,平铺(1,1) vs 平铺(2,1)凹凸不平的表面,产生了金…

XPM_CDC_SINGLE(UG974)

Parameterized Macro: Single-bit Synchronizer(参数化宏:单比特同步器) MACRO_GROUP: XPMMACRO_SUBGROUP: XPM_CDCFamilies: UltraScale, UltraScale 1、 Introduction(介绍) 此宏将一个一位信号从源时钟域同步到目…

UG凸起命令

凸起命令是拉伸命令的补充,可以方便的对曲面进行拉伸切除。 当端盖中几何体类型选择默认的截面平面的时候,相当于拉伸命令 当端盖中几何体类型选择凸起的面的时候,相当于拉伸其实曲线变为选择曲线在凸起面的投影曲线,然后基于凸起…

ios 之 数据库、地理位置、应用内跳转、推送、制作静态库

第一节:数据库 常见的API SQLite提供了一系列的API函数,用于执行各种数据库相关的操作。以下是一些常用的SQLite API函数及其简要说明:1. sqlite3_initialize:- 初始化SQLite库。通常在开始使用SQLite之前调用,但如果没有调用&a…

【金猿CIO展】乖宝宠物CIO王天刚:以数据为核心,转变业务模式

‍ 王天刚 本文由乖宝宠物CIO王天刚撰写并投递参与“数据猿年度金猿策划活动——2023大数据产业年度趋势人物榜单及奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 随着社会经济的快速发展,“宠物经济”悄然崛起,宠物在家中的角色地位有时…

w15php系列之基础类型

一、计算100之内的偶数之和 实现思路 所有的偶数除2都为0 代码实现 <?php # 记录100以内的偶数和 $number1; $num0; while($number<100){if($number%20){ $num$number;}$number1; } echo $num; ?>输出的结果 二、计算100之内的奇数之和 实现思路 所有的奇数除…

智能优化算法应用:基于战争策略算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于战争策略算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于战争策略算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.战争策略算法4.实验参数设定5.算法结果6.…

XxIJob入门-示例

一、部署 xxlJob (一) 下载地址&#xff0c; git clone 到本地。 http://gitee.com/xuxueli0323/xxl-job https://github.com/xuxueli/xxl-job (二) 插入 xxl_job 的sql脚本&#xff1a; 在项目的 /xxl-job/doc/db/tables_xxl_job.sql &#xff0c;找到sql脚本&#xff0c…

React 路由

引言 在我们之前写的页面当中&#xff0c;用我们的惯用思维去思考的话&#xff0c;可能会需要写很多的页面&#xff0c;例如做一个 tab 栏&#xff0c;我们可能会想每个选项都要对应一个 HTML 文件&#xff0c;这样会很麻烦&#xff0c;甚至不友好&#xff0c;我们把这种称为 …

【Java动态代理如何实现】

✅Java动态代理如何实现 ✅JDK动态代理和Cglib动态代理的区别 ✅拓展知识仓✅静态代理和动态代理的区别✅动态代理的用途✅Spring AOP的实现方式&#x1f4d1;JDK 动态代理的代码段&#x1f4d1;Cglib动态代理的代码块 ✅注意事项&#xff1a; 在Java中&#xff0c;实现动态代理…

使用PE信息查看工具和Dependency Walker工具排查因为库版本不对导致程序启动报错的问题

目录 1、问题说明 2、问题分析思路 3、问题分析过程 3.1、使用Dependency Walker打开软件主程序&#xff0c;查看库与库的依赖关系&#xff0c;找出出问题的库 3.2、使用PE工具查看dll库的时间戳 3.3、解决办法 4、最后 VC常用功能开发汇总&#xff08;专栏文章列表&…

浅谈springboot整合ganymed-ssh2远程访问linux

环境介绍 技术栈 springbootmybatis-plusmysqlganymed-ssh2 软件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 1.8 Spring Boot 2.7.13 mybatis-plus 3.5.3.2 SSH(远程连接工具)连接原理&#xff1a;ssh服务是一个守护进程(demon)&#xff0c;系统后台监听客户…

2006年AMC8数学竞赛中英文真题典型考题、考点分析和答案解析

今天距离2024年的AMC8美国数学竞赛举办还有二十多天&#xff0c;面临着期末考试的压力和紧张复习&#xff0c;更需要高效地准备AMC8比赛&#xff01;“在战争中学习战争”是最有效的方式&#xff0c;反复做历年的AMC8真题也是备考最有效的方式之一。 通过反复研究历年真题&…