09 . Kubernetes之pv、pvc及使用nfs网络存储应用

PV,PVC概述

PV的全称是: PersistentVolume (持久化卷),是对底层的共享存储的一种抽象,PV由管理员进行创建和配置,它和具体的底层的共享存储技术的实现方式有关,比如Ceph、GlusterFS、NFS等,都是通过插件机制完成与共享存储的对接.

PVC的全称是: PersistenVolumeClaim (持久化卷声明),PVC是用户存储的一种声明,PVC和Pod比较类型,Pod是消耗节点,PVC消耗的是PV资源,Pod可以请求CPU的内存,而PVC可以请求特定的存储空间和访问模式。对于真正存储的用户不需要关心底层的存储实现细节,只需要直接使用PVC即可.

但是通过PVC请求一定的存储空间也很有可能不足以满足对于存储设备的各种需求,而且不同的应用程序对于存储性能的要求也能也不尽相同,比如读写速度、并发性能等,为了解决这一问题,Kubernetes又为我们引入了一个新的资源对象: StorageClass,通过StorageClass的定义,管理员可以将存储资源定义为某种类型的资源,比如快速存储、慢速存储等,用户根据StorageClass的描述就可以非常直观的知道各种存储资源特性了,这样就可以根据应用的特性去申请合适的存储资源了.

PV和PVC生命周期

PV可以看作可用的存储资源,PVC则是对存储资源的需求,PV和PVC的互相关系遵循如下图

资源供应

Kubernetes支持两种资源的供应模式:静态模式(Staic)和动态模式(Dynamic)。资源供应的结果就是创建好的PV.

静态模式: 管理员手工创建许多PV,在定义PV时需要将后端存储的特性进行设置

动态模式: 管理员无需手动创建PV,而是通过StorageClass的设置对后端存储进行描述,标记为某种"类型(Class)",此时要求PVC对存储的类型进行声明,系统将自动完成PV的创建及PVC的绑定,PVC可以声明为Class为"",说明该PVC禁止使用动态模式

资源绑定(Binding)

在用户定义好PVC后,系统将根据PVC对存储资源的请求(存储空间和访问模式)在已存在的PV中选择一个满足PVC要求的PV,一旦找到,就将PV与用户定义的PVC进行绑定,然后用户的应用就可以使用这个PVC了。如果系统中没有满足PVC要求的PV,PVC则会无限期处于Pending状态,直到等到系统管理员创建了一个符合要求的PV。PV一旦绑定在某个PVC上,就被这个PVC独占,不能再与其他PVC进行绑定了。在这种情况下,当PVC申请的存储空间比PV的少时,整个PV的空间都能够为PVC所用,可能会造成资源的浪费。如果资源供应使用的是动态模式,则系统在PVC找到合适的StorageClass后,将会自动创建PV并完成PVC的绑定

资源使用(Using)

Pod 使用volume的定义,将PVC挂载到容器内的某个路径进行使用。volume的类型为persistentVoulumeClaim,在容器应用挂载了一个PVC后,就能被持续独占使用。不过,多个Pod可以挂载同一个PVC,应用程序需要考虑多个实例共同访问一块存储空间的问题

资源释放(Releasing)

当用户对存储资源使用哪个完毕后,用户可以删除PVC,与该PVC绑定的PV将会被标记为已释放,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还留在存储设备上,只有在清除之后该PV才能继续使用.

资源回收(Reclaiming)

对于PV,管理员可以设定回收策略(Reclaim Policy)用于设置与之绑定的PVC释放资源之后,对于遗留数据如何处理。只有PV的存储空间完成回收,才能供新的PVC绑定和使用。

1 . 静态资源下,通过PV和PVC完成绑定,并供Pod使用的存储管理机制

2 . 动态资源下,通过StorageClass和PVC完成资源动态绑定(系统自动生成PV,并供Pod使用的存储管理机制

存储卷概述

由于容器本身是非持久化的,因此需要解决在容器中运行应用程序遇到的一些问题。首先,当容器崩溃时,kubelet将重新启动容器,但是写入容器的文件将会丢失,容器将会以镜像的初始状态重新开始;第二,在通过一个Pod中一起运行的容器,通常需要共享容器之间一些文件。Kubernetes通过存储卷解决上述的两个问题。

在Docker有存储卷的概念卷,但Docker中存储卷只是磁盘的或另一个容器中的目录,并没有对其生命周期进行管理。Kubernetes的存储卷有自己的生命周期,它的生命周期与使用的它Pod生命周期一致。因此,相比于在Pod中运行的容器来说,存储卷的存在时间会比的其中的任何容器都长,并且在容器重新启动时会保留数据。当然,当Pod停止存在时,存储卷也将不再存在。在Kubernetes支持多种类型的卷,而Pod可以同时使用各种类型和任意数量的存储卷。在Pod中通过指定下面的字段来使用存储卷:

spec.volumes: 通过此字段提供指定的存储卷
spec.containers.volumeMounts: 通过此字段将存储卷挂载到容器中

存储卷类型和示例

当前Kubernetes支持如下所列的存储卷类型,并以hostPath、nfs和persistentVolumeClaim类型的存储卷为例,介绍如何定义存储卷,以及如何在Pod中被使用.

1* awsElasticBlockStore 2* azureDisk 3* azureFile 4* cephfs 5* configMap 6* csi 7* downwardAPI 8* emptyDir 9* fc (fibre channel) 10* flocker 11* gcePersistentDisk 12* gitRepo 13* glusterfs 14* hostPath 15* iscsi 16* local 17* nfs 18* persistentVolumeClaim 19* projected 20* portworxVolume 21* quobyte 22* rbd 23* scaleIO 24* secret 25* storageos 26* vsphereVolume
xample1 EmptyDir(两个Pod目录互相挂载)

EmptyDir是一个空目录,他的生命周期和所属的Pod是完全一致的,他用处是把同一Pod内的不同容器之间共享工作过程产生的文件,

1mkdir /storage 2cd /storage 3mkdir volumes 4 5cat pod_volume.demo1.yaml 6apiVersion: v1 7kind: Pod 8metadata: 9 name: pod-demo 10 namespace: default 11 labels: 12 app: myapp 13 tier: frontend 14 annotations: 15 youmen.com/created-by: "youmen admin" 16spec: 17 containers: 18 - name: myapp 19 image: ikubernetes/myapp:v1 20 imagePullPolicy: IfNotPresent 21 ports: 22 - name: http 23 containerPort: 80 24 volumeMounts: 25 - name: html 26 mountPath: /usr/share/nginx/html/ 27 28 - name: busybox 29 image: busybox:latest 30 imagePullPolicy: IfNotPresent 31 volumeMounts: 32 - name: html 33 mountPath: /data/ 34 command: ['/bin/sh', '-c'] 35 args: 36 - 'while true; do echo $(date) >> /data/index.html; sleep 3; done' 37 volumes: 38 - name: html 39 emptyDir: {} 40 41kubectl apply -f pod_volume.demo1.yaml 42 43curl 10.244.3.34 -s 44Tue Dec 24 15:37:09 UTC 2019 45Tue Dec 24 15:37:12 UTC 2019 46Tue Dec 24 15:37:15 UTC 2019 47Tue Dec 24 15:37:18 UTC 2019 48Tue Dec 24 15:37:21 UTC 2019 49Tue Dec 24 15:37:24 UTC 2019
Example2 HostPath(主机目录挂载)

依赖于node,这种会把宿主机的指定卷加载到容器之中,实现数据持久,但是如果Pod发生跨主机的重建,内容很难保证,或者Node节点宕机了
这种卷一般和DaemonSet搭配使用,用来操作主机文件,例如进行日志采集的FLK的FluentD就采用这种方式,加载主机的容器日志目录,达到收集本机所有日志的目的

1# hostPath 2# 将Pod里面的目录内容绑定到宿主机目录,Pod删除并不到导致宿主机删除. 3# 如果指定宿主机目录不存在要不要先创建取决于type 4mkdir /data/pod/volume1 -p 5cat pod-volhost.demo.yaml 6apiVersion: v1 7kind: Pod 8metadata: 9 name: pod-vol-hostpath 10 namespace: default 11spec: 12 containers: 13 - name: myapp 14 image: ikubernetes/myapp:v1 15 volumeMounts: 16 - name: html 17 mountPath: /usr/share/nginx/html/ 18 volumes: 19 - name: html 20 hostPath: 21 path: /data/pod/volume1 22 type: DirectoryOrCreate 23 24 25kubectl apply -f pod-volhost-demo.yaml 26echo youmen >> /data/pod/volume1/index.html 27kubectl get pods -o wide 28NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES 29pod-vol-hostpath 1/1 Running 0 3m49s 10.244.3.35 node1 <none> <none> 30curl 10.244.3.35 31youmen 32 33# 我们删除Pod,可以到Node主机查看目录,依然存在. 34[root@node1 ~]# cat /data/pod/volume1/index.html 35youmen

NFS网络共享存储

部署nfs
1# 建议找集群外的一台机器做NFS 2hostnamectl set-hostname stor01 3echo 172.19.0.18 stor01 >> /etc/hosts 4yum -y install nfs-utils 5mkdir -pv /data/volumes -p 6chmod 755 /data/volumes 7 8 9vim /etc/exports 10/data/volumes *(rw,no_root_squash,sync) 11 12# 存储目录,*允许所有人连接,rw读写权限,sync文件同时写入硬盘及内存,no_root_squash 使用者root用户自动修改为普通用户 13 14systemctl start nfs && systemctl enable nfs
验证nfs服务可用性
1# 查看nfs目录挂载权限 2cat /var/lib/nfs/etab 3/data/volumes *(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,rw,secure,no_root_squash,no_all_squash) 4 5# 检查下挂载目录是否正常 6showmount -e localhost 7Export list for localhost: 8/data/volumes *
挂载存储卷
1# 切换到k8s集群内的节点挂载存储卷 2yum -y install nfs-utils 3echo 172.19.0.18 stor01 >> /etc/hosts 4# 挂载测试以下,然后umount掉,待会创建Pod自动会挂载 5mount -t nfs stor01:/data/volumes /mnt 6 7# 验证一下 8df -h |grep nfs1 9nfs1:/data/volumes 17G 1.4G 16G 9% /mnt 10 11 12cat pod-volnfs.demo.yaml 13apiVersion: v1 14kind: Pod 15metadata: 16 name: pod-volnfs-demo 17 namespace: default 18spec: 19 containers: 20 - name: myapp 21 image: ikubernetes/myapp:v1 22 volumeMounts: 23 - name: html 24 mountPath: /usr/share/nginx/html/ 25 volumes: 26 - name: html 27 nfs: 28 path: /data/volumes 29 server: stor01 30 31kubectl get pods -o wide 32NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES 33pod-volnfs-demo 1/1 Running 0 20s 10.244.1.49 node2 <none> <none> 34curl 10.244.1.49 35nfs 36# 可以删除Pod再创建数据依然存在,哪怕节点宕掉依然数据不会丢失,但是当挂载的数据,Pod多了,效果就不尽人意了 37 38# 接下来我们通过pv,pvc来使用这个nfs存储

使用pv,pvc作为存储

Pv和Pvc是K8s的一种标准资源,Pvc被Pv调用后就会被绑定起来,取决于用户怎么绑,

因为pvc属于集群资源级别的不能定义在名成空间

创建pv
1# 这里使用nfs类型后端存储, 1g存储空间,访问模式为ReadWriteOnce,回收策略为Recyle 2 3cat nfs_demo1.yaml 4apiVersion: v1 5kind: PersistentVolume 6metadata: 7 name: pv1 #pv名称 8spec: 9 capacity: #存储能力,一个pv对象都要指定一个存储能力, 10目前仅支持存储空间的设置 11 storage: 1Gi #存储空间 12 accessModes: 13 - ReadWriteOnce #访问模式 14 persistentVolumeReclaimPolicy: Recycle #回收策略 15 nfs: #服务模式 (nfs、ceph、hostpath等) 16 path: /data/volumes #共享数据目录挂载点 17 server: nfs1 #nfs服务器地址 18 19 20kubectl apply -f nfs_demo1.yaml 21persistentvolume/pv1 created 22[root@master storage]# kubectl get pv 23NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE 24pv1 1Gi RWO Recycle Available 5s 25 26# pv1: 名称 27# 1Gi: 存储空间大小 28# RWO: 访问模式(ReadWriteOnce缩写) 29# Recycle: 回收策略 30# Available: PV状态 31 32# persistentVolumeReclaimPolicy回收策略 33# Retain (保留) 保留数据,需要管理员手动清理 34# Recycle (回收) 清除PV中的数据,效果相当于执行删除命令 35# Delete (删除)PV相连的后端存储完成volume的删除操作,常见于云服务商的存储服务 36# 不过需要注意的是,目前只有NFS和HostPath两类支持回收策略,一般设置Retain比较保险 37 38 39# 状态有以下几种 40# Available: PV状态,表示可用状态,还未被任何PVC绑定 41# Bound: 已绑定,已经绑定到某个PVC 42# Released: 已释放,对应的pvc已经删除,但资源还没有被集群收回 43# Failed: PV自动回收失败
pv相关配置说明

Capacity 存储能力

通过PV的capacity属性来设置存储空间,目前仅支持storage=数据大小,未来可能会加入IOPS、吞吐量等指标配置

AccessModes访问模式

AccessModes 是用来对PV进行访问模式的设置,用于描述用户应用对存储资源的访问权限

ReadWriteOnce (RWO):读写权限,但是只能被单个节点挂载

ReadOnlyMany (ROX):只读权限,可能被多个节点挂载

ReadWriteMany (RWX):读写权限,可以被多个节点挂载

注意: 一些pv可能支持多种访问模式,但挂载时候只可以使用一种访问模式,多种访问模式不奏效

PVC

PV实际上没有存储,相当于我们node一样,还需要创建Pod进行消费,接下来我们进行PVC的创建与配置

1# 创建一个数据卷声明 2apiVersion: v1 3kind: PersistentVolumeClaim 4metadata: 5 name: pvc-nfs 6spec: 7 accessModes: 8 - ReadWriteOnce 9 resources: 10 requests: 11 storage: 1Gi 12 13kubectl apply -f pvc-nfs-demo1.yaml 14 15kubectl get pvc 16NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE 17pvc-nfs Bound pv1 1Gi RWO 18 19kubectl get pv 20NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE 21pv1 1Gi RWO Recycle Bound default/pvc-nfs 10m 22# 当我们创建pvc之后,pv的状态变成了Bound绑定状态,并且和pvc的状态相同。 23# 并且可以看到pvc已经绑定到名称为pv1的volume上, 24# 同时在pv上可以看到绑定到名称为pvc-nfs的pvc中
查看pv,pvc
1[root@master storage]# kubectl describe pv pv1 2Name: pv1 3Labels: <none> 4Annotations: pv.kubernetes.io/bound-by-controller: yes 5Finalizers: [kubernetes.io/pv-protection] 6StorageClass: 7Status: Bound 8Claim: default/pvc-nfs 9Reclaim Policy: Recycle 10Access Modes: RWO 11VolumeMode: Filesystem 12Capacity: 1Gi 13Node Affinity: <none> 14Message: 15Source: 16 Type: NFS (an NFS mount that lasts the lifetime of a pod) 17 Server: nfs1 18 Path: /data/volumes 19 ReadOnly: false 20Events: <none> 21 22[root@master storage]# kubectl describe pvc pvc-nfs 23Name: pvc-nfs 24Namespace: default 25StorageClass: 26Status: Bound 27Volume: pv1 28Labels: <none> 29Annotations: pv.kubernetes.io/bind-completed: yes 30 pv.kubernetes.io/bound-by-controller: yes 31Finalizers: [kubernetes.io/pvc-protection] 32Capacity: 1Gi 33Access Modes: RWO 34VolumeMode: Filesystem 35Mounted By: <none> 36Events: <none> 37 38# 在Kubernetes中会自动帮我们查看pv状态为Available并且根据声明pvc容量storage的大小进行筛选匹配, 39# 同时还会根据AccessMode进行匹配。如果pvc匹配不到pv会一直处于pending状态。
根据Labels匹配PV与PVC

同时,pv与pvc中间还可以通过label标签进行匹配,配置如下

1# 记得下面配置文件修改一下名字,不可以重复 2apiVersion: v1 3kind: PersistentVolume 4metadata: 5 name: pv2 6 labels: #这里将pv设置一个labels 7 app: nfs 8spec: 9 capacity: 10 storage: 1Gi 11 accessModes: 12 - ReadWriteOnce 13 persistentVolumeReclaimPolicy: Recycle 14 nfs: 15 path: /data/volumes 16 server: nfs1 17--- 18apiVersion: v1 19kind: PersistentVolumeClaim 20metadata: 21 name: pvc2-nfs 22spec: 23 accessModes: 24 - ReadWriteOnce 25 resources: 26 requests: 27 storage: 1Gi 28 selector: # pvc匹配标签为app=nfs的pv 29 matchLabels: 30 app: nfs 31 32[root@master storage]# kubectl apply -f nfs_demo2.yaml 33[root@master storage]# kubectl get pv,pvc 34NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE 35persistentvolume/pv1 1Gi RWO Recycle Bound default/pvc-nfs 28m 36persistentvolume/pv2 1Gi RWO Recycle Bound default/pvc2-nfs 94s 37 38NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE 39persistentvolumeclaim/pvc-nfs Bound pv1 1Gi RWO 17m 40persistentvolumeclaim/pvc2-nfs Bound pv2 1Gi RWO 94s 41 42# 有一点需要注意,当我们pvc申请的容量小于我们pv的容量是可以进行绑定的 43# 当我们申请pvc的容量大于pv的容量是无法进行绑定的。 这里需要注意
Deployment引用pvc
1[root@master storage]# cat deployment-nfs1.yaml 2apiVersion: apps/v1 3kind: Deployment 4metadata: 5 name: pv-nfs-nginx 6spec: 7 replicas: 3 8 selector: 9 matchLabels: 10 app: pv-nfs-nginx 11 template: 12 metadata: 13 labels: 14 app: pv-nfs-nginx 15 spec: 16 containers: 17 - name: pv-nfs-nginx 18 image: nginx 19 ports: 20 - containerPort: 80 21 volumeMounts: #挂载,首先添加需要挂载的目录 22 - name: pv-nginx #挂载点的名称 23 mountPath: /usr/share/nginx/html #挂载点的路径 24 volumes: #绑定 25 - name: pv-nginx 26 persistentVolumeClaim: #将镜像中的nginx目录挂载到下面名称的pvc中 27 claimName: pvc-nfs #pvc名称 28--- 29 30apiVersion: v1 31kind: Service 32metadata: 33 name: nfs-pvc 34 labels: 35 app: pv-nfs-nginx 36spec: 37 type: NodePort 38 ports: 39 - port: 80 40 targetPort: 80 41 selector: 42 app: pv-nfs-nginx 43 44[root@master storage]# kubectl apply -f deployment-nfs1.yaml 45
检查Pod和svc状态
1[root@master storage]# kubectl get pods,svc |grep pv 2pod/pv-nfs-nginx-6b4759b5b8-95vhk 1/1 Running 0 74s 3pod/pv-nfs-nginx-6b4759b5b8-mjwhn 1/1 Running 0 58s 4pod/pv-nfs-nginx-6b4759b5b8-p4jhn 1/1 Running 0 11s 5service/nfs-pvc NodePort 10.0.0.57 <none> 80:31850/TCP 4m23s 6 7# 这里我们可以看到pod已经正常启动,并且svc也已经暴露端口了。 8# 如果需要更改显示内容,更改之前nfs存储里面的那个目录文件就可以了

由于我们的index.html直接挂在到了/data1/k8s目录下面,如果有很多个pod都使用pvc进行挂载,会造成我们数据目录的文件比较乱

这里我们添加一个subpathsubPath的目的是为了在单一Pod中多次使用同一个volume而设计的。

1[root@master storage]# cat deployment-nfs1.yaml 2apiVersion: apps/v1 3kind: Deployment 4metadata: 5 name: pv-nfs-nginx 6spec: 7 replicas: 3 8 selector: 9 matchLabels: 10 app: pv-nfs-nginx 11 template: 12 metadata: 13 labels: 14 app: pv-nfs-nginx 15 spec: 16 containers: 17 - name: pv-nfs-nginx 18 image: nginx 19 ports: 20 - containerPort: 80 21 volumeMounts: #挂载,首先添加需要挂载的目录 22 - name: pv-nginx #挂载点的名称 23 mountPath: /usr/share/nginx/html #挂载点的路径 24 subPath: nginx-pvc 25 volumes: #绑定 26 - name: pv-nginx 27 persistentVolumeClaim: #将镜像中的nginx目录挂载到下面名称的pvc中 28 claimName: pvc-nfs #pvc名称 29--- 30 31apiVersion: v1 32kind: Service 33metadata: 34 name: nfs-pvc 35 labels: 36 app: pv-nfs-nginx 37spec: 38 type: NodePort 39 ports: 40 - port: 80 41 targetPort: 80 42 selector: 43 app: pv-nfs-nginx 44 45[root@master storage]# kubectl apply -f deployment-nfs1.yaml 46 47# 当我们更新完pod之后,等pod正常启动。 48# 就可以看到在我们nfs存储目录下面单独创建了一个名称为nginx-pvc的目录, 49# 这个目录实际上就是我们subpath后面指定的名称 50[root@nfs1 ~]# ls /data/volumes/ 51index.html nginx-pvc 52[root@nfs1 ~]# ls /data/volumes/nginx-pvc/ 53[root@nfs1 ~]# mv /data/volumes/index.html /data/volumes/nginx-pvc/ 54 55# 这个目录下面也是没有任何文件的,我们需要将原来index.html拷贝过去即可 56 57# 现在我们删除deployment,下面的数据并不会删除。这样使用pv和pvc持久化就完成 58 59# 如果我们直接删除或者有pod在使用pv或者pvc是无法直接删除的, 60# 当我们使用Recycle模式时,删除所有pv和pvc后, 61# 数据也会进行删除。所以删除pv和pvc请谨慎操作 62[root@nfs1 ~]# cat /data/volumes/nginx-pvc/index.html 63Pvc Persistence

NFS存储的缺点

不支持动态创建持久卷,只能手工创建
先手工创建PV,再通过PV手工创建PVC,PVC就是真正可用的持久卷

PVC是和PV进行绑定的:
PVC会根据自己需求空间的大小自动选择合适的PV,比如需要一个5G的PVC,PV分别为2G,7G和10G,那么PVC会自动选择7G的,但是剩余的空间不是浪费了么?原因如下:
一个被绑定的PV只能用于一个PVC,他们是一对一绑定的,如果PVC大小只需要5G,但是所选的PV有7G,那么剩余的2G是没办法使用的,如果不想这样浪费空间只能使用动态创建的方式.

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

KVM调整cpu和内存

一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid