是否有一种方法可以直接从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"]
容器namenode立即终止。我还尝试了将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
答案 0 :(得分:0)
您无法在Dockerfile中写入网络服务。想象一下运行docker build
,运行组合的应用程序,将其拆解并再次运行。您将重复使用相同的构建映像,而无需重新运行Dockerfile步骤;仅保留图像本身中的内容。在大多数情况下,您需要进行少量的设置以在服务之间进行通信(Docker Compose可以为您完成此操作),但这不是在构建序列中设置的。答案与“您无法从Dockerfile运行数据库迁移”相同,但同样适用于Hadoop。
容器只做一件事。您的示例Dockerfile设置了另一个CMD,它等待namenode运行并对其进行设置。这是代替启动namenode进程的情况。一个Docker容器仅运行一个主命令和一个主命令;没有运行主命令的方法,也没有某种形式的辅助脚本。您显示的容器可能会起作用,但是您需要将其作为单独的容器与namenode容器一起运行。
您无需“在Docker中”即可访问Docker托管的服务。您可以使用Docker Compose ports:
指令使服务对主机可见您可以使用普通客户与他们互动。 docker exec
路径等效于“我先以root身份登录到服务器,然后...”,这通常不是您通常处理任何服务的方式。
您的服务器容器应仅运行服务器。在您的示例中,您既要尝试启动HDFS名称节点,又要从同一容器中填充服务器。您最好将namenode容器仅用作namenode并从另一个容器或从主机运行设置作业。 (有关其他要求的回转的一些信息,请参见standard postgres image's entrypoint script。)
Docker Compose不适用于一次性工作。。每次运行docker-compose up
时,它都会发现您的设置容器未运行,然后尝试重新启动它。其他功能更强大的协调器可能更合适。例如,Kubernetes职位很适合您的描述。