练习 1:ConfigMap(明文配置)
1. 核心概念
- 存储非敏感的配置数据(环境变量、配置文件)
- 命名空间级别资源,Pod 可以直接挂载使用
2. 编写 YAML 文件
创建 my-configmap.yaml:
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config # ConfigMap 名称
data:
# 键值对形式存储配置
APP_ENV: "test"
APP_PORT: "8080"
APP_NAME: "my-test-app"
3. 创建 + 验证
bash
# 创建 ConfigMap
kubectl apply -f my-configmap.yaml
# 查看所有 ConfigMap
kubectl get cm
# 查看详细配置(重点)
kubectl describe cm my-app-config
✅ 重点讲解
data:存放明文键值对,是 ConfigMap 的核心- 用途:给 Pod 注入环境变量、挂载配置文件
练习 2:Secret(敏感数据)
1. 核心概念
- 存储密码、密钥、token等敏感信息
- K8s 用 Base64 编码存储(不是加密,仅避免明文)
- 用法和 ConfigMap 几乎一致,安全性更高
2. 先编码敏感数据(必须做)
bash
# 对密码、用户名进行 Base64 编码
echo -n "admin" | base64 # 用户名编码
echo -n "Admin@123456" | base64 # 密码编码
记录输出结果(后面 YAML 要用):
用户名编码:YWRtaW4=
密码编码:QWRtaW5AMTIzNDU2
3. 编写 YAML 文件
创建 my-secret.yaml:
yaml
apiVersion: v1
kind: Secret
metadata:
name: my-app-secret
type: Opaque # 通用密钥类型
data:
# 填写上面编码后的值
USERNAME: YWRtaW4=
PASSWORD: QWRtaW5AMTIzNDU2
4. 创建 + 验证
bash
# 创建 Secret
kubectl apply -f my-secret.yaml
# 查看 Secret
kubectl get secret
# 查看详情(默认不会显示明文,只会显示数据长度)
kubectl describe secret my-app-secret
# 查看 USERNAME 和 PASSWORD 字段的 明文
kubectl get secret my-app-secret -o jsonpath='{.data.USERNAME}' | base64 -d
kubectl get secret my-app-secret -o jsonpath='{.data.PASSWORD}' | base64 -d
✅ 重点讲解
type: Opaque:最常用的自定义密钥类型- 绝对不要在 YAML 里写明文,必须用 Base64 编码
- Secret 数据仅在集群内安全传输,不会暴露到日志
练习 3:PV(持久化存储,管理员创建)
方式一: 自动创建 pv
Kind 集群自带自动存储类 ,你完全不用手动创建PV,直接用PVC就能自动生成PV,100%成功!
步骤1:创建极简PVC(依赖Kind自动创建PV)
新建 pvc.yaml,什么都不用改,直接用:
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
这个 PVC 能否自动创建并绑定 PV,完全取决于你的集群是否配置了 StorageClass(存储类)
Kind 集群内置了动态存储插件 local-path-provisioner,并默认创建了:
- 名为 standard 的 默认 StorageClass
- 该存储类会自动在 Kind 节点的本地临时目录中创建 PV
- 上面的 PVC 不写 storageClassName 也会自动匹配这个默认 SC → 直接自动创建 PV 并绑定
步骤2:创建PVC + 验证
bash
kubectl apply -f pvc.yaml
kubectl get pvc
✅ 此时还是 Pending(正常,因为延迟绑定)
步骤3:本地下载镜像 + 导入 Kind 集群
Kind 集群本身运行在 Docker 容器中,集群内部无法访问外网拉取镜像。
这是 Kind 专用命令,把本地镜像直接塞进 K8s 集群里,永远不用联网拉取
sh
# 1. 本地下载小镜像(宿主机执行,肯定成功)
docker pull busybox:1.36
# 2. 把本地镜像导入你的 Kind 集群(名字:my-first-cluster)
kind load docker-image busybox:1.36 --name my-first-cluster
步骤4:启动 pod
yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: busybox
image: busybox:1.36
command: ["sleep", "3600"]
volumeMounts:
- name: my-pvc
mountPath: /data
volumes:
- name: my-pvc
persistentVolumeClaim:
claimName: my-pvc
bash
kubectl apply -f pod.yaml
步骤5:最终验证
bash
kubectl get pvc # 状态变为 Bound
kubectl get pv # 自动生成了PV
步骤6: 验证 持久性
- 写入数据
sh
# 1. 进入Pod容器
kubectl exec -it test-pod -- sh
# 2. 在挂载的存储目录创建文件(测试持久化)
echo "k8s 练习成功!" > /data/success.txt
# 3. 查看文件
cat /data/success.txt
# 4. 退出容器
exit
- 删除 Pod(模拟 Pod 崩溃、重启、重建)
sh
kubectl delete pod test-pod
- 重新创建 Pod(使用同一个 PVC)
sh
kubectl apply -f pod-nginx-pvc.yaml
- 进入新 Pod,查看数据是否还在!
sh
# 进入新建的 Pod
kubectl exec -it test-pod -- sh
# 查看文件(重点!!!)
cat /data/test.txt
# 退出
exit
方式二: 手动创建 pv
必须让 PV 和 PVC 的 storageClassName 完全一致(都设为空)
PV YAML
yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
storageClassName: "" # 关键:空字符串
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /tmp/my-pv-data
PVC YAML
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
storageClassName: "" # 关键:和PV一致
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
✅ 重点讲解
- PV 是集群级别资源,不属于任何命名空间
accessModes:ReadWriteOnce:单节点可读写(测试首选)
persistentVolumeReclaimPolicy:Retain(删除 PVC 后数据保留)
练习 4:PVC(存储申请,用户使用)
1. 核心概念
- Pod 不直接使用 PV,而是通过 PVC 申请存储
- K8s 会自动匹配满足条件的 PV 并绑定
2. 编写 PVC YAML
创建 my-pvc.yaml:
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce # 必须和 PV 一致
resources:
requests:
storage: 1Gi # 申请大小,必须 ≤ PV
3. 创建 + 验证绑定
bash
# 创建 PVC
kubectl apply -f my-pvc.yaml
# 查看 PVC(状态:Bound 表示绑定 PV 成功)
kubectl get pvc
# 再次查看 PV(状态变为 Bound)
kubectl get pv
✅ 重点讲解
- PVC 是命名空间级别资源
- 绑定规则:
存储大小+访问模式必须匹配 PV Bound状态 = 存储就绪,可以给 Pod 使用
练习 5:环境变量 的形式 使用 ConfigMap & Secret 的数据
目标
创建一个 Nginx Pod,同时使用:
- ConfigMap 注入环境变量
- Secret 注入账号密码
- PVC 挂载持久化存储
编写整合 YAML
创建 my-pod.yaml:
yaml
apiVersion: v1
kind: Pod
metadata:
name: my-test-pod
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
# 1. 挂载 ConfigMap 作为环境变量
env:
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: my-app-config
key: APP_ENV
- name: APP_PORT
valueFrom:
configMapKeyRef:
name: my-app-config
key: APP_PORT
# 2. 挂载 Secret 作为环境变量
- name: USERNAME
valueFrom:
secretKeyRef:
name: my-app-secret
key: USERNAME
- name: PASSWORD
valueFrom:
secretKeyRef:
name: my-app-secret
key: PASSWORD
# 3. 挂载 PVC 持久化存储
volumeMounts:
- name: my-storage
mountPath: /usr/share/nginx/html # 容器内挂载目录
# 声明 PVC 存储卷
volumes:
- name: my-storage
persistentVolumeClaim:
claimName: my-pvc # 绑定我们创建的 PVC
创建 + 验证
bash
# 创建 Pod
kubectl apply -f my-pod.yaml
# 查看 Pod 状态(Running 为成功)
kubectl get pods
验证所有资源是否生效
1. 进入 Pod 查看 ConfigMap + Secret
bash
# 进入容器内部
kubectl exec -it my-test-pod -- sh
# 查看环境变量(能看到配置和密码)
env | grep APP_
env | grep USERNAME
env | grep PASSWORD
# 退出容器
exit
2. 验证持久化存储
bash
# 在容器的挂载目录创建文件
kubectl exec my-test-pod -- touch /usr/share/nginx/html/test.txt
# 查看文件(证明存储挂载成功)
kubectl exec my-test-pod -- ls /usr/share/nginx/html
练习 6:配置文件 的形式 使用 ConfigMap & Secret 的数据
将 ConfigMap 和 Secret 作为文件卷 挂载到容器内的指定目录,容器里的程序直接读取文件获取配置(而非读环境变量),这是生产环境 最常用的 方式。
创建 ConfigMap
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: wtt-app-config
data:
# 🔥 一个key = 一个完整配置文件(文件名:app.env)
app.env: |
APP_ENV=production
APP_PORT=8080
LOG_LEVEL=info
DEBUG=false
说明:
- app.env = 配置文件的文件名
- | = YAML 多行文本标记(保留换行,把下面所有内容当成一整个文件的内容)
- 整个 data 只有 1 个 Key,对应 1 个完整的配置文件
| 对比项 | 旧写法(键值对平铺) | 新写法(单配置文件) |
|---|---|---|
| ConfigMap 结构 | 多个独立key | 1个key = 1个文件名 + 完整文件内容 |
| 挂载到Pod后的效果 | 生成 3个零散文件 APP_ENV、APP_PORT、APP_NAME | 生成 1个完整文件 app.env(包含所有配置) |
| 程序读取方式 | 读N个零散文件(极不规范) | 读 1个标准配置文件(符合所有软件习惯) |
| 生产实用性 | 仅适合简单环境变量,不能当配置文件 | ✅ 标准用法,适配所有应用 |
| 维护成本 | 加配置就要加key,越用越乱 | 所有配置写在一个文件里,一目了然 |
创建 Secret
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: wtt-app-config
data:
# 🔥 一个key = 一个完整配置文件(文件名:app.env)
app.env: |
APP_ENV=production
APP_PORT=8080
LOG_LEVEL=info
DEBUG=false[root@VM-0-16-opencloudos single_node]# cat secret2.yaml
apiVersion: v1
kind: Secret
metadata:
name: wtt-app-secret
type: Opaque
# 🔥 用 stringData,直接写明文!
stringData:
credentials.env: |
USERNAME=admin
PASSWORD=123456
说明:
- Kubernetes 的 Secret -> data 字段:
✅ 只接受 Base64 编码字符串
❌ 不接受明文 - 免编码写法(新手首选): 用 stringData 替代 data,可以直接写明文,K8s 自动帮你转 Base64!
Pod
yaml
apiVersion: v1
kind: Pod
metadata:
name: whero-test-pod
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
# 挂载:持久化存储 + 配置文件 + 密钥文件
volumeMounts:
# 1. 原有 PVC 存储(不动)
- name: my-storage
mountPath: /usr/share/nginx/html
# 2. 挂载 ConfigMap → 【单个配置文件】app.env
- name: config-volume
mountPath: /etc/app/app.env # 容器内的文件完整路径
subPath: app.env # 核心!只挂载ConfigMap里的这个文件,不覆盖目录
# 3. 挂载 Secret → 【单个密钥文件】credentials.env
- name: secret-volume
mountPath: /etc/app/credentials.env
subPath: credentials.env # 核心!只挂载Secret里的这个文件
# 声明卷
volumes:
- name: my-storage
persistentVolumeClaim:
claimName: my-pvc
# 关联你创建的 ConfigMap
- name: config-volume
configMap:
name: wtt-app-config
# 关联你创建的 Secret
- name: secret-volume
secret:
secretName: wtt-app-secret
验证
yaml
# 进入容器
kubectl exec -it whero-test-pod -- sh
# 查看配置文件目录(只有 2 个文件!完美)
ls /etc/app/
# 输出:app.env credentials.env
# 查看完整配置文件
cat /etc/app/app.env
# 输出:所有配置都在这一个文件里
# cat /etc/app/app.env
APP_ENV=production
APP_PORT=8080
LOG_LEVEL=info
DEBUG=false
# 查看完整密钥文件
cat /etc/app/credentials.env
# 输出:所有密钥都在这一个文件里(自动解密明文)
# cat /etc/app/credentials.env
USERNAME=admin
PASSWORD=123456
优势(生产环境推荐)
- 配置更规范:程序直接读标准配置文件,兼容绝大多数应用
- 安全更高 :Secret 挂载为文件权限默认为
600,仅当前用户可读取 - 热更新 :ConfigMap/Secret 修改后,容器内文件自动同步更新(无需重启 Pod)