K8s临时卷与持久卷详解

Kubernetes

存储卷管理

临时卷
卷概述

卷是一个抽象化的存储设备

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

  1. 当容器奔溃或重启的时候,kubelet会以干净的镜像状态重启容器,容器内的历史数据会丢失
  2. 当容器被删除(K8S没有停止容器的概念,只有创建、删除),容器内的数据会被一起清理
  3. 多个容器中有共享文件或目录的需求

Kubernetes支持很多类型的卷

Pod可以同时使用任意数目的卷类型

Pod中的容器在奔溃或重启之后数据都不会丢失

临时卷

临时卷的生命周期与Pod相同,当Pod不存在时,K8S也会销毁临时卷

持久卷

当Pod执行结束或被删除以后,K8S不会销毁持久卷

如何使用卷?

使用卷时,在spec,volumes字段中设置为Pod提供的卷,并在spec,containers下volumeMounts字段中声明在容器中的挂载位置

卷挂载在镜像中指定路径下,Pod配置中的每个容器必须独立指定各个卷的挂载位置

卷不能挂载到其它卷之上,也不能与其它卷有硬链接

emptyDir卷

一种临时卷,本质是一个简单的空目录

当Pod被创建时,emptyDir也会被创建,并且和Pod在该节点上运行期间,一直存在。当Pod被从节点上删除时,emptyDir中的数据也会被永久删除

emptyDir的用途:临时空间,例如缓存服务器、数据统计分析、归并排序

​ 同一个Pod中容器共享数据

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

统计访问量(案例1)

[root@master ~]# vim myv1.yaml
---
apiVersion: v1
kind: Pod
metadata:
  name: web1
spec:
  terminationGracePeriodSeconds: 0
  restartPolicy: Always
  volumes:
  - name: logs
    emptyDir: {}
  containers:
  - name: nginx
    image: myos:nginx
    volumeMounts:
    - name: logs
      mountPath: /usr/local/nginx/logs
    ports:
    - protocol: TCP
      containerPort: 80
  - name: log
    image: myos:v2009
    volumeMounts:
    - name: logs
      mountPath: /logdata
    command: ["/bin/bash"]
    args:
    - -c
    - |
      while true;do
        awk '{IP[$1]++}END{for(i in IP)print(i,IP[i])}' /logdata/access.log
        sleep 60
      done

[root@master ~]# kubectl apply -f myv1.yaml
pod/web1 created
[root@master ~]# kubectl get pod -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP            NODE
web1   2/2     Running   0          59s   10.244.3.50   node-0003
[root@master ~]# curl -s http://10.244.3.50
[root@master ~]# curl -s http://10.244.3.50
[root@master ~]# curl -s http://10.244.3.50
Nginx is running !
[root@master ~]# kubectl logs web1 -c log
10.244.0.0 3
configMap卷

一种临时卷

configMap提供了向Pod注入配置数据的方法,允许你将配置文件与镜像分离,使容器化的应用具有可移植性

configMap在使用之前需要先创建它,configMap不是用来保存大量数据的,在其中保存的数据不得超过1M

configMap的用途:定义临时环境变量

​ 修改各种配置文件的参数,数据库的地址,用户名密码等

设置容器变量

# 使用变量创建 configMap
[root@master ~]# kubectl create configmap mycm1 --from-literal=x=123 --from-literal=y=456
configmap/mycm1 created

# 查看 configMap
[root@master ~]# kubectl get configmaps 
NAME               DATA   AGE
kube-root-ca.crt   1      2d5h
mycm1              1      54s

# 引用 configMap 设置环境变量
[root@master ~]# vim myv2.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: web2
spec:
  terminationGracePeriodSeconds: 0
  restartPolicy: Always
  containers:
  - name: nginx
    image: myos:nginx
    ports:
    - protocol: TCP
      containerPort: 80
    envFrom:
    - configMapRef:
        name: mycm1

[root@master ~]# kubectl apply -f myv2.yaml 
pod/web2 created
[root@master ~]# kubectl exec -it web2 -- /bin/bash
[root@web1 html]# echo ${x},${y}
123,456
配置系统时区

