CKA认证 | Day7 K8s存储

第七章 Kubernetes存储

1、数据卷与数据持久卷

为什么需要数据卷?

容器中的文件在磁盘上是临时存放的,这给容器中运行比较重要的应用程序带来一些问题。

  1. 问题1:当容器升级或者崩溃时,kubelet会重建容器,容器内文件会丢失;

  2. 问题2:一个Pod中运行多个容器并需要共享文件;

Kubernetes 卷(Volume) 这一抽象概念能够解决这两个问题。

1. 数据持久化
  • 容器的无状态性:Kubernetes 中的容器是无状态的,这意味着它们在重启或重新调度时,容器内的数据会丢失。
  • 持久化数据:通过使用数据卷,可以将数据持久化到外部存储系统中,确保数据在容器生命周期外仍然存在。
2. 数据共享
  • 多容器共享数据:在某些情况下,同一个 Pod 中的多个容器需要共享数据。数据卷允许这些容器共享同一个存储卷。
  • 跨容器协作:例如,一个容器生成日志文件,另一个容器需要读取这些日志文件。
3. 数据隔离
  • 独立存储:不同的 Pod 可以使用不同的数据卷,确保数据隔离,避免数据冲突。
  • 安全性:通过将敏感数据存储在独立的数据卷中,可以提高安全性。
4. 简化配置
  • 统一管理:使用数据卷可以简化应用程序的配置,因为存储配置可以在 Kubernetes 中集中管理。
  • 灵活性:可以根据需要选择不同的存储后端(如本地存储、云存储、网络文件系统等),而不需要修改应用程序代码。
5. 生命周期管理
  • 数据生命周期:数据卷可以独立于 Pod 的生命周期管理,确保数据在 Pod 重启或删除后仍然可用。
  • 自动挂载:Kubernetes 可以自动挂载和卸载数据卷,简化操作。

常用的数据卷:

官网:Volumes | Kubernetes

  • 节点本地存储(hostPath,emptyDir)
  • 网络存储(NFS,Ceph,GlusterFS)
  • 公有云存储(AWS EBS)
  • K8S资源存储(configmap,secret)

1.1 临时数据卷:emptyDir

emptyDir卷是一个临时存储卷,与Pod生命周期绑定一起,如果 Pod删除了卷也会被删除

应用场景:Pod中容器之间数据共享

选项:

  • sizeLimit:500Mi       //限制共享空间大小(比较少用)


示例:Pod内容器之间共享数据
apiVersion: v1
kind: Pod
metadata: 
  name: emptydir-test
spec:
  containers:
  - name: write-container    //程序讲数据写入到文件
    image: centos
    command: ["bash","-c","for i in {1..100};do echo $i >> 
/data/hello;sleep 1;done"]
    volumeMounts:
      - name: data-volume    //通过volume卷名称引用
        mountPath: /data
  - name: read-container     //程序从文件中读取数据
    image: centos
    command: ["bash","-c","tail -f /data/hello"]
    volumeMounts:
      - name: data-volume
        mountPath: /data
  volumes:      //定义卷的来源
  - name: data-volume
    emptyDir: {}    //{}中为空值

验证1:验证容器之间是否能够共享数据

[root@k8s-master-1-71 ~]# kubectl apply -f emptydir-test.yaml
[root@k8s-master-1-71 ~]# kubectl get pods
NAME            READY   STATUS    RESTARTS      AGE
emptydir-test   2/2     Running   1 (21s ago)   3m14s
# 进入write-container查看
[root@k8s-master-1-71 ~]# kubectl exec -it emptydir-test -- bash

[root@emptydir-test /]# tail -f /data/hello
...
99
100
command terminated with exit code 137
[root@emptydir-test /]# touch /data/aaa ; ls /data/     //往容器中写入临时文件
aaa  hello

## 注:脚本循环结束后退出容器,按照默认的策略Always进行容器重启。
# 进入read-container查看
[root@k8s-master-1-71 ~]# kubectl exec -it emptydir-test -c read-container -- bash
[root@emptydir-test /]# ls /data/
aaa  hello

验证2:实际存储位置(基于节点的存储)

补充:Kubelet的工作目录为/var/lib/kubelet/,负载维护Pod数据的

[root@k8s-master-1-71 ~]# kubectl get pods -o wide
NAME            READY   STATUS    RESTARTS      AGE    IP              NODE             NOMINATED NODE   READINESS GATES
emptydir-test   2/2     Running   2 (45s ago)   5m3s   10.244.114.48   k8s-node2-1-73   <none>           <none>

# 根据查看到的Pod所在节点,找到相应的容器ID
[root@k8s-node2-1-73 ~]# docker ps | grep emptydir-test(例如:7c26307b-b290-4bac-9a3b-6f18ffc26776)
6deb6dc27ab2   centos                                              "bash -c 'for i in {…"   44 seconds ago   Up 43 seconds             k8s_write-container_emptydir-test_default_7c26307b-b290-4bac-9a3b-6f18ffc26776_3
7bb46657087b   centos                                              "bash -c 'tail -f /d…"   7 minutes ago    Up 7 minutes              k8s_read-container_emptydir-test_default_7c26307b-b290-4bac-9a3b-6f18ffc26776_0
fd4c6c671807   registry.aliyuncs.com/google_containers/pause:3.7   "/pause"                  7 minutes ago    Up 7 minutes              k8s_POD_emptydir-test_default_7c26307b-b290-4bac-9a3b-6f18ffc26776_0

# 找到相关Pod关联的empty-dir目录,即可看到挂载的empty-dir目录内容
[root@k8s-node2-1-73 kubernetes.io~empty-dir]# pwd
/var/lib/kubelet/pods/7c26307b-b290-4bac-9a3b-6f18ffc26776/volumes/kubernetes.io~empty-dir

[root@k8s-node2-1-73 kubernetes.io~empty-dir]# ls data-volume/
aaa  bbb  hello

Pod是节点级别的,Pod中的容器都是捆绑在一个节点上,所以 Pod删除了,卷也会被删除

[root@k8s-master-1-71 ~]# kubectl delete -f emptydir-test.yaml
[root@k8s-node2-1-73 kubernetes.io~empty-dir]# ls data-volume/
ls: 无法访问data-volume/: 没有那个文件或目录

1.2 节点数据卷:hostPath

hostPath卷挂载Node的文件系统(即Pod所在节点)上文件或者目 录到Pod中的容器。

应用场景:Pod中容器需要访问宿主机的文件

选项:

  • path:    //将宿主机的目录或文件映射到容器中去

  • type:    //指定类型(目录或文件)


示例:将宿主机/tmp目录挂载到容器/data目录
apiVersion: v1
kind: Pod
metadata:
  name: hostpath-test
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 36000
    volumeMounts:
      - name: data-volume
        mountPath: /data
  volumes:
  - name: data-volume
    hostPath:
      path: /tmp        //Pod所在节点的/tmp目录
      type: Directory

验证:

[root@k8s-master-1-71 ~]# kubectl apply -f hostpath-test.yaml

[root@k8s-master-1-71 ~]# kubectl get pods -o wide
NAME            READY   STATUS    RESTARTS   AGE   IP              NODE             NOMINATED NODE   READINESS GATES
hostpath-test   1/1     Running   0          86s   10.244.114.49   k8s-node2-1-73   <none>           <none>

# 查看Pod所在节点的/tmp目录
[root@k8s-node2-1-73 ~]# ls /tmp/
systemd-private-85c79618aae44d7cbb01bccc046ecb10-chronyd.service-UMOhQf
systemd-private-fdf2b8d40ff841319feb738a463a8f6f-chronyd.service-GJT2Mn

# 进入容器查看/data目录是否有相关映射文件
[root@k8s-master-1-71 ~]# kubectl exec -it hostpath-test -- sh
/ # ls /data/
systemd-private-85c79618aae44d7cbb01bccc046ecb10-chronyd.service-UMOhQf
systemd-private-fdf2b8d40ff841319feb738a463a8f6f-chronyd.service-GJT2Mn

1.3 网络数据卷:NFS

NFS:是一个主流的文件共享服务器(注:每个Node上都要安装nfs-utils包)

# 服务端部署
[root@k8s-node1-1-72 ~]# yum install -y nfs-utils
[root@k8s-node1-1-72 ~]# vi /etc/exports     //NFS共享配置目录
/ifs/kubernetes *(rw,no_root_squash)
# 解释:
共享目录 访问来源限制(权限)
[root@k8s-node1-1-72 ~]# mkdir -p /ifs/kubernetes

[root@k8s-node1-1-72 ~]# systemctl enable nfs --now

# 客户端测试
[root@k8s-node2-1-73 ~]# yum install -y nfs-utils
[root@k8s-node2-1-73 ~]# mount -t nfs 192.168.1.72:/ifs/kubernetes /mnt
[root@k8s-node2-1-73 ~]# df -Th | grep /ifs/kubernetes
192.168.1.72:/ifs/kubernetes nfs4       37G  4.3G   33G   12% /mnt

NFS卷:提供对NFS挂载支持,可以自动将NFS共享路径 挂载到Pod中

选项:

  • server: //指定NFS地址

  • path: /指定NFS共享目录


示例:将Nginx网站程序根目录持久化到 NFS存储,为多个Pod提供网站程序文件
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nfs-pod

  name: nfs-pod
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: web
        image: nginx
        volumeMounts:
        - name: data-volume
          mountPath: /usr/share/nginx/html    //挂载的目录
      volumes:
      - name: data-volume      //volume卷名称
        nfs:
          server: 192.168.1.72     //指定NFS地址
          path: /ifs/kubernetes    //NFS共享目录

验证1:容器之间的数据是否共享

[root@k8s-node2-1-73 ~]# kubectl apply -f nfs-pod.yaml
[root@k8s-master-1-71 ~]# kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE

nfs-pod-9b57f886-d8rzx   1/1     Running   0          10m
nfs-pod-9b57f886-tk99z   1/1     Running   0          55s
nfs-pod-9b57f886-wpr9q   1/1     Running   0          10m

# 进入容器1,创建文件测试
[root@k8s-node2-1-73 ~]# kubectl exec -it nfs-pod-9b57f886-d8rzx -- bash
root@nfs-pod-9b57f886-d8rzx:/# df -Th |grep /ifs/kubernetes
192.168.1.72:/ifs/kubernetes nfs4      37G  4.3G   33G  12% /usr/share/nginx/html
root@nfs-pod-9b57f886-d8rzx:~# touch /usr/share/nginx/html/aaaaa
root@nfs-pod-9b57f886-d8rzx:~# ls /usr/share/nginx/html/
aaaaa

# 进入容器2,查看文件
[root@k8s-node2-1-73 ~]# kubectl exec -it nfs-pod-9b57f886-tk99z -- bash
root@nfs-pod-9b57f886-tk99z:/# ls /usr/share/nginx/html/
aaaaa

验证2:增加/删除Pod是否能继续使用共享存储数据

# 删除Pod,查看是否能继续使用共享存储数据
[root@k8s-master-1-71 ~]# kubectl delete pod nfs-pod-9b57f886-tk99z

[root@k8s-master-1-71 ~]# kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nfs-pod-9b57f886-d8rzx   1/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小安运维日记

Hey~ 感谢您的充电支持!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值