DAGパイプラインとJobの距離を測る
한국어 원문으로 표시합니다.
목표
Argo Workflows 의 DAG·아티팩트·템플릿 재사용을 매니페스트로 표현하고, 같은 일을 쿠버네티스 Job 과 CronJob 으로도 실제로 올려 두 모델의 표현력 차이를 눈으로 확인합니다.
왜 중요한가
Workflows 를 도입할지 판단하려면 Job 으로 어디까지 되는지 알아야 합니다. Job 은 재시도(backoffLimit)와 병렬(parallelism)까지는 표현하지만 작업 사이의 의존성과 파일 전달은 표현하지 못합니다. 그래서 Job 만 쓰는 조직은 결국 컨테이너 하나에 셸 스크립트를 몰아넣거나 클러스터 밖 오케스트레이터에 순서를 맡기게 되고, 두 방법 모두 실패 지점을 잃습니다. 이 실습에서 두 매니페스트를 나란히 만들어 보면 그 경계선이 어디인지 손에 남습니다.
단계
/root/capa-wf/디렉터리를 만들고workflow.yaml에 apiVersionargoproj.io/v1alpha1, kindWorkflow,metadata.namecapa-build,spec.entrypointmain을 쓰세요.spec.templates에는 name 이main인 템플릿이 있어야 합니다.main템플릿에dag.tasks를 만들고checkout,build,test세 태스크를 넣으세요.build는checkout에,test는build에 의존하게 하고checkout에는 dependencies 를 붙이지 마세요.spec.templates에 name 이build인 템플릿을 두고,inputs.parameters에 이름이revision인 파라미터를,outputs.artifacts에 이름이binary이고 path 가/out/app인 아티팩트를 선언하세요./root/capa-wf/cronworkflow.yaml에 kindCronWorkflow,metadata.namecapa-nightly,spec.schedule0 3 * * *,spec.concurrencyPolicyForbid,spec.workflowSpec.entrypointmain을 쓰세요./root/capa-wf/workflowtemplate.yaml에 kindWorkflowTemplate,metadata.namecapa-common을 쓰고 그 안에 name 이notify인 템플릿을 두세요. 그리고workflow.yaml의maindag 에notify태스크를 추가하되templateRef.name은capa-common,templateRef.template은notify, dependencies 는test로 하세요.- 클러스터에 네임스페이스
capa-wf를 만들고 그 안에 Jobcapa-build-job을 실제로 만드세요.spec.backoffLimit은2, 파드의restartPolicy는Never, 컨테이너 이미지는busybox:1.36입니다. - 같은 네임스페이스에 CronJob
capa-nightly-job을 실제로 만드세요.spec.schedule은0 3 * * *,spec.concurrencyPolicy는Forbid,spec.successfulJobsHistoryLimit은1입니다. - 같은 네임스페이스에 컨피그맵
capa-wf-summary를 실제로 만드세요. 키dag-tasks에는workflow.yaml의maindag 태스크 개수를, 키cron-schedule에는cronworkflow.yaml의 schedule 값을, 키job-name에는capa-build-job을 넣으세요.
참고
kubectl create job capa-build-job --image=busybox:1.36 -n capa-wf --dry-run=client -o yaml로 뼈대를 뽑은 뒤 backoffLimit 을 채우면 빠릅니다.- dag 태스크 개수는
yq '.spec.templates[] | select(.name == "main") | .dag.tasks | length' /root/capa-wf/workflow.yaml로 셀 수 있습니다. - 흔한 실수 1: CronWorkflow 안에 Workflow 의 spec 필드를 바로 쓰는 것. 한 단계 감싸는 필드가 있습니다.
- 흔한 실수 2: 크론 표현식에 공백이 들어간 문자열을 따옴표 없이 쓰는 것. YAML 에서 따옴표로 감싸세요.
Workflow 골격과 entrypoint
/root/capa-wf/ 디렉터리를 만들고 workflow.yaml 에 apiVersion argoproj.io/v1alpha1, kind Workflow, metadata.name capa-build, spec.entrypoint main 을 쓰세요. spec.templates 에는 name 이 main 인 템플릿이 있어야 합니다.
entrypoint 는 templates 배열 안에 있는 템플릿의 name 을 가리킵니다. 가리키는 이름이 실제로 존재하지 않으면 워크플로는 시작조차 하지 못합니다.
의존성 그래프 그리기
main 템플릿에 dag.tasks 를 만들고 checkout, build, test 세 태스크를 넣으세요. build 는 checkout 에, test 는 build 에 의존하게 하고 checkout 에는 dependencies 를 붙이지 마세요.
dag.tasks 의 각 항목은 name 과 template(또는 templateRef), 그리고 dependencies 를 가집니다. 그래프의 시작 노드에는 dependencies 를 붙이지 않습니다.
파라미터와 아티팩트
spec.templates 에 name 이 build 인 템플릿을 두고, inputs.parameters 에 이름이 revision 인 파라미터를, outputs.artifacts 에 이름이 binary 이고 path 가 /out/app 인 아티팩트를 선언하세요.
parameters 는 문자열, artifacts 는 파일입니다. 출력 아티팩트에는 이름과 컨테이너 안 경로가 함께 필요합니다.
CronWorkflow 로 주기 실행
/root/capa-wf/cronworkflow.yaml 에 kind CronWorkflow, metadata.name capa-nightly, spec.schedule 0 3 * * *, spec.concurrencyPolicy Forbid, spec.workflowSpec.entrypoint main 을 쓰세요.
CronWorkflow 는 Workflow 의 spec 을 통째로 한 필드 아래에 품습니다. 그 필드 이름을 찾는 것이 이 단계의 절반입니다.
WorkflowTemplate 재사용
/root/capa-wf/workflowtemplate.yaml 에 kind WorkflowTemplate, metadata.name capa-common 을 쓰고 그 안에 name 이 notify 인 템플릿을 두세요. 그리고 workflow.yaml 의 main dag 에 notify 태스크를 추가하되 templateRef.name 은 capa-common, templateRef.template 은 notify, dependencies 는 test 로 하세요.
templateRef 는 어느 오브젝트의(name) 어느 템플릿을(template) 쓸지 두 값을 모두 필요로 합니다. 이 태스크도 그래프의 일부이므로 선행 조건을 걸어야 합니다.
같은 일을 하는 Job 을 실제로 올리기
클러스터에 네임스페이스 capa-wf 를 만들고 그 안에 Job capa-build-job 을 실제로 만드세요. spec.backoffLimit 은 2, 파드의 restartPolicy 는 Never, 컨테이너 이미지는 busybox:1.36 입니다.
Job 파드의 restartPolicy 는 Always 를 쓸 수 없습니다. 재시도 횟수는 파드가 아니라 Job 스펙의 필드 하나로 정합니다.
CronJob 으로 같은 주기 표현하기
같은 네임스페이스에 CronJob capa-nightly-job 을 실제로 만드세요. spec.schedule 은 0 3 * * *, spec.concurrencyPolicy 는 Forbid, spec.successfulJobsHistoryLimit 은 1 입니다.
CronJob 에도 동시 실행 정책이 있습니다. 기록 보존 개수를 정하는 필드가 성공과 실패 각각 따로 있다는 점도 확인하세요.
파일과 클러스터를 잇는 요약
같은 네임스페이스에 컨피그맵 capa-wf-summary 를 실제로 만드세요. 키 dag-tasks 에는 workflow.yaml 의 main dag 태스크 개수를, 키 cron-schedule 에는 cronworkflow.yaml 의 schedule 값을, 키 job-name 에는 capa-build-job 을 넣으세요.
앞 단계에서 만든 파일에서 값을 뽑아야 합니다. yq 로 뽑은 결과를 그대로 컨피그맵 값으로 넣으면 되고, 손으로 세도 됩니다.