본문 바로가기
AWS

AWS Batch와 EKS(k8s)를 사용하여 배치를 돌려보자

by parkjp 2024. 1. 29.

목차

 

  1. 필수 조건 체크 

  2. EKS 클러스터 생성 

  3. 배치 인스턴스 전용 네임스페이스 생성

  4. 역할 기반 엑세스 제어(RBAC)를 통한 엑세스 활성화

  5. GPU 노드를 위한 NVIDIA 플러그인 설치 (GPU Node Only)
  6. AWS Batch 컴퓨팅 환경 생성
  7. 작업 대기열 생성 및 컴퓨팅 환경 연결

  8. 작업 정의 생성

  9. 작업 제출(시작)
반응형

1. 필수 조건 체크

AWS Batch를 EKS로 돌리려면 여타 체크해야 할 부분들이 있다.

우선 작성 시점 문서에서는 아래와 같이 제시하고 있다.

 

  • aws cli 2.8.6 버전 이상 또는 1.26.0 이상
  • kubectl 1.23 버전 이상
  • eksctl 0.115.0 버전 이상
  • 사용하는 IAM 보안 주체에는 EKS IAM 역할 및 서비스 연결 역할, CloudFormation, VPC 및 관련 리소스를 사용할 수 있는 권한 필요
  • 현재 블로그 작성시점에 AWS Batch에서 지원하는 EKS 클러스터 버전이 문서에 1.27까지만 나와있다. 1.28이상으로 해보진 않아서 모르겠지만 필자는 1.27버전으로 진행하였다.

 

2. EKS 클러스터 생성

 

EKS 클러스터는 콘솔에서도 간단하게 할 생성할 수 있고 eksctl 커맨드로도 생성할 수 있다.

 

콘솔에서 클러스터를 생성할 때 클러스터 IAM 역할을 생성해야하는데 

AmazonEKSClusterPolicy라는 관리형 정책을 가진 역할을 만들어 연결하면 된다.

 

아래는 eksctl 커맨드로 클러스터를 생성하는 방법이다.

https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html

 

Getting started with Amazon EKS – eksctl - Amazon EKS

To get started as simply and quickly as possible, this topic includes steps to create a cluster and nodes with default settings. Before creating a cluster and nodes for production use, we recommend that you familiarize yourself with all settings and deploy

docs.aws.amazon.com

 

클러스터를 만든 후 local에 kubeconfig를 등록해주고 진행하자.

 

3. 배치 인스턴스 전용 네임스페이스 생성

 

아래와 같이 yml파일을 만들고 kubectl apply -f ${your-yml-file-path}로 네임스페이스를 생성한다.

네임스페이스 이름은 각자 지어주자.

apiVersion: v1,
kind: Namespace
metadata:
  name: ${namespace}
  labels:
    name: ${namespace}

 

 

 

4. 역할 기반 엑세스 제어(RBAC)를 통한 엑세스 활성화

 

AWS Batch가 노드와 포드를 감시하도록 하는 클러스터에 대한 Kubernetes 역할을 생성하고 역할을 바인딩해보자.