[root@master ~]# vim myv2.yaml 
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: timezone
data:
  TZ: "Asia/Shanghai"

---
apiVersion: v1
kind: Pod
metadata:
  name: web2
spec:
  terminationGracePeriodSeconds: 0
  restartPolicy: Always
  containers:
  - name: nginx
    image: myos:nginx
    ports:
    - protocol: TCP
      containerPort: 80
    envFrom:
    - configMapRef:
        name: timezone

[root@master ~]# kubectl delete -f myv2.yaml
pod "web2" deleted
[root@master ~]# kubectl apply -f myv2.yaml
configmap/timezone created
pod/web2 created
[root@master ~]# kubectl exec -it web2 -- /bin/bash
[root@web2 html]# date  +%T
配置Nginx解析PHP

# 拷贝 5/public/info.php 到 master 主机,创建测试页面
[root@master ~]# mkdir webphp
[root@master ~]# echo "Hello Nginx ." >webphp/info.html
[root@master ~]# cp info.php webphp/

# 把目录做 configMap
[root@master ~]# kubectl create configmap website --from-file=webphp
configmap/website created

# 修改 nginx 配置文件,并做成 ConfigMap
[root@master ~]# kubectl cp web2:/usr/local/nginx/conf/nginx.conf ./nginx.conf
[root@master ~]# vim nginx.conf
        location ~ \.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            include        fastcgi.conf;
        } 

[root@master ~]# kubectl create configmap webconf --from-file=nginx.conf
configmap/webconf created
[root@master ~]# kubectl get configmaps 
NAME               DATA   AGE
timezone           1      73m
webconf            1      5s
website            2      4m18s
修改Pod配置文件

[root@master ~]# vim myv2.yaml
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: timezone
data:
  TZ: "Asia/Shanghai"

---
apiVersion: v1
kind: Pod
metadata:
  name: web2
spec:
  terminationGracePeriodSeconds: 0
  restartPolicy: Always
  volumes:
  - name: myphp
    configMap:
      name: website
  - name: webconf
    configMap:
      name: webconf
  containers:
  - name: nginx
    image: myos:nginx
    volumeMounts:
    - name: myphp
      mountPath: /usr/local/nginx/html/myphp
    - name: webconf
      subPath: nginx.conf
      mountPath: /usr/local/nginx/conf/nginx.conf
    ports:
    - protocol: TCP
      containerPort: 80
    envFrom:
    - configMapRef:
        name: timezone
  - name: php
    image: myos:phpfpm
    volumeMounts:
    - name: myphp
      mountPath: /usr/local/nginx/html/myphp
    envFrom:
    - configMapRef:
        name: timezone

[root@master ~]# kubectl delete -f myv2.yaml 
pod "web2" deleted
[root@master ~]# kubectl apply -f myv2.yaml 
pod/web2 created
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP            NODE
web2   2/2     Running   0          7s    10.244.3.13   node-0003
[root@master ~]# curl http://10.244.3.13/myphp/info.php
<pre>
Array
(
    [REMOTE_ADDR] => 10.244.0.0
    [REQUEST_METHOD] => GET
    [HTTP_USER_AGENT] => curl/7.29.0
    [REQUEST_URI] => /info.php
)
php_host:       web2
1229
保护敏感数据(案例2)

# 修改 nginx.conf 配置文件,启用认证
[root@master ~]# vim nginx.conf 
        location ~ ^/myphp/.+\.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            include        fastcgi.conf;
            auth_basic "Website Admin";
            auth_basic_user_file "/usr/local/nginx/conf/webauth";
        }
[root@master ~]# kubectl delete configmaps webconf 
configmap "webconf" deleted
[root@master ~]# kubectl create configmap webconf --from-file=nginx.conf 
configmap/webconf created

# 修改 configmap 之后重建 Pod
[root@master ~]# kubectl delete -f myv2.yaml 
configmap "timezone" deleted
pod "web2" deleted
[root@master ~]# kubectl apply -f myv2.yaml 
configmap/timezone created
pod/web2 created

