容器持久化存储
容器的本质是进程,对于进程,Linux
系统有进程组的概念来将其组织在一起。在k8s
里面,使用Pod
这个逻辑概念来维护容器间的关系。
![](https://img-blog.csdnimg.cn/img_convert/f11f4a3ed01d27d3c554954ec66d7bcb.png)
有了Pod
后,我们的应用程序需要被创建和管理,这就引出了ReplicaSet
和Deployment
;然后需要将部署好的应用暴露给外部进行访问,Service
可以提供一个固定的 ip 和端口让外部访问。
对于有状态的应用,可以使用StatefulSet
来进行状态的恢复,在上一节概念介绍[1]里面有提到,有状态的应用是离不开持久化存储的。
引子
在Docker
中,如果一个容器在运行过程中会产生数据并写入到文件系统,当关闭这个容器,用镜像再启动一个容器的时候,你就会意识到新容器并不会识别前一个容器写入文件系统内的任何内容。
对于有状态的应用,我们希望下次启动的应用可以保持住上次的状态;在k8s
里面可以通过定义存储卷来满足这个需求,它们不像Pod
这样的顶级资源,而是被定义为Pod
的一部分,并和Pod
共享相同的生命周期。因此在Pod
里面容器重新启动期间,卷的内容是不变的,
卷
emptyDir
在Pod
中如何定义卷?让我们从emptyDir
开始。设想一个这样的例子,一个Pod
应用由两个容器,容器 A 不断产生数据,容器 B 将 A 产生的数据作为输出。此时,这两个容器就需要使用同一个卷。
让我们实际操作一下,vim fortune-pod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: fortune
spec:
containers:
- image: luksa/fortune
name: html-generator
volumeMounts:
- name: html
mountPath: /var/htdocs
- image: nginx:alpine
name: web-server
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- containerPort: 80
protocol: TCP
volumes:
- name: html
emptyDir: {}
说明一下上述配置文件的含义:fortune
镜像是k8s in action
书中示例打包的镜像,相当于上面说的不断产生数据的容器 A,其中名为html
的容器挂载在var/htdocs
中;而nginx
也挂载了相同的html
卷,不过位置在/usr/share/nginx/html
,上面两个容器共用的卷就是emptyDir: {}
。
启动来感受一下:
kubectl create -f fortune-pod.yaml
# 输出
pod/fortune c