正在构建或已经构建了数据管道的人们真的经常会使用 SFTP 来将数据发送到另一个位置或从另一个位置获取数据供自己使用。SFTP 已存在很长时间,已成为数据传输的标准。团队可以使用 Snowflake 驱动程序来解决这些问题,但是这需要不同的工具和代码。
在这篇文章中,我将展示如何在Snowflake中启动一个SFTP服务器,以允许直接通过SFTP访问Snowflake Stages。这现在可以利用Snowflake Container Services来实现。在这篇文章中,我将使用ngrok,但也可以与Ockam一起工作。这些服务是必要的,用于跨越您运行客户端的位置和Snowflake托管位置之间的网络边界。
如果你想跟着一起操作,你需要在ngrok注册一个账号,并且在Snowflake注册一个付费账户。在[Snowflake]有一个付费账户是访问其容器云服务所必需的。
在开始构建容器并启动服务之前,需要先做几件事:
这条 SQL 会满足所有这些要求。
使用角色 ACCOUNTADMIN; 创建角色 sftp_role,如果它不存在; 创建数据库 sftp_db,如果它不存在; 创建模式 sftp_schema,如果它不存在; 创建或替换网络规则 ngrok_egress_access 模式 = EGRESS 类型 = HOST_PORT 值列表 = ('connect.ngrok-agent.com:443', 'crl.ngrok-agent.com:80'); 创建或替换外部访问集成 ngrok_egress_access_integration 允许网络规则 = (ngrok_egress_access) 启用 = true; 将数据库 sftp_db 的所有权授予角色 sftp_role 并复制当前权限; 将模式 sftp_db.sftp_schema 的所有权授予角色 sftp_role 并复制当前权限; 授予角色 sftp_role 对外部访问集成 ngrok_egress_access_integration 的使用权限; 创建或替换仓库 sftp_warehouse 仓库大小='X-SMALL'; 授予角色 sftp_role 对仓库 sftp_warehouse 的使用权限; 创建计算池 sftp_compute_pool 最小节点数 = 1 最大节点数 = 1 实例类型 = CPU_X64_XS; 授予角色 sftp_role 对计算池 sftp_compute_pool 的使用和监控权限; 将角色 SFTP_ROLE 授予角色 ACCOUNTADMIN; 切换到角色 sftp_role; 使用数据库 sftp_db; 使用模式 sftp_schema; 使用仓库 sftp_warehouse; 创建镜像仓库 sftp_repository,如果它不存在; 创建或替换阶段 sftp_stage,加密设置为类型 'SNOWFLAKE_SSE'; 显示镜像仓库;
下一步是为sftp创建一个sftp容器。我选择以atmoz/sftp为基础,因为它看起来很受欢迎且易于使用。我制作了一个Dockerfile,基于该镜像,并添加了密钥,这样我就可以通过密钥对认证来访问SFTP用户。
# 从atmoz/sftp:latest拉取镜像 FROM atmoz/sftp:latest # 将公钥复制到指定目录 COPY sftp_host_rsa_key.pub /home/foo/.ssh/keys/sftp_host_rsa_key.pub # 设置权限为只读 RUN chmod 444 /home/foo/.ssh/keys/sftp_host_rsa_key.pub
密钥对是在构建脚本中生成的。除了构建之外,我还选择了上传。你会注意到我设置了一个环境变量,REPOSITORY_URL,将其设置为Snowflake之前创建的仓库URL。
#!/bin/bash if [ ! -f ./sftp_host_rsa_key ] then echo "生成SFTP服务器的密钥对..." ssh-keygen -b 4096 -t rsa -f ./sftp_host_rsa_key -N '' fi echo "正在构建SFTP服务器的镜像..." docker pull --platform linux/amd64 atmoz/sftp:latest # 拉取最新版的SFTP镜像... docker buildx build --platform linux/amd64 -t ${REPOSITORY_URL}/sftp:latest --push . # 构建并推送镜像...
我用的是 M2 Mac,因此我需要指定平台为 amd64 架构,因为 Snowflake 容器服务需要是 amd64 架构。
我还会创建一个容器来运行 ngrok,然后在这个服务中运行它。
我选择在这里基于 ngrok/ngrok 镜像构建一个自定义镜像,以便嵌入配置信息。
# 从 ngrok/ngrok:latest 拉取镜像 COPY ./ngrok.yml /etc/ngrok.yml # 复制配置文件到容器中指定位置 CMD [ "start", "--all", "--config", "/etc/ngrok.yml" ] # 启动 ngrok 并加载配置文件
我想让 ngrok.yml 文件被生成,所以我写了一个 bash 脚本。为了让它正常工作,你还需要设置环境变量 NGROK_AUTHTOKEN。
#!/bin/sh IP_ADDRESS=`curl ipinfo.io/ip` # 获取公共IP地址 cat ngrok.yml.tpl | sed "s/NGROK_AUTHTOKEN/$NGROK_AUTHTOKEN/g" | sed "s/IP_ADDRESS/$IP_ADDRESS/g" > ngrok.yml # 使用sed命令替换模板文件中的变量,并生成ngrok.yml文件 docker buildx build --platform linux/arm64/v8,linux/amd64 -t ${REPOSITORY_URL}/ngrok:latest --push . # 使用Docker构建并推送ngrok镜像
此脚本将变量插入到模板中,并保存以便在构建容器时使用。
这是未替换的模板版本。
version: 2 authtoken: NGROK_AUTHTOKEN log_level: debug log_format: json log: stdout tunnels: sftp: proto: tcp addr: localhost:22 # 请注意,IP 限制功能需要付费(示例:允许特定 IP 地址 /32)。 # ip_restriction: # allow_cidrs: [IP_ADDRESS/32]
我取消了 IP 限制的注释,因为免费账户无法使用这个功能……这次演示用密钥对认证就行了,但任何在生产环境里运行此程序的人都应该用付费订阅来进一步加强这个的安全性。
现在两张图片都已经上传了,我设置了这个服务。这些步骤是在Snowflake上运行的,以启动所有内容。
USE ROLE SFTP_ROLE; USE DATABASE SFTP_DB; USE SCHEMA SFTP_SCHEMA; CREATE SERVICE sftp_service IN COMPUTE POOL sftp_compute_pool FROM SPECIFICATION $ spec: containers: - name: sftp image: /sftp_db/sftp_schema/sftp_repository/sftp:latest args: - foo::1001 volumeMounts: - name: stage mountPath: /home/foo/stage - name: ngrok image: /sftp_db/sftp_schema/sftp_repository/ngrok:latest volumes: - name: stage source: "@SFTP_STAGE" $ EXTERNAL_ACCESS_INTEGRATIONS = (ngrok_egress_access_integration) MIN_INSTANCES=1 MAX_INSTANCES=1;
那之后,我能够在桌面上运行一个SFTP客户端软件,并使用由构建过程生成的密钥对连接到ngrok控制台提供的URL(该URL也在容器日志中给出)。我上传了一个文件,该文件被放入Snowflake存储阶段中,我能够将Snowflake表中的数据卸载到存储阶段,并轻松地提供给SFTP客户端。
那真的很有趣,也展示了Snowflake容器服务有多强大。它是一个非常强大的构建模块,你也许应该考虑用它来加速你的项目进程,并且让你能用你喜欢的工具和语言工作。
代码都在这里,链接是:here。
我很快会再写一篇文章,介绍如何使用Ockam在Snowflake Containers服务上搭建一个webdav服务器。