# 创建认证文件
[root@master ~]# kubectl exec -it web2 -c nginx -- /bin/bash
[root@web2 html]# yum install -y httpd-tools
[root@web2 html]# htpasswd -nbm admin 123456 >/usr/local/nginx/conf/webauth
[root@web2 html]# exit

# 访问验证
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE    IP            NODE
web2   2/2     Running   0          100s   10.244.2.20   node-0002
[root@master ~]# curl http://10.244.2.20/myphp/info.html
Nginx is running !
[root@master ~]# curl http://10.244.2.20/myphp/info.php
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.17.6</center>
</body>
</html>
[root@master ~]# curl -u admin:123456 http://10.244.2.20/myphp/info.php
<pre>
Array
(
    [REMOTE_ADDR] => 127.0.0.1
    [REQUEST_METHOD] => GET
    [HTTP_USER_AGENT] => curl/7.29.0
    [REQUEST_URI] => /myphp/info.php
)
php_host:       web
1229
secret卷

一种临时卷

secret类似于configMap但专门用于保存机密数据

在设置secret的data字段时,所有键值都必须是经过base64编码的字符串

secret用途:为容器配置环境变量

​ 挂载配置文件/目录到容器

​ 由kubelet在为Pod拉取镜像时使用(需要登录的仓库)

![4](C:\Users\GUCI\Desktop\4.png)[root@master ~]# kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123456
secret/mysecret created
[root@master ~]# kubectl get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-qw9b9   kubernetes.io/service-account-token   3      5d1h
mysecret              Opaque                                2      54s
[root@master ~]# kubectl get secrets mysecret -o yaml
apiVersion: v1
data:
  password: MTIzNDU2
  username: YWRtaW4=
kind: Secret
metadata:
  creationTimestamp: "2022-09-03T09:51:10Z"
  name: mysecret
  namespace: default
  resourceVersion: "288864"
  uid: fec7e9bc-f957-40b5-ab7a-0382c75c3224
type: Opaque
Pod 映射 secret

[root@master ~]# vim myv3.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: web3
spec:
  terminationGracePeriodSeconds: 0
  restartPolicy: Always
  containers:
  - name: nginx
    image: myos:nginx
    ports:
    - protocol: TCP
      containerPort: 80
    envFrom:
    - secretRef:
        name: mysecret

[root@master ~]# kubectl apply -f myv3.yaml 
pod/web3 created
[root@master ~]# kubectl exec -it web3 -- /bin/bash
[root@web3 html]# echo ${username},${password}
admin,123456

[root@master ~]# kubectl delete -f myv3.yaml 
pod "web3" deleted
[root@master ~]# kubectl delete secrets mysecret
secret "mysecret" deleted
为案例2配置用户名密码

# 生成加密 base64 数据
[root@master ~]# kubectl exec -it web2 -c nginx -- /bin/bash
[root@web2 html]# yum install -y httpd-tools
[root@web2 html]# htpasswd -nbm admin 123456 |base64
YWRtaW46JGFwcjEkdGJqOXJISUckdk9DRFpDaFZJUHl0ZHdGSXl1Qm91MAoK
[root@web2 html]# exit

# 使用 secret 设置密码
[root@master ~]# vim myv2.yaml 
---
kind: Secret
apiVersion: v1
metadata:
  name: myauth
type: Opaque
data:
  webauth: YWRtaW46JGFwcjEkdGJqOXJISUckdk9DRFpDaFZJUHl0ZHdGSXl1Qm91MAoK

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: timezone
data:
  TZ: "Asia/Shanghai"

---
apiVersion: v1
kind: Pod
metadata:
  name: web2
