gpt4 book ai didi

docker - 为什么我无法从 Kubernetes 容器之间的共享 PersistentVolumeClaim 中读取文件?

转载 作者:行者123 更新时间:2023-12-02 20:53:52 25 4
gpt4 key购买 nike

我有一个 docker 图像 felipeogutierrez/tpch-dbgen我使用 docker-compose 构建的我把它推到docker-hub注册表使用 travis-CI .

version: "3.7"
services:
other-images: ....
tpch-dbgen:
build: ../docker/tpch-dbgen
image: felipeogutierrez/tpch-dbgen
volumes:
- tpch-dbgen-data:/opt/tpch-dbgen/data/
- datarate:/tmp/
stdin_open: true
这是 Dockerfile构建这个图像:
FROM gcc AS builder
RUN mkdir -p /opt
COPY ./generate-tpch-dbgen.sh /opt/generate-tpch-dbgen.sh
WORKDIR /opt
RUN chmod +x generate-tpch-dbgen.sh && ./generate-tpch-dbgen.sh
最后,这个脚本创建了一个目录 /opt/tpch-dbgen/data/包含一些我想从我在 Kubernetes 上运行的另一个 docker 镜像中读取的文件。然后,我创建了一个 Flink 镜像,可以在 Kubernetes 中运行。该镜像启动了 3 个 Flink 任务管理器和一个从镜像中读取文件的流应用程序 tpch-dbgen-data .我认为正确的方法是创建一个 PersistentVolumeClaim所以我可以分享目录 /opt/tpch-dbgen/data/来自图片 felipeogutierrez/tpch-dbgen到我在 Kubernetes 中的 flink 镜像。所以,首先我有这个文件来创建 PersistentVolumeClaim :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: tpch-dbgen-data-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Mi
然后,我正在创建一个 initContainers启动图像 felipeogutierrez/tpch-dbgen然后启动我的图片 felipeogutierrez/explore-flink:1.11.1-scala_2.12 :
apiVersion: apps/v1
kind: Deployment
metadata:
name: flink-taskmanager
spec:
replicas: 3
selector:
matchLabels:
app: flink
component: taskmanager
template:
metadata:
labels:
app: flink
component: taskmanager
spec:
initContainers:
- name: tpch-dbgen
image: felipeogutierrez/tpch-dbgen
#imagePullPolicy: Always
env:
command: ["ls"]
# command: ['sh', '-c', 'for i in 1 2 3; do echo "job-1 `date`" && sleep 5s; done;', 'ls']
volumeMounts:
- name: tpch-dbgen-data
mountPath: /opt/tpch-dbgen/data
containers:
- name: taskmanager
image: felipeogutierrez/explore-flink:1.11.1-scala_2.12
#imagePullPolicy: Always
env:
args: ["taskmanager"]
ports:
- containerPort: 6122
name: rpc
- containerPort: 6125
name: query-state
livenessProbe:
tcpSocket:
port: 6122
initialDelaySeconds: 30
periodSeconds: 60
volumeMounts:
- name: flink-config-volume
mountPath: /opt/flink/conf/
- name: tpch-dbgen-data
mountPath: /opt/tpch-dbgen/data
securityContext:
runAsUser: 9999 # refers to user _flink_ from official flink image, change if necessary
volumes:
- name: flink-config-volume
configMap:
name: flink-config
items:
- key: flink-conf.yaml
path: flink-conf.yaml
- key: log4j-console.properties
path: log4j-console.properties
- name: tpch-dbgen-data
persistentVolumeClaim:
claimName: tpch-dbgen-data-pvc
Flink 流应用程序正在启动,但无法读取目录 /opt/tpch-dbgen/data 中的文件图片的 felipeogutierrez/tpch-dbgen .我收到错误: java.io.FileNotFoundException: /opt/tpch-dbgen/data/orders.tbl (No such file or directory) .这很奇怪,因为当我尝试进入容器时 felipeogutierrez/tpch-dbgen我可以列出文件。所以我想我的 Kubernetes 配置有问题。有谁知道指出我在 Kubernetes 配置文件中缺少什么?
$ docker run -i -t felipeogutierrez/tpch-dbgen /bin/bash
root@10c0944a95f8:/opt# pwd
/opt
root@10c0944a95f8:/opt# ls tpch-dbgen/data/
customer.tbl dbgen dists.dss lineitem.tbl nation.tbl orders.tbl part.tbl partsupp.tbl region.tbl supplier.tbl
另外,当我列出容器的日志时 tpch-dbgen我可以看到目录 tpch-dbgen我想读的。虽然我无法执行命令 command: ["ls tpch-dbgen"]在我的 Kubernetes 配置文件中。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
flink-jobmanager-n9nws 1/1 Running 2 17m
flink-taskmanager-777cb5bf77-ncdl4 1/1 Running 0 4m54s
flink-taskmanager-777cb5bf77-npmrx 1/1 Running 0 4m54s
flink-taskmanager-777cb5bf77-zc2nw 1/1 Running 0 4m54s
$ kubectl logs flink-taskmanager-777cb5bf77-ncdl4 tpch-dbgen
generate-tpch-dbgen.sh
tpch-dbgen

最佳答案

Docker 有一个不寻常的功能,在某些特定情况下,它会从镜像中填充新创建的卷。您不应依赖此功能,因为它完全忽略了底层镜像中的更新,并且不适用于 Kubernetes。
在您的 Kubernetes 设置中,您创建一个新的空 PersistentVolumeClaim,然后将其挂载到 init 和主容器中的实际数据上。与所有 Unix 挂载一样,这会隐藏该目录中先前的数据。没有什么会导致数据被复制到该卷中。这与其他所有类型的挂载方式相同,除了 Docker 命名卷挂载:如果您将 Compose 设置更改为进行主机绑定(bind)挂载,或者使用本地开发系统进行操作,您将看到相同的行为使用 USB 驱动器作为“卷”。
您需要使您的 init 容器(或其他东西)显式地将数据复制到目录中。例如:

initContainers:
- name: tpch-dbgen
image: felipeogutierrez/tpch-dbgen
command:
- /bin/cp
- -a
- /opt/tpch-dbgen/data
- /data
volumeMounts:
- name: tpch-dbgen-data
mountPath: /data # NOT the same path as in the image
如果主进程修改了这些文件,您可以使命令更智能,或者将脚本写入您的镜像,仅在单个文件不存在时复制它们。
让您的镜像在启动时而不是在镜像构建时生成数据文件可能更有意义。这可能看起来像:
FROM gcc
COPY ./generate-tpch-dbgen.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/generate-tpch-dbgen.sh
CMD ["generate-tpch-dbgen.sh"]
然后在您的 init 容器中,您可以运行默认命令(生成脚本),并将工作目录设置为卷目录
initContainers:
- name: tpch-dbgen
image: felipeogutierrez/tpch-dbgen
volumeMounts:
- name: tpch-dbgen-data
mountPath: /opt/tpch-dbgen/data # or anywhere really
workingDir: /opt/tpch-dbgen/data # matching mountPath

关于docker - 为什么我无法从 Kubernetes 容器之间的共享 PersistentVolumeClaim 中读取文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64008325/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com