使用 docker-compose 将文件放入 HDFS
Putting file into HDFS using docker-compose
有没有办法直接从 Docker-compose/Dockerfile 自动将某些文件(比方说 data.json)放入 HDFS?
当我启动 namenode 和 datanode 时,我可以使用
进入容器
docker exec -it namenode [datanode] bash
,并使用
hdfs dfs -put data.json hdfs:/
(安全模式结束时)
这行得通,但我需要一种自动 运行 的方法。当我尝试从 Dockerfile 构建容器并输入命令时:
FROM bde2020/hadoop-namenode:1.1.0-hadoop2.8-java8
WORKDIR /data
ADD hdfs_writer/data.json /data
# ADD python_script.py /data
CMD ["hdfs dfsadmin -safemode wait && hdfs dfs -put ./data.json hdfs:/"]
# CMD ["python python_script.py"]
容器名称节点立即终止。我还尝试了 python 脚本,我将其添加到容器中并使用 CMD 运行 它。
python_script
import time
import os
os.system("hdfs dfsadmin -safemode wait")
os.system("hdfs dfs -put -f data.json hdfs:/")
while True:
time.sleep(5)
在那种情况下,容器是 运行ning,但是如果我检查日志并尝试使用 hdfs dfs -ls hdfs:/
列出 hdfs,则会出现以下错误
safemode: Call From 662aae005e8b/172.20.0.5 to namenode:8020 failed on connection exception: java.net.ConnectException: Connection refused; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused
19/04/18 14:36:36 WARN ipc.Client: Failed to connect to server: namenode/172.20.0.5:8020: try once and fail.
我从错误日志中阅读了推荐的 link,老实说,我不确定我是否理解我应该做什么。
您对可能的解决方案的任何建议或想法对我来说都非常有价值,因为我是这个领域的新手而且我没有太多经验。
如果您需要更多信息,我很乐意提供。
docker-compose.yml(只是一部分)
namenode:
#docker-compose.yml and Dockerfile are in the dame directory
build: .
volumes:
- ./data/namenode:/hadoop/dfs/name
environment:
- CLUSTER_NAME=cluster
env_file:
- ./hadoop.env
ports:
- 50070:50070
datanode:
image: bde2020/hadoop-datanode:1.1.0-hadoop2.8-java8
depends_on:
- namenode
volumes:
- ./data/datanode:/hadoop/dfs/data
env_file:
- ./hadoop.env
hadoop.env
CORE_CONF_fs_defaultFS=hdfs://namenode:8020
CORE_CONF_hadoop_http_staticuser_user=root
CORE_CONF_hadoop_proxyuser_hue_hosts=*
CORE_CONF_hadoop_proxyuser_hue_groups=*
HDFS_CONF_dfs_webhdfs_enabled=true
HDFS_CONF_dfs_permissions_enabled=false
HDFS_CONF_dfs_blocksize=1m
YARN_CONF_yarn_log___aggregation___enable=true
YARN_CONF_yarn_resourcemanager_recovery_enabled=true
YARN_CONF_yarn_resourcemanager_store_class=org.apache.hadoop.yarn.server.resourcemanager.recovery.FileSystemRMStateStore
YARN_CONF_yarn_resourcemanager_fs_state___store_uri=/rmstate
YARN_CONF_yarn_nodemanager_remote___app___log___dir=/app-logs
YARN_CONF_yarn_log_server_url=http://historyserver:8188/applicationhistory/logs/
YARN_CONF_yarn_timeline___service_enabled=true
YARN_CONF_yarn_timeline___service_generic___application___history_enabled=true
YARN_CONF_yarn_resourcemanager_system___metrics___publisher_enabled=true
YARN_CONF_yarn_resourcemanager_hostname=resourcemanager
YARN_CONF_yarn_timeline___service_hostname=historyserver
YARN_CONF_yarn_resourcemanager_address=resourcemanager:8032
YARN_CONF_yarn_resourcemanager_scheduler_address=resourcemanager:8030
YARN_CONF_yarn_resourcemanager_resource__tracker_address=resourcemanager:8031
您不能在 Docker 文件中写入网络服务。 想象一下 运行ning docker build
, 运行合并您的应用程序,将其拆下,然后 运行 再次合并。您将重复使用相同的构建图像,而无需重新 运行 执行 Docker 文件步骤;只保留图像本身的内容。在大多数情况下,您需要一些少量的设置来在服务之间进行通信(Docker Compose 可以为您完成此操作),但这不是在构建序列中设置的。这与 "you can't run database migrations from a Dockerfile" 的答案相同,但同样适用于 Hadoop。
一个容器只做一件事。你的示例Docker文件设置了一个不同的 CMD,它等待 namenode 运行ning 并设置它向上。这发生 而不是 启动名称节点进程。一个Docker容器运行只有一个主命令和一个主命令;没有办法 运行 一个主要命令和某种形式的辅助支持脚本。您显示的容器可能会工作,但您需要 运行 将其作为名称节点容器旁边的单独容器。
您无需 "in Docker" 即可访问 Docker 托管服务。 您可以使用 Docker 撰写 ports:
指令使服务对主机可见,此时您可以使用普通客户端与它们交互。 docker exec
路径等同于 "I ssh to my server as root, and then...",这根本不是您通常处理任何服务的方式。
您的服务器容器应该只有 运行 个服务器。 在您的示例中,您既尝试启动 HDFS namenode 又从同一个容器填充服务器;你最好让 namenode 容器只是 namenode 并且 运行 从另一个容器或主机设置作业。 (请参阅 standard postgres image's entrypoint script 以了解其他情况下所需的旋转。)
Docker Compose 不适合一次性工作。 每次您 运行 docker-compose up
它都会发现您的设置容器未 运行ning 并尝试重新启动它。其他更强大的协调器可能更合适;例如,Kubernetes 作业非常适合您所描述的内容。
有没有办法直接从 Docker-compose/Dockerfile 自动将某些文件(比方说 data.json)放入 HDFS? 当我启动 namenode 和 datanode 时,我可以使用
进入容器docker exec -it namenode [datanode] bash
,并使用
hdfs dfs -put data.json hdfs:/
(安全模式结束时)
这行得通,但我需要一种自动 运行 的方法。当我尝试从 Dockerfile 构建容器并输入命令时:
FROM bde2020/hadoop-namenode:1.1.0-hadoop2.8-java8
WORKDIR /data
ADD hdfs_writer/data.json /data
# ADD python_script.py /data
CMD ["hdfs dfsadmin -safemode wait && hdfs dfs -put ./data.json hdfs:/"]
# CMD ["python python_script.py"]
容器名称节点立即终止。我还尝试了 python 脚本,我将其添加到容器中并使用 CMD 运行 它。
python_script
import time
import os
os.system("hdfs dfsadmin -safemode wait")
os.system("hdfs dfs -put -f data.json hdfs:/")
while True:
time.sleep(5)
在那种情况下,容器是 运行ning,但是如果我检查日志并尝试使用 hdfs dfs -ls hdfs:/
列出 hdfs,则会出现以下错误
safemode: Call From 662aae005e8b/172.20.0.5 to namenode:8020 failed on connection exception: java.net.ConnectException: Connection refused; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused
19/04/18 14:36:36 WARN ipc.Client: Failed to connect to server: namenode/172.20.0.5:8020: try once and fail.
我从错误日志中阅读了推荐的 link,老实说,我不确定我是否理解我应该做什么。
您对可能的解决方案的任何建议或想法对我来说都非常有价值,因为我是这个领域的新手而且我没有太多经验。
如果您需要更多信息,我很乐意提供。
docker-compose.yml(只是一部分)
namenode:
#docker-compose.yml and Dockerfile are in the dame directory
build: .
volumes:
- ./data/namenode:/hadoop/dfs/name
environment:
- CLUSTER_NAME=cluster
env_file:
- ./hadoop.env
ports:
- 50070:50070
datanode:
image: bde2020/hadoop-datanode:1.1.0-hadoop2.8-java8
depends_on:
- namenode
volumes:
- ./data/datanode:/hadoop/dfs/data
env_file:
- ./hadoop.env
hadoop.env
CORE_CONF_fs_defaultFS=hdfs://namenode:8020
CORE_CONF_hadoop_http_staticuser_user=root
CORE_CONF_hadoop_proxyuser_hue_hosts=*
CORE_CONF_hadoop_proxyuser_hue_groups=*
HDFS_CONF_dfs_webhdfs_enabled=true
HDFS_CONF_dfs_permissions_enabled=false
HDFS_CONF_dfs_blocksize=1m
YARN_CONF_yarn_log___aggregation___enable=true
YARN_CONF_yarn_resourcemanager_recovery_enabled=true
YARN_CONF_yarn_resourcemanager_store_class=org.apache.hadoop.yarn.server.resourcemanager.recovery.FileSystemRMStateStore
YARN_CONF_yarn_resourcemanager_fs_state___store_uri=/rmstate
YARN_CONF_yarn_nodemanager_remote___app___log___dir=/app-logs
YARN_CONF_yarn_log_server_url=http://historyserver:8188/applicationhistory/logs/
YARN_CONF_yarn_timeline___service_enabled=true
YARN_CONF_yarn_timeline___service_generic___application___history_enabled=true
YARN_CONF_yarn_resourcemanager_system___metrics___publisher_enabled=true
YARN_CONF_yarn_resourcemanager_hostname=resourcemanager
YARN_CONF_yarn_timeline___service_hostname=historyserver
YARN_CONF_yarn_resourcemanager_address=resourcemanager:8032
YARN_CONF_yarn_resourcemanager_scheduler_address=resourcemanager:8030
YARN_CONF_yarn_resourcemanager_resource__tracker_address=resourcemanager:8031
您不能在 Docker 文件中写入网络服务。 想象一下 运行ning docker build
, 运行合并您的应用程序,将其拆下,然后 运行 再次合并。您将重复使用相同的构建图像,而无需重新 运行 执行 Docker 文件步骤;只保留图像本身的内容。在大多数情况下,您需要一些少量的设置来在服务之间进行通信(Docker Compose 可以为您完成此操作),但这不是在构建序列中设置的。这与 "you can't run database migrations from a Dockerfile" 的答案相同,但同样适用于 Hadoop。
一个容器只做一件事。你的示例Docker文件设置了一个不同的 CMD,它等待 namenode 运行ning 并设置它向上。这发生 而不是 启动名称节点进程。一个Docker容器运行只有一个主命令和一个主命令;没有办法 运行 一个主要命令和某种形式的辅助支持脚本。您显示的容器可能会工作,但您需要 运行 将其作为名称节点容器旁边的单独容器。
您无需 "in Docker" 即可访问 Docker 托管服务。 您可以使用 Docker 撰写 ports:
指令使服务对主机可见,此时您可以使用普通客户端与它们交互。 docker exec
路径等同于 "I ssh to my server as root, and then...",这根本不是您通常处理任何服务的方式。
您的服务器容器应该只有 运行 个服务器。 在您的示例中,您既尝试启动 HDFS namenode 又从同一个容器填充服务器;你最好让 namenode 容器只是 namenode 并且 运行 从另一个容器或主机设置作业。 (请参阅 standard postgres image's entrypoint script 以了解其他情况下所需的旋转。)
Docker Compose 不适合一次性工作。 每次您 运行 docker-compose up
它都会发现您的设置容器未 运行ning 并尝试重新启动它。其他更强大的协调器可能更合适;例如,Kubernetes 作业非常适合您所描述的内容。