概述
本文介绍了如何在 Kubernetes (K8S) 集群中部署微服务,并模拟常见的故障场景(如 Pod 故障、节点故障、网络故障)以测试系统的容错能力。通过本实验,了解 Kubernetes 的自动恢复机制以及如何通过监控和日志分析快速定位和解决问题。
在 Kubernetes (K8S) 中,几乎所有的资源都可以通过 YAML 文件来定义和生成。YAML 文件是 Kubernetes 中最常用的资源定义方式,在本文中会通过一些yaml定义来创建服务和资源。
一.微服务部署
1.创建命名空间
为了隔离资源,首先创建一个命名空间,可以用不同的方法创建,这里分别列出来,选择其一即可。
使用命令行工具创建命名空间:
命令直接创建命名空间,操作简单但无法定义标签、注解等元数据,适合临时或快速使用。
# 通过命令直接创建命名空间
kubectl create namespace microservices# 查询当前所有命名空间
kubectl get namespaces
使用 YAML 文件创建命名空间:
通过定义 YAML 文件并使用 kubectl apply 创建命名空间,支持附加标签、注解等元数据,适合需要复杂配置或长期维护的场景。
# 生成并编辑yaml文件
vi microservices.yaml# 进入vi编辑界面输入i进入编辑模式,写入下方内容后按ESC,输入wq 保存退出
apiVersion: v1
kind: Namespace
metadata:name: microservices# 退出后输入以下命令创建命名空间
kubectl apply -f microservices.yaml # 查询当前所有命名空间
kubectl get namespaces
2.部署微服务
自主式 Pod 部署:
自主式 Pod 的特点是没有控制器管理,因此如果 Pod 被删除或发生故障,Kubernetes 不会自动恢复它。一般可以用于测试,生产环境不建议使用此方式。
自主式 Pod 的示例:
# 生成并编辑yaml文件
vi pod.yaml# 进入vi编辑界面输入i进入编辑模式,写入下方内容后按ESC,输入wq 保存退出
apiVersion: v1
kind: Pod
metadata:name: test-podzzsnamespace: microserviceslabels:app: tomcat
spec:containers:- name: tomcat-javaports:- containerPort: 8080image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/tomcat:9.0.67-jdk8imagePullPolicy: IfNotPresent# 退出后输入以下命令创建命名空间
kubectl apply -f pod.yaml# 查询pod状态,创建需要时间,开始是ContainerCreating,Running后才是正常
kubectl get pods -n microservices
控制器模式部署:
控制器模式是 Kubernetes 推荐的管理 Pod 的方式。控制器(如 Deployment、StatefulSet、DaemonSet 等)负责确保 Pod 的期望状态与实际状态一致。如果 Pod 被删除或发生故障,控制器会自动创建新的 Pod 以维持期望的副本数。
Deployment 控制器的示例
# 生成并编辑yaml文件
vi deployment.yaml# 进入vi编辑界面输入i进入编辑模式,写入下方内容后按ESC,输入wq 保存退出
apiVersion: apps/v1
kind: Deployment
metadata:name: test-podkzqnamespace: microservices
spec:replicas: 3selector:matchLabels:app: tomcattemplate:metadata:labels:app: tomcatspec:containers:- name: tomcat-javaports:- containerPort: 8081image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/tomcat:9.0.67-jdk8imagePullPolicy: IfNotPresent# 退出后输入以下命令创建命名空间
kubectl apply -f deployment.yaml# 查询pod状态,创建需要时间,开始是ContainerCreating,Running后才是正常
kubectl get pods -n microservices
3.暴露服务
概述:暴露服务是通过 Kubernetes 的 Service 资源为 Pod 提供一个稳定的网络访问入口,使用标签选择器(Label Selector)将一组 Pod 绑定到 Service,并通过 ClusterIP、NodePort 或 LoadBalancer 等类型为这些 Pod 分配一个固定的 IP 地址或 DNS 名称,使集群内部或外部的客户端能够可靠地访问应用程序,同时屏蔽 Pod 的动态 IP 变化和故障转移的复杂性,确保服务的高可用性和可访问性。
使用命令行工具创建 Service
通过命令式命令行快速创建 Service,仅支持关键参数配置,适合简单场景和快速测试,但灵活性和可管理性受限。自主式 Pod 没有控制器管理,因此 kubectl expose 无法自动获取其标签并生成 selector,故而不能直接使用 kubectl expose 命令创建 Service。此处用的是控制器模式的pod示例。
参数解释:
–port:定义 Kubernetes 服务(Service)对外暴露的端口,集群内部或其他服务通过该端口访问该服务。
–target-port:定义 Pod 中应用程序实际监听的端口.
NodePort:定义 Kubernetes 在每个节点上暴露的端口,用于外部访问。
# 创建Service
kubectl expose deployment test-podkzq --port=7081 --target-port=8080 --type=NodePort --namespace=microservices# 查询Service状态
kubectl get svc -n microservices# 访问测试
# 如果是内部交互可以用--port的端口及服务状态内的IP,如果外部访问就用node节点的IP和服务状态内的端口号
使用 YAML 文件创建Service
通过声明式 YAML 文件详细定义 Service 的所有配置,适合复杂场景和版本控制,确保灵活性和可重复性。
# 生成并编辑yaml文件
vi service.yaml# 进入vi编辑界面输入i进入编辑模式,写入下方内容后按ESC,输入wq 保存退出
apiVersion: v1
kind: Service
metadata:name: tomcat-kzq-servicenamespace: microservices
spec:selector:app: tomcatports:- protocol: TCPport: 7081targetPort: 8080type: NodePort# 退出后输入以下命令创建 Service
kubectl apply -f service.yaml# 查询及验证跟命令行创建是一样的
二.模拟故障观测
1.Pod故障模拟
仅适用于控制器模式部署的Pod
# 查询当前pod信息
kubectl get pod -n microservices# 删除pod,模拟故障
kubectl delete pod test-podkzq-57c469fd46-2qvvz -n microservices# 观察恢复 Kubernetes 会自动重新创建 Pod。使用以下命令观察 Pod 状态
kubectl get pods -n microservices -w
2.节点故障模拟
# 查询当前pod所处节点
kubectl get pods -n microservices -o wide# 在node节点停止服务,模拟节点故障
sudo systemctl stop kubelet# 观察Pod迁移 Kubernetes 会将 Pod 调度到其他可用节点
kubectl get pods -n microservices -o wide
调度前:
调度后:默认情况下,Pod 会容忍节点不可用一段时间(默认是 5 分钟),会在这个时间后调度
部分知识点梳理
名称空间namespace
概述:
Namespace是一种用于将集群资源划分为多个虚拟集群的机制。这些虚拟集群被称为命名空间 Namespace,每个 Namespace 提供了一个独立的环境,使得不同的团队、项目或应用可以在同一个 Kubernetes 集群中运行,而不会相互干扰。
主要特点:
资源隔离(将不同的资源隔离在不同的逻辑空间,避免命名冲突)
权限控制(通过RBAC为不同的命名空间设置不同的权限,确保访问授权)
资源配额(限制每个命名空间的资源用量,防止资源过度占用)
网络隔离(通过网络策略实现不同的命名空间网络隔离)
应用场景:多团队协作,多环境管理,资源配额管理,应用生命周期管理