96SEO 2026-02-19 12:43 7
。

阅读本文需要读者对k8s的基本概念#xff0c;比如Pod、Deployment、Service、Namespace等基础概念有所了解#xff0c;尚且不了解的同学推荐先阅读本系列的第一篇文章《K8S系列一#xff1a;概念入门》[1]…
本文是K8S系列第四篇主要面向对k8s新手同学。
阅读本文需要读者对k8s的基本概念比如Pod、Deployment、Service、Namespace等基础概念有所了解尚且不了解的同学推荐先阅读本系列的第一篇文章《K8S系列一概念入门》[1]阅读本文还需要读者对k8s的服务部署有一定深入的了解特别是怎么通过Pod部署自己的服务尚且不熟悉的同学推荐阅读本系列前一篇文章《K8S系列三单服务部署》[2]。
本文旨在讲述如何基于k8s集群管理一群服务包括如何做高可用Hight
AvailableHA部署和管理、如何做服务平滑升级、如何隔离不同业务的服务等。
因此本文将重点介绍以下的k8s对象/资源API
Deployment无状态、多服务管理StatefulSet有状态、多服务管理Namespace不同服务资源隔离
正文开始之前我们需要统一一个观点日常生产中所说的“服务”或者说是传统的“服务”对应的是k8s的Pod对象因为k8s有一个Service对象经常被翻译和理解为服务其实也没啥毛病。
在上一篇文章《K8S系列三单服务部署》[2]中详细介绍了如何在k8s集群中部署一个可用的服务包括容器环境的使用、数据卷的挂载、配置文件的使用、服务网络的配置。
k8s会根据提交的Pod的yaml文件自动拉取镜像、挂载数据和配置文件、流量负载均衡器等以确保镜像容器内的服务正常运行。
答案是不够因为还需要把部署在k8s集群上的服务更有效地管理起来即服务管理。
于是问题又来了什么是服务管理或者说为什么需要服务管理
AvailableHA。
虽然在实际生产中后台服务架构设计原则没有统一的标准不过大部分后台服务必须考虑“三高”的问题高并发、高性能、高可用。
前两天看到一个非常有趣的话题
话糙理不糙啊加机器扩充服务实例绝对是首选正经来说面试官实际想听到的是对“三高”的理解、具体解决措施等仔细分析“加机器”这个操作其实就是高可用的一种很有效的解决手段而且在实际生产中往往一个程序也会部署几个服务实例并且为了做有效容灾服务实例会分布在不同的机器、机房、区域。
显然是可以的做法也挺简单的准备好N份Pod的yaml文件设置好正确的镜像地址、挂载的数据卷、配置以及配置好网络只需要确保这N份yaml文件除了名字之外其余内容完全相同譬如pod_1,pod_2,…,pod_n接着用kubectl工具提交给k8s集群N个服务实例就部署好了。
比如部署后发现分配的CPU和内存资源太少了需要修改Pod的yaml文件。
这个时候就是灾难了因为你得人为修改这N份yaml文件。
且不说损耗人力更重要的是极易出错就算是用shell脚本你也会发现用起来没那么顺畅。
其次实际生产中服务发布上线之后总是免不了迭代谁还不会写一两个Bug了客户/产品经理的需求单岂是一两次就提完了的。
这就意味着必须升级线上服务。
也是可以的。
做法也不复杂首先把k8s集群中已经部署的Pod服务删除然后再把修改好的N份Pod的yaml文件提交给k8s完成部署或者直接修改kubectl
xxx线上服务的配置信息k8s会先删除老Pod再创建新的Pod。
不过这种操作会有个很大的问题在删除Pod和新建Pod中间会有一段时间无法正常服务客户端请求全部失败。
这就需要衡量你的服务是否能够接受这样子的“缺陷”当然你可以通过选择请求流量最小譬如晚上操作也可以提前告知用户接下来某个时间段要更新服务、这个时间内不要向我发送请求。
其实你也可以选择这么部署再准备N份Pod的yaml文件名字换另一组譬如pod_n1,pod_n2,…,pod_nn然后先提交部署新的N份yaml紧接着再删除老的N个Pod。
实际生产中往往会管理多条业务线的服务于是一个非常合理的需求自然而然就提出了能否把不同业务线的服务分开管理一方面防止不同服务互相干扰另一方面方便做资源隔离和管理。
但是这种做法太重了首先是部署k8s是一件相对耗时耗力的事情其次实际生产环境也不一定有这么多的机器。
最佳的方案是能够在一套k8s集群中完成当然不排除在一些项目中会要求部署多套k8s集群。
综上我们可以发现仅仅使用PodVolume,ConfigMap,Secret和Service包括其中一种对象无法满足更多的常见的、可能更复杂的实际生产场景。
k8s自然有解决办法和机制这也是本文讨论的服务管理这也是本文要重点讨论的几个API对象概括来说
管理无状态的服务用Deployment管理有状态服务用StatefulSet隔离服务资源用Namespace
接下来我们来看Deployment、StatefulSet和Namespace分别是怎么使用的吧
官方文档总是说些听不懂的话而且这里又引入了新的名词ReplicaSet。
这个是什么
首先Deployment、ReplicaSet和Pod之间的关系如下图片引自书籍《k8s-in-action》[4]
其次在《K8S系列一概念入门》[1]文中对Deployment、ReplicaSet和Pod三者之间的关系有过介绍
ReplicaSet的作用就是管理和控制Pod管控他们好好干活。
但是ReplicaSet受控于Deployment。
形象来说ReplicaSet就是总包工头Deployment手下的小包工头。
但是上面的描述会有点小问题。
严格来说ReplicaSet是一个独立的API对象所谓的“ReplicaSet受控于Deployment”是当创建了Deployment对象后它会自动创建ReplicaSet来管理Pod。
这就好像你准备装修你的房子Deployment就是一个非常棒的装修公司而ReplicaSet则是实际干活的包工头而Pod则是每个干活的工人。
装修公司只需要告诉包工头这个工程需要多少个工人干活之后包工头就会实时监控每个工人如果有M个工人请假包工头会马上再雇佣M个工人参与进来。
如果你觉得说这批工人做工质量不行啊我需要升级更好的。
那么装修公司会马上撤走这个工程队包括包工头和他手下所有工人再雇佣新的工程队包括新的包工头和新的工人。
可以看到**Deployment的高可用实际上是ReplicaSet的特性Deployment实际特性则是做服务的平滑升级**也就对应了上面例子提到的“更换工程队”。
好的那就让我们一起来看看Deployment的yaml文件来自官网[3]
nginxtemplate:metadata:labels:app:
80对比Pod的yaml文件我们会发现Deployment比Pod多了几个字段
‘replicas’控制实际在运行的Pod数量‘selector’通过该label管理对应的Pod请留意’template.metadata.labels’
由此也可以窥探到Deployment通过ReplicaSet管理Pod的内在机制创建’replicas’个Pod并且赋予Pod用户指定的label和一个名为’pod-template-hash’的label内容为一个随机生成9位数的hash值通过’selector’实时匹配在运行的Pod数量不足则创建、非Running状态的杀死后重建、超过则杀死多余的。
管理过程如下图
接下来让我们分别来看Deployment的两个特性高可用和平滑升级。
HAIT术语指系统无中断地执行其功能的能力代表系统的可用性程度。
是进行系统设计时的准则之一。
高可用性系统与构成该系统的各个组件相比可以更长时间运行。
高可用的核心是无中断提供服务。
因此提升高可用可以从几个方面入手
提升程序的鲁棒性减少crash增加服务实例如采取主从冷热和双主双热甚至是多主的集群工作方式
实际生产中最佳手段还是增加服务实例毕竟谁也不能保证自己写的程序没有Bug。
而Deployment的就可以做到确保k8s集群中实时存在用户需要的N个服务在正常工作。
笔者做了一个实验假设我需要的是3个服务实例那么只需要设置Deployment的yaml文件的’replicas:
3’即可提交后发现集群上确实启动了三个Pod。
紧接着模拟线上服务挂了的状态手动删除了其中一个Pod再来看k8s中Pod的情况发现马上有新的Pod被拉起。
下图展示了整个过程删除的Pod名字为’kubia-depl-765b79cff9-grzbm’而被Deployment新拉起来的Pod名字为’‘kubia-depl-765b79cff9-zxx5g’
前文已经说过Deployment的高可用实际上是ReplicaSet的特性。
这个怎么理解呢
我们在通过Deployment部署Pod服务之后到k8s分别查看Deployment、ReplicaSet和Pod会发现一个有趣的现象ReplicaSet的名字是则Deployment名字基础上加了一个’-9位hash值’生成的并且其’selector’的label用户自定义的label‘pod-template-hash:9位hash值’而Pod的名字则是ReplicaSet名字基础上再增加一个’-5位hash值’生成的并且其label严格等于ReplicaSet的’selector’的label。
如下图所示
因此确保’replicas’数量的Pod运行的特性的提供者就是ReplicaSet不信你可以尝试一口气把所有的Pod都删除了最后发现还是会被ReplicaSet拉起来。
该过程如下图
上面我们已经看到其实用ReplicaSet也能够管理多个服务并且k8s最早开源的时候也没有Deployment对象。
但是之后发现在实际生产中程序版本迭代是一件常见且相对高频的操作。
于是就推出了Deployment早前有ReplicationController自动Deployment推出之后就不被推荐使用了。
在《k8s-in-action》[4]中第九章专门介绍了Deployment的升级书中有一幅描述Deployment升级的示意图
可以看到升级过程和上一节高可用提到的实时确保’replicas’个Pod在运行是不一样的后者是依靠ReplicaSet完成的而前者则是Deployment的功能特性。
但凡修改Deployment中非’replicas’的其他有效字段镜像地址’image’、资源’resources’都会触发Deployment的升级。
笔者做了一个实验修改了’resources’可以看到
然而实际生产中仅仅知道Deployment会做平滑升级还不足够还需要掌握选择升级策略和控制升级频率。
关于这块希望做更详细了解的同学建议阅读《Deployment
Strategies》[6]和《Kubernetes部署策略详解》[7]。
Deployment有两种升级策略Recreate和RollingUpdate。
前者是先把所有旧的/已有的Pod全部销毁然后再拉起新的后者则是一个一个销毁旧的/已有的Pod同时再一个一个拉起新的。
RollingUpdate是默认的。
Deployment升级频率
这里重点介绍RollingUpdate策略的参数主要原因它是大部分实际生产中最佳的选择。
RollingUpdaterollingUpdate:maxSurge:
25%敲重点maxSurge和maxUnavailable是相对比较重要且理解不直观的两个参数网上关于这俩参数的解读有很多大部分的解释仍旧不直观。
笔者结合实验在这里尝试解释
核心理解点在于maxSurge关系到启动新的Pod的速度而maxUnavailable则关联到杀死旧的Pod的速度。
RollingUpdate的任务就是一个一个销毁旧的/已有的Pod同时再一个一个拉起新的。
我们假设’replica’为rpmaxSurge为ms绝对值而maxUnavailable为mu绝对值。
实际上RollingUpdate是先拉起mu个新的Pod同时销毁min{msmu剩余的}个旧的/已有的确保旧的/已有的被销毁了而新的被拉起了之后再拉起mu个新的Pod同时销毁min{msmu剩余的}个旧的/已有的。
借用《k8s-in-action》[4]的过程图来说明
由此可见maxSurge和maxUnavailable越大更新越快反之更新会越慢。
并且k8s要求maxSurge和maxUnavailable不能同时为0为什么
因为都为0的话根本没办法更新了那么到底要怎么设置这两个值这就要视实际生产要求而定。
实验一replicas4maxSurge0maxUnavailable1,2,4。
实验二replicas2maxUnavailable0maxSurge1,2
但是由于笔者试用的k8s集群资源有限一次至多4个Pod在跑而且时不时会被抢占资源因此只能做replicas2的实验再大一点就会跑不起来。
大家可以自行实验。
不知道会不会有同学在想如果我追求快速升级迭代那是不是把maxSurge设置跟’replicas’一样最好一次性就升级好了
但是请注意笔者分享自己实际遇到的坑k8s集群总归会有资源不足的情况比如cpu、gpu甚至是ip资源因此在资源非常紧张的时候如果maxSurge越大升级反而不见得越快并且在资源恰好足够的时候maxSurge大于零就会造成升级卡主因为RollingUpdate实际升级过程是先拉起maxSurge新实例紧接着销毁maxUnavailable个旧的/已有的实例。
切忌小心升级别以为用了k8s就万事大吉
在讨论StatefulSet之前笔者先说明实际生产中笔者所用业务并没有使用到该类管理器API对象所有的知识都是从《k8s-in-action》[4]学习的。
首先我们要知道为什么需要StatefulSet或者说它和Deployment不同点在哪
《k8s-in-action》[4]在第十章一开头花了很大的篇幅在描述这个问题笔者通过书籍、网上博客和实验感觉文章《StatefulSet和Deployment的区别
稳定的、唯一的网络标识。
稳定的、持久的存储。
有序的、优雅的部署和伸缩。
有序的、优雅的删除和停止。
有序的、自动的滚动更新。
而在文章《Kubernetes服务之StatefulSets简介》[9]则对于StatefulSet的用法细节总结得很好
笔者试验了StatefulSet的CURD发现其创建和扩缩容确实都是按顺序扩增、缩小但是如果直接把StatefulSet删除的话那么所有的Pod也就被删除了
创建可以看到Pod是逐个被创建并且以StatefulSet的名字id(从0开始递增)的形式为其名字。
扩容可以看到扩增的Pod是在已有的id基础上继续递增并且也是逐个创建。
笔者这个时候在思考如果仅仅是其中一个Pod挂了会怎么样实验后发现StatefulSet会拉起并且StatefulSet并没有中间创建ReplicaSet或者ReplicationController因此有理由相信StatefulSet自己实现了实时监督Pod和拉起失败Pod的能力可能复用了StatefulSet的代码。
仅仅从CURD层面看StatefulSet和Deployment是完全不一样的。
至于其他方面的特性笔者还没来得及深入了解挖个坑吧
namespace那么为什么要特别为它设立一个章节呢因为越是基础越是重要也越是容易被忽略请一定合理为不同的项目创建Namespace
实际生产中使用kubectl工具时会发现有些API对象有缩写比如pod是poreplicaset就写rs。
怎么查看呢
api-resources非常重要可以看到当前k8s的所有API对象、其缩写、它是否可以被Namespace隔离等
最后如果文章中有纰漏非常欢迎留言或者私信指出有理解错误的地方更是欢迎留言或者私信告知。
总之非常欢迎大家留言或者私信交流更多k8s的问题。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback