文章目录
主要内容
- emptyDir
- hostPath
预备知识
存储卷(Storage Volume)是一种用于持久化存储数据的抽象概念,通常用于容器化环境中。它提供了一种独立于容器的数据存储解决方案,使得容器可以在不同的主机或容器实例之间共享和访问相同的数据。
存储卷可以被看作是容器内的一个目录,它可以在容器启动时挂载到容器的指定路径,从而使得容器可以读写该路径下的数据。与容器内的普通目录不同,存储卷的生命周期不受容器的生命周期限制,即使容器被删除或重新创建,存储卷中的数据仍然保留。
1 容器中的文件在磁盘上是临时存放的,这给在其中运行的某些应用程序会带来一些问题,其一是当容器在崩溃时,kubelet 会以干净的状态重启重启容器,原有容器中的文件会丢失。第二个问题是,我们会在同一 Pod 中运行多个容器,而这些容器之间会有共享文件的情况出现。解决这些问题的办法是使用 Kubernetes Volume。
2 Kubernetes 支持很多类型的卷。Pod 可以同时使用任意数目的卷类型。临时卷类型的生命周期与Pod 相同,但持久卷可以比 Pod 有更长的存活期长。当 Pod 被删除时,临时卷也会被删除,但持久卷会保留在磁盘上。对于给定 Pod 中任何类型的卷,当该 Pod 中的任何容器重启期间 Pod 中的数据都不会丢失。
3 可在.spec.volumes 字段设置为 Pod 提供的卷,并在.spec.containers[*].volumeMounts字段中声明卷在容器中的挂载位置
存储卷的主要优势包括:
- 数据持久性:存储卷中的数据可以持久保存,不受容器的生命周期限制。
- 数据共享:多个容器可以共享同一个存储卷,使得它们可以访问和修改相同的数据。
- 数据迁移:存储卷可以在不同的主机或容器实例之间迁移,使得数据的迁移和复制更加方便。
- 数据备份和恢复:存储卷可以用于数据备份和恢复,通过将存储卷的快照进行备份,可以保证数据的安全性。
存储卷可以有多种类型,例如本地存储卷、网络存储卷等,具体的实现方式取决于所使用的容器平台或存储解决方案。常见的存储卷技术包括Docker的卷(Volume)、Kubernetes的持久卷(Persistent Volume)、AWS的EBS卷等。
使用存储卷可以提供更可靠、灵活和可扩展的数据存储解决方案,使得容器化应用能够更好地管理和持久化数据。
一.emptyDir
emptyDir是Kubernetes中的一种卷类型,用于在容器中创建一个空目录,并将其挂载到容器的指定路径上。emptyDir卷是临时性的,它的生命周期与所在的Pod相同,当Pod被删除或重新调度时,emptyDir卷中的数据也会被删除。
emptyDir卷的主要特点和用法如下:
-
临时性存储:emptyDir卷适用于需要在容器中创建临时文件或共享临时数据的场景。它提供了一个空目录,容器可以在其中读写数据,但数据不会持久保存。
-
Pod级别的共享:emptyDir卷是在Pod级别上共享的,即同一个Pod中的所有容器都可以访问和修改emptyDir卷中的数据。这使得容器之间可以共享临时数据,例如日志文件、临时缓存等。
-
自动创建和删除:emptyDir卷是由Kubernetes自动创建和删除的,当Pod被创建时,Kubernetes会为每个emptyDir卷创建一个唯一的空目录,并将其挂载到Pod的指定路径上。当Pod被删除时,emptyDir卷中的数据也会被自动删除。
emptyDir卷的使用示例:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: my-image
volumeMounts:
- name: my-volume
mountPath: /data
volumes:
- name: my-volume
emptyDir: {}
上述示例中,创建了一个名为my-pod的Pod,并在其中定义了一个名为my-volume的emptyDir卷。然后,在my-container容器中将my-volume卷挂载到了容器的/data路径上。
emptyDir卷是Kubernetes中常用的一种卷类型,适用于需要在容器中共享临时数据的场景。但需要注意的是,由于emptyDir卷是临时性的,不适合用于需要持久保存数据的场景。如果需要持久化存储数据,可以考虑使用其他类型的卷,如持久卷(Persistent Volume)或云存储卷(Cloud Volume)。
当 Pod 被分派到某个 Node 上时,emptyDir 卷就会被创建,并且在 Pod 在该节点上运行期间一直会存在。就像其名称表示的那样,emptyDir 卷最初是空的。尽管 Pod 中的容器挂载 emptyDir 卷的路径可能会有不同,但这些容器都可以读写 emptyDir 卷中相同的文件。当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会被永久删除。容器崩溃并不会导致 Pod 从节点上移除,因此在容器崩溃期间 emptyDir 卷中的数据是安全的。
1.emptyDir
代码如下(示例):
cat > emptydir.yml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: emptydir
spec:
containers:
- image: httpd
imagePullPolicy: IfNotPresent
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
sizeLimit: 2G
EOF
kubectl create -f emptydir.yml
kubectl get -f emptydir.yml -o wide
crictl ps | grep -i test-container
crictl inspect 0397f786c92d0 | grep cache
kubectl delete -f emptydir.yml
可以看到,数据卷被创建到了 cka-worker2 节点的 /var/lib/kubelet/pods/eb721a7e-1513-46fd-b7dd-68b5119628e7/volumes/kubernetes.io~emptydir/cache-volume
2.解释
下面是每句命令的详细解释:
-
cat > emptydir.yml <<EOF
:将接下来的内容输入到emptydir.yml
文件中。 -
apiVersion: v1
:指定使用的Kubernetes API版本。 -
kind: Pod
:定义创建的资源类型为Pod。 -
metadata:
:定义Pod的元数据。 -
name: emptydir
:指定Pod的名称为emptydir
。 -
spec:
:定义Pod的规格。 -
containers:
:定义Pod中的容器列表。 -
- image: httpd
:指定容器使用的镜像为httpd
。 -
imagePullPolicy: IfNotPresent
:设置镜像拉取策略为如果本地不存在才拉取。 -
name: test-container
:指定容器的名称为test-container
。 -
volumeMounts:
:定义容器的挂载点列表。 -
- mountPath: /cache
:指定挂载点的路径为/cache
。 -
name: cache-volume
:指定挂载点的名称为cache-volume
。 -
volumes:
:定义Pod的卷列表。 -
- name: cache-volume
:指定卷的名称为cache-volume
。 -
emptyDir:
:定义一个空目录卷。 -
sizeLimit: 2G
:设置空目录的大小限制为2GB。 -
EOF
:结束文件输入。 -
kubectl create -f emptydir.yml
:使用kubectl
命令创建一个Pod,其中的配置从emptydir.yml
文件中读取。 -
kubectl get -f emptydir.yml -o wide
:使用kubectl
命令获取刚刚创建的Pod的详细信息,包括IP地址等。 -
crictl ps | grep -i test-container
:使用crictl
命令查找正在运行的容器,其中grep -i test-container
用于过滤出包含test-container
的行。 -
crictl inspect 0397f786c92d0 | grep cache
:使用crictl
命令查找容器的详细信息,其中0397f786c92d0
是容器的ID,grep cache
用于过滤出包含cache
的行。 -
kubectl delete -f emptydir.yml
:使用kubectl
命令删除之前创建的Pod,其中的配置从emptydir.yml
文件中读取。
二.hostPath
hostPath 卷能将主机节点文件系统上的文件或目录挂载到 Pod 中。但要注意的是,要尽可能避免使用这个类型的卷,它会限制 Pod 的迁移性。
hostPath是Kubernetes中的一种卷类型,用于将宿主机的文件或目录挂载到容器中。它允许容器访问宿主机上的文件系统,可以用于读取或写入宿主机上的文件。
hostPath卷的主要特点和用法如下:
-
宿主机文件系统访问:hostPath卷将宿主机的文件或目录挂载到容器中,容器可以直接访问宿主机文件系统中的内容。这使得容器可以读取或写入宿主机上的文件,例如读取日志文件、配置文件等。
-
宿主机依赖性:hostPath卷的挂载依赖于宿主机上的文件或目录,因此宿主机上的文件或目录必须存在并且具有正确的权限。如果宿主机上的文件或目录不存在或权限不正确,容器将无法正常访问。
-
宿主机文件共享:hostPath卷可以在同一个宿主机上的多个Pod之间共享文件。多个Pod可以将同一个宿主机路径挂载为hostPath卷,从而实现宿主机文件的共享和同步。
hostPath卷的使用示例:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: my-image
volumeMounts:
- name: my-volume
mountPath: /data
volumes:
- name: my-volume
hostPath:
path: /host/path
上述示例中,创建了一个名为my-pod的Pod,并在其中定义了一个名为my-volume的hostPath卷。然后,在my-container容器中将my-volume卷挂载到了容器的/data路径上。这样,容器就可以访问宿主机上的/host/path路径下的文件。
需要注意的是,hostPath卷的使用需要谨慎,因为它将宿主机的文件系统暴露给容器,可能存在安全风险。此外,当Pod调度到不同的宿主机上时,hostPath卷将无法访问宿主机上的文件,因此不适合用于需要跨宿主机访问文件的场景。如果需要持久化存储数据或跨宿主机访问文件,可以考虑使用其他类型的卷,如持久卷(Persistent Volume)或网络存储卷(Network Volume)。
1.下面的例子中,挂载一个特定目录到容器中,并通过 nginx 对外展示其中的 index.html。
代码如下(示例):
cat > hostpath.yml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: hostpathtest
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: hostpathpod
ports:
- name: web
containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /data
type: DirectoryOrCreate
EOF
kubectl create -f hostpath.yml
kubectl get -f hostpath.yml -o wide
2.在 cka-worker2 节点写入首页信息:
代码如下(示例):
echo hello, hostwrite! > /data/index.html
curl http://172.16.245.2
kubectl delete -f hostpath.yml
3.解释
下面是每句命令的详细解释:
-
cat > hostpath.yml <<EOF
:将接下来的内容输入到hostpath.yml
文件中。 -
apiVersion: v1
:指定使用的Kubernetes API版本。 -
kind: Pod
:定义创建的资源类型为Pod。 -
metadata:
:定义Pod的元数据。 -
name: hostpathtest
:指定Pod的名称为hostpathtest
。 -
spec:
:定义Pod的规格。 -
containers:
:定义Pod中的容器列表。 -
- image: nginx
:指定容器使用的镜像为nginx
。 -
imagePullPolicy: IfNotPresent
:设置镜像拉取策略为如果本地不存在才拉取。 -
name: hostpathpod
:指定容器的名称为hostpathpod
。 -
ports:
:定义容器的端口列表。 -
- name: web
:指定端口的名称为web
。 -
containerPort: 80
:指定容器监听的端口为80。 -
volumeMounts:
:定义容器的挂载点列表。 -
- mountPath: /usr/share/nginx/html
:指定挂载点的路径为/usr/share/nginx/html
。 -
name: test-volume
:指定挂载点的名称为test-volume
。 -
volumes:
:定义Pod的卷列表。 -
- name: test-volume
:指定卷的名称为test-volume
。 -
hostPath:
:定义一个主机路径卷。 -
path: /data
:指定主机路径为/data
。 -
type: DirectoryOrCreate
:指定主机路径的类型为目录,如果不存在则创建。 -
EOF
:结束文件输入。 -
kubectl create -f hostpath.yml
:使用kubectl
命令创建一个Pod,其中的配置从hostpath.yml
文件中读取。 -
kubectl get -f hostpath.yml -o wide
:使用kubectl
命令获取刚刚创建的Pod的详细信息,包括IP地址等。 -
echo hello, hostwrite! > /data/index.html
:在主机的/data
目录下创建一个名为index.html
的文件,并写入内容hello, hostwrite!
。 -
curl http://172.16.245.2
:使用curl
命令向Pod的IP地址发送HTTP请求,获取返回的内容。 -
kubectl delete -f hostpath.yml
:使用kubectl
命令删除之前创建的Pod,其中的配置从hostpath.yml
文件中读取。
总结
以上是今天要讲的内容,学到了emptyDir,hostPath。