有没有办法从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)
在这种情况下,容器正在运行,但如果我检查日志并尝试使用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.
我从错误日志中读到推荐的链接,说实话,我不确定我明白应该怎么做。
任何关于可能的解决方案的建议或想法对我来说都是非常有价值的,因为我是这个领域的新手并且我没有太多经验。 如果您需要更多信息,我很乐意提供。
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
您无法在Dockerfile中写入联网服务。想象一下,运行docker build
,运行你的组合应用程序,将其拆除,然后再次运行它。您将重用相同的构建映像,而无需重新运行Dockerfile步骤;只保留图像本身的内容。在大多数情况下,您需要一些少量的设置来在服务之间进行通信(Docker Compose可以为您执行此操作),但这不是在构建序列期间设置的。这与“您无法从Dockerfile运行数据库迁移”的答案相同,但它同样适用于Hadoop。
容器只做一件事。您的示例Dockerfile设置了一个不同的CMD,它等待namenode运行并进行设置。发生这种情况而不是启动namenode进程。 Docker容器只运行一个主命令和一个主命令;没有办法运行主命令以及某种形式的辅助支持脚本。您显示的容器可能会起作用,但您需要将其作为一个单独的容器与namenode容器一起运行。
您无需“在Docker中”访问Docker托管的服务。您可以使用Docker Compose ports:
指令使服务对主机可见,此时您可以使用普通客户端与它们进行交互。 docker exec
路径相当于“我ssh到我的服务器作为root,然后......”,这不是你通常处理任何服务的方式。
您的服务器容器应该只运行服务器。在您的示例中,您既可以尝试启动HDFS名称节点,也可以从同一容器填充服务器;你最好只让namenode容器成为namenode并从另一个容器或主机运行安装作业。 (请参阅standard postgres image's entrypoint script,了解其他所需的回转情况。)
Docker Compose不适合一次性工作。每次运行docker-compose up
时,它都会发现您的安装容器没有运行并尝试再次启动它。其他更强大的协调者可能更适合;例如,Kubernetes Job非常适合您所描述的内容。