本文一起看下如何挂载本地的磁盘到POD中。
现实世界中的存储设备有非常非常多的种类,如本文要分析的计算机磁盘,还包括NFS(一种网络磁盘存储协议),Ceph(一种分布式的文件存储系统),不管是哪种方式,最终都是通过将数据存储到硬盘来实现持久化,但是不同种类写入数据的方式是不相同的,k8s针对这些不同的存储目标进行抽象定义了PersistentValume API对象,如下:
dongyunqi@mongodaddy:~/k8s$ kubectl api-resources|egrep -w 'PersistentVolume|KIND'
NAME SHORTNAMES APIVERSION NAMESPACED KIND
persistentvolumes pv v1 false PersistentVolume
现在不同存储系统的抽象已经有了,那么具体该怎么使用办呢?能不能让pv拥有这种能力呢?自然是可以的,但是这又不符合单一职责的原则了,所以对于这些存储系统的具体使用k8s又定义了一个新的API对象,Persistent Volume Claim,如下:
dongyunqi@mongodaddy:~/k8s$ kubectl api-resources|egrep -w 'PersistentVolumeClaim|KIND'
NAME SHORTNAMES APIVERSION NAMESPACED KIND
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
最后,这么多的存储系统,当多了之后,混杂在一起,势必造成混乱,为此k8s又定义了StorageClass来进行分类维护,如下:
dongyunqi@mongodaddy:~/k8s$ kubectl api-resources|egrep -w 'StorageClass|KIND'
NAME SHORTNAMES APIVERSION NAMESPACED KIND
storageclasses sc storage.k8s.io/v1 false StorageClass
这样,需要用到的3个API对象我们就介绍完毕了,三者的关系我们可以参考下图:

下面我们看一个实际的例子。
毫无疑问,我们需要先定义磁盘的抽象PV,yaml如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: host-10m-pv
spec:
storageClassName: host-test
accessModes:
- ReadWriteOnce
capacity:
storage: 10Mi
hostPath:
path: /tmp/host-10m-pv/
主要属性介绍如下:
name: host-10m-pv
名字,见名知意,基于host的10m的pv
storageClassName: host-test
存储class,进行分类,根据具体业务即可
- ReadWriteOnce
读写策略,完整如下:
ReadWriteOnce:存储卷可读可写,但只能被一个节点上的Pod挂载。
ReadOnlyMany:存储卷只读不可写,可以被任意节点上的Pod多次挂载。
ReadWriteMany:存储卷可读可写,也可以被任意节点上的Pod多次挂载。
这里是本地磁盘,自然是只能被一个节点上的POD挂载
storage: 10Mi
大小10MB,但这里使用的是国际标准,不同于我们用的KB(1024 byte),MB(1024*1024 byte),一定不要写错
path: /tmp/host-10m-pv/
要挂载的本地磁盘目录,没有的话需要手动创建该目录
接着我们应用PV,如下:
kubectl apply -f host-path-pv.yml

接着我们就要来使用已经定义的PV了,方式自然是定义persistent volume claim,如下:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: host-5m-pvc
spec:
storageClassName: host-test
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Mi
storage: 5Mi代表要求的大小是5MB,然后我们应用:
kubectl apply -f host-path-pv.yml
操作完成后k8s就会寻找存储class类型为host-test,大小满足5M的PV,最终找到了pv host-10m-pv,就将其给pvc host-5m-pvc使用,这个使用和被使用确定的过程,我们叫做绑定 bound,如下就显示二者就处于Bound状态了:
需要的是5m但有10m,此时怎么办呢?剩余5m就免费赠送了,因为没有更合适的了。
dongyunqi@mongodaddy:~/k8s$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
host-10m-pv 10Mi RWO Retain Bound default/host-5m-pvc host-test 3h27m
dongyunqi@mongodaddy:~/k8s$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
host-5m-pvc Bound host-10m-pv 10Mi RWO host-test 3h33m
此时PVC已经绑定了PV,接下来我们就该将PVC挂载到POD中了,定义POD如下:
apiVersion: v1
kind: Pod
metadata:
name: host-pvc-pod
spec:
volumes:
- name: host-pvc-vol
persistentVolumeClaim:
claimName: host-5m-pvc
containers:
- name: ngx-pvc-pod
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: host-pvc-vol
mountPath: /tmp
通过claimName: host-5m-pvc声明pvc host-5m-pvc为卷volume,然后在volumeMounts挂载卷到mountPath: /tmp目录中,如果一切顺利的话,我们在POD中的/tmp目录更新文件的内容都会同步写到宿主机Node的/tmp/host-10m-pv/目录,应用后,我们进入POD中验证,如下:
dongyunqi@mongodaddy:~/k8s$ kubectl exec -it host-pvc-pod -- sh
/ # ls /tmp
/ # cd /tmp/
/tmp # ls
/tmp # touch a.txt
/tmp # echo "content writed by pod" > a.txt
/tmp # cat a.txt
content writed by pod
/tmp #
查看POD所在Node(注意这里一定要是POD所在的Node,不确定POD在哪里可通过-o wide确定):
dongyunqi@mongomummy:~/k8s/images$ cd /tmp/host-10m-pv/
dongyunqi@mongomummy:/tmp/host-10m-pv$ ls
a.txt
dongyunqi@mongomummy:/tmp/host-10m-pv$ cat a.txt
content writed by pod
这样就算POD销毁重建,新建的文件也依然在,也就实现了持久化,如下测试:
dongyunqi@mongodaddy:~/k8s$ kubectl delete pod host-pvc-pod
pod "host-pvc-pod" deleted
dongyunqi@mongodaddy:~/k8s$ kubectl apply -f host-path-pod.yml
pod/host-pvc-pod created
dongyunqi@mongodaddy:~/k8s$ kubectl get pod
NAME READY STATUS RESTARTS AGE
host-pvc-pod 1/1 Running 0 11s
dongyunqi@mongodaddy:~/k8s$ kubectl exec -it host-pvc-pod -- sh
/ # cat /tmp/a.txt
content writed by pod
/ # exit
dongyunqi@mongodaddy:~/k8s$
本文分析了实现磁盘挂载到POD中需要用到的PV persistent volume,PVC persistent volume claim,Storage Class这三个API对象,并一起看了一个实际的例子,实现了POD中数据的持久化。希望本文能够帮助到你。
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
我的Rails站点使用了一个确实不是很好的gem。每次我需要做一些新的事情时,我最终不得不花费与向实际Rails项目添加代码一样多的时间来为gem添加功能。但我不介意,我将我的Gemfile设置为指向我的gem的GitHub分支(我尝试提交PR,但维护者似乎已经下台)。问题是我真的没有找到一种合理的方法来测试我添加到gem的新东西。在railsc中测试它会特别好,但我能想到的唯一方法是a)更改~/.rvm/gems/.../foo。rb,这看起来不对或者b)升级版本,推送到Github,然后运行bundleup,这除了耗时之外显然是一场灾难,因为我不确定我所做的promise是否正
我希望访问我机器上的所有HTTP流量(我的Windows机器-不是服务器)。据我了解,拥有一个本地代理是所有流量路线的必经之路。我一直在谷歌搜索但未能找到任何资源(关于Ruby)来帮助我。非常感谢任何提示或链接。 最佳答案 WEBrick中有一个HTTP代理(Rubystdlib的一部分)和here's一个实现示例。如果你喜欢生活在边缘,还有em-proxy伊利亚·格里戈里克。这postIlya暗示它似乎确实需要一些调整来解决您的问题。 关于ruby-如何捕获所有HTTP流量(本地代理)
我正在尝试找出一种方法来显示来自不在RAILS_ROOT下(在RedHat或Ubuntu环境中)的已安装文件系统的图像。我不想使用符号链接(symboliclink),因为这个应用程序实际上是通过Tomcat部署的,而当我关闭Tomcat时,Tomcat会尝试跟随符号链接(symboliclink)并删除挂载中的所有图像。由于这些文件的数量和大小,将图像放在public/images下也不是一种选择。我查看了send_file,但它只会显示一张图片。我需要在一个格式良好的页面中显示6个请求的图像。由于膨胀,我宁愿不使用Base64编码,但我不知道如何将图像数据与呈现的页面一起传递下去。
我刚刚在我的Ubuntu9.10服务器上安装了TeamBox。我使用提供的服务器脚本在端口3000上启动并运行它。它的运行速度非常慢,从另一台计算机连接时每个HTTP请求最多需要30秒。我使用链接从shell加载TeamBox,一点也不花时间。然后我设置了一个SSH隧道,它再次运行得非常快。我通过此服务器上的apache以及SAMBA等运行了大约30个虚拟主机,没有任何问题。我该如何解决这个问题? 最佳答案 我的redmine(ruby,webrick)太慢了。现在我解决了这个问题:apt-getinstallmongrelruby
我刚刚在本地设置了我的第一个Jekyll项目。我已经让服务器运行,但我忘了使用自动标志。所以现在我想停止服务器并使用标志重新启动。但是,在我启动服务器后的命令行中,我没有得到新的提示,所以我无法输入任何新命令。我不太习惯命令行,所以我真的很感激知道我应该做什么!我正在使用MacOSX和terminal.app,如果有区别的话! 最佳答案 psaux|grepjekyll|awk'{print$2}'|xargskill-9 关于ruby-如何停止jekyll本地服务器,我们在StackO
我相信我对这个问题有一个很好的答案,但我想确保ruby-philes没有更好的方法来做到这一点。基本上,给定一个输入字符串,我想在适当的情况下将该字符串转换为整数,或在适当的情况下将其转换为float。否则,只返回字符串。我会在下面发布我的答案,但我想知道是否有更好的方法。例如:to_f_or_i_or_s("0523.49")#=>523.49to_f_or_i_or_s("0000029")#=>29to_f_or_i_or_s("kittens")#=>"kittens" 最佳答案 我会尽可能避免在Ruby中使用正则表达式
文章目录一基础定义二创建逻辑卷2-1准备物理设备2-2创建物理卷2-3创建卷组2-4创建逻辑卷2-5创建文件系统并挂载文件三扩展卷组和缩减卷组3-1准备物理设备3-2创建物理卷3-3扩展卷组3-4查看卷组的详细信息以验证3-5缩减卷组四扩展逻辑卷4-1检查卷组是否有可用的空间4-2扩展逻辑卷4-3扩展文件系统五删除逻辑卷5-1备份数据5-2卸载文件系统5-3删除逻辑卷5-4删除卷组5-5删除物理卷六LVM逻辑卷缩容6-1缩容注意事项6-2标准缩容步骤一基础定义LVM,LogicalVolumeManger,逻辑卷管理,Linux磁盘分区管理的一种机制,建立在硬盘和分区上的一个逻辑层,提高磁盘分
当我运行服务器并转到localhost:3000时,我收到此错误:ActiveRecord::ConnectionNotEstablishedNoconnectionpoolwithidprimaryfound.有问题的代码:activerecord(5.0.0)lib/active_record/connection_adapters/abstract/connection_pool.rb:874:in`retrieve_connection' 最佳答案 我会发表评论,但我缺乏声誉。反正这个错误有时候是sqlite版本导致的。我建