8. Kubernetes核心资源之数据存储持久化

  1. **Volumes常见类型: **
  • 常规存储:EmptyDir、HostPath
  • 高级存储:PV、PVC
  • 配置存储:ConfigMap、Secret
  • 其他:网络存储系统 NFS、CIFS,包括云服务商提供的、本地、分布式
  1. **EmptyDir : **
  • 当 Pod 指定到某个节点上时,首先创建的是一个 emptyDir 卷,只要 Pod 在该节点上运行卷就一直存在

  • 当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会永久删除

  • 容器崩溃并不会导致 Pod 被从节点上移除,所以容器崩溃时 emptyDir 卷中的数据是安全的。

  • 用途 : 临时缓存空间

  • 案例 volume-emptydir.yaml

  • pod里面定义两个容器,一个产生日志,一个是读日志输出到控制台

image.png

apiVersion: v1
kind: Pod
metadata:
  name: xdclass-volume-emptydir
  namespace: dev
spec:
  containers:
  - name: xdclass-nginx
    image: nginx:1.20
    ports:
    - containerPort: 80
    volumeMounts:  # 将nginx-log-volume挂在到nginx容器中,对应的目录为 /var/log/nginx
    - name: nginx-log-volume
      mountPath: /var/log/nginx

	- name: xdclass-busybox
    image: busybox:1.35.0 
    command: ["/bin/sh","-c","tail -f /usr/local/test/access.log"] # 容器启动后初始命令,读取指定文件中内容
    volumeMounts:  # 将nginx-log-volume挂在到busybox容器中,对应的目录为 /logs
    - name: nginx-log-volume
      mountPath: /usr/local/test

	volumes: # 这里声明volume存储劵, name为nginx-log-volume,类型是emptyDir
  - name: nginx-log-volume
    emptyDir: {}
  • **操作 : **
#创建
kubectl apply -f volume-emptydir.yaml

#查看
kubectl get pods -n dev -o wide

#访问nignx 产生访问日志
curl ip

#查看容器输出 -f 后是 pod的名称
kubectl logs -f xdclass-volume-emptydir -n dev -c xdclass-busybox

# 删除
kubectl delete -f volume-emptydir.yaml

  1. **HostPath : **
  • Directory 给定的目录路径必须存在
  • DirectoryOrCreate 如果给定路径不存在,将根据需要在那里创建一个空目录
  • File 给定路径上必须存在对应文件
  • FileOrCreate 如果给定路径不存在,将根据需要在那里创建一个空文件

image.png

  • 案例 volume-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: xdclass-volume-hostpath
  namespace: dev
spec:
  containers:
  - name: xdclass-nginx
    image: nginx:1.20
    ports:
    - containerPort: 80
    volumeMounts:  # 将nginx-log-volume挂在到nginx容器中,对应的目录为 /var/log/nginx
    - name: nginx-log-volume
      mountPath: /var/log/nginx

	- name: xdclass-busybox
    image: busybox:1.35.0 
    command: ["/bin/sh","-c","tail -f /usr/local/test/access.log"] # 容器启动后初始命令,读取指定文件中内容
    volumeMounts:  # 将nginx-log-volume挂在到busybox容器中,对应的目录为 /logs
    - name: nginx-log-volume
      mountPath: /usr/local/test

	volumes: # 这里声明volume存储劵, name为nginx-log-volume,类型是hostPath
  - name: nginx-log-volume
    hostPath:
    	path: /usr/local/test
    	type: DirectoryOrCreate #如果给定路径不存在,将根据需要在那里创建一个空目录
  • **操作 : **
#创建
kubectl apply -f volume-hostpath.yaml

#查看
kubectl get pods -n dev -o wide

#访问nignx 产生访问日志
curl ip

#查看容器输出 -f 后是 pod的名称
kubectl logs -f xdclass-volume-hostpath -n dev -c xdclass-busybox

#去节点对应的目录查看文件是否有,即pod运行的节点,主节点上是没的!!!!
ls /usr/local/test

# 删除
kubectl delete -f volume-hostpath.yaml
  • **emptyDir和hostPath对比 : **
  • 都是本地存储卷方式
  • emptyDir是临时存储空间,完全不提供持久化支持;
  • hostPath的卷数据是持久化在node节点的文件系统中的,即便pod已经被删除了,volume卷中的数据还留存在node节点上

  1. **ConfigMap : **
  • 是K8S的一种API对象,用来把【非加密数据】保存到键值对中,比如etcd
  • 可以用作环境变量、命令行参数等,将环境变量、配置信息和容器镜像解耦,便于应用配置的修改
# 命令格式
kubectl create configmap NAME --from-literal=key1=value1 --from-literal=key2=value2
  • **操作 : **
kubectl create configmap xdclass-config --from-literal=account=xdclass --from-literal=password=123456

#查看
kubectl get cm xdclass-config -o yaml

apiVersion: v1
data:
  account: xdclass
  password: password
kind: ConfigMap
metadata:
  creationTimestamp: "2022-07-04T06:36:18Z"
  name: xdclass-config
  namespace: default
  resourceVersion: "1716676"
  selfLink: /api/v1/namespaces/default/configmaps/xdclass-config
  uid: 6ae2890e-fad3-452c-9179-78dd63ddbbba
apiVersion: v1
kind: ConfigMap
metadata:
  name: xdclass-configmap
  namespace: dev
data:
  info: 
    username:xdclass
    password:123456
    
# 操作

#创建
kubectl create -f configmap.yaml


# 查看configmap详情
kubectl describe cm xdclass-configmap -n dev
  • 创建pod的yaml,pod-configmap.yaml,然后吧将创建的configmap挂载进去
apiVersion: v1
kind: Pod
metadata:
  name: pod-configmap
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.20
    volumeMounts: # configmap挂载的目录
    - name: config
      mountPath: /config

  volumes: # 声明configmap
  - name: config
    configMap:
      name: xdclass-configmap
  • **操作 : **
#创建pod
kubectl create -f pod-configmap.yaml

#查看
kubectl get pod pod-configmap -n dev

#进入容器
kubectl exec -it pod-configmap -n dev -- /bin/sh
# cd /config
# cat info

username:xdclass
password:123456

  • **Secret : **

  • 用来保存敏感信息,例如密码、秘钥、证书、OAuth 令牌和 ssh key等

  • 就不需要把这些敏感数据暴露到镜像或者Pod中

  • Secret有多种类型 :

    • dockerconfigson : 用来存储私有 docker registry的认证信息
  • ServiceAccount :

    • 只要与Kubernetes API有交互的Pod,都会自动拥有此种类型的Secret
    • K8S自动创建,并且会自动挂载到Pod的 /run/secrets/kubernetes.io/serviceaccount 目录中
  • 操作 :

#查看
kubectl get pod -A | grep 'kube-proxy'

#进到容器,加了 -- /bin/bash,不会有警告
kubectl exec -it -n kube-system kube-proxy-9wb4g -- /bin/sh

#查看
ls -l /run/secrets/kubernetes.io/serviceaccount

cd /run/secrets/kubernetes.io/serviceaccount

cat ca.crt

  • **Opaque : **加密类型为base64,其特点就是将明文改为了密文
echo -n 'admin' | base64  #账号
echo -n '123456' | base64 #密码

#创建secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MTIzNDU2
#创建
kubectl apply -f secret.yaml 

# 查看secret的信息
kubectl get secret

# 查看mysecret详细信息
kubectl get secret mysecret -o yaml

#将secret挂载到Pod的Volume中,创建pod-secret-volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret
spec:
  containers:
  - name: nginx
    image: nginx:1.20
    volumeMounts: # secret挂载
    - name: xdclass-config
      mountPath: /etc/secret
  volumes:
  - name: xdclass-config
    secret:
      secretName: mysecret

#创建pod
kubectl apply -f pod-secret-volume.yaml

#查看
kubectl get pod -o wide

#查看secret, 在pod中的secret信息实际已经被解密
kubectl exec -it pod-secret -- /bin/sh
#ls /etc/secret
#cat /etc/secret/username
#cat /etc/secret/password


#删除secret
kubectl delete secret mysecret

  • **NFS(Network File System) : **

  • 一种基于TCP/IP 传输的网络文件系统协议, 通过使用NFS协议,可以像访问本地目录一样访问远程服务器中的共享资源

  • NFS服务的实现依赖于RPC (Remote Process Call,远端过程调用)机制,以完成远程到本地的映射过程

  • 需要安装nfs-utils、 rpcbind 软件包来提供NFS共享服务,前者用于NFS共享发布和访问,后者用于RPC支持

  • 采用TCP/IP传输网络文件,适合局域网环境,简单操作

    • NFS端口:2049
    • RPC端口:111

image.png

  • **部署NFS服务器 : **
  • 下载nfs-util (主从均执行, 对应要用到的节点都需要安装,但是不需要启动)
yum install nfs-utils -y
  • 创建目录(nfs服务器)
#目录可以自定义
mkdir /opt/nfsdata