spec:
  terminationGracePeriodSeconds: 0
  restartPolicy: Always
  volumes:
  - name: myphp
    configMap:
      name: website
  - name: webconf
    configMap:
      name: webconf
  - name: webauth
    secret:
      secretName: myauth
      items:
      - key: webauth
        path: webauth
        mode: 0644
  containers:
  - name: nginx
    image: myos:nginx
    volumeMounts:
    - name: myphp
      mountPath: /usr/local/nginx/html/myphp
    - name: webconf
      subPath: nginx.conf
      mountPath: /usr/local/nginx/conf/nginx.conf
    - name: webauth
      subPath: webauth
      mountPath: /usr/local/nginx/conf/webauth
    ports:
    - protocol: TCP
      containerPort: 80
    envFrom:
    - configMapRef:
        name: timezone
  - name: php
    image: myos:phpfpm
    volumeMounts:
    - name: myphp
      mountPath: /usr/local/nginx/html/myphp
    envFrom:
    - configMapRef:
        name: timezone

[root@master ~]# kubectl delete pod web2 
pod "web2" deleted
[root@master ~]# kubectl apply -f myv2.yaml 
configmap/timezone created
secret/myauth created
pod/web2 created
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP            NODE
web2   2/2     Running   0          4s    10.244.3.22   node-0003
[root@master ~]# curl -u admin:123456 http://10.244.3.22/myphp/info.php
<pre>
Array
(
    [REMOTE_ADDR] => 10.244.0.0
    [REQUEST_METHOD] => GET
    [HTTP_USER_AGENT] => curl/7.29.0
    [REQUEST_URI] => /myphp/info.php
)
php_host:       web2
1229
持久卷
hostPath卷

hostPath卷的本质是使用本地设备,例如磁盘,分区、目录、Socket、CharDevice、BlockDevice等hostPath卷的可用性取决于底层节点的可用性,如果节点变得不健康,那么hostPath卷也将不可被访问

hostPath卷里面的数据不会随着Pod技术而消失

#配置相同的Pod,可能在不同的节点上表现不同,因为不同节点上映射的文件内容不同

在这里插入图片描述
在这里插入图片描述

[root@master ~]# vim myv5.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: web5
spec:
  terminationGracePeriodSeconds: 0
  restartPolicy: Always
  volumes:
  - name: mydata
    hostPath:
      path: /var/log
      type: DirectoryOrCreate
  containers:
  - name: nginx
    image: myos:nginx
    ports:
    - protocol: TCP
      containerPort: 80
    volumeMounts:
    - name: mydata
      mountPath: /log

[root@master ~]# kubectl apply -f myv5.yaml 
pod/web5 created
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP            NODE
web5   1/1     Running   0          4s    10.244.2.28   node-0002
[root@master ~]# kubectl exec -it web5 -- /bin/bash
# 在不同的预节点显示的数据不同
[root@web5 data]# cat /log/messages
... ...
# 创建的数据可以永久保存,即使 Pod 被删除也不会丢失
[root@web5 data]# echo "hello world" >/log/myfile.txt

[root@master ~]# kubectl delete -f myv5.yaml 
pod "web5" deleted

[root@node-0002 ~]# cat /var/log/myfile.txt
hello world
NFS卷

NFS是持久卷

NFS卷的内容在删除Pod时会被卸载(umount),而不是被删除NFS卷可以在不同节点的Pod共享数据

NFS卷的用途:NFS最大的功能就是在不同节点的不同Pod中共享读写数据,本地NFS客户端可以透明的读写位于远端NFS服务器的文件,就像访问本地文件一样

搭建NFS服务器

# 搭建 NFS 服务
[root@registry ~]# yum install -y nfs-utils
[root@registry ~]# mkdir -m 0777 /var/webroot
[root@registry ~]# echo "This is NFS server" >/var/webroot/index.html
[root@registry ~]# echo -e "/var/webroot\t*(rw)" >/etc/exports
[root@registry ~]# systemctl enable --now nfs
# 在 master 上验证服务
[root@master ~]# yum install -y nfs-utils
[root@master ~]# showmount -e registry
Export list for registry:
/var/webroot *
# 在所有节点安装 NFS 模块
[root@node-0001 ~]# yum install -y nfs-utils
[root@node-0002 ~]# yum install -y nfs-utils
[root@node-0003 ~]# yum install -y nfs-utils
搭建NFS服务器

