使用docker-compose将文件放入HDFS

时间:2019-04-18 15:32:20

标签: docker docker-compose hdfs

是否有一种方法可以直接从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

1 个答案:

答案 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职位很适合您的描述。