【问题标题】:shell script having ssh command inside docker container fails with - ssh: not found在 docker 容器中具有 ssh 命令的 shell 脚本失败并显示 - ssh: not found
【发布时间】:2020-12-02 03:14:31
【问题描述】:

我有一个在 docker 容器上运行的 Spring Boot Java 应用程序,它尝试运行一个 shell 脚本。 shell 脚本有一个 ssh 命令,运行时出现以下错误

    2020-08-12 09:22:29.425  INFO 1 --- [io-11013-exec-1] b.n.i.s.d.e.service.EmrManagerService    : Executing spark submit, calling shell script: /tmp/temp843155675494688636.sh 172.29.199.15
    2020-08-12 09:22:29.434 DEBUG 1 --- [io-11013-exec-1] b.n.i.s.d.e.service.EmrManagerService    : Starting Input Stream:
    2020-08-12 09:22:29.435  INFO 1 --- [io-11013-exec-1] b.n.i.s.d.e.service.EmrManagerService    : #1 arg: 172.29.199.15
    2020-08-12 09:22:29.436  INFO 1 --- [io-11013-exec-1] b.n.i.s.d.e.service.EmrManagerService    : Exist Value127
    2020-08-12 09:22:29.436 ERROR 1 --- [io-11013-exec-1] b.n.i.s.d.e.service.EmrManagerService    : Starting Error Stream:
    2020-08-12 09:22:29.436 ERROR 1 --- [io-11013-exec-1] b.n.i.s.d.e.service.EmrManagerService    : 
    /tmp/temp843155675494688636.sh: line         5: ssh: not found

当直接运行 jar 而不是作为 docker 容器运行时,相同的代码可以正常工作。 是否与 docker 容器中无法识别 ssh 有关?

    shell script - 
    #!/bin/bash
    
    
    echo "#1 arg:" $1
    ssh -i /home/dnaidaasd/aws-oneid-idaas-2020Q2.pem -oStrictHostKeyChecking=no hadoop@$1 '/etc/alternatives/jre/bin/java -Xmx1000m -server \ 
    -XX:OnOutOfMemoryError="kill -9 %p" -cp "/usr/share/aws/emr/instance \
    -controller/lib/*" -Dhadoop.log.dir=/mnt/var/log/hadoop/steps/s-100-120 \
    -Dhadoop.log.file=syslog -Dhadoop.home.dir=/usr/lib/hadoop \ 
    -Dhadoop.id.str=hadoop -Dhadoop.root.logger=INFO,DRFA -Djava.library.path=:/usr/lib/hadoop-lzo/lib/native:/usr/lib/hadoop/lib/native \
    -Dhadoop.policy.file=hadoop-policy.xml -Djava.net.preferIPv4Stack=true \
    -Djava.io.tmpdir=/mnt/var/lib/hadoop/steps/s-14611-353/tmp \
    -Dhadoop.security.logger=INFO,NullAppender \
    -Dsun.net.inetaddr.ttl=30 \
    org.apache.hadoop.util.RunJar /var/lib/aws/emr/step-runner/hadoop-jars/command-runner.jar spark-submit \
    --conf spark.hadoop.mapred.output.compress=true \
    --conf spark.hadoop.mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec \
    --class biz.neustar.idaas.services.dataprofile.ProfileMain \
    --name IdaasProfile --conf spark.dynamicAllocation.enabled=true \
    --conf spark.executor.instances=2 --conf spark.driver.memory=8G \
    --conf spark.executor.memory=4G --conf spark.executor.cores=1 \
    --conf spark.sql.catalogImplementation=hive \
    --jars s3://oneid-idaas-dev-us-east-1/dev/emr/TestIdaasProfile/spark-core_2.11-2.4.5.jar,s3://oneid-idaas-dev-us-east-1/dev/emr/TestIdaasProfile/spark-sql_2.11-2.4.5.jar,s3://oneid-idaas-dev-us-east-1/dev/emr/TestIdaasProfile/spark-mllib_2.11-2.4.5.jar,s3://oneid-idaas-dev-us-east-1/dev/emr/TestIdaasProfile/jackson-module-scala_2.11-2.6.7.1.jar,s3://oneid-idaas-dev-us-east-1/dev/emr/TestIdaasProfile/jackson-databind-2.6.7.jar  s3://oneid-idaas-dev-us-east-1/dev/emr/TestIdaasProfile/data-profile-14.0.jar' \
    $2 $3 $4

这个 shell 脚本被称为 -

public void executeSparkSubmit(String masterNodeIp, String pathToScript, String input_hive_table, String s3_output_path,  String output_hive_table ) throws IOException, InterruptedException, DataProfileServiceException {

        log.info("Executing spark submit, calling shell script: " + pathToScript + " " + masterNodeIp);
        ProcessBuilder pb = new ProcessBuilder("sh", pathToScript, masterNodeIp, input_hive_table, s3_output_path, output_hive_table);
        Process pr = pb.start();

Dockerfile 的内容是:

FROM openjdk:8-jdk-alpine
ADD ./data-profile-provider/build/libs/data-profile-provider-203.2.0-SNAPSHOT.jar data-profile.jar
EXPOSE 11013
ENTRYPOINT ["java", "-jar", "data-profile.jar", "application.properties"]

【问题讨论】:

  • 容器内好像没有安装 ssh 客户端。容器基于什么图像?
  • @KonradBotor docker 镜像只是一个 Web 应用程序服务。它回答了你的问题吗?
  • 不,它没有。如果它是在 Docker Hub 上发布的,我需要图像名称和标签;如果它是自定义的,我需要它构建的 Dockerfile。
  • 这是一个自定义图像。@KonradBotor
  • FROM openjdk:8-jdk-alpine 添加 ./data-profile-provider/build/libs/data-profile-provider-203.2.0-SNAPSHOT.jar data-profile.jar EXPOSE 11013 ENTRYPOINT ["java", "-jar", "data-profile.jar", "application.properties"] Docker 文件@KonradBotor

标签: docker ssh


【解决方案1】:

正如我所怀疑的 - 您的图像是基于 Alpine 的,并且默认情况下 Alpine 没有安装 SSH 客户端。

已更正Dockerfile:

FROM openjdk:8-jdk-alpine
RUN apk add --no-cache openssh-client
ADD ./data-profile-provider/build/libs/data-profile-provider-203.2.0-SNAPSHOT.jar data-profile.jar
EXPOSE 11013
ENTRYPOINT ["java", "-jar", "data-profile.jar", "application.properties"]

编辑:我忘了补充一点,Alpine 也没有 Bash。幸运的是,您的应用使用 sh scriptname.sh 调用您的脚本 - 否则您会收到 bash: not found 错误。

【讨论】:

  • 没问题。如果你接受我的回答就好了。
【解决方案2】:

SSH 可能未安装。

我这里的示例假设一个 Ubuntu/Linux 映像派生自您当时没有指定 Dockfile 内容。

如果您的容器可以成功启动(忽略您的应用程序失败的事实),您只需在命令行上运行ssh 即可查看(它会为您提供类似于command not found 的内容)

要在 Docker 容器中运行命令:由于 Ubuntu 映像已安装 bash,您可以这样运行:

docker exec -ti containername bash

在 Docker 容器内:(我的一个没有安装 SSH 的容器)

  ssh
  ssh: command not found

您继承的基础容器可能没有安装该工具。您继承的大多数 Docker 容器通常都考虑到“最低限度”,因此您的自定义 Docker 映像需要安装它。

只需添加您可以添加到 Dockerfile 中的运行命令,确保您的用户能够运行这些命令。 (在此示例中,我确保容器映像用户为 root 此示例仅安装 ssh-client(这是必需的)

USER root

RUN apt-get update \
  && apt-get install openssh-client

USER mydockercontaineruser

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-07
    • 2019-07-01
    • 1970-01-01
    • 2017-08-15
    • 2018-06-07
    • 2011-04-25
    • 2013-03-01
    • 2018-03-29
    相关资源
    最近更新 更多