[root@master ~]# vim myv6.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: web6
spec:
  terminationGracePeriodSeconds: 0
  restartPolicy: Always
  volumes:
  - name: website
    nfs:
      server: registry
      path: /var/webroot
  containers:
  - name: nginx
    image: myos:nginx
    ports:
    - protocol: TCP
      containerPort: 80
    volumeMounts:
    - name: website
      mountPath: /usr/local/nginx/html

[root@master ~]# kubectl apply -f myv6.yaml 
pod/web6 created
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP            NODE
web6   1/1     Running   0          3s    10.244.1.18   node-0001
[root@master ~]# curl http://10.244.1.18/
This is NFS server

# 清理实验 Pod
[root@master ~]# kubectl delete -f myv6.yaml 
pod "web6" deleted
PV/PVC

PV的全称是Persistent Volume,是持久卷

PVC的全称是PersistentVolumeClaim,是持久卷声明

PV/PVC的用途:存储的管理是一个与计算实例的管理完全不同的话题。管理员希望能提供一种通用的API来完成Pod对卷的部署管理与使用。PV/PVC就是为了满足这种需求而诞生的,PV/PVC的引入使集群具备了存储的逻辑抽象能力

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

持久卷(PV)
[root@master ~]# vim pv.yaml
---
kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv-local
spec:
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 30Gi
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /var/weblog
    type: DirectoryOrCreate

---
kind: PersistentVolume
apiVersion: v1
metadata:                       
  name: pv-nfs
spec:
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
    - ReadOnlyMany
    - ReadWriteMany
  capacity:
    storage: 20Gi
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: registry
    path: /var/webroot

[root@master ~]# kubectl apply -f pv.yaml 
persistentvolume/pv-local created
persistentvolume/pv-nfs created
[root@master ~]# kubectl get persistentvolume
NAME       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv-local   30Gi       RWO            Retain           Available                                   2s
pv-nfs     20Gi       RWO,ROX,RWX    Retain           Available                                   2s
持久卷声明(PVC)
[root@master ~]# vim pvc.yaml
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pvc1
spec:
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 18Gi

---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pvc2
spec:
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 15Gi

[root@master ~]# kubectl apply -f pvc.yaml 
persistentvolumeclaim/pvc1 created
persistentvolumeclaim/pvc2 created
[root@master ~]# kubectl get persistentvolumeclaims 
NAME   STATUS   VOLUME     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc1   Bound    pv-local   30Gi       RWO                           8s
pvc2   Bound    pv-nfs     20Gi       RWO,ROX,RWX                   8s
Pod 调用 PVC

[root@master ~]# cat myv7.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: web7
spec:
  terminationGracePeriodSeconds: 0
  restartPolicy: Always
  volumes:
  - name: logdata
    persistentVolumeClaim:
      claimName: pvc1
  - name: website
    persistentVolumeClaim:
      claimName: pvc2 
  containers:
  - name: nginx
    image: myos:nginx
    ports:
    - protocol: TCP
      containerPort: 80
    volumeMounts:
    - name: logdata
      mountPath: /usr/local/nginx/logs
    - name: website
      mountPath: /usr/local/nginx/html

[root@master ~]# kubectl apply -f myv7.yaml 
pod/web7 created
[root@master ~]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP            NODE
web7   1/1     Running   0          19s   10.244.1.20   node-0001
[root@master ~]# curl http://10.244.1.20/
This is NFS server

[root@master ~]# kubectl delete -f myv7.yaml 
pod "web7" deleted

[root@node-0001 ~]# cat /var/weblog/access_log 
10.244.0.0 - - [27/Jun/2022:02:00:12 +0000] "GET / HTTP/1.1" 200 19 "-" "curl/7.29.0"
10.244.0.0 - - [27/Jun/2022:02:00:14 +0000] "GET / HTTP/1.1" 200 19 "-" "curl/7.29.0"
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

故辞运维

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值