第7章Kubernetes存储 ,HeadLess,StatefulSet完整学习笔记

📅 发布时间:2026/8/30 20:06:00
第7章Kubernetes存储 ,HeadLess,StatefulSet完整学习笔记 实验环境3节点K8s集群192.168.24.11为Master192.168.24.12/13为Node节点所有实操均适配该环境。7.1 存储分类K8s存储分为元数据类配置/身份信息和真实数据类临时/持久化存储两大类按需选择分类资源类型核心作用元数据ConfigMap存储非敏感配置配置文件、环境变量、命令行参数元数据Secret存储敏感信息密码、Token、密钥元数据Downward API容器运行时获取自身Pod/容器的元数据真实数据Volume解决容器崩溃文件丢失、Pod内多容器共享文件问题真实数据PV/PVC持久化存储的抽象解耦Pod和底层存储7.2 ConfigMap配置管理核心概念ConfigMap是K8s的配置中心实现采用注入机制而非共享机制共享机制如NFS每次读取文件都产生网络IO适合多小文件场景注入机制ConfigMap一次注入后多次读取无网络IO适合配置文件少且小的场景因为它的优势根本不在“存文件”而在“配置管理”和“运维范式”。类比传统运维的配置中心修改ConfigMap后Pod内挂载的文件会自动更新有延迟无需重新构建镜像重要参数参数作用cmConfigMap的简写--from-file基于文件创建ConfigMap文件名作为key文件内容作为value--from-literal直接指定keyvalue创建ConfigMap适合短配置--dry-runclient -o yaml模拟创建资源输出YAML格式用于生成资源清单immutable: true标记ConfigMap为不可变防止误修改降低apiserver负载实操示例1. 创建ConfigMap方式1基于文件创建# 在Master节点创建测试文件 mkdir -p /root/k8s-storage cd /root/k8s-storage cat chengke.file EOF namezhangsan password123 EOF # 创建ConfigMap文件名chengke.file作为key kubectl create configmap info-config --from-filechengke.file # 验证 kubectl get cm info-config -o yaml注意如果文件内容是keyvalue格式后续可注入为环境变量如果是非keyvalue格式如多行文本只能挂载为文件使用。方式2基于字面量创建kubectl create configmap literal-config \ --from-literalnamechengke \ --from-literalpassword123生成资源清单推荐kubectl create configmap info-config --from-filechengke.file \ --dry-runclient -o yaml info-config.yaml2. 使用ConfigMap方式1注入为环境变量# env-pod.yaml apiVersion: v1 kind: Pod metadata: name: cm-env-pod spec: containers: - name: test-container image: nginx:1.27.4 command: [/bin/sh, -c, env] env: - name: USERNAME # 容器内环境变量名 valueFrom: configMapKeyRef: name: literal-config # 关联的ConfigMap名 key: name # ConfigMap中的key - name: PASSWORD valueFrom: configMapKeyRef: name: literal-config key: password restartPolicy: Never创建后查看日志kubectl logs cm-env-pod可看到USERNAMEchengke和PASSWORD123。方式2作为启动命令参数# command-pod.yaml apiVersion: v1 kind: Pod metadata: name: cm-command-pod spec: containers: - name: test-container image: nginx:1.27.4 command: [/bin/sh, -c, echo $USERNAME $PASSWORD] env: - name: USERNAME valueFrom: configMapKeyRef: name: literal-config key: name - name: PASSWORD valueFrom: configMapKeyRef: name: literal-config key: password restartPolicy: Never查看日志kubectl logs cm-command-pod输出chengke 123。方式3挂载为文件# volume-pod.yaml apiVersion: v1 kind: Pod metadata: name: cm-volume-pod spec: containers: - name: myapp-container image: nginx:1.27.4 volumeMounts: - name: config-volume mountPath: /etc/config # 容器内挂载目录 volumes: - name: config-volume configMap: name: literal-config # 关联的ConfigMapConfigMap data (namechengke, password123) │ │ ② configMap.name 引用 ▼ Volume (nameconfig-volume) │ │ ① volumeMounts.name 匹配 → mountPath: /etc/config ▼ 容器内的 /etc/config/ 目录 │ ▼ /etc/config/name → 内容: chengke /etc/config/password → 内容: 123进入容器验证kubectl exec -it cm-volume-pod -- /bin/bash ls /etc/config # 输出name password cat /etc/config/name # 输出chengke3. 热更新ConfigMap更新后挂载为Volume的文件会延迟10秒左右自动更新但环境变量不会更新。且更新ConfigMap不会触发Pod滚动更新需要手动触发# 修改ConfigMap的nginx端口为8080 kubectl edit cm default-nginx # 打补丁触发Deployment滚动更新version/config的值任意只要变化就会触发 kubectl patch deployment hotupdate-deploy \ --patch {spec:{template:{metadata:{annotations:{version/config:20260101}}}}}易错点更新ConfigMap后nginx配置变了但nginx没有重载访问还是旧端口需要重启Pod或触发滚动更新才能让配置生效。4. 不可变ConfigMapapiVersion: v1 kind: ConfigMap metadata: name: default-nginx data: default.conf: | server { listen 80; server_name localhost; } immutable: true # 标记为不可变注意不可变是不可逆的修改需要先删除ConfigMap再重建。注意事项/易错点--from-file的文件如果是非keyvalue格式无法注入为环境变量只能挂载为文件热更新仅对Volume挂载生效环境变量注入的ConfigMap更新后不会同步挂载为文件的ConfigMap默认是软链接目的是支持热更新不要手动修改容器内挂载的文件不可变ConfigMap无法回退生产环境重要配置建议开启防止误修改适用场景应用配置文件管理如nginx.conf、redis.conf环境变量注入避免配置硬编码到镜像需要动态更新配置且不需要重建Pod的场景7.3 Secret敏感信息管理核心概念Secret是专门存储敏感数据的资源和ConfigMap的区别Secret存储在节点内存中不会写入物理磁盘etcd中Secret以加密形式存储查看Secret时不会明文显示value使用方式和ConfigMap基本一致但value必须是base64编码重要参数参数作用type: Opaque用户自定义敏感数据最常用type: kubernetes.io/dockerconfigjson镜像仓库认证信息type: kubernetes.io/tlsTLS证书defaultMode挂载文件的权限十进制如400对应八进制0400420对应八进制0644items指定只挂载Secret中的部分key到自定义路径实操示例1. 创建Secret方式1命令行创建value自动base64编码kubectl create secret generic mysecret \ --from-literalusernameadmin \ --from-literalpassword39528$vdg7Jb方式2资源清单创建需手动base64编码# 编码 echo -n admin | base64 # 输出YWRtaW4 echo -n 39528$vdg7Jb | base64 # 输出Mzk1MjgkdmRnN0pi# secret.yaml apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4 password: Mzk1MjgkdmRnN0pi Opaque 是 Kubernetes Secret 的默认类型意思是“通用、无结构限制的密钥” 里面可以放任意 key-value比如数据库密码、API Key、自定义令牌等 Kubernetes 不会对 Opaque 的内容做格式校验也不强制你用什么 key 名易错点base64编码必须用echo -n否则会带换行符解码后内容错误。2. 使用Secret方式1注入为环境变量和ConfigMap用法一致Secret的值会自动解码env: - name: TEST_USER valueFrom: secretKeyRef: name: mysecret key: username进入容器执行env可看到TEST_USERadmin。方式2挂载为Volume# secret-volume-pod.yaml apiVersion: v1 kind: Pod metadata: name: secret-volume-pod spec: containers: - name: myapp-container image: nginx:1.27.4 volumeMounts: - name: secret-volume mountPath: /data readOnly: true volumes: - name: secret-volume secret: secretName: mysecret defaultMode: 256 # 八进制0400只读权限进入容器验证cat /data/username输出admin。方式3自定义挂载路径和权限volumes: - name: secret-volume secret: secretName: mysecret items: - key: username # 只挂载username这个key path: my-group/my-username # 自定义路径 mode: 256 # 单独设置该文件的权限为0400注意指定items后只有列出的key会被挂载其他key不会挂载且这种挂载方式不支持热更新。3. 热更新和ConfigMap规则一致Volume挂载的Secret会延迟更新约1-2分钟子路径挂载的Secret不支持热更新环境变量注入的Secret不会更新4. 不可变Secret和ConfigMap一样添加immutable: true即可apiVersion: v1 kind: Secret metadata: name: mysecret immutable: true type: Opaque data: username: YWRtaW4 password: Mzk1MjgkdmRnN0pi注意事项/易错点Secret不是绝对安全拥有集群管理员权限的用户可以解码查看Secret内容生产环境需配合RBAC限制权限base64编码是可逆的不要误以为是加密敏感数据建议结合外部密钥管理系统如Vault挂载Secret的文件默认权限是0644生产环境建议设置defaultMode: 2560400降低泄露风险指定items挂载的Secret不支持热更新需要更新时必须重建Pod适用场景存储数据库密码、API Token、SSH密钥镜像仓库私有认证信息dockerconfigjson类型TLS证书存储tls类型7.4 Downward APIPod元数据注入核心概念让容器在运行时获取自身Pod/容器的元数据无需耦合K8s API Server。支持两种暴露方式环境变量适合静态元数据不支持热更新Volume挂载支持热更新适合动态变化的元数据如标签、注解重要参数参数作用fieldRef引用Pod级别的字段如metadata.name、metadata.namespaceresourceFieldRef引用容器资源字段如requests.cpu、limits.memorydivisor资源字段的单位除数默认1CPU默认单位为毫核内存默认单位为字节实操示例1. 环境变量方式# downward-env.yaml apiVersion: v1 kind: Pod metadata: name: downward-env-pod spec: containers: - name: myapp image: nginx:1.27.4 command: [/bin/sh, -c, env] env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name # Pod名称 - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace # Pod所在命名空间 - name: CPU_REQUEST valueFrom: resourceFieldRef: containerName: myapp resource: requests.cpu # CPU请求值默认毫核 - name: MEMORY_LIMIT valueFrom: resourceFieldRef: containerName: myapp resource: limits.memory # 内存限制值默认字节 restartPolicy: Never查看日志kubectl logs downward-env-pod可看到注入的环境变量。2. Volume挂载方式支持热更新# downward-volume.yaml apiVersion: v1 kind: Pod metadata: name: downward-volume-pod labels: app: downward-test spec: containers: - name: myapp image: nginx:1.27.4 resources: limits: cpu: 1 memory: 512Mi requests: cpu: 0.5 memory: 256Mi volumeMounts: - name: downward-api-volume mountPath: /etc/podinfo volumes: - name: downward-api-volume downwardAPI: items: - path: labels # 挂载为/etc/podinfo/labels文件 fieldRef: fieldPath: metadata.labels - path: cpu_request resourceFieldRef: containerName: myapp resource: requests.cpu验证热更新# 给Pod添加标签 kubectl label pod downward-volume-pod domainchengke.com # 进入容器查看 kubectl exec -it downward-volume-pod -- cat /etc/podinfo/labels # 输出domainchengke.com说明热更新生效3. 容器内访问K8s API扩展如果需要在容器内获取其他Pod的信息需要配置RBAC权限# rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: test-api-cluster-admin-binding subjects: - kind: ServiceAccount name: test-api namespace: default roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io --- apiVersion: v1 kind: ServiceAccount metadata: name: test-api --- apiVersion: v1 kind: Pod metadata: name: curl-pod spec: serviceAccountName: test-api # 关联ServiceAccount containers: - name: main image: curlimages/curl:8.14.1 command: [sleep, 9999]进入容器访问APITOKEN$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) CAPATH/var/run/secrets/kubernetes.io/serviceaccount/ca.crt NS$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace) curl -H Authorization: Bearer $TOKEN --cacert $CAPATH https://kubernetes/api/v1/namespaces/$NS/pods注意事项/易错点环境变量方式不支持热更新Pod标签/注解修改后环境变量不会变化resourceFieldRef的divisor默认是1比如requests.cpu0.5会显示为500m毫核limits.memory512Mi会显示为536870912字节Downward API只能获取当前Pod的元数据无法获取其他Pod的信息需要访问API Server才能实现适用场景应用需要获取自身Pod名称、命名空间、IP等信息根据Pod标签动态调整应用行为如监控采集打标、日志分类需要动态获取资源限制调整应用内存/CPU参数的场景7.5 Volume临时存储Volume是K8s的存储抽象解决两个问题容器崩溃后kubelet重启容器时文件丢失Pod内多个容器需要共享文件7.5.1 emptyDir临时空目录核心概念Pod被调度到Node时创建Pod删除时数据永久删除容器崩溃不会删除Pod因此数据不会丢失支持两种类型普通emptyDir存储在Node的/var/lib/kubelet/pods/pod-uid/volumes/kubernetes.io~empty-dir/目录内存型emptyDir存储在节点内存中速度快节点重启/Pod驱逐后数据丢失重要参数参数作用emptyDir: {}创建普通emptyDirmedium: Memory创建内存型emptyDirsizeLimit内存型emptyDir的大小限制不能超过Pod的内存限制实操示例示例1Pod内多容器共享日志# emptydir-pod.yaml apiVersion: v1 kind: Pod metadata: name: emptydir-pod spec: containers: - name: nginx image: nginx:1.27.4 volumeMounts: - name: logs-volume mountPath: /var/log/nginx # nginx日志目录 - name: busybox image: busybox:1.36 command: [/bin/sh, -c, tail -f /logs/access.log] volumeMounts: - name: logs-volume mountPath: /logs volumes: - name: logs-volume emptyDir: {}验证访问nginx在busybox容器中可以看到nginx的访问日志。示例2内存型emptyDir# emptydir-mem.yaml apiVersion: v1 kind: Pod metadata: name: emptydir-mem-pod spec: containers: - name: myapp image: nginx:1.27.4 resources: limits: memory: 1Gi # Pod内存限制1Gi requests: memory: 512Mi volumeMounts: - name: mem-volume mountPath: /data volumes: - name: mem-volume emptyDir: medium: Memory sizeLimit: 500Mi # 内存限制500Mi不能超过Pod的内存限制易错点如果写入内存型emptyDir的数据超过sizeLimitPod会被驱逐。注意事项/易错点普通emptyDir存储在Node磁盘Node磁盘满会导致Pod异常内存型emptyDir的数据在Node重启/Pod驱逐后会丢失适合临时缓存场景emptyDir的读写性能依赖Node磁盘性能内存型emptyDir性能极高但容量有限适用场景容器间临时文件共享如日志收集、数据预处理临时缓存如排序中间结果、崩溃恢复检查点内存型emptyDir适合对延迟敏感、数据量小的场景如缓存、临时计算7.5.2 hostPath节点目录挂载核心概念将Node节点的文件系统挂载到Pod中Pod可以访问节点的文件/目录。重要参数type字段type值行为空字符串默认不检查挂载路径存在即挂载DirectoryOrCreate路径不存在则创建空目录权限0755Directory路径必须存在目录否则Pod启动失败FileOrCreate文件不存在则创建空文件权限0644File文件必须存在否则Pod启动失败实操示例# hostpath-pod.yaml apiVersion: v1 kind: Pod metadata: name: hostpath-pod spec: containers: - name: myapp image: nginx:1.27.4 volumeMounts: - name: test-volume mountPath: /test-pd volumes: - name: test-volume hostPath: path: /test # 节点上的目录 type: Directory # 要求目录必须存在前置操作在两个Node节点创建目录mkdir -p /test echo $(hostname) /test/index.html验证进入Pod查看/test-pd/index.html内容和Pod所在Node的主机名一致。注意事项/易错点调度不确定性不同Node的hostPath内容可能不同Pod调度到不同Node行为不一致生产环境谨慎使用权限问题hostPath的文件默认只有root可写需要特权容器才能修改或修改Node上的文件权限资源统计问题调度器不会考虑hostPath的资源占用可能导致Node资源超卖如果type: Directory但Node上没有对应目录Pod会一直处于ContainerCreating状态通过kubectl describe pod hostpath-pod可看到错误原因适用场景需要访问节点资源的场景如采集节点日志、运行Docker daemon运行节点监控组件如cAdvisor、Node Exporter单节点集群的临时存储不适合多节点集群7.6 PV/PVC持久化存储核心概念PVPersistentVolume持久卷集群层面的存储资源抽象由管理员预先创建或通过StorageClass动态创建类似“磁盘”PVCPersistentVolumeClaim持久卷声明用户对存储的请求类似“磁盘申请”Pod通过PVC使用PV实现Pod和底层存储解耦绑定流程PVC根据容量、访问模式、存储类匹配符合条件的PV绑定后Pod才能使用重要参数访问模式必须完全匹配模式说明适用存储ReadWriteOnceRWO单节点读写云硬盘、本地盘ReadOnlyManyROX多节点只读NFS、CephFSReadWriteManyRWX多节点读写NFS、CephFS回收策略PV删除后的行为策略说明适用场景Retain保留PVC删除后PV保留数据需管理员手动清理重要数据如数据库数据Delete删除PVC删除后自动删除PV和数据临时存储Recycle回收已弃用不推荐使用-PV生命周期Available可用→Bound已绑定→Released已释放→Failed失败注意事项/易错点绑定条件严格PV的容量≥PVC请求容量、访问模式完全匹配、存储类一致否则无法绑定PVC保护机制Pod正在使用PVC时删除PVC会延迟删除直到Pod不再使用防止数据丢失Retain策略注意PVC删除后PV处于Released状态无法被其他PVC绑定需要手动删除PV的spec.claimRef字段才能复用删除PVC不会自动删除PV数据除非回收策略是Delete生产环境重要数据建议用Retain策略适用场景有状态应用需要持久化数据的场景如MySQL、Redis、文件服务需要跨Pod/跨节点共享数据的场景如静态资源存储数据需要独立于Pod生命周期存在的场景7.7 Headless Service无头服务核心概念普通Service会分配ClusterIP通过kube-proxy做负载均衡Headless Service不分配ClusterIPDNS直接解析到后端Pod的IP适合需要直接访问Pod的场景。核心特点不分配ClusterIP设置spec.clusterIP: NoneDNS解析返回所有后端Pod的IP列表无负载均衡需要配合selector匹配PodDNS记录格式{pod-name}.{service-name}.{namespace}.svc.cluster.local实操示例# headless-svc.yaml apiVersion: v1 kind: Service metadata: name: nginx-headless spec: clusterIP: None # 标记为Headless Service selector: app: nginx ports: - port: 80 targetPort: 80验证DNS解析在集群内Pod中执行nslookup nginx-headless.default.svc.cluster.local # 返回所有匹配selector的Pod的IP注意事项/易错点Headless Service不会做负载均衡需要应用自身实现负载均衡逻辑Headless Service无法直接被集群外访问需要配合NodePort/LoadBalancer类型Service暴露必须指定selector否则无法自动关联Pod无selector的Headless Service需要手动创建EndpointSlice适用场景有状态应用如StatefulSet需要固定Pod标识分布式系统如数据库集群、分布式缓存需要Pod间直接通信需要直接访问特定Pod进行调试的场景7.8 StatefulSet有状态应用部署核心概念StatefulSet是管理有状态应用的工作负载和Deployment的核心区别稳定的网络标识Pod名称固定格式statefulset-name-序号如web-0、web-1DNS记录固定稳定的持久存储每个Pod绑定独立的PVC名称固定格式pvc-name-pod-namePod重建后自动绑定原PVC数据不丢失有序管理部署/扩缩/滚动更新都是有序的先0再1先1再0实操示例基于NFS的StatefulSet部署前置步骤搭建NFS服务在Master节点192.168.24.11操作# 所有节点安装NFS客户端 yum install -y nfs-utils # Master节点创建共享目录 mkdir -p /data/nfs/{1..3} chmod -R 666 /data/nfs chown -R nobody:nobody /data/nfs echo NFS Volume 1 /data/nfs/1/index.html echo NFS Volume 2 /data/nfs/2/index.html echo NFS Volume 3 /data/nfs/3/index.html # 配置NFS共享 cat /etc/exports EOF /data/nfs/1 192.168.24.0/24(rw,no_root_squash,sync) /data/nfs/2 192.168.24.0/24(rw,no_root_squash,sync) /data/nfs/3 192.168.24.0/24(rw,no_root_squash,sync) EOF # 启动NFS服务 systemctl enable --now nfs-server exportfs -rv # 刷新配置步骤1创建PV静态制备# pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv-1 spec: capacity: storage: 1Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain nfs: server: 192.168.24.11 # NFS服务器地址Master节点 path: /data/nfs/1 --- apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv-2 spec: capacity: storage: 1Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain nfs: server: 192.168.24.11 path: /data/nfs/2 --- apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv-3 spec: capacity: storage: 1Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain nfs: server: 192.168.24.11 path: /data/nfs/3创建PVkubectl apply -f pv.yaml步骤2创建Headless Service# sts-svc.yaml apiVersion: v1 kind: Service metadata: name: nginx-sts-svc spec: clusterIP: None selector: app: nginx-sts ports: - port: 80 targetPort: 80创建Servicekubectl apply -f sts-svc.yaml步骤3创建StatefulSet# statefulset.yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: nginx-sts spec: serviceName: nginx-sts-svc # 必须关联Headless Service replicas: 3 selector: matchLabels: app: nginx-sts template: metadata: labels: app: nginx-sts spec: containers: - name: nginx image: nginx:1.27.4 ports: - containerPort: 80 volumeMounts: - name: nginx-storage mountPath: /usr/share/nginx/html volumeClaimTemplates: # PVC模板每个Pod会自动创建独立的PVC - metadata: name: nginx-storage spec: accessModes: [ReadWriteOnce] resources: requests: storage: 1Gi创建StatefulSetkubectl apply -f statefulset.yaml验证# 查看Pod名称固定为nginx-sts-0、nginx-sts-1、nginx-sts-2 kubectl get pods -l appnginx-sts # 查看PVC名称固定为nginx-storage-nginx-sts-0、nginx-storage-nginx-sts-1... kubectl get pvc # 访问Pod验证数据每个Pod挂载的是不同的NFS目录 kubectl exec -it nginx-sts-0 -- curl localhost # 输出NFS Volume 1注意事项/易错点必须关联Headless ServiceStatefulSet的spec.serviceName必须指定已存在的Headless Service否则无法创建PVC不会自动删除删除StatefulSet后PVC会保留重新创建StatefulSet会自动绑定原PVC数据不丢失有序扩缩容扩容时先创建nginx-sts-3再创建nginx-sts-4缩容时先删除nginx-sts-4再删除nginx-sts-3滚动更新卡住默认使用OrderedReady策略如果某个Pod启动失败滚动更新会卡住需要手动修复故障Pod优雅删除删除StatefulSet前建议先缩容到0保证Pod优雅终止kubectl scale statefulset nginx-sts --replicas0适用场景有状态应用MySQL主从、Redis集群、Elasticsearch、ZooKeeper、Kafka需要固定网络标识、持久存储的应用需要有序部署/扩缩/更新的场景本章常用命令速查命令作用kubectl get cm/pvc/pv/svc/sts查看ConfigMap/PVC/PV/Service/StatefulSetkubectl describe cm cm-name查看ConfigMap详情kubectl edit cm cm-name编辑ConfigMapkubectl patch deployment deploy-name --patch {spec:{template:{metadata:{annotations:{version/config:xxx}}}}}触发Deployment滚动更新kubectl label pod pod-name keyvalue给Pod添加标签kubectl exec -it pod-name -- /bin/bash进入Pod容器kubectl logs pod-name -c container-name查看容器日志本章核心易错点汇总ConfigMap/Secret热更新仅对Volume挂载生效环境变量注入不生效Secret的base64编码必须用echo -n否则带换行符导致解码错误hostPath的type: Directory时Node上无对应目录会导致Pod一直PendingPV和PVC绑定需要容量、访问模式、存储类完全匹配StatefulSet必须关联Headless Service删除后PVC不会自动删除内存型emptyDir的sizeLimit不能超过Pod的内存限制否则Pod会被驱逐