我正在尝试在kubernetes中运行indy-nodes。这些indy节点是沙箱节点,在容器内的/var/lib/indy目录中写入数据。当我在安装了卷的情况下运行pod时,它没有在卷目录中写入任何内容。尽管它在卷内创建了一个目录,但它始终是空的。但是,当我创建一个没有卷挂载选项的pod时,容器在/var/lib/indy中写入数据。
以下是Dockerfile:
哈斯特宾:https://hastebin.com/hitinefizi.nginx
Kubernetes部署:
{{- $root := .}}
{{- range .Values.indy}}
---
apiVersion: apps/v1
kind: Deployment
metadata:
# namespace: {{$root.Values.namespace}}
name: {{.name}}
spec:
selector:
matchLabels:
name: {{.name}}
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
name: {{.name}}
spec:
containers:
- name: {{.name}}
image: {{.image}}
volumeMounts:
- name: {{$root.Values.pv.metadata.name}}
mountPath: "/var/lib/indy/sandbox"
subPath: "volume/indy/{{.name}}/sandbox"
ports:
- containerPort: {{ index .ports 0 }}
- containerPort: {{ index .ports 1 }}
nodeSelector:
nodeType: {{$root.Values.hosts.blockchain}}
volumes:
- name: {{$root.Values.pv.metadata.name}}
{{- if eq $root.Values.storage.type "nfs" }}
persistentVolumeClaim:
claimName: {{$root.Values.pvc.metadata.name}}
{{- else }}
hostPath:
path: /var/kubeshare/
{{- end }}
{{- end}}卷内目录:
[root@centos1 kubeshare]# tree volume/indy/
volume/indy/
|-- indy-node1
|-- indy-node2
|-- indy-node3
`-- indy-node容器内无卷的目录/var/lib/indy:
root@indy-node1-587c4758bf-2hpp6:/var/lib/indy# tree -L 3
.
|-- plugins
`-- sandbox
|-- data
| `-- Node1
|-- domain_transactions_genesis
|-- keys
| |-- Node1
| |-- Node1C
| |-- Node2
| |-- Node3
| `-- Node4
|-- node1_additional_info.json
|-- node1_info.json
|-- node1_version_info.json
`-- pool_transactions_genesis我不确定为什么会发生这种情况。如有任何帮助/建议,我们将不胜感激。
更新:当我尝试使用本地卷时,docker-compose也会发生同样的事情。
发布于 2020-04-27 15:20:37
在docker中安装与Linux上安装的标准行为一致。Linux mount命令docs say
The previous contents (if any) and owner and mode of dir become invisible, and as long as this filesystem remains mounted
这也是Docker中的工作方式。如果您挂载一个本地目录,或者一个名为docker 的现有卷,挂载位置上容器中的文件系统的内容将被屏蔽(或者我们也可以称之为"overriden")。
正在发生的事情的简化示例
有dockerfile
FROM alpine:3.9.6
WORKDIR /home/root/greetings
RUN echo "hello world" > /home/root/greetings/english.txt
CMD sleep 60000并构建它的docker build -t greetings:1.0 .
现在创建下面的docker-compose.yml
version: '3.7'
services:
greetings:
container_name: greetings
image: greetings:1.0
volumes:
- ./empty:/home/root/greetings并在其旁边创建空目录empty。
启动它docker-compose up -d。当容器运行时,让我们进入容器,看看里面的文件结构是什么样子的。docker exec -ti greetings sh。现在,当我们在里面的时候,如果你运行ls /home/root/greetings,你会看到目录是空的--即使在Dockerfile文件中,我们已经将文件/home/root/greetings/english.txt放到了镜像的文件系统中。
如果命名的docker容器是新的并且不包含任何数据,那么命名docker容器的行为会更理想。如果你在容器中已经有一些数据的位置挂载了这样的容器,那么命名的卷会将这些数据复制到它上面。
您可以通过将docker-compose.yml调整为以下值来尝试此操作
version: '3.7'
services:
greetings:
container_name: greetings
image: greetings:1.0
volumes:
- greetingsvol:/home/root/greetings
volumes:
greetingsvol:
driver: local如果您重复这个过程并将自己执行到容器中,您将看到文件/home/root/greetings/english.txt仍然在那里。
这是因为当您使用cd进入/home/root/greetings时,您看到的不是实际容器的文件系统,而是挂载的设备-名称为docker卷-已由给定位置上容器的原始文件的副本初始化。(假设docker卷greetingsvol以前不存在。)
问题的解决方案
您正在将主机上的目录/var/kubeshare挂载到容器的/var/lib/indy/sandbox。让我们看看容器在启动时在那个位置上存储了什么(indypool是我在本地主机上命名built沙箱镜像的方式)
docker run --rm indypool ls /var/lib/indy/sandbox
domain_transactions_genesis
keys
pool_transactions_genesis因此,如果您将本地目录挂载到/var/lib/indy/sandbox上,它将隐藏这些文件,并且池将无法启动(因此不会创建node1_additional_info.json等文件)。
所以我认为你有两个选择:
除非有充分的理由,否则请使用
/var/lib/indy/sandbox中的原始图像数据保存到您的/var/kubeshare中。然后你就可以保持其他的东西不变了。这样,目录将被包含与容器期望在那里找到的数据完全相同的新文件系统所遮蔽。https://stackoverflow.com/questions/61437680
复制相似问题