概述

在使用 Amazon Glue 进行大数据处理时,我们经常需要安装额外的 Python 包。由于安全和网络限制,直接从公共 PyPI 安装可能不可行。或者即便配置了国内镜像源,也可能会因为镜像源的不稳定或网络波动导致安装失败从而导致Job失败。本文将介绍如何创建私有 Python 包仓库,并在 Glue Job 中使用这些私有包。

先决条件

  1. 账号备案:确保 AWS 账号已完成相关备案
  2. Glue Job 关联 Connection:配置正确的网络连接
  3. S3 Endpoint 配置:确保 VPC 中有访问 S3 的端点
  4. 桶策略配置:允许来自指定 VPC Endpoint 的请求

实施步骤

1. 创建包列表文件

首先创建需要安装的包列表:

vim modules_to_install.txt

文件内容示例:

azure-storage-blob
azure-core
cryptography

2. 编写部署脚本

创建部署脚本 script_S3URL.sh

#!/bin/bash
set -ex
# 安装必要的依赖
yum -y install gcc python3-devel python3

# 创建虚拟环境
python3 -m venv wheel-env
source wheel-env/bin/activate

# 安装打包工具
pip install wheel
mkdir wheelhouse cache

# 构建 wheel 包
cd cache
for f in $(cat /tmp/modules_to_install.txt); do pip wheel $f -w ../wheelhouse; done
cd ..

# 设置变量
set -euo pipefail
BUCKET=$1; PREFIX=${2:-}; REGION=$3; RECURSIVE_FLAG="--recursive"
TMP=$(mktemp)
INDEX=index.html

# 同步到 S3
aws s3 sync ./wheelhouse/ "s3://${BUCKET}/${PREFIX}/wheelhouse"

# 生成每个对象的S3 URL地址
aws s3 ls "s3://${BUCKET}/${PREFIX}/wheelhouse" $RECURSIVE_FLAG \
  | awk 'NF>=4 && $NF !~ /\/$/ {print $NF}' \
  | while read -r KEY; do
      echo "https://${BUCKET}.s3.${REGION}.amazonaws.com.cn/${KEY}"
    done > "$TMP"

# 生成 HTML 索引文件
{
  echo 'LinksLinks'
  while IFS= read -r url; do
    url_no_q=${url%%\?*}
    f=${url_no_q##*/}
    echo "$f"
  done < "$TMP"
  echo ''
} > "$INDEX"

rm "$TMP"
echo "Done! $INDEX 已生成,共 $(grep -c '<a href' "$INDEX") 个链接。"

# 上传索引文件
aws s3 cp ./index.html "s3://${BUCKET}/${PREFIX}/index.html"
echo "https://${BUCKET}.s3.${REGION}.amazonaws.com.cn/${PREFIX}/index.html"

# 清理环境
deactivate
rm -rf cache wheel-env
exit

3. 运行 Docker 容器构建包

根据 Glue 版本选择对应的镜像:

docker run --user root \
-v "$PWD":/tmp \
-v /home/ec2-user/.aws:/root/.aws \
public.ecr.aws/glue/aws-glue-libs:5 \
/tmp/script_S3URL.sh menglonq tmp/wheel-env cn-north-1

Tips: script_S3URL脚本的3个参数分别是 桶名 perfix region 注意perfix后面不要写/号。另外,需要运行环境可以访问国外的ecr镜像源,本测试环境是香港的EC2。

不同 Glue 版本对应的镜像:

  • Glue 5.0: public.ecr.aws/glue/aws-glue-libs:5

  • Glue 4.0: public.ecr.aws/glue/aws-glue-libs:glue_libs_4.0.0_image_01

  • Glue 3.0: public.ecr.aws/glue/aws-glue-libs:glue_libs_3.0.0_image_01

  • Glue 2.0: public.ecr.aws/glue/aws-glue-libs:glue_libs_2.0.0_image_01

在输出中找到index.html对象的URL地址,后面–find-links会用到。

4. 配置 S3 桶策略

确保桶策略允许来自 VPC Endpoint 的访问:

{
    "Sid": "Statement1",
    "Effect": "Allow",
    "Principal": "*",
    "Action": "s3:*",
    "Resource": [
        "arn:aws-cn:s3:::menglonq",
        "arn:aws-cn:s3:::menglonq/*"
    ],
    "Condition": {
        "StringEquals": {
            "aws:SourceVpce": "vpce-xxxxxxxx"
        }
    }
}

5. 在 Glue Job 中使用私有包

在 Glue Job 配置中添加以下参数:

  • --additional-python-modules:
    azure-storage-blob,azure-core,cryptography

  • --python-modules-installer-option:
    --no-index --find-links=https://menglonq.s3.cn-north-1.amazonaws.com.cn/tmp/wheel-env/index.html --trusted-host s3.cn-north-1.amazonaws.com.cn

技术要点

  1. 环境一致性:使用与 Glue 相同版本的 Docker 镜像确保环境一致性
  2. 安全访问:通过 VPC Endpoint 限制 S3 访问,增强安全性
  3. 离线安装:预先构建 wheel 包,避免运行时下载
  4. 索引生成:自动生成包索引文件,方便包管理

总结

通过本文介绍的方法,可以有效地在 Amazon Glue Job 中使用私有 Python 包仓库。这种方法不仅提高了安全性,还确保了依赖包的一致性和可靠性,特别适用于有严格网络限制的企业环境。

实际部署时,建议将这一过程集成到 CI/CD 流水线中,实现依赖包的自动更新和部署。

更多推荐