在本节中,我们将使用 AWS Batch 从 S3 中提取图像,从中创建动画 GIF 视频,然后将结果上传回 S3。
具体来说,我们将:
Job Definition
。将需要一个 S3 存储桶来存储源图像和结果动画 GIF:
export BUCKET_NAME=batch4eks-$(uuidgen --random | cut -d'-' -f1)
echo "export BUCKET_NAME=${BUCKET_NAME}" | tee -a ~/.bash_profile
aws s3 mb s3://${BUCKET_NAME}
cat << EOF
***** Take Note of Your Bucket Name *****
Bucket Name = ${BUCKET_NAME}
*****************************************
EOF
在本章中,我们将创建容器 Dockerfile 配置文件,其中安装了所有必需的软件包。
创建ECR
:
export ECR_REPO_NAME_GIF=eks-make-gif-$(uuidgen --random | cut -d'-' -f1)
echo "export ECR_REPO_NAME_GIF=${ECR_REPO_NAME_GIF}" | tee -a ~/.bash_profile
aws ecr create-repository \
--repository-name ${ECR_REPO_NAME_GIF} \
--image-scanning-configuration scanOnPush=true \
--region ${AWS_REGION}
将repositoryUri
的值保存到的 Bash 环境和 Bash 配置文件中:
export ECR_REPO_GIF="${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO_NAME_GIF}"
echo "export ECR_REPO_GIF=${ECR_REPO_GIF}" >> ~/.bash_profile
创建一个用于存放 Dockerfile 的项目目录:
mkdir make-gif
cd make-gif
创建一个脚本来下载图片,并将其推送到 S3 存储桶中。它需要两个位置参数:图像的源 URL;以及 GIF 的输出位置:
cat > copy-to-s3.sh <<EOF
#!/bin/bash
# make a temp directory for this job
tmp_dir=\$(mktemp -d -t copy-to-s3-XXXXXXXXXX)
cd \$tmp_dir
# pull pictures from source
curl -o src_image "\$1"
# upload to given S3 key
aws s3 cp src_image "\$2"
EOF
创建一个脚本来收集源图像并生成动画 GIF,然后将其上传到 S3 存储桶中。它将使用上面两个位置参数:
cat > make-gif.sh <<EOF
#!/bin/bash
# make a temp directory for this job
tmp_dir=\$(mktemp -d -t make-gif-XXXXXXXXXX)
cd \$tmp_dir
# pull pictures from S3 source
aws s3 sync \$1 .
# create the gif
convert -delay 50 -loop 0 * movie.gif
# upload it back to s3
aws s3 cp movie.gif \$2
EOF
使脚本可执行:
chmod +x *.sh
为容器创建 Dockerfile:
echo 'FROM public.ecr.aws/amazonlinux/amazonlinux:latest
RUN yum install -y ImageMagick unzip glibc-devel less groff
RUN cd /tmp &&\
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
unzip awscliv2.zip && \
./aws/install
COPY copy-to-s3.sh /usr/local/bin/copy-to-s3.sh
COPY make-gif.sh /usr/local/bin/make-gif.sh
' > Dockerfile
现在应该有一个如下所示的目录:
make-gif/
├── copy-to-s3.sh
├── Dockerfile
└── make-gif.sh
构建容器并将其推送到 ECR:
echo "Logging in to ECR..."
aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
echo "Build started on `date`"
echo "Building the Docker image..."
docker build -t $ECR_REPO_NAME_GIF:latest .
docker tag $ECR_REPO_NAME_GIF:latest $ECR_REPO_GIF:latest
echo "Build completed on `date`"
echo "Pushing the Docker image..."
docker push $ECR_REPO_GIF:latest
现在,在私有 ECR 存储库中拥有一个可访问的工作容器,可以在批处理作业中使用。
Batch任务的Pod将需要访问S3和 ECR。本节我们将使用IRSA实现
获取提供的用于访问 S3 和 ECR 的policy文档:
curl 'https://pingfan.s3.amazonaws.com/files/ecr-s3-access-iam-policy.json' --output ecr-s3-access-iam-policy.json
创建policy并将 ARN 存储在环境变量中
export BATCH_EKS_S3ECR_POLICY_ARN=$(aws iam create-policy --policy-name "ecr-s3-access-iam-policy" --policy-document file://./ecr-s3-access-iam-policy.json --output text --query Policy.Arn)
创建 IAM 角色并使用eksctl
将其与 Kubernetes Service Account
关联:
export BATCH_EKS_S3ECR_SA="${BATCH_EKS_CLUSTER_NAME}-s3ecr-sa"
export BATCH_EKS_S3ECR_ROLE="${BATCH_EKS_CLUSTER_NAME}-s3ecr-role"
eksctl create iamserviceaccount --name ${BATCH_EKS_S3ECR_SA} \
--namespace ${BATCH_EKS_NAMESPACE} \
--cluster ${BATCH_EKS_CLUSTER_NAME} \
--role-name ${BATCH_EKS_S3ECR_ROLE} \
--attach-policy-arn ${BATCH_EKS_S3ECR_POLICY_ARN} \
--approve
将这些值保存在的 Bash 配置文件中以供以后使用:
echo "export BATCH_EKS_S3ECR_SA=${BATCH_EKS_S3ECR_SA}" >> ~/.bash_profile
echo "export BATCH_EKS_S3ECR_ROLE=${BATCH_EKS_S3ECR_ROLE}" >> ~/.bash_profile
echo "export BATCH_EKS_S3ECR_POLICY_ARN=${BATCH_EKS_S3ECR_POLICY_ARN}" >> ~/.bash_profile
结果如下: