k8s实战-2
- 一、Deployment
- 1.多副本
- 2.扩缩容
- 3.自愈&故障转移
- 4.滚动更新
- 5.版本回退
- 二、Service
- 1.ClusterIP
- 2.NodePort
- 总结
一、Deployment
Deployment
是 k8s
中的一个资源对象,用于管理应用的副本(Pods)
。它的主要作用是确保集群中运行着指定数量的应用实例(Pods)
简单理解:
-
Deployment
类似于一个“控制器”,它负责确保集群中有一定数量的某个应用的实例在运行。 -
你可以把它想象成一个“工厂”,这个工厂负责生产并维护一定数量的产品(
Pods
)。 -
如果产品(
Pods
)出现问题或者需要更新,工厂会自动修复或替换这些产品,确保始终有指定数量的产品在运行
功能特点:
-
版本管理:通过滚动更新(
Rolling Update
)的方式,可以逐步更新应用的实例而不影响服务的可用性。 -
回滚:如果更新失败,可以轻松回滚到以前的版本。
-
自动扩展:可以根据负载自动增加或减少应用实例的数量。
-
健康检查:自动检测并替换故障的实例。
1.多副本
使用命令行的方式创建多副本,其中关键字--replicas=
:指定副本的数量
kubectl create deployment my-dep --image=nginx --replicas=3
使用yaml
文件的方式创建多副本
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: my-dep
name: my-dep
spec:
replicas: 3
selector:
matchLabels:
app: my-dep
template:
metadata:
labels:
app: my-dep
spec:
containers:
- image: nginx
name: nginx
2.扩缩容
就是可以修改副本的数量
扩充或减少副本:
kubectl scale --replicas=5 deployment/my-dep
当然也可以使用如下语句:
kubectl edit deployment my-dep
#修改 replicas
3.自愈&故障转移
自愈是指系统在检测到故障时自动修复自身的能力。通常,自愈策略是在不影响服务可用性的前提下,通过自动重启服务实例、替换故障组件等方式来恢复系统的正常运行。
案例:Web 应用的自愈
假设你有一个部署在 Kubernetes
集群上的 Web
应用,该应用通过一个 Deployment
管理,确保始终有三个副本(Pods)
在运行。以下是自愈的详细过程:
初始状态:
有三个副本(Pods)在运行:Pod A、Pod B 和 Pod C。
应用通过一个 Service 被外部客户端访问。
发生故障:
Pod B 因为某种原因(如内存溢出、CPU 使用率过高)变得不可用。
自动修复:
Deployment 配置了健康检查(Health Checks),通过探测器(Probes)检测到 Pod B 已经不再健康。
Kubernetes 自动终止 Pod B,并启动一个新的 Pod D 来替代 Pod B。
新的 Pod D 加入集群,并且 Service 会将其纳入负载均衡池。
最终状态:
系统恢复正常,有三个健康的副本(Pod A、Pod D 和 Pod C)在运行。
外部客户端通过 Service 访问应用时,不会察觉到任何中断。
故障转移是指在主系统(Primary System
)发生故障时,自动切换到备用系统(Secondary System
)的过程。通常,故障转移用于处理更严重的故障,如整个节点或区域的故障。
案例:数据库的故障转移
假设你有一个分布式数据库系统,该系统由两个数据库实例组成:一个主数据库(Primary Database
)和一个从数据库(Secondary Database
)。以下是故障转移的详细过程:
初始状态:
主数据库运行在节点 A 上,负责读写操作。
从数据库运行在节点 B 上,负责同步主数据库的数据,并准备在需要时接管主数据库的功能。
发生故障:
节点 A 因为硬件故障而完全不可用。
自动切换:
故障检测机制(如心跳监测)检测到节点 A 的故障。
自动切换脚本或工具(如 MySQL 的高可用性解决方案)将从数据库提升为主数据库。
从数据库 B 成为主数据库,开始接受读写操作。
客户端的连接指向新的主数据库。
最终状态:
系统恢复正常,客户端通过新的主数据库(原从数据库 B)继续进行读写操作。
如果可能的话,可以修复或替换节点 A,并将其重新配置为从数据库。
4.滚动更新
滚动更新是一种部署策略,通过逐步替换旧的应用程序实例**(Pods)**来部署新版本的应用程序。在滚动更新的过程中,新版本的应用程序会逐渐取代旧版本的应用程序,直到所有实例都被更新为止。
优点
平滑过渡:在更新过程中,始终保持一部分应用实例可用,避免服务中断。
回滚方便:如果新版本出现问题,可以轻松回滚到旧版本。
健康检查:确保只有健康的新实例才被投入使用。
滚动更新的工作流程
滚动更新的一般工作流程如下:
创建新版本:创建一个带有新版本标签的 Deployment。
逐步替换:Kubernetes 逐步终止旧版本的 Pods,并创建新版本的 Pods。
健康检查:确保新创建的 Pods 是健康的,然后再终止旧版本的 Pods。
完成更新:重复上述步骤,直到所有旧版本的 Pods 都被新版本的 Pods 替换
案例说明
假设你有一个部署在 Kubernetes 集群上的 Web 应用,该应用通过一个 Deployment 管理,确保始终有三个副本**(Pods)**在运行。以下是滚动更新的详细过程:
初始状态
初始部署:
你有一个带有标签 app:1.0 的 Deployment。
Deployment 确保有三个副本(Pods)在运行:Pod A、Pod B 和 Pod C。
应用通过一个 Service 被外部客户端访问。
更新应用
创建新版本:
你更新 Deployment 的配置,使其使用带有标签 app:1.1 的新版本镜像。
逐步替换:
Kubernetes 开始逐步终止旧版本的 Pods,并创建新版本的 Pods。
假设 Kubernetes 首先终止 Pod A,并创建一个新的 Pod D 使用标签 app:1.1 的镜像。
健康检查:
新创建的 Pod D 通过健康检查,表明它已经准备好接收流量。
Pod A 被终止,Pod D 加入集群。
重复过程:
Kubernetes 继续终止 Pod B,并创建 Pod E 使用标签 app:1.1 的镜像。
Pod E 通过健康检查,Pod B 被终止,Pod E 加入集群。
最后,Pod C 被终止,Pod F 被创建并加入集群。
更新完成
最终状态:
系统恢复正常,有三个带有标签 app:1.1 的健康副本(Pod D、Pod E 和 Pod F)在运行。
外部客户端通过 Service 访问应用时,不会察觉到任何中断。
可以通过如下代码来查看滚动更新状态
kubectl rollout status deployment/deployment名称
5.版本回退
#历史记录
kubectl rollout history deployment/你的deploy名称
#查看某个历史详情
kubectl rollout history deployment/你的deploy名称 --revision=2
#回滚(回到上次)
kubectl rollout undo deployment/你的deploy名称
#回滚(回到指定版本)
kubectl rollout undo deployment/你的deploy名称 --to-revision=2
二、Service
Service
是 Kubernetes
中的一个抽象层,用于定义一组 Pod
的逻辑集合以及访问这些 Pod
的策略。它是应用间的网络服务发现和负载均衡的基础。
简单理解:
Service 类似于一个“电话簿”,它知道如何找到你的应用实例(Pods)。
你可以把它想象成一个“电话交换机”,这个交换机负责将流量转发到正确的地方。
即使应用实例(Pods)的 IP 地址和端口发生变化,Service 仍然能够正确地找到它们并进行通信。
功能特点:
网络发现:Service 提供了一个固定的 IP 地址和端口号,即使后端的 Pods 发生变化,Service 的地址也不会变。
负载均衡:Service 会将请求均匀地分发到后端的 Pods 上,确保负载均衡。
访问策略:可以定义 Service 的访问方式,如 ClusterIP、NodePort 或 LoadBalancer。
1.ClusterIP
ClusterIP
是默认的服务类型,它为服务分配一个集群内的虚拟 IP
地址(Cluster IP
)。这个 IP
地址只能在集群内部访问,不能直接从集群外部访问。
特点:
内部访问:只能从集群内部访问,不能直接从集群外部访问。
固定 IP 地址:为服务分配一个固定的 Cluster IP 地址。
负载均衡:在集群内部将流量均匀地分发到后端的 Pods。
健康检查:自动过滤掉不健康的 Pods,确保只将请求发送到健康的 Pods。
使用场景:
内部服务:当你只需要在集群内部访问服务时,使用 ClusterIP 类型。
内部微服务:内部微服务之间相互调用时,可以使用 ClusterIP。
示例:
创建一个 ClusterIP
类型的服务:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 9376
type: ClusterIP
kubectl apply -f path/to/service.yaml
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service ClusterIP 10.96.5.203 <none> 80/TCP 1d
也可以通过命令行方式:
# 等同于没有--type的
kubectl expose deployment my-dep --port=8000 --target-port=80 --type=ClusterIP
2.NodePort
NodePort
类型的服务为集群中的每个节点分配一个固定的端口(Node Port)
。这个端口可以从集群外直接访问,通过 Node Port 在这里插入代码片
可以访问到集群内的服务。
特点:
外部访问:可以从集群外部通过 <node-ip>:<node-port> 的形式访问服务。
固定端口范围:端口范围通常在 30000-32767 之间(可配置)。
自动负载均衡:在集群内部将流量均匀地分发到后端的 Pods。
使用场景:
简单外部访问:当你需要从集群外部简单地访问服务时,使用 NodePort 类型。
开发和测试环境:在开发和测试环境中,快速暴露服务以便测试。
示例:
创建一个 NodePort在这里插入代码片
类型的服务:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 9376
nodePort: 30000
type: NodePort
kubectl apply -f path/to/service.yaml
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service NodePort 10.96.5.203 <none> 80:30000/TCP 1d
总结
本篇主要介绍了k8s的deployment和service的一些基础概念和命令,具体还是的实际的动手操作。