AWS Batch 시작

이거 뭐야?


좀 더 큰 일괄 처리를 위해 AWS Batch에 들어가 당시 조사한 것을 정리했다.주로 환경 구조 주위의 상황을 총결하였다.
해설에 나타난 모든 소스 코드는 여기에 요약되어 있으니 관심 있는 분들은 사용하세요.
yu-croco/sample_aws_batch_terraform

AWS Batchis란 무엇입니까?


AWS 공식 기준AWS Batch
AWS Batch를 사용하면 개발자, 과학자, 엔지니어가 AWS에서 수십만 개의 대량 계산 임무를 간단하고 효율적으로 수행할 수 있다.AWS Batch에서는 전송된 배치 작업의 양과 구체적인 리소스 요구에 따라 컴퓨팅 리소스(CPU 또는 메모리 최적화 인스턴스 등)의 최적 수량과 유형을 동적으로 제공합니다.
따라서 일괄 처리를 처리하는 자원을 제공한다.
그 밖에
AWS Batch에서는 AWS Fargate, Amazon EC2, 광점 인스턴스 등 광범위한 AWS 컴퓨팅 서비스와 기능이 배치 컴퓨팅 워크로드를 계획 및 스케줄링하고 실행됩니다.
따라서 EC2와 Fargate 등을 선택할 수 있습니다.

콘셉트


What Is AWS Batch?에 따르면 다음과 같은 개념이 있다.

Jobs


AWS Batch에 던지는 Job 단위입니다.셸 스크립트와 Docker container image 등은 그것과 맞먹는다.
Job은 EC2 또는 Fargate에서 컨테이너 자원으로 시작합니다.또한 Job은 특정 값을 지정하여 다른 Job을 참조할 수도 있으며, 어떤 Job의 성공을 통해 다른 Job을 수행할 수도 있습니다.

Job Definitions


Job의 시작 방법을 설정합니다(내부에서 ECS와 관련된 API를 이동하는 것 같습니다).
실행할 컨테이너에 필요한 메모리, CPU, 환경 변수 등을 지정하거나 IAM Role을 활용해 AWS 리소스 등에 접근할 수 있다.AWS Batch가 ECR에서 Docker pull을 실행할 때 이 곳에서 권한을 부여합니다.

Job Queues


AWS Batch에서 Job을 실행할 때, Job는Queue에 저장되며, 설정된 우선순위에 따라 처리됩니다.

Compute Environment


Job Definition을 실행하는 가상 환경을 정의합니다.EC2/Fargate와 같은 실례 유형(c5.2xlarge 등)과 vCPU 등 자원의 하한/상한 등을 설정합니다.

Terraform으로 구성해 볼게요.


테라폼 공식 샘플을 빌려 쓰면서 구성을 본다.
*subnet 등 인터넷 주위의 일은 모두 생략했으니 마음에 드는 사람은 한 번 보세요yu-croco/sample_aws_batch_terraform.개인적으로는 AWS Batch 자체의 자원 정의보다 인터넷 주변의 준비에 더 열중하고 있다.

job definition 주위


locals {
  job_definition = {
    command = ["echo", "hello world"],
    image = "alpine:latest",
    memory = 1024,
    vcpus = 1,
    "jobRoleArn": aws_iam_role.job_definition.arn,
  }
}

resource "aws_iam_role" "job_definition" {
  name = "aws-batch-job-role-${var.batch_name}"
  assume_role_policy = data.aws_iam_policy_document.assume_to_aws_batch.json
}

data "aws_iam_policy_document" "assume_to_aws_batch" {
  statement {
    effect = "Allow"
    actions = [
      "sts:AssumeRole",
    ]
    principals {
      type = "Service"
      identifiers = [
        "ecs-tasks.amazonaws.com",
      ]
    }
  }
}

// terraform applyの度に差分が出てversion更新されるので、運用のベスプラはちょっとわからない..
resource "aws_batch_job_definition" "job_definition" {
  name = "aws-batch-job-definition"
  type = "container"
  container_properties = data.template_file.job-definition.rendered
}

data "template_file" "job-definition" {
  template = jsonencode(local.job_definition)
}

컴퓨터 환경 주위


/*
 note: 仕様上、一度作成するとAMIが固定される。最新のAMIを適応するためにはコンピューティング環境を作り直す必要がある。
 https://docs.aws.amazon.com/ja_jp/batch/latest/userguide/compute_environments.html#managed_compute_environments
*/
resource "aws_batch_compute_environment" "aws-batch-computing-environment" {
  // ユニークである必要があるため、create_before_destroyのlife cycleで先に作成される
  // 新しいリソース名が既存のリソース名とかぶらないようにする必要がある。
  compute_environment_name = "aws-batch-compute-env"
  service_role = aws_iam_role.aws-batch-service-role.arn
  type = "MANAGED"
  state = "ENABLED"

  // 仕様上cpuとサービスロール以外はupdateができない
  // 指定値を変えるとaws_batch_compute_environmentがreplaceされる
  compute_resources {
    // 他にも色々ある https://docs.aws.amazon.com/ja_jp/batch/latest/userguide/allocation-strategies.html
    allocation_strategy = "BEST_FIT"
    instance_role = aws_iam_instance_profile.aws-batch-instance-role.arn
    instance_type = ["c4.large"]
    max_vcpus = 32
    min_vcpus = 0
    security_group_ids = [aws_security_group.aws_batch.id]
    subnets = var.subnets
    type = "EC2"
    // こうすることでAWS側での推奨AMIが更新されると自動でcompute environmentがreplaceされる
  }

  // 削除時に先にroleが削除され、コンピューティング環境の削除でスタックする。根本的な対処はちょっと謎..
  // https://github.com/hashicorp/terraform-provider-aws/issues/8549
  depends_on = [aws_iam_role.aws-batch-service-role]

  // ジョブキューはコンピューティング環境を最低限一つは指定する必要があるため、
  // replaceになる場合は `create_before_destroy` である必要がある
  lifecycle {
    create_before_destroy = true
  }
}

// AWS Batchのインスタンスが使用する
resource "aws_iam_role" "aws-batch-instance-role" {
  name = "${var.name}-aws-batch-instance-role"
  force_detach_policies = true
  assume_role_policy = data.aws_iam_policy_document.instance-assume-role.json
}

// ここにECRやCloudWatch周りの権限は含まれている
resource "aws_iam_role_policy_attachment" "aws-batch-instance-role" {
  role = aws_iam_role.aws-batch-instance-role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
}

resource "aws_iam_instance_profile" "aws-batch-instance-role" {
  name = "${var.name}-aws-batch-instance-profile"
  role = aws_iam_role.aws-batch-instance-role.name
}

data "aws_iam_policy_document" "instance-assume-role" {
  statement {
    actions = [
      "sts:AssumeRole"
    ]

    effect = "Allow"

    principals {
      type = "Service"
      identifiers = [
        "ec2.amazonaws.com",
      ]
    }
  }
}

// AWS Batchそのものが使用する
resource "aws_iam_role" "aws-batch-service-role" {
  name = "${var.name}-aws-batch-service-role"
  // ロールを破棄する前にロールが持つポリシーを強制に切り離す
  force_detach_policies = true
  assume_role_policy = data.aws_iam_policy_document.service-assume-role.json
}

resource "aws_iam_role_policy_attachment" "aws-batch-service-role" {
  role = aws_iam_role.aws-batch-service-role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSBatchServiceRole"
}

data "aws_iam_policy_document" "service-assume-role" {
  statement {
    actions = [
      "sts:AssumeRole",
    ]

    effect = "Allow"

    principals {
      type = "Service"
      identifiers = [
        "batch.amazonaws.com",
      ]
    }
  }
}

주위


resource "aws_batch_job_queue" "this" {
  name                 = var.name
  state                = "ENABLED"
  // 同じコンピューティング環境に複数job queueがある場合には、priorityの値が高いほうがより優先的に処理される
  priority             = 1
  compute_environments = var.compute_environment_arns
}

밀착점


Job은 Runnable로 쌓기


