当前位置: 首页 > news >正文

K8s的配置存储与实战

配置与存储:应用“吃喝”的保障

  • ConfigMap:存储配置文件

  • Secret:存放密码或密钥

  • PV/PVC:持久化存储的资源与资源绑定

K8s存储:临时存储与持久化存储

  • 临时存储

    • emptyDir:在同一个Pod内的不同容器间共享数据,和Pod生命周期相同,Pod创建时创建,Pod销毁时销毁,临时存储;

    • configMap:(配置映射)存储配置文件(如:my.cnf/redis.conf/nginx.conf);

    • secret:存储敏感数据(如密码、私钥、证书等);

    • downwardAPI:存储Pod与容器元数据(如名称、IP)。

存储类型

生命周期

共享范围

典型用途

emptyDir

与 Pod 一致

同一 Pod 内容器

临时数据共享

configMap

独立于 Pod

跨 Pod 配置共享

配置文件挂载

secret

独立于 Pod

跨 Pod 敏感信息

密码、证书挂载

PersistentVolume

独立于 Pod

跨 Pod/命名空间

持久化数据(如数据库)

  • 持久化存储:将数据存储到磁盘空间;

    • hostpath :让Pod中容器直接挂载当前Node节点的目录;

    • PV :持久化存储卷,用于关联存储介质(后台存储),相当于“硬盘”;每个PV都有权限、容量;

    • PVC :在Pod中设置的持久化存储需求,启动Pod时,根据需求自动匹配相应的PV,从而实现数据目录的映射;在容器中的目录上挂载存储介质;

    • StorageClass :存储类,根据PVC的需求自动创建PV,使用时更加方便快捷。

维度

PV (Persistent Volume)

PVC (Persistent Volume Claim)

角色定位

集群中的"物理硬盘"
存储资源本身

用户的"硬盘申请单"
存储资源请求

创建者

集群管理员创建

应用开发者/用户创建

作用范围

集群级别资源
跨Namespace可用

Namespace级别资源
仅在当前Namespace有效

核心功能

定义具体存储属性:
- 存储类型(NFS/本地等)
- 容量大小
- 访问模式

声明存储需求:
- 需要多大容量
- 读写权限要求
- 存储类选择

生命周期状态

Available → Bound → Released → Failed

Pending → Bound → Deleted

绑定关系

被PVC绑定使用

主动绑定到合适的PV

使用方式

Pod通过PVC间接使用PV

Pod直接引用PVC名称

工作流程简化:

管理员创建 PV → 用户创建 PVC → 系统自动绑定 → Pod 使用 PVC

  • 存储方式:

    • NFS

    • CEPH

    • MINIO

    • ……

存算分离:

  • 将存储与运算分离,集中存储,方便管理;

存储实战

emptyDir

# 示例一:基础共享(磁盘介质)

# 两个容器通过磁盘介质的emptyDir共享日志文件

vim 13-emptydir.yaml

apiVersion: v1

kind: Pod

metadata:

  name: log-share-pod

spec:

  volumes:

  - name: log-storage

    emptyDir:

      sizeLimit: 512Mi

  containers:

  - name: app

    image: busybox:latest

    command: ["/bin/sh", "-c", "mkdir -p /var/log/app && while true; do echo \"$(date) 访问日志: ...\" >> /var/log/app/app.log; sleep 3; done"]

    volumeMounts:

    - name: log-storage

      mountPath: /var/log/app

  - name: log-collector

    image: busybox:latest

    command: ["/bin/sh", "-c", "tail -f /logs/app.log"]

    volumeMounts:

    - name: log-storage

      mountPath: /logs

# 创建Pod,然后查看log-collector容器的日志输出

kubectl apply -f 13-emptydir.yaml

# 通过路径验证两个容器中的文件是否相同,如果两个MD5值相同证明文件相同

# 在app容器中检查文件

kubectl exec log-share-pod -c app -- md5sum /var/log/app/app.log

# 在log-collector容器中检查文件  

kubectl exec log-share-pod -c log-collector -- md5sum /logs/app.log

示例二:内存介质(tmpfs)+ 只读权限

vim 14-emptydir-tmpfs.yaml

apiVersion: v1

kind: Pod

metadata:

  name: cache-share-pod

spec:

  volumes:

  - name: cache-volume

    emptyDir:

      medium: Memory

      sizeLimit: 256Mi

  containers:

  - name: cache-generator

    image: busybox:latest

    command: ["/bin/sh", "-c", "while true; do echo \"缓存数据: $(date +%s)\" > /cache/data; sleep 5; done"]

    volumeMounts:

    - name: cache-volume

      mountPath: /cache

  - name: cache-reader

    image: busybox:latest

    command: ["/bin/sh", "-c", "while true; do echo \"读取到: $(cat /read-only-cache/data)\"; sleep 5; done"]

    volumeMounts:

    - name: cache-volume

      mountPath: /read-only-cache

      readOnly: true

# 创建Pod

kubectl apply -f 14-emptydir-tmpfs.yaml

# 查看Pod状态

kubectl get pod cache-share-pod

## 验证内存emptyDir功能

# 查看cache-generator容器的日志(写入端)(什么都不会出现是正常的,因为输出被重定向到了文件,可以通过检查文件内容来验证数据是否正确写入和共享)

kubectl logs cache-share-pod -c cache-generator -f

# 查看cache-reader容器的日志(读取端)

kubectl logs cache-share-pod -c cache-reader -f

## 验证只读权限

# 在cache-reader容器中尝试写入(应该失败)

kubectl exec -it cache-share-pod -c cache-reader -- sh -c "echo '测试写入' > /read-only-cache/test.txt"

# 在cache-generator容器中尝试写入(应该成功)

kubectl exec -it cache-share-pod -c cache-generator -- sh -c "echo '测试写入' > /cache/test.txt && echo '写入成功'"

Configmap

vim 15-emptydir-configmap.yaml

apiVersion: v1

kind: ConfigMap

metadata:

  name: app-config01

data:

  app.conf: |

    # 应用基础配置

    app.name=my-application

    app.version=1.0.0

    server.port=8080

    debug.mode=false

  logback.xml: |

    <?xml version="1.0" encoding="UTF-8"?>

    <configuration>

      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

        <encoder>

          <pattern>%d{yyyy-MM-dd HH:mm:ss} - %msg%n</pattern>

        </encoder>

      </appender>

      <root level="INFO">

        <appender-ref ref="STDOUT" />

      </root>

    </configuration>

  environment.properties: |

    # 环境配置

    database.url=jdbc:postgresql://localhost:5432/testdb

    cache.enabled=true

    feature.toggle.new-ui=true

# 应用ConfigMap

kubectl apply -f 15-emptydir-configmap.yaml

# 查看ConfigMap,或者可以用describe验证创建

kubectl get configmaps

# 创建Pod

vim 16-dapi-pod-configmap.yaml

apiVersion: v1

kind: Pod

metadata:

  name: dapi-test-pod

spec:

  containers:

  - name: test-container

    image: busybox:latest

    command: [ "/bin/sh", "-c", "sleep 3600" ]

    volumeMounts:

    - name: app-config

      mountPath: /etc/app-config/

  volumes:

  - name: app-config

    configMap:

      name: app-config01

# 应用Pod

kubectl apply -f 16-dapi-pod-configmap.yaml

# 查看Pod状态

kubectl get pod

## 验证ConfigMap挂载

# 查看Pod日志

kubectl logs dapi-test-pod

# 进入Pod验证文件

root@master:~/yaml# kubectl exec -it dapi-test-pod -- /bin/sh

# 然后就变成

/ #

# 在容器内检查

ls /etc/app-config/

cat /etc/app-config/app.conf

cat /etc/app-config/logback.xml

cat /etc/app-config/environment.properties

# 退出容器

exit


Secret

1. Service Account Secret(自动创建)

vim 17-service-account-secret-pod.yaml

apiVersion: v1

kind: Pod

metadata:

  name: sa-test-pod

spec:

  automountServiceAccountToken: true    #显式启用

  containers:

  - name: test-container

    image: busybox:latest

command: ["/bin/sh", "-c", "echo '检查Service Account目录...'; sleep 3; find /run -name '*serviceaccount*' 2>/dev/null || find /var -name '*serviceaccount*' 2>/dev/null || echo '未找到serviceaccount目录'; sleep 3600"]

# 创建Pod并等待Pod运行起来

kubectl apply -f 17-service-account-secret-pod.yaml

kubectl get pod

# 进入Pod里验证

kubectl exec -it sa-test-pod -- /bin/sh

/ # find / -name "*serviceaccount*" 2>/dev/null

显示/var/run/secrets/kubernetes.io/serviceaccount

/ # ls /var/run/secrets/kubernetes.io/serviceaccount

显示ca.crt     namespace  token

/ # cat /var/run/secrets/kubernetes.io/serviceaccount/namespace

显示default/ # 然后输入exit退出即可

2. Opaque Secret(存储密码密钥)

## 创建Opaque Secret

