开发者社区 > 云原生 > 容器服务 > 正文

FTP上传文件在Docker容器中失败

我有一个使用库apache commons-net的spring boot应用程序, 我有一个在AWS EC2上运行的FTP服务器。 Filezilla正常连接并上传文件。 本地应用正常连接并上传文件。 当我使用Docker运行此应用程序时,该应用程序成功连接到ftp,但无法上传文件。 回复代码是:500

Dockerfile:

FROM openjdk:11
RUN mkdir /app
COPY build/libs/aws-batch1-1.0.0.jar /app/aws-batch1.jar
ENTRYPOINT ["java","-jar","/app/aws-batch1.jar","Test"]

映像构建命令:

docker build -t aws-batch1 .

图像运行命令:

docker run aws-batch1

代码连接FTP:

private boolean connectFTPServer() throws IOException {
        LOGGER.info("CONNECT");
        boolean flg = true;
        try {
            ftpClient.connect(FTP_SERVER_ADDRESS, FTP_SERVER_PORT_NUMBER);
            ftpClient.login(FTP_USERNAME, FTP_PASSWORD);
        } catch (IOException e) {
            LOGGER.error("CONNECT FAILED", e);
            flg = false;
        }

        int replyCode = ftpClient.getReplyCode();
        LOGGER.info("replyCode: " + replyCode);
        if (!FTPReply.isPositiveCompletion(replyCode)) {
            flg = false;
        }
        if (!flg) {
            throw new IOException();
        }
        return flg;
    }

代码上传文件:

public boolean uploadFile(byte[] content, String fileName)
            throws IOException {
        boolean flg = false;
        LOGGER.info("uploadFile");
        if (connectFTPServer()) {
            LOGGER.info("connectFTPServer success");
            LOGGER.info("content: " + new String(content));
            try (InputStream is = new ByteArrayInputStream(content)) {
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                boolean storeFile = ftpClient.storeFile(fileName, is);
                LOGGER.info("storeFile: " + storeFile);
                LOGGER.info("ftpClient.getReplyCode(): " + ftpClient.getReplyCode());

                flg = storeFile &&
                        ftpClient.getReplyCode() ==
                                FTPReply.CLOSING_DATA_CONNECTION;
                if (!flg) {
                    throw new IOException("FTP error");
                }
            } finally {
                closeConnectionFTPClient();
            }
        }
        return flg;
    }

在本地成功上传时记录:

uploadFile
CONNECT
replyCode: 230
connectFTPServer success
content: test
storeFile: true
ftpClient.getReplyCode(): 226

在Docker上载失败时记录日志:

uploadFile
CONNECT
replyCode: 230
connectFTPServer success
content: test
storeFile: false
ftpClient.getReplyCode(): 500

请帮我。我是否缺少任何步骤?

更新:谢谢@Metin我已经更新了连接到ftp客户端的代码,如下所示:

private boolean connectFTPServer() throws IOException {
        LOGGER.info("CONNECT");
        boolean flg = true;
        try {
            ftpClient.connect(FTP_SERVER_ADDRESS, FTP_SERVER_PORT_NUMBER);
            ftpClient.login(FTP_USERNAME, FTP_PASSWORD);
            ftpClient.enterLocalPassiveMode();
        } catch (IOException e) {
            LOGGER.error("CONNECT FAILED", e);
            flg = false;
        }

        int replyCode = ftpClient.getReplyCode();
        LOGGER.info("replyCode: " + replyCode);
        if (!FTPReply.isPositiveCompletion(replyCode)) {
            flg = false;
        }
        if (!flg) {
            throw new IOException();
        }
        return flg;
    }

而且有效!

问题来源:Stack Overflow

展开
收起
montos 2020-03-25 09:21:01 2192 0
1 条回答
写回答
取消 提交回答
  • 您可能想了解主动和被动模式ftp 的区别:[主动和被动FTP之间有什么区别(https://stackoverflow.com/questions/1699145/what-is-the-difference-between-active-and-passive-ftp)?

    您应该得出的结论是,由于服务器会主动尝试启动与ftp客户端的数据连接,因此活动模式ftp不适合容器化的ftp客户端,这对于容器是不可能的(除非容器使用网络:主机,通常是不需要的)。

    另一方面,在被动模式ftp下,服务器将告诉ftp客户端下一个数据连接需要使用哪个端口。

    回答来源:Stack Overflow

    2020-03-25 09:21:37
    赞同 展开评论 打赏

国内唯一 Forrester 公共云容器平台领导者象限。

相关电子书

更多
应用 Docker 进行持续交付:用技术改变交付路程 立即下载
从Docker到容器服务 立即下载
Docker@Alibaba——超大规模Docker化的实战经验 立即下载