Kubernets学习圣经: 底层原理和实操
说在前面:
现在拿到offer超级难,甚至连面试电话,一个都搞不到。
尼恩的技术社群中(50+),很多小伙伴凭借 “左手云原生+右手大数据”的绝活,拿到了offer,并且是非常优质的offer,据说年终奖都足足18个月。
而云原生的核心组件是 K8S,但是 K8S 又很难。从Java高薪岗位和就业岗位来看,K8S 现在对于 高级工程师, 架构师,越来越重要,下面是一个高薪Java岗位的K8S技能要求:

市面上很多的pdf和视频,都是从技术角度来说的,讲的晦涩难懂。
在这里,尼恩从架构师视角出发,基于自己的尼恩Java 架构师知识体系和知识宇宙,对K8S的核心原理做一个宏观的介绍, 一共十二部分, 组成一本《K8S学习圣经》
《K8S学习圣经》 带大家穿透K8S,实现K8S自由,让大家不迷路。
《K8S学习圣经》的组成
- 第一部分:云原生(Cloud Native)的原理与演进
- 第二部分:穿透K8S的8大宏观架构
- 第三部分:最小化K8s环境实操
- 第四部分:Kubernetes 基本概念
- 第五部分:Kubernetes 工作负载
- 第六部分:Kubernetes 的资源控制
- 第七部分: SVC负载均衡底层原理
- 第八部分: Ingress底层原理和实操
- 第九部分: 蓝绿发布、金丝雀发布、滚动发布、A/B测试 实操
- 第十部分: 服务网格Service Mesh 宏观架构模式和实操
- 第十一部分: 使用K8S+Harber 手动部署 Springboot 应用
- 第十二部分: CICD核心实操 :jenkins流水线部署springboot应用到k8s集群
- 第十三部分: k8s springboot 生产实践(高可用部署、基于qps动态扩缩容、prometheus监控)
- 第十四部分:k8s生产环境容器内部JVM参数配置解析及优化
米饭要一口一口的吃,不能急。
结合《K8S学习圣经》,尼恩从架构师视角出发,左手云原生+右手大数据 +SpringCloud Alibaba 微服务 核心原理做一个宏观的介绍。由于内容确实太多, 所以写多个pdf 电子书:
(1) 《 Docker 学习圣经 》PDF (V1已经完成)
(2) 《 SpringCloud Alibaba 微服务 学习圣经 》PDF (V1已经完成)
(3) 《 K8S 学习圣经 》PDF (coding…)
(4) 《 flink + hbase 学习圣经 》PDF (planning …)
以上学习圣经,并且后续会持续升级,从V1版本一直迭代发布。 就像咱们的《 尼恩 Java 面试宝典 》一样, 已经迭代到V60啦。
40岁老架构师尼恩的掏心窝: 通过一系列的学习圣经,带大家穿透“左手云原生+右手大数据 +SpringCloud Alibaba 微服务“ ,实现技术 自由 ,走向颠覆人生,让大家不迷路。
本PDF 《K8S 学习圣经》完整版PDF的 V1版本,后面会持续迭代和升级。供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。
以上学习圣经的 基础知识是 尼恩的 《 高并发三部曲 》,建议在看 学习圣经之前,一定把尼恩的《 Java高并发三部曲 》过一遍,切记,切记。
本部分目录(第六部分)
文章目录
第六部分:Kubernetes 的资源控制
动态的扩容缩容的重要性
在微服务应用中,在高并发场景下, 需要对 springboot、SpringCloud 、nginx 应用进行动态的扩容缩容
- 当微服务的性能不足以支撑庞大的访问量,可以动态扩容
- 而当访问量减少时,过多的微服务实例会白白占用服务器资源,造成资源浪费时,可以动态缩容。
所以动态的扩容缩容 ,是高并发应用的标配。
但是,社群中很多的小伙伴,不懂动态的扩容缩容 底层原理。
没有做过 动态的扩容缩容实操。因此,很容易错过很多 高质量的 offer。
目前业界主流的方案,是基于K8S实现 动态的扩容缩容。
这一个部分, 尼恩带着大家,从Deployment 资源对象 入手,一步一步,带大家最终,完成基于K8S实现 动态的扩容缩容实操。
1:Deployment 资源对象
为了更好地解决Pod编排的问题,k8s在V1.2版本开始,引入了deployment资源对象,
注意:
deployment资源并不直接管理pod,而是通过管理replicaset来间接管理pod,
简单的说:deployment管理replicaset,而 replicaset管理pod。

deployment的主要功能有下面几个:
- 支持replicaset的所有功能
- 支持发布的停止、继续
- 支持版本的滚动更新和版本回退
- 扩容和缩容
所以: 我们部署一个应用一般不直接写Pod,而是部署一个Deployment
Deployment 使用场景:Deployment 主要针对无状态服务,有状态服务使用 StatefulSet. 那么,什么是无状态服务, 什么是有状态服务, 这个咱们稍微晚点介绍。
Deploy编写规约
https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/#writing-a-deployment-spec
Deployment的创建
编写一个Deployment的yaml赋予Pod自愈和故障转移能力。 基本格式如下:
.metadata.name指定deploy名字replicas指定副本数量selector指定匹配的Pod模板。template声明一个Pod模板
下面是一个例子 deployment-demo.yml
apiVersion: apps/v1 #版本号
kind: Deployment #类型
metadata: #元数据
name: demo-deployment #rs名称
namespace: default #所属命名空间
labels: #标签
controller: deploy
spec: #详情描述
replicas: 3 #副本数量
revisionHistoryLimit: 5 #保留历史版本,默认是10
paused: false #暂停部署,默认是false
progressDeadlineSeconds: 600 #部署超时时间(s),默认是600
strategy: #策略
type: RollingUpdate #滚动更新策略
rollingUpdate: #滚动更新
maxSurge: 1 #最大额外可以存在的副本数,可以为百分比,也可以为整数
maxUnavailable: 1 #最大不可用状态的pod的最大值,可以为百分比,也可以为整数
selector: #选择器,通过它指定该控制器管理哪些pod
matchLabels: #Labels匹配规则
app: nginx-gateway
matchExpressions: #Expression匹配规则
- {
key: app, operator: In, values: [nginx-gateway]}
template: #模板,当副本数量不足时,会根据下面的模板创建pod副本
metadata:
labels:
app: nginx-gateway
spec:
containers:
- name: nginx-gateway
image: harbor.daemon.io/demo/nginx-gateway:1.0-SNAPSHOT
ports:
- containerPort: 80
通过 下面的命令进行操作:
# 创建 deployment 资源对象, 进一步创建 rs对象, pod 对象
kubectl apply -f deployment-demo.yml
# 查看 deployment 资源对象
kubectl get deployments
# 查看 ReplicaSet 资源对象
kubectl get ReplicaSet
使用kubectl get deployments 查看 deployment 资源对象

在检查集群中的 Deployment 时,所显示的字段有:
- NAME 列出了集群中 Deployment 的名称。
- READY 显示应用程序的可用的 副本 数。显示的模式是“就绪个数/期望个数”。
- UP-TO-DATE 显示为了达到期望状态已经更新的副本数。
- AVAILABLE 显示应用可供用户使用的副本数。
- AGE 显示应用程序运行的时间。
使用 kubectl get ReplicaSet 查看 ReplicaSet 资源对象

ReplicaSet 输出中包含以下字段:
- NAME 列出名字空间中 ReplicaSet 的名称;
- DESIRED 显示应用的期望副本个数,即在创建 Deployment 时所定义的值。 此为期望状态;
- CURRENT 显示当前运行状态中的副本个数;
- READY 显示应用中有多少副本可以为用户提供服务;
- AGE 显示应用已经运行的时间长度。
注意:
ReplicaSet 的名称始终被格式化为 [Deployment名称]-[随机字符串] 。
其中的随机字符串是使用 pod-template-hash 作为种子随机生成的。
Deployment 资源、replicaset资源、Pod资源 三者之间的关系
一个Deploy产生三个
- Deployment资源
- replicaset资源
- Pod资源
Deployment控制RS,RS控制Pod的副本数
ReplicaSet: 只提供了副本数量的控制功能
Deployment: 每部署一个新版本就会创建一个新的副本集,利用他记录状态
Deployment 基本操作
副本扩容
原本定义3个副本,现在扩容到10个副本
kubectl scale deployment demo-deployment --replicas 10