조사해 보니 aws batch 중 가장 많이 어울리는 곳인 것 같아요.
원인 사항은 Jobs Stuck in RUNNABLE Status로 정리되어 있으며, 여러 가지 가능성이 있을 수 있으며, 디버깅은 상당히 번거롭다.
이번에는 자신이 열중하고 있는 곳을 총결산해 보자.
* 다음과 같이 참고할 수 있다고 생각합니다.
  • AWS Batch 작업이 RUNNAMBLE 상태에서 중지되는 이유는 무엇입니까?
  • Troubleshooting AWS Batch
  • Compute 환경에서 ECS 서비스 endpoint에 액세스할 수 없습니다.


    다음과 같은 느낌으로 보면 계산 환경에서 ECS 서비스 endpoint에 접근해야 한다.
    No internet access for compute resources
    Compute resources need access to communicate with the Amazon ECS service endpoint. This can be through an interface VPC endpoint or through your compute resources having public IP addresses.
    For more information about interface VPC endpoints, see Amazon ECS Interface VPC Endpoints (AWS PrivateLink) in the Amazon Elastic Container Service Developer Guide.
    If you do not have an interface VPC endpoint configured and your compute resources do not have public IP addresses, then they must use network address translation (NAT) to provide this access. For more information, see NAT Gateways in the Amazon VPC User Guide. For more information, see Tutorial: Creating a VPC with Public and Private Subnets for Your Compute Environments.
    처리 방법은 다음과 같은 3가지가 있다.
    개인적으로 2. ECS Interface VPC Endpoints (AWS PrivateLink)を使用する가 좋을 것 같아요.ECR 등도 사용하고 저쪽도 프라이빗링크용 설정을 잘 하면 이쪽과 합쳐서 편하게 할 수 있을 것 같아요.

    1. 계산 환경이 설정된subnet에서 공용 IPv4 주소를 자동으로 분배할 수 있습니다


    AWS Batch 작업이 RUNNAMBLE 상태에서 중지되는 이유는 무엇입니까?에서 다음과 같은 설명은 거기에 부합되어야 한다고 생각합니다.
  • 컴퓨팅 환경의 각 서브넷에 대해 [설명]을 선택하고 [공용 IPv4 주소의 자동 할당] 속성의 값을 확인합니다.
  • 2. ECS Interface VPC Endpoint(AWS PrivateLink) 사용


    참조Amazon ECS interface VPC endpoints (AWS PrivateLink)는 다음 3개의 VPC Endpoint(PrivateLink)를 만들면 인터넷을 거치지 않고 AWS 내부의 통신을 통해 ECS 서비스 endpoint에 접근할 수 있다.
  • com.amazonaws.region.ecs-agent
  • com.amazonaws.region.ecs-telemetry
  • com.amazonaws.region.ecs
  • 3. Nat Gateway 사용


    참조Tutorial: Creating a VPC with Public and Private Subnets for Your Compute EnvironmentsNAT Gateway를 통해 ECS 서비스 endpoint에 액세스하는 느낌.
    그 결과 NAT Gateway뿐만 아니라 퍼블릭 subnetauto-assigned public IPv4 addresses이 엔블리해야 한다는 느낌(제대로 조사하지 못했다)??

    ComputeEnvironment는 기본적으로 Replace에 의해


    계산 환경의 규범상 cpu와 서비스 역할 이외의 변경은 Replace 처리가 된다.게다가 Job Quee는 컴퓨팅 환경과 연관이 있어야 하기 때문에 컴퓨팅 환경이 Replace에 의해 저하될 수 있습니다.
    따라서 컴퓨팅 환경create_before_destroy = true에 라이프사이클을 추가하여 Job Queue와 연관된 컴퓨팅 환경을 확보합니다.

    기타 TIPS

  • 계산 환경 실례 유형은 뒤이어 바꿀 수 없습니다
  • 변경 시 리플렉스를 통해 새로운 것이 일어난다.job queue는 컴퓨터입니다.환경 의존 때문에 컴퓨터환경 측면에서 설정된 라이프스케일은 나무랄 데가 없는 것 같다
  • [AWS Batch] Terraform 고육계는 계산 환경의 실례 유형을 뒤에서 변경합니다
  • 잡감

  • AWS Batch의 기능 자체는 대단하지만 자원 준비는 힘들다.
  • 내부에서 다른 서비스를 사용하는 경우도 있고 한 번의 이동을 위해 준비한 자원이 많다
  • 앙증맞다온통 퍼블릭 subnet을 전제로 한 글들로, 몰입create_before_destroy = true을 해소하느라 힘들었다.
  • 디테일에 결함이 있음
  • 참고 자료

  • Resource: aws_batch_compute_environment
  • Resource: aws_batch_job_definition
  • Resource: aws_batch_job_queue
  • AWS 재입문 블로그 릴레이 AWS Batch 편
  • AWS Batch 소개
  • Terraform, AWS Batch, and AWS EFS
  • Jobs Stuck in RUNNABLE Status
  • 좋은 웹페이지 즐겨찾기