#给路径授权
chmod 777 /opt/nfsdata
  • 编辑/etc/exports 配置文件(nfs服务器)
vim /etc/exports
# 目录的读写权限暴露给这个网段的全部主机
/opt/nfsdata 172.31.101.0/24(rw,insecure,sync)

**解释 : **
172.31.101.0/24表示的IP范围, 换成32位二进制,四组,每组8位
/24 表示前24位不变,后8位由全0变化到全1的过程,也就是由“00000000”变化到“11111111”
又因为全0是子网网络地址,全1是子网广播地址,这两个地址是不分配给主机使用的。
所以有效的可分配的范围是前24位不变,后8位由“00000001”变化为“11111110”的范围
再转换回十进制就是172.31.101.1~172.31.101.254

**参数 : **

  • rw 共享目录可读可写

  • secure 限制客户端只能从小于1024的tcp/ip端口连接服务器;

  • insecure允许客户端从大于1024的tcp/ip端口连接服务器;

  • sync 将数据同步写入内存缓冲区与磁盘中,效率低,但可以保证数据的一致性;

  • async 将数据先保存在内存缓冲区中,必要时才写入磁盘;

  • **启动rpcbind(安装nfs依赖包会自动下载)和nfs服务 : **

systemctl start rpcbind
systemctl start nfs
  • **验证 : **
showmount -e localhost

  • **NFS持久卷挂载 : **
apiVersion: v1
kind: Pod
metadata:
  name: xdclass-nfs
  namespace: dev
  labels: 
    apps: nginx-nfs
spec:
  containers:
  - name: nginx
    image: nginx:1.20
    ports:
    - containerPort: 80
    volumeMounts:
    - name: logs-volume
      mountPath: /var/log/nginx
  volumes:
  - name: logs-volume
    nfs:
      server: 192.168.100.150  #nfs服务器地址
      path: /opt/nfsdata #共享文件路径
  • **操作 : **
# 创建pod
kubectl apply -f pod-log-volume.yaml

# 暴露服务
kubectl expose pod xdclass-nfs -n dev --port=80 --target-port=80 --type=NodePort

# 查看nfs服务器的/opt/nfsdata
kubectl exec -it xdclass-nfs -- /bin/sh
cd /opt/nfsdata
ls

# 查看日志
tail -f access.log

  • **PV 持久卷(Persistent Volume): **

  • 是集群中由管理员配置的一段网络存储,它是集群的一部分资源和底层存储密切相关,对象包含存储实现的细节,即 对接NFS、CIFS等存储系统

  • 不同的PV会对应到不用的存储资源,这样在部署pod的时候直接调用集群内部的pv即可

  • PV没有命名空间隔离概念

  • **PVC 持久卷声明 (Persistent Volume Claim): **

  • 假如存在很多PV, K8S 要用PV的时候直接调用某个PV的话,那如果需要的是存储能力比较大存储资源,所以这个时候需要一个一个去对比pv,这样很耗费资源(因为要满足需求)

  • PVC是用户存储的一种声明, PVC 可以请求特定的存储空间和访问模式,PVC 消耗的是 PV 资源

  • PVC必须与对应的PV建立关系,PVC会根据定义的PV去申请

  • 创建pod的时候会附带一个PVC的请求,PVC的请求相当于就是去寻找一个合适的pv

  • 使用逻辑 :

    • 在 pod 中定义一个存储卷(该存储卷类型为 PVC),定义的时候按指定大小,PVC 必须与对应的 PV 建立关系,PVC 会根据定义的需求【去 PV 申请】,而 PV 是由存储空间创建出来的
  • **PV和PVC逻辑 : **

  • PV 是集群中的【资源】,PVC 是对这些【资源的请求】

  • PV 和 PVC 之间的相互作用遵循这个生命周期

  • Provisioning(配置) —> Binding(绑定) —> Using(使用) —> Releasing(释放) —> Recycling(回收)

  • **PV的yaml模板 : **

apiVersion: v1
kind: PersistentVolume
metadata:
  name: xdclass-pv