副本缩容
原本定义3个副本,现在缩容到2个副本
kubectl scale deployment demo-deployment --replicas 2

Deployment 更新机制
仅当 Deployment Pod 模板(即 .spec.template )发生改变时,例如模板的标签或容器镜像被更新, 就会触发 Deployment 滚动更新。 其他更新(如对 Deployment 执行扩缩容的操作)不会触发滚动更新动作。
滚动更新 原理:
创建新的rs,准备就绪后,替换旧的rs(此时不会删除,因为revisionHistoryLimit 指定了保留几个版本)
准备:升级镜像
升级一下 nginx 的镜像,并且导入

可以使用命令,将 镜像从1.0更新到2.0
kubectl set image deployment/demo-deployment nginx-gateway=harbor.daemon.io/demo/nginx-gateway:2.0
在线修改yaml
也可以使用 使用edit命令 在线修改yaml
kubectl edit deployment/demo-deployment
deployment "nginx-deployment" edited
滚动机制相关的命令
- 新创建: 当 Deployment controller 观测到有新的 deployment 被创建时,会直接创建出一个新的 ReplicaSet 来做这件事。
- 变更: 当更新了一个的已存在并正在进行中的 Deployment,每次更新 Deployment都会创建一个新的 ReplicaSet并扩容它,同时回滚之前扩容的 ReplicaSet ,将它添加到旧的 ReplicaSet 列表中,开始缩容。
查看可用的回滚版本
kubectl rollout history deployment demo-deployment
查看滚动状态
kubectl rollout status deployments demo-deployment
监控更新过程
kubectl get deployments demo-deployment --watch

回滚到上一个步骤
kubectl rollout undo deployment/demo-deployment
暂停和恢复
在暂停状态下的更新操作,多次更改,只会触发一次 rolling 记录
kubectl rollout pause deployment/nginx-deployment
回滚策略
记录保留
.spec.revisionHistoryLimit默认设置保留数量为 2。
在 Deployment 中设置来指定保留多少旧的 ReplicaSet。余下的将在后台被当作垃圾收集。
滚动更新数量
.spec.strategy指定新的Pod替换旧的Pod的策略
使用Deployment 进行灰度发布
使用Deployment 进行金丝雀发布(灰度发布)、蓝绿发布、滚动发布 的原理与实操,
请参见《K8S学习圣经》的第九部分。

2:副本资源 RC、副本集RS 资源对象
RC: ReplicasController 副本控制器
RS:ReplicasSet:副本集;
Deployment【滚动更新特性】默认的 控制器的是ReplicasSet 副本集
实际上 RS 和 RC 的功能基本一致,目前唯一的一个区别就是 :
RC 只支持基于等式的 selector(env=dev 或 environment!=qa),但 RS 还支持基于表达式的 selector(version in (v1.0, v2.0)), RS对复杂的运维管理就非常方便了。
虽然ReplicasSet强大,但是我们也不直接写RS;都是直接写Deployment的,Deployment会自动产生RS。Deployment每次的滚动更新都会产生新的RS。
接下来, 咱们还是从RC开始介绍吧。
RC(Replication Controller)
Replication Controller 简称 RC,RC 是 Kubernetes 系统中的核心概念之一,简单来说,RC 可以保证在任意时间运行 Pod 的副本数量,能够保证 Pod 总是可用的。
如果实际 Pod 数量比指定的多,那就干掉多余的,
如果实际数量比指定的少就新启动一些 Pod,当 Pod 失败、被删除或者挂掉后,RC 都会去自动创建新的 Pod 来保证副本数量,所以生产场景中,哪怕只有一个pod,也应该使用 RC 来管理我们的 Pod。
就是由于RC的副本控制机制,哪怕运行 Pod 的节点挂了,RC 检测到 Pod 失败了,就会去合适的节点重新启动一个 Pod 就行,不需要我们手动去新建一个 Pod 了。
下面我们使用 RC 来管理一个 Nginx 的 Pod,YAML 文件如下:

上面的 YAML 文件相对于我们之前的 Pod 的格式:
- kind:资源对象的种类,这里创建的是 RC
- spec.replicas: 指定 Pod 的副本数量,默认为 1,此处为 2
- spec.selector: RC 通过该属性,来筛选要控制的 Pod,可以理解为筛选对应标签
- spec.template: 这里就是我们之前的 Pod 的定义的模块,比如容器镜像、名称、端口、环境变量
- spec.template.metadata.labels: Pod的标签,注意这里的 Pod 的 labels 要和 spec.selector 相同,这样 RC 就可以来控制当前这个 Pod 了。
这个 YAML 文件中的意思就是定义了一个 RC 资源对象,它的名字叫 nginx-gateway-rc,保证一直会有 3个 Pod 运行。
注意 spec.selector 和 spec.template.metadata.labels 这两个字段必须相同,否则会创建失败的,
当然我们也可以不写 spec.selector,这样就默认与 Pod 模板中的 metadata.labels 相同了。
所以为了避免不必要的错误的话,不写为好。
然后我们来创建上面的 RC 对象(保存为 nginx-rc-demo.yaml):
kubectl create -f demo-rc.yaml
或者
kubectl apply -f ndemo-rc.yaml
查看 RC:
kubectl get rc
查看详细的描述信息:
kubectl describe rc nginx-gateway-rc

接下来我们再通过 RC 来修改下 Pod 的副本数量为 4:
kubectl apply -f nginx-rc-demo.yaml
或者执行下面的命令编辑 RC 也可以
kubectl edit rc nginx-rc-demo

RS(Replication Set)
Replication Set 简称 RS,随着 Kubernetes 的高速发展,官方已经推荐我们使用 RS 和 Deployment 来代替 RC 了,实际上 RS 和 RC 的功能基本一致,目前唯一的一个区别就是 RC 只支持基于等式的 selector(env=dev 或 environment!=qa),但 RS 还支持基于集合的 selector(version in (v1.0, v2.0)),这对复杂的运维管理就非常方便了。
kubectl 命令行工具中关于 RC 的大部分命令同样适用于我们的 RS 资源对象。
不过我们也很少会去单独使用 RS,它主要被 Deployment 这个更加高层的资源对象使用,除非用户需要自定义升级功能或根本不需要升级 Pod,在一般情况下,我们推荐使用 Deployment 而不直接使用 Replica Set。
ReplicatSet的三个部分
RS 资源对象的创建跟 RC 的创建方法大同小异。

ReplicaSet 需要 apiVersion、kind 和 metadata 字段。
对于 ReplicaSet 而言,其 kind 始终是 ReplicaSet。
然后,ReplicaSet 也需要 .spec 部分。.spec 部分分为replicas 副本数、selector 选择器(选择算符)、Pod模板三个部分:
(1)一个用来标明应该维护的副本个数的数值、
(2)一个用来识别可获得的 Pod 的集合的选择算符、
(3)一个用来指定应该创建新 Pod 以满足副本个数条件时要使用的 Pod 模板。
replicas
你可以通过设置 .spec.replicas 来指定要同时运行的 Pod 个数。 如果实际的pod数量与预期不符合,ReplicaSet 创建、删

本文详细介绍了Kubernetes的核心组件,包括Deployment、ReplicaSet、DaemonSet和StatefulSet的原理与用法,以及如何通过HorizontalPodAutoscaling(HPA)实现动态扩容缩容。内容涵盖各组件的创建、管理、更新机制以及在不同场景下的应用,强调了动态扩容缩容在高并发应用中的重要性。此外,文章还讨论了使用K8S进行灰度发布、蓝绿发布等高级操作,以及如何实现基于CPU利用率的自动伸缩。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