# 通过命令行创建Secret

kubectl create secret generic app-secrets \

  --from-literal=username=admin \

  --from-literal=password=secret123 \

  --from-literal=database-url="db://admin:secret@db.example.com/app"

# 验证Secret内容

kubectl get secret app-secrets -o jsonpath='{.data}' | base64 -d

显示base64: invalid input

## 创建使用Opaque Secret的Pod

cat > 19-opaque-test-pod.yaml << 'EOF'

apiVersion: v1

kind: Pod

metadata:

  name: opaque-test-pod

spec:

  containers:

  - name: test-container

    image: busybox:latest

    command: ["/bin/sh", "-c", "sleep 3600"]

    env:

    - name: USERNAME

      valueFrom:

        secretKeyRef:

          name: app-secrets

          key: username

    - name: PASSWORD

      valueFrom:

        secretKeyRef:

          name: app-secrets

          key: password

    volumeMounts:

    - name: secret-volume

      mountPath: /etc/secrets

      readOnly: true

  volumes:

  - name: secret-volume

    secret:

      secretName: app-secrets

EOF

kubectl apply -f 19-opaque-test-pod.yaml

3. Docker Registry Secret(私有仓库认证)(kubernetes.io/dockerconfigjson 类型

## 创建Docker Registry Secret

# 创建用于私有Docker仓库的secret

kubectl create secret docker-registry my-registry-key \

  --docker-server=192.168.57.200:8099 \

  --docker-username=admin \

  --docker-password=password123 \

  --docker-email=admin@example.com

# 查看创建的secret详情

kubectl get secret my-registry-key -o yaml

# 或者查看类型

kubectl get secret my-registry-key -o jsonpath='{.type}'

# 输出会是: kubernetes.io/dockerconfigjson

## 创建使用Registry Secret的Pod

cat > 18-registry-test-pod.yaml << EOF

apiVersion: v1

kind: Pod

metadata:

  name: registry-test-pod

spec:

  containers:

  - name: test-container

    image: busybox:latest

    command: ["/bin/sh", "-c", "echo '这个Pod使用了Docker Registry Secret'; sleep 3600"]

  imagePullSecrets:

  - name: my-registry-key

EOF

# 创建Pod

kubectl apply -f 18-registry-test-pod.yaml

## 验证

# 查看所有secret

kubectl get secrets

# 查看各个Pod状态

kubectl get pods

# 进入Pod查看详细内容

kubectl exec -it opaque-test-pod -- /bin/sh

# 在容器内查看:

env | grep USERNAME

env | grep PASSWORD

ls -la /etc/secrets/

cat /etc/secrets/database-url

exit

### 清理资源

# 删除所有测试资源

kubectl delete pod sa-test-pod opaque-test-pod registry-test-pod

kubectl delete secret app-secrets my-registry-key


K8s存储之volume

卷的类型:

  • emptyDir:与pod的生命周期是一致的,它的最实际实用是提供Pod内多容器的volume数据共享;

    • 用法有:

    • 1、暂存空间,例如用于基于磁盘的合并排序

    • 2、用作长时间计算崩溃恢复时的检查点

    • 3、Web服务器容器提供数据时,保存内容管理器容器提取的文件

  • hostPath:将主机文件系统上的某个目录挂载到 Pod 中,可以使用本地节点的磁盘资源;

    • 具有持久化能力,但仅限固定节点。

    • 适合需要在特定节点上存储数据的场景,daemonset控制器。

    • 存储卷只能在节点本地使用,无法跨节点共享(缺点)。

    • hostPath 卷的使用需要谨慎,因为它会与节点的文件系统直接交互,可能引发数据一致性和安全性问题。

  • PersistentVolume(PV) & PersistentVolumeClaim(PVC)

  • StorageClass

emptyDir

## 验证两个容器如何通过共享卷来交换数据(容器间的数据共享和通信)

vim 20-volume-pod.yaml

apiVersion: v1

kind: Pod

metadata:

  name: test-volume

spec:

  containers:

  - name: volume-pod-1

    image: 192.168.57.200:8099/library/nginx:latest

    imagePullPolicy: IfNotPresent

    volumeMounts:

    - mountPath: /test-1

      name: volume

      

  - name: volume-pod-2

    image: 192.168.57.200:8099/library/busybox:latest

    imagePullPolicy: IfNotPresent

    command: ["/bin/sh", "-c", "sleep 600"]

    volumeMounts:

    - mountPath: /test-2

      name: volume

      

  volumes:

  - name: volume

    emptyDir: {}  # 必须指定卷类型

kubectl apply -f 20-volume-pod.yaml

# 进入busybox容器验证共享卷

kubectl exec -it test-volume -c volume-pod-2 -- /bin/sh

# 在busybox容器中创建文件 → 测试写入功能:

/ # ls -la /test-2/

total 8

drwxrwxrwx    2 root     root          4096 Nov 14 03:26 .

drwxr-xr-x    1 root     root          4096 Nov 14 03:26 ..

/ # echo "hello from pod-2" > /test-2/shared-file.txt

/ # exit

# 进入nginx容器验证

kubectl exec -it test-volume -c volume-pod-1 -- /bin/bash

# 在nginx容器中读取文件 → 验证共享是否成功:

root@test-volume:/# ls -la /test-1/

total 12

drwxrwxrwx 2 root root 4096 Nov 14 03:28 .

drwxr-xr-x 1 root root 4096 Nov 14 03:26 ..

-rw-r--r-- 1 root root   17 Nov 14 03:28 shared-file.txt

root@test-volume:/# cat /test-1/shared-file.txt

应该能看到hello from pod-2

root@test-volume:/# exit

后续实验与之前相似就不做了。


补充hostPath

# 创建Pod YAML文件

vim 21-hostpath-pod.yaml

apiVersion: v1

kind: Pod

metadata:

  name: hostpath

spec:

  containers:

  - name: test-container

    image: 192.168.57.200:8099/library/busybox:latest

    command: ["/bin/sh", "-c", "sleep 3600"]

    volumeMounts:

    - mountPath: /host-logs

      name: host-volume

  volumes:

  - name: host-volume

    hostPath:

      path: /tmp/hostpath-test

      type: DirectoryOrCreate

kubectl apply -f 21-hostpath-pod.yaml

# 查看Pod状态

kubectl get pods

# 查看Pod是在哪个节点上执行的,方便一会儿验证

kubectl get pod hostpath -o wide

# 进入容器

kubectl exec -it hostpath -- /bin/sh

# 在容器内操作

ls -la /host-logs/

echo "Hello from container!" > /host-logs/test-file.txt

cat /host-logs/test-file.txt

exit

# 在主机上验证(在node节点上执行)

ls -la /tmp/hostpath-test/

cat /tmp/hostpath-test/test-file.txt

http://www.dtcms.com/a/609466.html

相关文章:

  • 【Claude code】CLI 、VS code扩展配置
  • csp39 3,4,5 题
  • 操作系统新
  • 易语言DLL文件反编译技巧与方法 | 深入探讨DLL文件反编译的工具与技巧
  • DJ串烧库 2.0.3| 专业的DJ串烧音乐平台,提供高清音质和多种风格的串烧佳作
  • 如何保证分布式锁的高可用和高性能?
  • 收费报名网站怎么做互联网设计师是干什么的
  • 宣传商务型的网站吉林市城市建设学校网站
  • “WebSocket /socket.io/?EIO=4transport=websocket“ 403
  • Linux 逻辑卷管理
  • FFmpeg原始帧处理-滤镜设置视频宽高比
  • 【Python办公】处理 CSV和Excel 文件操作指南
  • Unity Shader Graph 3D 实例 - 一个简单的3D打印效果
  • ReAct 框架实现(基于langgraph)
  • 流媒体,包含哪些技术?Zynq MP方案
  • 网站支持ipv6做哪些改造app公司网站模板
  • 怎么做刷东西的网站网址免费全自动推广平台
  • 校园墙|校园社区|基于Java+vue的校园墙小程序系统(源码+数据库+文档)
  • Linux/宝塔上没有ssl证书的站点使用https访问会跳转的其他有ssl证书网站
  • Centos环境中Django项目中gunicorn的配置和使用
  • LangGraph系列:多智能体终极方案,ReAct+MCP工业级供应链系统
  • 移动端 HTTPS 抓包实战,多工具组合分析与高效排查指南
  • 自动化测试工具Parasoft C/C++test如何导入IAR项目
  • 蓝桥杯嵌入式赛道—-软件篇(GPIO输出模式配置)
  • 仿第四城地方门户网站模板python可以做网站吗
  • ToDesk如何充当分屏显示器?扩展屏、多屏结合虚拟屏都可行!
  • qKnow 知识平台开源版 v1.0.3 发布:Docker Compose 部署 多项稳定性优化和关键问题修复
  • 【Prompt学习技能树地图】检索增强生成(RAG)核心技术剖析与实践指南
  • Zookeeper在Kafka中的作用
  • MySQL数据表操作