아래 작업은 각 EKS 클러스터마다 한 번씩 수행해야 한다.

 

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ${aws-batch-cluster-role}
rules:
  - apiGroups: [""]
    resources: ["namespaces"]
    verbs: ["get"]
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["daemonsets", "deployments", "statefulsets", "replicasets"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["rbac.authorization.k8s.io"]
    resources: ["clusterroles", "clusterrolebindings"]
    verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ${aws-batch-cluster-role-binding}
subjects:
- kind: User
  name: ${aws-batch}
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: ${aws-batch-cluster-role}
  apiGroup: rbac.authorization.k8s.io

 

마찬가지로 kubectl apply -f ${your-yml-file-path}로 role을 생성하고 바인딩하자.

 

위 작업을 했다면

포드를 관리하고 수명 주기를 관리할 AWS Batch에 대한 네임스페이스 범위 Kubernetes 역할을 생성하고 바인딩하자.

이 작업은 각 고유 네임스페이스마다 한 번씩 수행해야 한다.

 

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: ${aws-batch-compute-environment-role}
  namespace: ${namespace}
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["create", "get", "list", "watch", "delete", "patch"]
  - apiGroups: [""]
    resources: ["serviceaccounts"]
    verbs: ["get", "list"]
  - apiGroups: ["rbac.authorization.k8s.io"]
    resources: ["roles", "rolebindings"]
    verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ${aws-batch-compute-environment-role-binding}
  namespace: ${namespace}
subjects:
- kind: User
  name: ${aws-batch}
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: ${aws-batch-compute-environment-role}
  apiGroup: rbac.authorization.k8s.io

 

${namespace}는 위에서 생성한 네임스페이스 이름으로 해야한다.

마찬가지로 kubectl apply -f ${your-yml-file-path}로 role을 생성하고 바인딩하자.

 

위 작업까지 다 되었다면 eks aws-auth 구성 맵을 업데이트하여 RBAC 권한을 AWS Batch 서비스 연결 역할에 매핑해야한다. 

기존에는 eks-node-role만 configMap에 등록이 되어있을텐데

(만약 안되어있다면 아래 전체를 등록하자)

아래와 같이 AWSServiceRoleForBatch역할을 추가해 주자.

- rolearn: arn:aws:iam::${your-account-id}:role/${your-eks-node-role}
  username: system:node:{{EC2PrivateDNSName}}
  groups:
    - system:bootstrappers
    - system:nodes
- rolearn: arn:aws:iam::${your-account-id}:role/AWSServiceRoleForBatch
  username: ${aws-batch}

 

 

5. GPU 노드를 위한 NVIDIA 플러그인 설치

 

GPU를 가진 노드를 돌릴게 아니라면 6번 목차로 넘어가면 된다.

 

아래 yml파일을 받아서 적용해야한다.

https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.12.2/nvidia-device-plugin.yml

 

적용하기 전에 아래 부분을 꼭 추가하고 적용하자.

- key: batch.amazonaws.com/batch-node
  operator: Exists

 

kubectl apply -f nvidia-device-plugin.yml 커맨드 실행.

 

 

6. AWS Batch 컴퓨팅 환경 생성

 

컴퓨팅 환경 생성은 aws 콘솔에서 진행해보도록 하겠다.

여기서부터는 아주 간단하다.

콘솔에서 AWS Batch를 검색하여 왼쪽 메뉴를 보면 컴퓨팅 환경이라고 보인다.

생성을 눌러주자.

AWS Batch Compute Environment

 

위 목차에서 생성한 EKS 클러스터를 선택해주고 마찬가지로 위에서 생성한 네임스페이스를 입력해 주자.

다음 단계에서 원하는 인스턴스와 네트워크 구성을 해주고 마치면 된다.

 

7. 작업 대기열 생성 및 컴퓨팅 환경 연결

 

작업 대기열을 생성할 때 위에서 생성한 컴퓨팅 환경을 선택하여 연결시켜야 한다.

 

AWS Batch Job Queue

 

마우스로 간단하게 선택하고 클릭하여 생성하자.

 

8. 작업 정의 생성

 

작업 정의는 배치를 돌릴 인스턴스에 어떤 도커 이미지를 가져와 실행할 것인지 정할 수 있고,

어떤 파라미터를 받을 것인지 정할 수 있다.

 

GPU가 없는 노드를 실행하려면 콘솔에서 진행하면 되지만

GPU를 가진 노드를 실행하려면 콘솔에서는 gpu를 몇개를 쓸 것인지 정하는 부분이 없어서 콘솔로 진행하면 안된다.

AWS 문서에서 제시하는 예시를 보자.

 

./batch-eks-gpu-jd.json

{
    "jobDefinitionName": "MyGPUJobOnEks_Smi",
    "type": "container",
    "eksProperties": {
        "podProperties": {
            "hostNetwork": true,
            "containers": [
                {
                    "image": "nvcr.io/nvidia/cuda:10.2-runtime-centos7",
                    "command": ["nvidia-smi"],
                    "resources": {
                        "limits": {
                            "cpu": "1",
                            "memory": "1024Mi",
                            "nvidia.com/gpu": "1"
                        }
                    }
                }
            ]
        }
    }
}

aws batch register-job-definition --cli-input-json file://./batch-eks-gpu-jd.json

 

위 예시를 보고 각자에 맞춰서 생성하면 되겠다.

 

9. 작업 제출 (작업 시작)

 

작업을 시작하는 부분은 각 언어별 SDK로 진행을 해도 되고 커맨드로 진행을 해도 된다.

 

aws batch submit-job --job-queue ${your-job-queue} 
  --job-definition ${your-job-definition} --job-name ${job-name}

 

 

반응형