redis 服务问题

问题类型 | 缓存雪崩(Cache Avalanche) | 缓存击穿(Cache Breakdown/Penetration with Hot Key) | 缓存穿透(Cache Penetration) |
---|---|---|---|
定义 | 大量缓存数据同时失效,导致大量请求直接打到数据库上。 | 热点数据(频繁访问的数据)在缓存中过期,导致大量请求直接打到数据库上。 | 请求查询一个不存在的数据,导致每次请求都直接打到数据库上。 |
原因 | - 缓存过期时间设置相同 - 缓存服务器宕机 | - 热点数据缓存过期 - 并发请求量大 | - 恶意攻击或业务逻辑错误导致查询不存在的数据 |
影响 | - 数据库瞬间承受大量请求,可能导致崩溃 - 系统响应时间变长 | - 数据库压力骤增 - 热点数据访问延迟增加 | - 数据库频繁执行无效查询,浪费资源 - 可能引发数据库性能问题 |
解决方案 | - 设置不同的过期时间(随机过期时间) - 使用互斥锁或队列控制请求 - 部署高可用缓存集群 | - 热点数据永不过期或设置较长的过期时间 - 使用互斥锁或分布式锁控制请求 | - 缓存空值或默认值 - 使用布隆过滤器过滤无效请求 - 接口层校验参数 |

shell
#关联GitLab服务器HIS-BACKEND项目与Programer主机HIS-BACKEND代码
[root@Programer ~]# cd HIS/HIS-BACKEND/
[root@Programer HIS-BACKEND]# git init #初始化仓库
已初始化空的 Git 仓库于 /root/HIS/HIS-BACKEND/.git/
[root@Programer HIS-BACKEND]# git remote add origin http://192.168.88.20/devops/HIS-BACKEND.git #关联本地与远程
[root@Programer HIS-BACKEND]# git remote -v
origin http://192.168.88.20/devops/HIS-BACKEND.git (fetch)
origin http://192.168.88.20/devops/HIS-BACKEND.git (push)
[root@Programer HIS-BACKEND]# git add ./ #添加代码到暂存区
[root@Programer HIS-BACKEND]# git commit -m "Init Backend Code" #提交本地版本库
[root@Programer HIS-BACKEND]# git tag v1 #创建v1标签
[root@Programer HIS-BACKEND]# git push -u origin --all #推送本地所有分支
[root@Programer HIS-BACKEND]# git push -u origin --tags #推送本地所有标签
总共 0(差异 0),复用 0(差异 0),包复用 0
sh
config : 配置git行为,用户名,邮箱等
init : 初始化一个git仓库
add : 将工作区文件添加到暂存区
commit : 将暂存区文件添加到本地仓库
push : 将本地仓库的文件推送到远程仓库
DOCKER
sh
# 上帝进程
容器启动时执行的第一个进程
只能在前台运行
# entrypoint
特性 | ENTRYPOINT |
CMD |
---|---|---|
作用 | 定义容器的主命令(不可轻易覆盖)。 | 定义默认参数或可覆盖的命令。 |
是否可被覆盖 | 仅通过 --entrypoint 覆盖。 |
通过 docker run 后的命令直接覆盖。 |
参数传递 | CMD 的内容会作为参数传递给 ENTRYPOINT 。 |
无(除非单独使用)。 |
推荐用法 | 固定主命令(如服务启动)。 | 提供默认参数或辅助命令。 |