spec:
  capacity:
    storage: 5Gi #存储大小
  accessModes: #访问模式
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle #回收策略
  storageClassName: slow #存储类别
  nfs: #卷插件
    path: /tmp
    server: 192.168.100.150
  • **存储大小:**存储大小是可以设置和请求的唯一资源。 未来可能会包含 IOPS、吞吐量等属性

  • 访问模式:用户对资源的访问权限

    • ReadWriteOnce(RWO):读写权限,只能被单个节点挂载
    • ReadOnlyMany(ROX): 只读权限,可以被多个节点挂载
    • ReadWriteMany(RWX):读写权限,可以被多个节点挂载
  • 存储类别:

  • 每个 PV 可以属于某个类,通过将其 storageClassName属性设置为某个 StorageClass 的名称来指定。

  • 特定类的 PV 卷只能绑定到请求该类存储卷的 PVC 申领。

  • 未设置 storageClassName 的 PV 卷没有类设定,只能给到那些没有指定特定 存储类的 PVC 申领。

  • 回收策略(当PV不再被使用了之后的处理策略)

  • 保留 Retain – 当PV对象被删除之后,与之相关的位于外部的基础设施中的数据仍然存在(如nfs),需要根据实际情况手动回收

  • 回收 Recycle – 相当于在卷上执行rm -rf /volume/* 操作,之后该卷可以用于新的pvc申领

  • 删除 Delete – 当PV对象被删除之后,与之相关的位于外部的基础设施中的数据也被一并删除(如nfs),需要根据实际情况手动回收,更多是云厂商设备

  • 状态( PV 的生命周期有4种不同状态)

  • Available(可用)——一块空闲资源还没有被任何声明绑定

  • Bound(已绑定)——卷已经被声明绑定

  • Released(已释放)——声明被删除,但是资源还未被集群重新声明

  • Failed(失败)——该卷的自动回收失败

  • **PVC的yaml模板 : **

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: xdclass-pvc
  namespace: dev
spec:
  accessModes: # 访问模式
  - ReadWriteMany
  selector: # 采用label标签对PV选择过滤
  storageClassName: # 存储类别,设置对应的class的PV才能被系统选出
  resources: # 需要存储资源的请求
    requests:
      storage: 3Gi
  • **需求 : **

  • 基于NFS存储,创建2个PV

  • 创建PVC绑定PV

  • 创建Pod挂载PVC

  • 创建目录

mkdir /opt/nfsdata/pv1
mkdir /opt/nfsdata/pv2
chmod 777 /opt/nfsdata/pv1
chmod 777 /opt/nfsdata/pv2
  • 修改配置文件
vim /etc/exports
#暴露nfs服务
/opt/nfsdata/pv1 172.31.101.0/24(rw,insecure,sync)
/opt/nfsdata/pv2 172.31.101.0/24(rw,insecure,sync)
  • 重启NFS
systemctl restart nfs
  • **创建两个PV : ****kubectl apply -f pv.yaml **
apiVersion: v1
kind: PersistentVolume
metadata:
  name:  xdclass-pv1
spec:
  capacity: 
    storage: 1Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: 192.168.100.150
    path: /opt/nfsdata/pv1
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name:  xdclass-pv2
spec:
  capacity: 
    storage: 2Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: 192.168.100.150
    path: /opt/nfsdata/pv2
  • **查看PV : ****kubectl get pv -o wide**

  • **创建PVC,使用pvc.yaml : ****kubectl apply -f pvc.yaml **

  • (与PV不同,PVC不属于集群资源,拥有自己的名称空间)

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: xdclass-pvc1
  namespace: dev
spec:
  accessModes: 
  - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: xdclass-pvc2
  namespace: dev
spec:
  accessModes: 
  - ReadWriteMany
  resources:
    requests:
      storage: 2Gi
  • **查看pvc : ****kubectl get pvc -n dev**

  • **创建pod 挂载pvc : **

apiVersion: v1
kind: Pod
metadata:
  name: xdclass-pod1
  namespace: dev
spec:
  containers:
  - name: xdclass-busybox
    image: busybox
    command: ["/bin/sh","-c","while true;do echo hello xdclass pod1 >> /opt/print.txt; sleep 5; done;"]
    volumeMounts:
    - name: volume
      mountPath: /opt/
  volumes:
    - name: volume
      persistentVolumeClaim:
        claimName: xdclass-pvc1
        readOnly: false
---
apiVersion: v1
kind: Pod
metadata:
  name: xdclass-pod2
  namespace: dev
spec:
  containers:
  - name: xdclass-busybox
    image: busybox
    command: ["/bin/sh","-c","while true;do echo hello xdclass pod2 >> /opt/print.txt; sleep 5; done;"]
    volumeMounts:
    - name: volume
      mountPath: /opt/
  volumes:
    - name: volume
      persistentVolumeClaim:
        claimName: xdclass-pvc2
        readOnly: false
  • 创建pod完成后,到nfs服务器查看 /opt/nfsdata/pv1/print.txt
  • tail -f pv1/print.txt
  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值