FTP 到谷歌存储

Posted

技术标签:

【中文标题】FTP 到谷歌存储【英文标题】:FTP to Google Storage 【发布时间】:2017-09-15 03:17:36 【问题描述】:

每天都会将一些文件上传到 FTP 服务器,我需要 Google Cloud Storage 下的这些文件。我不想让上传文件的用户安装任何其他软件并让他们继续使用他们的 FTP 客户端。 有没有办法将 GCS 用作 FTP 服务器?如果没有,我如何创建一个定期从 FTP 位置获取文件并将它们放入 GCS 的作业? 换句话说:最好和最简单的方法是什么?

【问题讨论】:

似乎一种方法是在 VM 上设置 FTP 服务器并使用 gcsfs 将此服务器连接到 GCS,如此处所述ilyapimenov.com/blog/2015/01/19/ftp-proxy-to-gcs.html - 这对您有用吗? 【参考方案1】:

您可以自己编写一个上传到 GCS 的 FTP 服务器,例如基于 pyftpdlib

定义一个自定义处理程序,在收到文件时存储到 GCS

import os
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
from pyftpdlib.authorizers import DummyAuthorizer
from google.cloud import storage

class MyHandler:
    def on_file_received(self, file):
        storage_client = storage.Client()
        bucket = storage_client.get_bucket('your_gcs_bucket')
        blob = bucket.blob(file[5:]) # strip leading /tmp/
        blob.upload_from_filename(file)
        os.remove(file)
    def on_... # implement other events

def main():
    authorizer = DummyAuthorizer()
    authorizer.add_user('user', 'password', homedir='/tmp', perm='elradfmw')

    handler = MyHandler
    handler.authorizer = authorizer
    handler.masquerade_address = add.your.public.ip
    handler.passive_ports = range(60000, 60999)

    server = FTPServer(("127.0.0.1", 21), handler)
    server.serve_forever()

if __name__ == "__main__":
    main()

我已经在 Google Container Engine 上成功运行了它(它需要一些努力才能让被动 FTP 正常工作),但在 Compute Engine 上应该很简单。按照上面的配置,在防火墙上打开21端口和60000-60999端口。

要运行它,python my_ftp_server.py - 如果你想监听 21 端口,你需要 root 权限。

【讨论】:

这个文件应该放在哪里?用户如何通过 ftp 客户端进行身份验证(主机名、用户、密码是什么)? 我认为 crazystick 建议用户使用 FTP 服务器进行身份验证,而您正在运行的 FTP 服务器具有将对象上传到 GCS 的凭据。因此,您写入 FTP 服务器,FTP 服务器将该上传流转发到 GCS。 是的 - 查看 pyftpdlib 的文档,您会发现许多身份验证选项。在上面的示例中,每个人都将使用用户名“user”和密码“password”连接到 FTP 服务器,所有文件都被转储到具有默认安全性的同一个 GCS 存储桶中。在 Compute Engine / Container Engine 上运行可以获得 GCS 的凭据 谢谢...我知道我可能要求的太多了,但是该文件应该放在哪里以及需要在 Compute Engine 中的 VM 中进行哪些配置更改?另外,是否应该考虑被动 FTP 和连接到外部 IP? 我添加了一些额外的配置选项,您可能希望在 GCE 上运行它。要让它自动启动,您必须为它编写一个 systemd 服务。这应该是微不足道的,并且有很多资源可以解释如何进行。【参考方案2】:

您可以使用gsutil rsync 或开源rclone tool 在FTP 服务器和Google Cloud Storage 之间设置一个cron 和rsync

如果您无法在 FTP 服务器上定期运行这些命令,您可以将 FTP 服务器挂载为本地文件系统或驱动器(Linux、Windows)

【讨论】:

你是如何 rsync 作为存储桶源的? 您需要将存储桶作为文件系统安装在某处,例如使用 gcs-fuse cloud.google.com/storage/docs/gcs-fuse【参考方案3】:

我已经在 Google Compute 的虚拟机中使用 gcsfs 成功设置了到 GCS 的 FTP 代理(jkff 在我的问题的评论中提到),并附有以下说明: http://ilyapimenov.com/blog/2015/01/19/ftp-proxy-to-gcs.html

但需要进行一些更改:

在 /etc/vsftpd.conf 中将 #write_enable=YES 更改为 write_enable=YES 在您的 GC 项目中添加防火墙规则以允许 访问端口 21 和被动端口 15393 到 15592 (https://console.cloud.google.com/networking/firewalls/list)

一些可能的问题:

如果本地ip可以访问FTP服务器,远程ip不能访问,可能是你没有设置防火墙规则 如果你可以访问ftp服务器,但是不能写,可能是因为你需要write_enable=YES 如果您想读取在 /mnt 上创建的文件夹,但出现 I/O 错误,可能是因为 gcsfs_config 中的存储桶不正确。

另外,您的 ftp 客户端需要使用设置为“被动”的传输模式。

【讨论】:

我们这样做了,但是所有现成的 FTP 解决方案都出现了大量间歇性错误。最后唯一成功的是 pyftpdlib,我们确实在安装了 FUSE 的 GCS 上运行它。 我们也尝试过,但有时我们会遇到 gcsfuse 断开连接的错误,因此我不建议您将其运行用于生产用途 链接不再可用:/【参考方案4】:

在谷歌云中设置一个虚拟机,使用一些 *nix 风格。在其上设置 ftp,并将其指向文件夹 abc。使用 google fuse 将 abc 挂载为 GCS 存储桶。瞧——在 gcs / ftp 之间来回切换,无需编写任何软件。 (小字:如果你推送太多数据,fuse 会卷起来并死掉,所以定期反弹它,每周一次或每天一次;你可能还需要设置 mount 或 fuse 以允许所有用户的权限)

【讨论】:

以上是关于FTP 到谷歌存储的主要内容,如果未能解决你的问题,请参考以下文章

如何将本地 svn 存储库迁移到谷歌代码的 svn 存储库?

如何将 spatie laravel 存储的备份上传到谷歌驱动器?

如何将文件从 colab 或云存储复制到谷歌驱动器?

凭证 JSON 文件到谷歌 colab

在将应用程序(spring boot)部署到谷歌应用程序引擎时,没有使用sql db?

将 geoJSON 对象直接加载到谷歌地图 v3