Dockerfile 详解
指令 | 说明 |
---|---|
FROM | 指定基础镜像(scratch 代表空镜像) |
RUN | 在容器内执行命令,可以写多条 |
ADD | 把文件拷贝到容器内,如果文件是 tar.xx 格式,会自动解压 |
COPY | 把文件拷贝到容器内,不会自动解压 |
ENV | 设置启动容器的环境变量 |
WORKDIR | 设置启动容器的默认工作目录(唯一) |
CMD | 容器默认的启动参数(唯一) |
ENTRYPOINT | 容器默认的启动命令(唯一) |
USER | 启动容器使用的用户(唯一) |
EXPOSE | 使用镜像创建的容器默认监听使用的端口号/协议 |
sh
wget http://raw.githubusercontent.com/Ljohn001/ljohn_ops/master/redis/redis3.x.sh
curl -O https://raw.githubusercontent.com/Ljohn001/ljohn_ops/master/redis/redis3.x.sh
shell
# 嵌入式脚本 command
initsvc:
container_name: init
image: myos:8.5
command:
- sh
- -c
- |
for i in {1..9}
do
sleep 1
echo "${HOSTNAME} && $${HOSTNAME}" # $宿主机变量 $$ 容器内变量
done
熟悉 k8s/kubernetes 架构及操作,包括 pod、service、deployment 等核心组件
熟悉 Docker、包括 Dockerfile 制作镜像、Harbor 私有镜像仓库管理
熟悉使用华为云平台搭建和管理集群,了解阿里云、腾讯云等平台
熟悉使用 CentOS、Ubuntu、RHEL、Debian、Rocky 等主流 Linux 操作系统
熟悉 Ansible 自动化运维工具,能编写 Playbook 脚本,实现自动化运维
熟悉 CI/CD 流程与自动化工具,通过 Jenkins,Gitlab 实现代码管理
熟悉 Shell 语言的编写以及 sed、awk、grep 正则表达式的使用
熟悉 Lvs、Haproxy、Keepalived、Nginx 等高可用及负载均衡的安装和配置
熟悉 Web 服务器的配置和管理,包括 Apache、Nginx、Tomcat
熟悉网络通信原理,OSI 七层模型、TCP/IP 协议/Iptables 防火墙
熟悉 MySQL、Redis 数据库相关技术,掌握主从同步、读写分离的应用以及中间件部署调优
熟悉 RedHat 虚拟化 KVM、VMware 虚拟化技术
熟悉主流运维监控 Zabbix、Promethus、Grafana 的部署使用
了解 RocketMQ、RabbitMQ、kafka 消息队列
k8s
sh
角色和对应的组件
# master
APIServer # 整个系统的对外接口 供客户端和其他组件调用 后端元数据存储在etcd中(键值数据库)
Scheduler # 对集群内的资源进行分配和调度
ControllerManager # 管理控制器 大总管
etcd (重要 做高可用集群) # 注意很有可能面试会问,比如如何备份master 怎么做高可用
# 基于go语言 k8s运行中产生的所有元数据都存储在etcd中
# NOde
kubelet # 守护进程 负责在节点上维护和管理pod的运行
kube-proxy #
Runtime # 容器运行时 用于创建容器
# 镜像仓库
harbor
calico # 用来解决不同节点直接的容器实现互通,子网路由的方式 也可以设置网络策略 是一直种实现容器间网络互通的就解决方案 还有一种就是端口映射

