kubernetes集群系列资料13--存储机制介绍

一、K8S存储机制介绍  

  k8s的stateful控制组件是为有状态服务而设计的,有状态服务需要对数据进行存储;k8s有4种存储机制,主要为:

  1)configMap:为K8S存储配置文件而设计的,configMap可以用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制大对象。
  2)secret:为了解决密码、token、密钥等敏感数据的配置加密而设计,而不需要将这些敏感数据暴露到镜像或pod.spec中,可以volume或环境变量的方式使用。
  3)volume:为容器提供共享存储卷,避免发生容器崩溃重启后容器中文件丢失的问题。当pod不存在时,volume也不复存在;k8s支持多种类型的卷,pod可使用任意数量的卷。
  4)persistentVolume/persistentVolumeClai:

二、configMap介绍

  许多应用程序从配置文件、命令行参数或环境变量中读取配置信息,而configMap API给我们提供了向容器注入配置信息的机制。
  传统生成环境中,配置文件注册中心负责向n个集群n个节点应用程序的提供配置信息,该中心需要自行构建,没有较好的开源方案。应用程序向配置文件注册中心提供本节点的信息(如:IP、hostname),配置文件注册中心根据规则为该节点应用程序更新配置,应用程序按照新配置进行重载后运行。
  k8s集群中,configMap充当了配置文件注册中心的作用。pod向configMap申请配置,configMap为各pod下发不同的配置。
  configMap创建配置有3中方式:使用目录创建、使用文件创建、使用字面值创建。

1、使用目录创建configMap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mkdir configMapFile;cd configMapFile
cat > game.properties <<eof
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
enemies.code.passphrase=UUDDLRLRBABAS
enemies.code.allowed=true
enemies.code.lives=30
eof
 
cat >ui.properties<<eof
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
eof
 
kubectl create configmap game-config --from-file=../configMapFile #创建configMap;
kubectl get configmap               #查看configMap;
kubectl get cm game-config -o yaml  #以yaml格式输出game-config配置;
kubectl get cm game-config -o json    #以yaml格式输出game-config配置;

 2、使用文件创建configMap

1
2
kubectl create configmap game-config2 --from-file=../configMapFile/game.properties #使用文件创建configMap;
kubectl get cm game-config2 -o yaml

  多次使用文件创建,与在该目录下一次性批量创建效果相同。

3、使用字面量创建configMap

1
2
kubectl create configmap game-config3 --from-literal=special.how=very --from-literal=special.type=charm #使用字面量创建configMap;
kubectl get cm game-config3 -o yaml

4、案例:使用configMap向pod注入环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cat >special-config.yaml<<eof
apiVersion: v1
kind: ConfigMap
metadata:
    name: special-config
    namespace: default
data:
    special.how: very
    special.type: charm
eof
kubectl apply -f special-config.yaml #使用yaml文件创建configMap;
 
cat >env-config.yaml<<eof
apiVersion: v1
kind: ConfigMap
metadata:
    name: env-config
    namespace: default
data:
    log_level: INFO
eof
kubectl apply -f env-config.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
cat >pod_configMapTest.yaml<<eof
apiVersion: v1
kind: Pod
metadata:
    name: dapi-test-pod
    namespace: default
spec:
    containers:
        - name: test-container
          image: hub.atguigu.com/library/nginx:latest
          command: ["/bin/sh","-c","env"]
          env:                              #设置pod环境变量;
            - name: SPECIAL_LEVEL_KEY
              valueFrom:                    #向pod环境变量注入special-config配置中某个键的值;
                configMapKeyRef:
                    name: special-config
                    key: special.how
            - name: SPECIAL_TYPE_KEY
              valueFrom:
                configMapKeyRef:
                    name: special-config
                    key: special.type
          envFrom:                          #向pod注入env.config配置中所有键值对;
            - configMapRef:
                name: env-config
    restartPolicy: Never
eof
kubectl apply -f pod_configMapTest.yaml

验证结果显示:环境变量包含导入的变量SPECIAL_LEVEL_KEY、SPECIAL_TYPE_KEY、log_level。

 5、案例:通过volume来使用configMap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cat >pod_configMapTest_1.yaml<<eof
apiVersion: v1
kind: Pod
metadata:
    name: dapi-test-pod-1
    namespace: default
spec:
    containers:
    - name: test-container
      image: hub.atguigu.com/library/nginx:latest
      command: ["/bin/sh","-c","ls /etc/config/"]
      volumeMounts:                     #指定挂载卷;
        - name: config-volume           #指定挂载卷名称;
          mountPath: /etc/config        #指定挂载卷挂载点;
    volumes:
        - name: config-volume
          configMap:
            name: special-config        #将configMap导入pod的volume中,有不同的选型。基本方式为:将文件填入volume,键以文件名显示,值以内容显示;
    restartPolicy: Never
eof
kubectl apply -f pod_configMapTest_1.yaml

5、案例:configMap热更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
cat >config_update_test.yaml<<eof
apiVersion: v1
kind: ConfigMap
metadata:
    name: log-config
    namespace: default
data:
    log_level: INFO
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: my-nginx
    namespace: default
spec:
    replicas: 1
    template:
        metadata:
            labels:
                run: my-nginx
        spec:
            containers:
            - name: my-nginx
              image: hub.atguigu.com/library/nginx:latest
              ports:
              - containerPort: 80
              volumeMounts:                     #指定挂载卷;
                - name: config-volume           #指定挂载卷名称;
                  mountPath: /etc/config        #指定挂载卷挂载点;
            volumes:
                - name: config-volume
                  configMap:
                    name: log-config        #将configMap导入pod的volume中,有不同的选型。基本方式为:将文件填入volume,键以文件名显示,值以内容显示;
            restartPolicy: Always
eof
kubectl apply -f config_update_test.yaml
kubectl exec $(kubectl get pod -l run=my-nginx -o=name |cut -d "/" -f2) -it -- cat /etc/config/log_level #查看导入pod的configMap配置,该值以volume文件存在;

验证结果:配置写入volume的log_level文件。

 

6、案例:configMap热更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
cat >config_update_test.yaml<<eof
apiVersion: v1
kind: ConfigMap
metadata:
    name: log-config
    namespace: default
data:
    log_level: INFO
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: my-nginx
    namespace: default
spec:
    replicas: 1
    template:
        metadata:
            labels:
                run: my-nginx
        spec:
            containers:
            - name: my-nginx
              image: hub.atguigu.com/library/nginx:latest
              ports:
              - containerPort: 80
              volumeMounts:                     #指定挂载卷;
                - name: config-volume           #指定挂载卷名称;
                  mountPath: /etc/config        #指定挂载卷挂载点;
            volumes:
                - name: config-volume
                  configMap:
                    name: log-config        #将configMap导入pod的volume中,有不同的选型。基本方式为:将文件填入volume,键以文件名显示,值以内容显示;
            restartPolicy: Always
eof
kubectl apply -f config_update_test.yaml
kubectl exec $(kubectl get pod -l run=my-nginx -o=name |cut -d "/" -f2) -it -- cat /etc/config/log_level #查看导入pod的configMap配置,该值以volume文件存在;
kubectl edit configmap log-config #修改configMap配置log_level值改为DEBUG;
kubectl patch deployment my-nginx --patch '{"spec":{"template":{"metadata":{"annotations":{"version/config":"20210618 14:53:00"}}}}}' #手动指定20210618 14:53:00重新加载配置文件,以便配置文件生效;
kubectl exec $(kubectl get pod -l run=my-nginx -o=name |cut -d "/" -f2) -it -- cat /etc/config/log_level #查看log_level值是否修改;

验证结果:configMap配置已热更新。

 三、secret介绍 

service Account:用来访问K8S API,由K8S自动创建,并且会自动挂载到pod的/run/secrets/kubernetes.io/serviceaccount目录中;对于有些pod(如coreDNS、flannel)来说,需要与K8S API进行交互,K8S API不是谁都可以访问的,必须通过挂载SA后pod才能访问K8S API;

opaque:base64编码格式的secret,用来存储密码、密钥等;opaque类型的数据是一个map类型,要求value是base64编码格式;
kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息;

1、SA案例

1
2
3
4
kubectl run nginx --image nginx #创建名为nginx的depoloyment及pod;
kubectl get deployment;kubectl get pods
kubectl exec nginx-7bb7cd8db5-czg6s ls /run/secrets/kubernetes.io/serviceaccount #查看sa的默认挂载的目录;
kubectl get secret -n kube-system #查看集群自动创建的secret;

 

 2、opaque案例

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
echo -n 'admin' |base64     #输出以base64加密结果为YWRtaW4=;
echo -n '1qaz@WSX' |base64  #输出以base64加密结果为MXFhekBXU1g=;
echo -n 'YWRtaW4=' |base64 -d  #输出YWRtaW4=的解密结果为admin;
cat >secret.yml<<eof
apiVersion: v1
kind: Secret
metadata:
    name: mysecret
data:
    username: YWRtaW4=
    password: MXFhekBXU1g=
eof
kubectl apply -f secret.yml
kubectl get secret
#将secret挂载到volume中
cat >secret-pod.yml<<eof
apiVersion: v1
kind: Pod
metadata:
    labels:
        name: secret-test
    name: secret-test
spec:
    volumes:
    - name: secrets
      secret:
        secretName: mysecret
    containers:
    - image: hub.atguigu.com/library/nginx:latest
      name: db
      volumeMounts:
      - name: secrets
        mountPath: '/etc/secrets'
        readOnly: true
eof
kubectl apply -f secret-pod.yml
kubectl get pod
kubectl exec secret-test -it -- cat /etc/secrets/username #验证secret是否导入volume中;

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#将secret导出到pod的环境变量中
cat >secret-pod-out.yml<<eof
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: secret-pod-out-deployment
spec:
    replicas: 2
    template:
        metadata:
            labels:
                app: secret-pod-out-deployment
        spec:
            containers:
            - image: hub.atguigu.com/library/nginx:latest
              name: pod-1
              ports:
              - containerPort: 80
              env:
              - name: TEST_USER
                valueFrom:
                    secretKeyRef:
                        name: mysecret
                        key: username
              - name: TEST_PASSWORD
                valueFrom:
                    secretKeyRef:
                        name: mysecret
                        key: password
eof
kubectl apply -f secret-pod-out.yml
kubectl get pod
kubectl exec secret-pod-out-deployment-7b8f585846-2cvj6 -it -- echo $TEST_PASSWORD #验证secret是否导入pod中;

 

3、kubernetes.io/dockerconfigjson案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
kubectl create secret docker-registry myregistrykey --docker-server=hub.atguigu.com --docker-username=admin --docker-password=Harbor12345 --docker-email=admin@example.com #创建docker registry认证的secret;私有仓库不进行认证就无法下载镜像,因此需要创建该secret来存储私有docker registry的认证信息<br>cat >myregistry-secret.yml<<eof
apiVersion: v1
kind: Pod
metadata:
    name: foo
spec:
    containers:
        - image: hub.atguigu.com/library/nginx:latest
          name: foo
    imagePullSecrets:
        - name: myregistrykey
eof
kubectl apply -f myregistry-secret.yml
kubectl get pod

 

 四、volume介绍

docker中,容器崩溃后重启时数据不会丢失;但K8S中,容器崩溃时,该容器的文件会丢失,kubelet重启该容器,容器以镜像最初状态重新启动;POD中同时运行的多个容器需要共享文件。
k8s支持以下类型的卷:emptyDir;hostPath;iscsi;local;nfs;awsElasticBlockStore;azureDisk;azureFile;cephfs;csi;downwardAPI;fc;flocker;gcePersistentDisk;gitRepo;glusterfs;persistentVolumeClaim;projected;portworxVolume;quobyte;rbd;scaleIO;secret;storageos;vsphereVolume;

1、emptyDir介绍  

当pod被分配给节点时,首先创建emptyDir卷,并且只要该pod在该节点上运行,该卷就会存在。该卷最初时空的,pod中容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同的路径上。当处于任何原因从节点中删除pod时,emptyDir中数据将被永久删除。
empty的用法有:
  暂存空间,如:用于基于磁盘的合并排序;
  用作长时间计算崩溃恢复时的检查点;
  web服务器容器提供数据时,保存内容管理器容器提取的文件;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
cat >volume-emptyDir.yml<<eof
apiVersion: v1
kind: Pod
metadata:
    name: volume-test-pod
spec:
    containers:
    - image: hub.atguigu.com/library/nginx:latest
      name: volume-test-container
      volumeMounts:
      - mountPath: /cache
        name: cache-volume
    - image: hub.atguigu.com/library/busybox:latest
      name: liveness-exec-container
      imagePullPolicy: IfNotPresent
      command: ["/bin/sh","-c","touch /tmp/live;sleep 6000s"]
      volumeMounts:
      - mountPath: /test
        name: cache-volume     
    volumes:
    - name: cache-volume
      emptyDir: {}
eof
kubectl apply -f volume-emptyDir.yml
kubectl get pod
kubectl exec volume-test-pod -c volume-test-container -it -- touch /cache/test.txt
kubectl exec volume-test-pod -c volume-test-container -it -- ls /cache
kubectl exec volume-test-pod -c liveness-exec-container -it -- ls /test

 

2、hostPath介绍  

hostPath卷:将主机节点的文件系统中文件或目录挂载到集群中;用途如下:
  运行需要访问docker内部的容器;使用/var/lib/docker的hostPath;
  在容器中运行cAdvisor(K8S中一个用于监控docker的组件);使用/dev/cgroups的hostPath;
  允许pod指定给定的hostPath是否应该在pod运行之前存在,是否应该创建,以及它应该以什么形式存在;
hostPath卷属性有path,type;
  type: #type默认值为空,用于向后兼容,意味着在挂载hostPath卷之前不会执行任何检查。
  type:DirectoryOrCreate #如果在给定的路径上没有任何东西存在,则根据需要创建一个空目录,权限为0755,与kubelet具有相同的组和所有权;
  type:Directory #给定的路径上必须存在目录;
  type:FileOrCreate #如果在给定的路径上没有任何东西存在,则根据需要创建一个空文件,权限为0644,与kubelet具有相同的组和所有权;
  type:File #给定的路径上必须存在文件;
  type:Socket #给定的路径上必须存在UNIX套接字;
  type:CharDevice #给定的路径上必须存在字符设备;
  type:BlockDevice #给定的路径上必须存在块设备;
使用hostPath卷注意事项:
  由于每个节点上的文件都不同,具有相同配置的pod在不同节点上的行为可能会有所不同;
  当K8S按照计划添加资源感知调度时,将无法考虑hostPath使用的资源;
  在底层主机上创建的文件或目录只能由root写入。您需要在特权容器中以root身份运行进程,或修改主机上文件权限以便写入hostPath卷。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cat >volume-hostPath.yml<<eof
apiVersion: v1
kind: Pod
metadata:
    name: hostpath-volume-pod
spec:
    containers:
    - image: hub.atguigu.com/library/nginx:latest
      name: hostPath-volume--container
      volumeMounts:
      - mountPath: /cache
        name: cache-volume
    volumes:
    - name: cache-volume
      hostPath:
        path: /data
        type: Directory
eof
kubectl apply -f volume-hostPath.yml  #确保调度节点存在/data/目录;
kubectl get pod
kubectl exec volume-test-pod -c volume-test-container -it -- touch /cache/test.txt

 

五、PV及PVC介绍

 PV(persistentVolume)

  是由管理设置的存储,它是集群的一部分。就像节点是集群中的资源一样,PV也是集群中的资源。PV是volume之类的卷插件,但居于哦独立于使用PV的pod的生命周期。此API对象包含存储实现的细节,接NFS,iSCSI或特定于云供应商的存储系统。

PVC(persistentVolumeClaim)
  是用户存储的请求。它与pod相似。pod消耗节点资源,PVC消耗PV资源。pod可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式(如:可以读/写一次或只读多次模式挂载);

静态PV
  集群管理员创建一些PV。他们带有可供集群用户使用的实际存储的细节他们存在于K8S API中,可用于消费;

动态PV(实现方式复杂,价格昂贵,不太成熟,但是是未来的趋势)
  当管理员创建静态PV都不匹配用户的persistentVolumeClaim时,集群可能会尝试动态地为PVC创建卷。此配置基于StorageClasses:PVC必须请求[存储类],并且管理员必须创建并配置该类才能进行动态创建。声明该类为“”可以有效地金庸其动态配置。
  要启用基于存储级别的动态存储配置,集群管理员需要启用API server上的DefaultStorageClass【准入控制器】。例如,通过确保DefaultStorageClass位于API server组件的--admission-control标志,使用逗号分隔的有序值列表中,可以完成此操作。

绑定
  master中的控制环路监视新的PVC,寻找匹配的PV(如果可能),并将它们绑定在一起。如果为新的PVC动态调配PV,则该环路将始终将PV绑定到PVC。否则,用户总会得到他们所请求的存储,但是容量可能超出要求的数量。一旦PV和PVC绑定后,PersistentVolumeClaimbanging是排他性的,不管它们是如何绑定的。PVC跟PV绑定是一对一的映射。一般情况下,PVC规定容量一般小于PV容量,很少情况会出现近似相等。

持久化卷声明的保护
  PVC保护的目的是确保由POD正在使用的PVC不会从系统中移除,因为如果被移除的话可能会导致数据丢失。当启用PVC保护alpha功能时,如果用户删除了一个pod正在使用的PVC,则该PVC不会被立即删除。PVC的删除将被推迟,指导PVC不再被任何pod使用。注意:当pod状态为pending并且pod已经分配给节点或pod为running状态时,PVC处于活动状态。

PV类型以插件形式实现。K8S目前支持以下插件类型:
  awsElasticBlockStore;azureDisk;azureFile;FC(fiber channel);
  FlexVolume;Flocker;NFS;iSCSI;RBD(ceph block device);cephFS;
  cinder(openstack block storage);glusterfs;vshpereVolume;quobyte volumes;
  HostPath;VMware Photon;portworx Volumes;scaleIO volumes;storageOS;

PV访问模式:
  persistentVolume可以资源提供者支持的任何方式挂载到主机上。供应商具有不同的功能,每个PV的访问模式都将被设置为怪卷支持的特定模式;如:NFS可支持多个读/写客户端,但特定的NFS PV可能以只读方式导出到服务器。每  个PV都有一套自己的用来描述特定功能的访问模式。一个卷只能使用一种访问模式挂载,即使它支持很多访问模式。
  ReadWriteOnce(RWO)---该卷可以被单个节点以读/写模式挂载;
  ReadOnlyMany(ROX)---该卷可以被多个节点以只读模式挂载;
  ReadWriteMany(RWX)---该卷可以被多个节点以读/写模式挂载;

回收策略:
  retain(保留)---手动回收;PV不再被pod使用,但也不允许其他pod使用,等待管理员去手动释放数据。
  recycle(回收)---基本擦除(rm -rf /thevolume/*);最新版K8S不支持。
  delete(删除)---关联的存储资产(如AWS EBS|GCE PD|AZURE DISK|OPENSTACK CINDER)将被删除;
  当前只有NFS和hostPath支持回收策略。AWS EBS|GCE PD|AZURE DISK|OPENSTACK CINDER支持删除策略。

卷可以处于以下某种状态:
  available(可用)---一块空闲资源还没有被任何声明绑定;
  bound(已绑定)---卷已经被声明绑定;
  released(已释放)---声明被删除,但是资源还未被集群重新声明。
  failed(失败)---该卷的自动回收失败。
命令行会显示绑定到PV的PVC的名称。

创建statefuSet前必须要创建要给SVC;

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
##安装NFS服务器(选定K8S集群之外的主机部署,IP为192.168.66.100)
yum install -y nfs-common nfs-utils rpcbind
mkdir /nfsdata
chmod 777 /nfsdata          #慎用权限;
chown nfsnobody /nfsdata
cat >>/etc/exports<<eof 
/nfsdata *(rw,no_root_squash,no_all_squash,sync) #创建一个nfs文件系统;
eof
systemctl enable rpcbind;systemctl start rpcbind;systemctl status rpcbind
systemctl enable nfs;systemctl start nfs;systemctl status nfs
mkdir /nfs{1..3}            #在nfs服务器创建3个空目录;
chmod 777 /nfs{1..3}        
chown nfsnobody /nfs{1..3}
 
cat >>/etc/exports<<eof     #在创建3个nfs文件系统;
/nfs1 *(rw,no_root_squash,no_all_squash,sync)
/nfs2 *(rw,no_root_squash,no_all_squash,sync)
/nfs3 *(rw,no_root_squash,no_all_squash,sync)
eof
systemctl restart rpcbind nfs
##所有K8S集群节点安装工具
yum install -y nfs-utils rpcbind
mkdir /nfs_test/
showmount -e 192.168.66.100
mount -t nfs 192.168.66.100:/nfsdata /nfs_test/ #将nfs服务器192.168.66.100的/nfsdata挂载至本机/nfs_test目录下;
cd /nfs_test/
echo "nfs_test" >test.txt #在nfs服务器192.168.66.100的/nfsdata与本机/nfs_test目录下都可看见创建的test.txt;
umount /nfs_test/ #卸载挂载的nfs服务器192.168.66.100的/nfsdata;
 
##部署PV
cat >PV.yml<<eof
apiVersion: v1
kind: PersistentVolume
metadata:
    name: nfspv1
spec:
    capacity:
        storage: 10Gi                       #声明卷的容量;
    accessModes:
        - ReadWriteOnce                     #声明访问方式;
    persistentVolumeReclaimPolicy: Retain   #声明回收策略;
    storageClassName: nfs                   #指定要绑定PV的类;非常重要的一个指标;
    nfs:
        path: /nfsdata
        server: 192.168.66.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: nfspv01
spec:
    capacity:
        storage: 5Gi                       #声明卷的容量;
    accessModes:
        - ReadWriteMany                     #声明访问方式;
    persistentVolumeReclaimPolicy: Retain   #声明回收策略;
    storageClassName: slow                   #指定要绑定PV的类;非常重要的一个指标;
    nfs:
        path: /nfs1
        server: 192.168.66.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: nfspv02
spec:
    capacity:
        storage: 5Gi                       #声明卷的容量;
    accessModes:
        - ReadWriteOnce                     #声明访问方式;
    persistentVolumeReclaimPolicy: Retain   #声明回收策略;
    storageClassName: nfs                   #指定要绑定PV的类;非常重要的一个指标;
    nfs:
        path: /nfs2
        server: 192.168.66.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
    name: nfspv03
spec:
    capacity:
        storage: 1Gi                       #声明卷的容量;
    accessModes:
        - ReadWriteOnce                     #声明访问方式;
    persistentVolumeReclaimPolicy: Retain   #声明回收策略;
    storageClassName: nfs                   #指定要绑定PV的类;非常重要的一个指标;
    nfs:
        path: /nfs3
        server: 192.168.66.100
eof
kubectl apply -f PV.yml
kubectl get pv          #此时pv可以直接挂载至pod使用了;但正常情况下,使用PVC来调用PV;
##创建服务并使用PVC
cat >PVC.yml<<eof
apiVersion: v1
kind: Service
metadata:
    name: nginx
    labels:
        app: nginx
spec:
    ports:
    - port: 80
      name: web
    clusterIP: None
    selector:
        app: nginx
---
apiVersion: apps/v1
kind: StatefulSet       #创建statefuSet前必须要创建要给SVC;
metadata:
    name: web
spec:
    selector:
        matchLabels:
            app: nginx
    serviceName: "nginx"  #必须为无头服务(即该服务必须为clusterIP: None)才行;
    replicas: 3
    template:
        metadata:
            labels:
                app: nginx
        spec:
            containers:
            - name: nginx
              image: hub.atguigu.com/library/nginx:latest
              ports:
              - containerPort: 80
                name: web
              volumeMounts:
              - name: www
                mountPath: /usr/share/nginx/html
    volumeClaimTemplates:                           #声明卷的请求;
    - metadata:
        name: www
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: "nfs"
        resources:
            requests:
                storage: 1Gi
eof
kubectl apply -f PVC.yml
kubectl get pv
kubectl get pvc
kubectl get pod
kubectl get statefulset

1
2
3
4
5
6
7
8
9
10
11
###测试NFS卷的使用
##在NFS服务器操作
cd /nfs3        #根据实际pv确定目录;
echo "hello world" >index.html
chmod 777 index.html
chown nfsnobody index.html
##在K8S master操作
curl 10.244.2.157           #该IP为名为web-0的pod调度节点的IP;
kubectl delete pod web-0   
kubectl get pod -o wide
curl 10.244.2.159           #访问新pod,其pv内容不会变化。

 1、PV手动回收

 

 

 

 

 删除statefulset、pod、pvc后,需要手动释放pv时,需要至NFS服务器删除对应目录下的文件及pv下的claimRef字段内容。

 

 

 

 

 

 

 

 

 

 

 

  

 

 

  

  

  

 

 

 

 

 

 

  

 

 

  

 

 

posted on   chalon  阅读(218)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示