sh
# 循环上传镜像
# read 可以用来批量赋值 _ 其他值赋给_但是不用
docker images|while read i t _;do
[[ "${t}" == "TAG" ]] && continue
[[ "${i}" =~ ^"harbor:443/".+ ]] && continue
docker tag ${i}:${t} harbor:443/k8s/${i##*/}:${t}
docker push harbor:443/k8s/${i##*/}:${t}
docker rmi ${i}:${t} harbor:443/k8s/${i##*/}:${t}
done
1、获取证书哈希值和token
sh
[root@master calico]# kubeadm token create --ttl=0 --print-join-command
kubeadm join 192.168.88.50:6443 --token rgrlf1.7pmhqwe4kvz8y4ay --discovery-token-ca-cert-hash sha256:87a9a99c8c4c2231760ea0645703cb77a2775f18f8d1414b71867f7b098e2435
kubeadm token create --ttl=0 --print-join-command
kubeadm join 192.168.88.50:6443 --token rgrlf1.7pmhqwe4kvz8y4ay --discovery-token-ca-cert-hash sha256:87a9a99c8c4c2231760ea0645703cb77a2775f18f8d1414b71867f7b098e2435

k8s为什么要关闭swap
维度 | 禁用 Swap 的必要性 |
---|---|
性能 | 避免磁盘 I/O 导致的延迟不可预测,确保低延迟应用的 SLO 达标。 |
调度 | 保证 requests/limits 精确反映物理内存使用,避免调度决策错误。 |
隔离 | 防止 Pod 通过 Swap 占用其他 Pod 的磁盘 I/O 资源,维护 Cgroups 隔离性。 |
稳定性 | 避免 OOM Killer 行为异常和连接跟踪表性能下降,减少节点级故障。 |
设计一致性 | 符合云原生无状态假设,与公有云实践保持一致,降低运维复杂度。 |
kubectl

sh
[root@master ~]# kubectl get nodes master -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master Ready control-plane 20h v1.29.2 192.168.88.50 <none> Rocky Linux 8.6 (Green Obsidian) 4.18.0-372.9.1.el8.x86_64 containerd://1.6.28

sh
docker images|while read i t _;do
[[ "${t}" == "TAG" ]] && continue
[[ "${i}" =~ ^"harbor:443/".+ ]] && continue
docker tag ${i}:${t} harbor:443/library/${i##*/}:${t}
docker push harbor:443/library/${i##*/}:${t}
docker rmi ${i}:${t} harbor:443/library/${i##*/}:${t}
done
pod
概念
sh
pod 可以理解为一个陈放容器的盒子 也可以理解为豌豆荚
异步创建
用户发送创建pod的请求,api server 接受请求后将请求保存至etcd,并返回保存结果,然后scheduler 调度器,通过调度算法给pod分配计算节点,再把计算出来的结果保存至etcd,这几步都是在master主节点中进行,在计算机点 kubelet 守护进程,用于维护和管理pod运行,它接受到api server的调用之后,会去调用runtime 容器运行时创建容器,最后把创建的结果保存到etcd。

状态

核心命令


重点 排错语法 工作重点

logs
sh
# 语法
kubectl logs pods名称 {参数/选项}
# 例如查看 查看名称空间 kube-system 下的 kube-proxy-qgwhr pod 日志
kubectl logs kube-proxy-qgwhr -n kube-system
describe
sh
# 语法
kubectl describe 资源类型 {资源名称} {选项/参数}
# Events: 事物日志 用于排错
[root@master metrics]# kubectl describe -n kube-system pod metrics-server-8569457874-hnlkx
。。。。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 8m52s default-scheduler Successfully assigned kube-system/metrics-server-8569457874-hnlkx to node-0001
Warning Failed 8m10s (x3 over 8m51s) kubelet Failed to pull image "harbor:443/plugins/metrics-server:v0.6.4": failed to pull and unpack image "harbor:443/plugins/metrics-server:v0.6.4": failed to resolve reference "harbor:443/plugins/metrics-server:v0.6.4": failed to do request: Head "https://harbor:443/v2/plugins/metrics-server/manifests/v0.6.4": tls: failed to verify certificate: x509: certificate is not valid for any names, but wanted to match harbor
Warning Failed 8m10s (x3 over 8m51s) kubelet Error: ErrImagePull
Normal BackOff 7m32s (x6 over 8m50s) kubelet Back-off pulling image "harbor:443/plugins/metrics-server:v0.6.4"
Warning Failed 7m32s (x6 over 8m50s) kubelet Error: ImagePullBackOff
Normal Pulling 7m17s (x4 over 8m51s) kubelet Pulling image "harbor:443/plugins/metrics-server:v0.6.4"
Normal Pulled 7m3s kubelet Successfully pulled image "harbor:443/plugins/metrics-server:v0.6.4" in 13.254s (13.254s including waiting)
Normal Created 7m3s kubelet Created container metrics-server
Normal Started 7m2s kubelet Started container metrics-server
Pod 管理命令(2)
子命令 | 说明 | 备注 |
---|---|---|
exec | 在某一个容器内执行特定的命令 | 可选参数: -c 容器名称 |
cp | 在容器和宿主机之间拷贝文件或目录 | 可选参数: -c 容器名称 |
delete | 删除资源对象 | 可选参数: -l 标签 |
exec
sh
# -- 选项终止符 区分 kubectl 的选项和容器内命令
[root@master ~]# kubectl exec -it myweb -- ls
index.html info.php
# 执行交互式命令 进入容器内部
[root@master ~]# kubectl exec -it myweb -- bash
[root@myweb html]#
cp
sh
# 上传文件到容器内 跟docker一样要写容器内绝对路径
[root@master ~]# kubectl cp 1.txt myweb:/var/www/html
[root@master ~]# kubectl exec -it myweb -- tree /var/www/html
/var/www/html
|-- 1.txt
|-- index.html
`-- info.php
# 拉取容器内的文件
[root@master ~]# kubectl cp myweb:/var/www/html /root/var
tar: Removing leading `/' from member names
[root@master ~]# ls
1.txt init myos.tar.xz plugins root var
[root@master ~]# tree var/
var/
├── 1.txt
├── index.html
└── info.php
sh
cp其实就是通过tar流传输数据 跟docker cp 的原理是两码事
docker是单机 k8s是跨服务器


delete
sh
# 可以删除k8s中的任何文件 容器 节点 名称空间
[root@master ~]# kubectl delete pods myweb
pod "myweb" deleted
[root@master ~]# kubectl get pods
No resources found in default namespace.
[root@master ~]# kubectl delete namespaces work
namespace "work" deleted
[root@master ~]# kubectl get namespaces
NAME STATUS AGE
default Active 24h
kube-node-lease Active 24h
kube-public Active 24h
kube-system Active 24h
资源清单文件 要求会默写
sh
[root@master ~]# vim myweb.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: myweb
spec:
containers:
- name: nginx
image: myos:nginx
status: {}
---
# 资源类型
kind:
# 版本
apiVersion:
# 资源属性
metadata:
name:
# 资源特征
spec:
containers:
- name:
image:
# 状态
status: {}
语法
yaml
# 只有键值对和数组这两种数据类型
# 键值对格式 键值对用花括号
key: value
key:
value
key: {key: v1}
key:
key: v1
key:
key:
v1
# 数组 一个- 代表一个数组元素
[aa,bb,cc]
等于
- aa
- bb
- cc
key: [aa,bb,cc]
key:
- aa
- bb
- cc
key:
- aa
- bb
- cc
# 嵌套
key: [aa,{k1: v1,k2: v2},[aa,bb,cc]]
key:
- aa
- {k1: v1,k2: v2}
- [aa,bb,cc]
key:
- aa
- k1: v1
k2: v2
- - aa
- bb
- cc
---
kind: Pod
apiVersion: v1
metadata: {name: myweb3}
spec: {containers: [{name: nginx,image: myos: nginx}]}
status: {}
# 关键字需要遵守key 小驼峰 value 大驼峰
sh
# 获取资源对象模板
[root@master ~]# kubectl create namespace work --dry-run=client -o yaml
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: null
name: work
spec: {}
status: {}
explain
sh
# explain 查看资源清单各个级别的参数
[root@master ~]# kubectl explain Pod.apiVersion
KIND: Pod
VERSION: v1

管理命令
子命令 | 说明 | 备注 |
---|---|---|
create | 创建文件中定义的资源 | 支持指令式和资源清单文件配置 |
apply | 创建(更新)文件中定义的资源 | 只支持资源清单文件(声明式) |
delete | 删除文件中定义的资源 | 支持指令式和资源清单文件配置 |
replace | 更改/替换资源对象 | 强制重建 --force |
sh
# apply 和 replace
# apply 更新pod里面的容器内容,并不会影响pod 而 replace则是强行重建pod 和原先的pod不是同一个
# apply 不可修改资源的名字
# 语法
kubectl create -f **.yaml
# 强制重建
[root@master ~]# kubectl get pods web1 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web1 1/1 Running 0 85s 10.244.21.134 node-0001 <none> <none>
[root@master ~]# kubectl replace --force -f web1.yaml
[root@master ~]# kubectl get pods web1 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web1 1/1 Running 0 51s 10.244.21.135 node-0001 <none> <none>
sh
# 拓展提高
# 与 kubectl apply -f myweb.yaml 功能相同 - 占位符 标准输入 标准输出
[root@master ~]# cat myweb.yaml |kubectl apply -f -
SH
[root@master ~]# kubectl create
clusterrolebinding (Create a cluster role binding for a particular cluster role)
clusterrole (Create a cluster role)
configmap (Create a config map from a local file, directory or literal value)
cronjob (Create a cron job with the specified name)
deployment (Create a deployment with the specified name)
ingress (Create an ingress with the specified name)
job (Create a job with the specified name)
namespace (Create a namespace with the specified name)
poddisruptionbudget (Create a pod disruption budget with the specified name)
priorityclass (Create a priority class with the specified name)
quota (Create a quota with the specified name)
rolebinding (Create a role binding for a particular role or cluster role)
role (Create a role with single rule)
secret (Create a secret using a specified subcommand)
serviceaccount (Create a service account with the specified name)
service (Create a service using a specified subcommand)
token (Request a service account token)
namespace
sh
# 创建名称空间
[root@master ~]# kubectl create namespace work
# 指定名称空间创建pod
[root@master ~]# kubectl -n work run myweb --image myos:httpd
# 不同名称空间里可以创建同名的pod 但这是两个不同的pod
[root@master ~]# kubectl get pods myweb -n work -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myweb 1/1 Running 0 58s 10.244.21.129 node-0001 <none> <none>
[root@master ~]# kubectl get pods myweb -n default -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myweb 1/1 Running 0 61m 10.244.243.193 node-0003 <none> <none>
lscpu
毫核计算


静态pod

sh
# 创建静态pod只需要在相应的计算节点的/etc/kubernetes/manifests/下创建一个资源清单即可,就可以直接创建出静态pod 创建的pod名称由节点的主机名和name属性拼接而成
---
kind: Pod
apiVersion: v1
metadata:
name: node-0001
spec:
containers:
- name: web
image: myos:httpd
status: {}
~

sh
# 修改资源清单内容后,pod也会相应的自动修改
metadata:
name: myweb
# 在主节点上无法通过delete删除静态pod,只有删除相应的资源清单才能删除静态pod

多容器pod

sh
# 由于共享网络ip所以会出现端口冲突的问题
sh
---
kind: Pod
apiVersion: v1
metadata:
name: tw1
spec:
containers:
- name: httpd
image: myos:httpd
- name: nginx
image: myos:nginx
嵌入式脚本
sh
# $ 只能调用容器内的变量,跟docker不同
---
kind: Pod
apiVersion: v1
metadata:
name: tw1
spec:
containers:
- name: httpd
image: myos:httpd
command:[sh]
args:
- -c
- |
ls
sh
# 当容器内的主进程(PID 1)退出时,容器会自动停止。如果容器内运行的是一个嵌入式脚本(如 Shell 脚本),且该脚本执行完毕后没有保持前台进程运行,容器就会立即退出。
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myweb 1/1 Running 2 (5h39m ago) 22h
myweb-node-0001 1/1 Running 0 5h19m
myweb3 1/1 Running 0 5h36m
tw3 0/1 CrashLoopBackOff 4 (65s ago) 2m42s
two 2/2 Running 0 66m
[root@master ~]# kubectl logs tw3
index.html
info.php
[root@master ~]# vim more.yaml
---
kind: Pod
apiVersion: v1
metadata:
name: tw3
spec:
containers:
- name: httpd
image: myos:httpd
command: [sh]
args:
- -c
- |
ls
宽限期
sh
# 默认30秒 防止数据丢失 损坏 数据库 消息队列 时间较长 让pod里面事务执行完成
terminationGracePeriodSeconds
标签
sh
# 可以用来做服务分区 把不同的pod部署在不同的节点上 比如说有的功能需要更好性能的服务器 则可以把这些性能好的服务器标签
# 查看标签
kubectl get pods --show-labels
# 创建标签 app=apache
kubectl label pod myhttp app=apache
# 删除标签
kubectl label pod myhttp app-
探针
sh
# 生存探针 必备
# 启动探针
# 就绪探针
特性 | 生存探针(Liveness Probe) | 启动探针(Startup Probe) | 就绪探针(Readiness Probe) |
---|---|---|---|
核心目的 | 检测容器是否存活,失败则重启容器 | 检测应用是否完成启动,避免被过早探测 | 检测容器是否可接收流量,失败则从端点移除 |
触发时机 | 容器启动后(由 initialDelaySeconds 控制) |
容器启动后立即开始(优先级最高) | 容器启动后(通常与 Liveness Probe 共用配置) |
失败后行为 | 重启容器(同一 Pod 内) | 阻塞 Liveness/Readiness Probe 直到成功 | 从 Service 端点移除 Pod,停止流量转发 |
典型场景 | 应用崩溃、死锁、内存泄漏 | 启动缓慢的应用(如 Java、数据库初始化) | 应用启动中、过载或依赖服务不可用 |
是否影响 Pod 生命周期 | 是(通过重启容器) | 是(延迟其他探针生效) | 否(仅影响流量路由) |
默认参数 | periodSeconds: 10 failureThreshold: 3 |
periodSeconds: 30 failureThreshold: 30 |
periodSeconds: 10 failureThreshold: 3 |
资源配置
sh
# 只配置了限额,配额的值使用限额的值 k8s要关闭swap的原因之一就是与资源配置有关
---
kind: Pod
apiVersion: v1
metadata:
name: blp1
spec:
containers:
- name: httpd
image: myos:httpd
resources:
limits:
cpu: 1500m
memory: 800Mi

特性 | 资源限额(Limits/Requests) | 资源配额(Resource Quotas) |
---|---|---|
作用对象 | 容器(间接影响 Pod) | 整个 Namespace |
配置位置 | Pod 的 spec.containers[].resources |
独立的 ResourceQuota 对象 |
限制内容 | 单个容器的资源上限/请求 | 命名空间内所有 Pod 的资源总量 |
触发后果 | 容器被终止(OOM)或节流(CPU) | Pod 创建失败(QuotaExceeded 错误) |
txt
写操作大于读操作
ceph 搭建分布式对像存储集群,用作视频和图片的存储 异地容灾
mycat实现读写分离
mysql双主双从+keepalived+mycat(2台)+双主分片写 存储元数据
Ceph
跨机房3副本 + 异地RGW同步
每周全量 + 每日增量备份至异地
MySQL
双主跨机房 + Keepalived VIP
每日XtraBackup全量 + 增量备份
redis?要用吗 ,用的话要不要,主从+哨兵?做高可用
不确定mysql主服务器数量
MySQL??
层级 | 容灾方案 | 备份方案 |
---|---|---|
Ceph | 跨机房3副本 + 异地RGW同步 | 每周全量 + 每日增量备份至异地 |
MySQL | 双主跨机房 + Keepalived VIP | 每日XtraBackup全量 + 增量备份 |
sh
在 Kubernetes 的调度过程中,过滤(Filtering/Predicates)、打分(Scoring/Prioritization) 和 绑定(Binding) 是三个核心阶段,它们共同决定了 Pod 如何被分配到合适的节点上。
sh
-.0
.-help
--dry-run=client -o yaml
卷
sh
背格式

PV 和 PVC 的关系
sh
在 Kubernetes 中,PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 是核心的持久化存储抽象机制,用于管理存储资源(如磁盘、NFS、云存储等)。它们通过解耦存储的提供(PV)和消费(PVC),实现了存储的灵活分配与动态管理。
角色 | PV | PVC |
---|---|---|
提供者 | 管理员或 StorageClass(动态) | 开发者(用户或应用) |
功能 | 定义存储的物理属性 | 声明存储的需求(容量、访问模式) |
绑定关系 | 1:1 绑定到 PVC | 1:1 绑定到 PV |
示例 | "这是一块 100Gi 的 NFS 存储" | "我需要 50Gi 的读写存储" |
PV:存储的"物理定义",描述存储的属性和位置。
PVC:存储的"需求声明",用户通过 PVC 申请存储。
绑定流程:PVC → 匹配 PV → 绑定 → Pod 使用。
sh
volumeMounts:
- name: nignx-conf
subPath: nginx.conf
# 用mountPath挂在的都是目录 只有加上subPath后才是文件
mountPath: /usr/local/nginx/conf/nginx.conf
emptyDir
的核心作用
(1) 提供临时存储
-
数据持久性 :数据仅在 Pod 运行期间存在,Pod 被删除(或崩溃重启)后,
emptyDir
中的数据会被永久清除。 -
存储位置
:
- 默认 :存储在节点磁盘上(路径如
/var/lib/kubelet/pods/<pod-id>/volumes/kubernetes.io~empty-dir/
)。 - 可选 :通过
medium: Memory
指定使用内存(tmpfs),性能更高但数据更易丢失(重启或 Pod 删除后丢失)。
- 默认 :存储在节点磁盘上(路径如
(2) 共享数据
- 容器间共享 :同一个 Pod 内的多个容器可以挂载同一个
emptyDir
,实现数据共享(例如 Sidecar 容器处理日志,主容器读取日志)。 - 无需持久化:适合临时交换数据(如缓存、中间计算结果、会话状态等)。
在 Kubernetes 中,是否使用单独的服务器存储数据 取决于你选择的卷类型 和存储后端 。卷的核心作用是抽象存储资源,让数据可以独立于容器生命周期流动(持久化或临时共享),但具体存储位置(本地节点、网络存储、云存储等)由卷类型决定。以下是详细分析:
1. 卷的存储位置:是否需要单独的服务器?
(1) 本地存储(节点磁盘/内存)
-
卷类型 :
emptyDir
、hostPath
-
存储位置 :当前节点(Pod 所在的 Kubernetes 节点服务器)。
-
特点
:
-
无需单独服务器:数据直接存储在运行 Pod 的节点上。
-
局限性
:
- 不跨节点:Pod 迁移到其他节点后,数据无法跟随(除非重新同步)。
- 节点故障风险:节点宕机时数据可能丢失(除非有备份)。
-
-
适用场景
:
- 临时缓存(
emptyDir
)。 - 访问节点文件(如
/var/log
,hostPath
)。 - 非关键数据(如测试环境)。
- 临时缓存(
示例:emptyDir
存储视频临时文件
yaml
volumes:
- name: video-cache
emptyDir:
medium: Memory # 使用节点内存存储(高性能)
sizeLimit: 2Gi # 限制大小为 2Gi
volumeMounts:
- name: video-cache
mountPath: /tmp/videos # 容器内路径
(2) 网络存储(需要单独的存储服务器/服务)
-
卷类型 :
PersistentVolumeClaim (PVC)
+ 存储后端(如 NFS、云盘、Ceph 等)。 -
存储位置 :独立的存储服务器或云存储服务(与 Kubernetes 节点分离)。
-
特点
:
- 跨节点共享 :多个 Pod 可以挂载同一个 PVC(如
ReadWriteMany
模式的 NFS)。 - 高可用性:存储后端通常有冗余机制(如云盘自动备份)。
- 需要额外配置:需提前部署存储服务(如 NFS 服务器)或使用云提供商的存储(如 AWS EBS)。
- 跨节点共享 :多个 Pod 可以挂载同一个 PVC(如
-
适用场景
:
- 持久化数据(如数据库、用户上传的视频/图片)。
- 需要跨节点访问的数据(如共享文件服务器)。
示例:NFS 存储用户上传的图片
-
部署 NFS 服务器
(单独的服务器或云存储):
bash# 在 NFS 服务器上创建共享目录 mkdir /data/nfs chown nobody:nobody /data/nfs
-
创建 Kubernetes PVC
:
yamlapiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-pvc spec: accessModes: [ "ReadWriteMany" ] # 多节点可读写 storageClassName: "nfs-client" # 需提前配置 StorageClass resources: requests: storage: 100Gi
-
Pod 挂载 PVC
:
yamlvolumeMounts: - name: nfs-storage mountPath: /usr/share/nginx/html/uploads # 存储用户上传的图片 volumes: - name: nfs-storage persistentVolumeClaim: claimName: nfs-pvc
(3) 云存储(AWS/Azure/GCP 等)
-
卷类型 :云提供商的 CSI 驱动(如
aws-ebs-csi-driver
、azure-disk-csi-driver
)。 -
存储位置 :云服务商的块存储/对象存储(如 AWS EBS、S3)。
-
特点
:
- 完全托管:无需自己维护存储服务器。
- 弹性扩展:按需调整存储大小和性能。
- 成本:按使用量计费(需权衡性能和价格)。
-
适用场景
:
- 云原生应用(如 AWS EKS、GCP GKE)。
- 需要全球低延迟访问的数据(如 CDN 边缘存储)。
示例:AWS EBS 存储视频数据库
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ebs-pvc
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "ebs-sc" # AWS EBS 存储类
resources:
requests:
storage: 500Gi # 500Gi 高性能 SSD
2. 卷如何实现数据流通?
卷通过挂载(Mount)机制将存储资源映射到容器内部,实现数据的持久化 和共享:
-
持久化:数据存储在卷中,容器重启或删除后数据保留。
-
共享
:
- 容器间共享 :同一 Pod 的多个容器挂载同一卷(如
emptyDir
)。 - 跨节点共享:通过网络存储(如 NFS、云存储)实现。
- 容器间共享 :同一 Pod 的多个容器挂载同一卷(如
示例:多容器共享 emptyDir
处理视频
yaml
containers:
- name: video-processor
image: video-encoder
volumeMounts:
- name: shared-data
mountPath: /input # 读取原始视频
- name: video-uploader
image: s3-uploader
volumeMounts:
- name: shared-data
mountPath: /output # 写入处理后的视频
volumes:
- name: shared-data
emptyDir: {} # 临时存储,处理完成后可迁移到持久化存储
3. 如何选择存储方案?
需求 | 推荐方案 | 是否需要单独服务器 |
---|---|---|
临时缓存(如视频转码) | emptyDir (内存或磁盘) |
否(使用节点本地存储) |
用户上传的图片/视频 | NFS / 云存储(如 S3 + CSI) | 是(NFS 服务器或云) |
数据库(如 MySQL) | 云盘(EBS/Azure Disk)或本地 SSD | 否(云托管)或 是(本地) |
跨节点共享配置文件 | ConfigMap / hostPath (开发测试) |
否(ConfigMap)或 是(hostPath ) |
高性能计算(如 AI 训练) | 分布式存储(如 Ceph、Alluxio) | 是(存储集群) |
4. 最佳实践
-
关键数据用持久化存储
:
- 用户上传的文件、数据库必须使用 PVC + 网络存储/云存储。
- 避免使用
emptyDir
存储重要数据(除非是临时处理)。
-
性能优化
:
- 视频/图片处理:使用 SSD 存储(如
gp3
存储类)。 - 大文件存储:结合对象存储(如 S3)和 CSI 挂载。
- 视频/图片处理:使用 SSD 存储(如
-
备份策略
:
- 定期快照持久化卷(如云盘的自动备份)。
- 使用 Velero 等工具备份整个 Namespace(包括 PVC)。
总结
-
是否需要单独服务器 :取决于卷类型。本地存储(
emptyDir
/hostPath
)不需要;网络存储(NFS/云存储)需要。 -
卷的作用:通过抽象存储资源,实现数据持久化、容器间共享和跨节点流动。
-
推荐方案
:
- 临时数据 :
emptyDir
(内存优先)。 - 持久化数据:PVC + 网络存储/云存储。
- 云环境:直接使用云提供商的 CSI 驱动(如 AWS EBS、S3)。
- 临时数据 :
service 管理
sh
# 如果service失效,则可能与这三个地方有关
# 标签要和web服务相同
selector:
app: web
# 端口别名要和web相同 targetPort: myhttp
# 固定ip地址要在范围之内 clusterIP: 10.245.88.80
---
kind: Service
apiVersion: v1
metadata:
name: web123
spec:
type: ClusterIP
clusterIP: 10.245.88.80
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: myhttp
# web1
---
kind: Pod
apiVersion: v1
metadata:
name: web1
labels:
app: web
spec:
containers:
- name: web
image: myos:httpd
ports:
- name: myhttp
protocol: TCP
containerPort: 80
对外发布服务
nodeport
ingress
