yml 파일을 잘 다뤄보자

yml 파일을 잘 다뤄보자

yml파일을 갖고 놀아보자

Yaml

YAMLXML, C, 파이썬, , RFC2822에서 정의된 e-mail 양식에서 개념을 얻어 만들어진 ‘사람이 쉽게 읽을 수 있는’ 데이터 직렬화 양식이다. 2001년에 클라크 에반스가 고안했고, Ingy dot Net 및 Oren Ben-Kiki와 함께 디자인했다. 위키백과

YAML의 이름은 YAML Ain’t Markup Language 라는 이름에서 유래되었고 원래의 뜻은 Yet Another Markup Language로 또 다른 마크업 언어였으나, 핵심은 문서 마크업이 아닌 데이터 중심에 있습니다. XML과 Json이 데이터 직렬화에 주로 사용되고 있는데, 많은 사람들이 YAML을 가벼운 마크업 언어로 사용하려고 하고 있습니다.

yaml이 있는데 yml은 뭐지?

yaml은 공식 확장자이며 그 외의 확장자로 yml도 사용됩니다. 옛날에는 파일의 확장자 길이가 3자로 제한되었기 때문에 3글자 확장자 스타일을 고수하는 사람들 때문에 yml파일 확장자가 보이는 것 같습니다.

왜 YAML을 사용할까?

yaml을 사용하는 이유는 간단합니다. 한 파일에서 모든 configuration을 관리하기 위해서 입니다. 혹시 yaml을 잘 접해보지 못하신 분들이 있다면, 블로그 파일구조를 살펴보면 좋을 것 같습니다. 저의 경우는 hexo를 사용하고 있는데, icarus theme를 들어가 보면 _config.yml파일로 이 테마의 구성요소를 관리할 수 있는 파일이 있습니다. 이 파일을 통해 글또 아이콘을 등록한다던가 category페이지를 오른쪽이나 왼쪽으로 옮기는 등의 작업을 간단하게 처리할 수 있습니다.

이것을 실무에도 적용하고 있는데, 저희 회사의 경우에는 Airflow의 추천 DAG와 Segmentation DAG들을 한 파일로 관리하기 위해 yaml파일을 만들어서 처리하고 있습니다. 고객사에 대한 정보와 고객사에 필요한 서버의 스펙이나 작업 메모리들을 yaml에 넣어서 굉장히 편리하게 작업 및 세부 리소스들을 관리할 수 있게 되었습니다. yaml과 github action 그리고 쉘 스크립트 등을 이용해서 작업을 하고 있는데, 기회가 되면 더 자세하게 소개해보도록 하겠습니다. 다른 회사의 경우에는 일반적으로 등장하는 것이 아마 kubernetes일 것입니다. kubernetes에서는 대부분의 정보를 yaml파일로 만들어서 kubectl에 제공합니다. 저희가 실무에서 사용하는 것과 비슷하게 kubernetes에서도 편리하게 컨테이너 이미지나 기타 설정을 편리하게 할 수 있겠습니다.

YAML 문법

YAML은 기본적으로 사람 눈으로 보기가 편합니다. 간단한 문법을 익히고 난다면, python 코드나 다른 코드들에 비해서 가독성이 훨씬 좋아 눈으로 어떤 작업을 할지 알아보기가 더 좋을 것이라고 생각됩니다. 그러면 yaml 문법들을 살펴보겠습니다!

주석과 기본 문법

yaml은 python과 마찬가지로 #을 주석을 다는 문자로 사용합니다. 코드 앞에 #표시를 해주면 그 라인은 읽지 않습니다. 또한 python과 비슷하게 indentation에 민감합니다. 파이썬에서는 tab(space 4번)을 주로 사용하지만 yaml에서는 기본이 스페이스바 두 번 입니다. 기본적인 문법은 쿠버네티스 안내서 에 너무 잘 정리가 되어있어서, 링크로 대체하겠습니다. 한 번 읽고 스크롤을 내려주시면 감사하겠습니다.

리스트

1
2
3
4
5
6
--- # block format
- apple
- banana
- kiwi
--- #inline format
[apple, banana, kiwi]

리스트의 형식은 두 가지로 나뉘어 집니다. block format과 inline format입니다. 저는 사실 이 포맷을 굉장히 오래 전 부터 봐왔습니다. hexo로 포스팅을 하다보면, 맨 위에 사이드 바나 태그, 카테고리를 정하는 부분이 있는데, 이 부분이 바로 yaml의 리스트 형식을 사용하고 있습니다.

hexo-yaml

예전에는 뭔지도 모르고 사용했었는데, 다시 살펴보니 구조가 눈에 들어오기 시작합니다.

해시

1
2
3
4
5
--- # Block
name: sanghyub
age: 29
--- # Inline
{name: sanghyub, age: 29}

해시는 키-밸류 구조라고 보시면 됩니다. 이것도 역시 Block, Inline방식이 있습니다. 저는 개인적으로 Block방식을 선호해서 주로 사용하고 있는데, 편한 걸 사용하시면 됩니다.

리스트와 해시

1
2
3
4
men: [sanghyub, lee]
women:
- sanghyub
- lee

만약 키에 여러 값들을 넣고 싶다면 위와 같은 방식으로 넣을 수 있습니다.

해시의 리스트

1
2
3
4
5
6
7
8
-
name: messi
assists: 61
goals: 99
-
name: Son
assists: 77
goals: 100

반대로 하고 싶다면 이런 방식을 사용하면 됩니다. 이해하기 어렵다면, 직접 파일을 만들어서 확인해보겠습니다.

python으로 값을 확인해보자

python으로 pyyaml을 불러와서 확인해보면 값이 위와 같이 들어가 있는 것을 확인해 볼 수 있습니다.

상속

yaml에서 재밌는 부분은 상속에 대한 부분입니다. 사실 이번 포스팅에서 주로 다루고 싶었던 것이기도 합니다. 위에서 말한 프로젝트를 진행했을 때에도, 이 상속을 처음 접하고 적용했습니다. 물론 처음엔 좀 헷갈렸지만 응용하면 코드를 적을 양이 효과적으로 줄어드는 것을 체감하실 수 있을 것입니다. 상속에서 중요한 것은 상속에 대한 문자와 Alias입니다. 미리 정한 양식에 별명을 붙이고 그 별명 붙인 것을 불러오면 내용을 그대로 사용할 수 있습니다. 굳이 똑같이 따라 칠 필요가 없어지는 것입니다.

Alias

1
2
3
b-anchor: &name value

b-alias: *name

별명은 굉장히 간단합니다. &로 별명을 붙여주면 끝입니다! 불러올 때는 *를 이용해서 값을 불러올 수 있습니다.

상속(<<)

1
2
3
4
5
6
7
8
9
maltese: &dog
cute: true
bark: "bow-wow"
jindol:
<<: *dog
nationality: "korea"
pug:
<<: *dog
ugly: true

위의 예시를 사용해서 상속의 종합적인 설명을 해보겠습니다. 말티즈라는 키에 여러 값들을 담아놨습니다. 귀여움과 짖음을 넣어 놨습니다. 말티즈는 개라는 특성을 담아둘만 한 것 같아서 &dog라고 별명을 붙여놨습니다. jindol이에 똑같은 개의 특성을 넣고 싶은데 타자 많이 치는 것은 싫어서 별명 붙인 것을 가져왔습니다. 그리고 추가적인 특성이 필요해서 값을 넣었습니다. pug도 마찬가지입니다. 기본적인 개의 특성은 별명을 불러와서 붙여넣었고 추가적인 특성을 붙여넣었습니다.

그리고 한 가지 더 알아야 할 점은, 이렇게 붙인 별명은 같은 디렉토리에서 공유가 가능하다는 것입니다. 즉, 한 yml파일에서 붙여놓은 별명을 다른 yml파일에서 *로 불러와서 사용이 가능합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#config.yml
EXECUTOR_SPEC:
10G-10G-15 : &10G-10G-15
executor_memory: 10G
driver_memory: 10G
num_executors: 15
20G-20G-30 : &20G-20G-30
executor_memory: 20G
driver_memory: 20G
num_executors: 30
20G-20G-50 : &20G-20G-50
executor_memory: 20G
driver_memory: 20G
num_executors: 50
50G-50G-50 : &50G-50G-50
executor_memory: 50G
driver_memory: 50G
num_executors: 50

feather: &feather
exspec:
<<: *10G-10G-15
middle: &middle
exspec:
<<: *20G-20G-30
lightheavy: &lightheavy
exspec:
<<: *20G-20G-50
heavy: &heavy
exspec:
<<: *50G-50G-50

Airflow의 각 DAG에서 EMR 스펙을 다르게 사용하고 Airflow의 DAG를 종합하는 yml파일이 있다고 가정해 봅시다. 만약에 위와 같이 yml이 작성되어 있지 않았다면, 종합하는 yml파일의 고객사 DAG마다 executor, driver 메모리, 익스큐터 수를 일일이 지정해줘야 되었을 것입니다. 고객사가 100개라면? 100개씩 적는 노가다를 하다가 정신이 혼미해져서 휴먼에러가 발생할 가능성이 매우 높아질 수 있습니다. 그렇다면, Airflow를 통해 실행한 DAG들에 심각한 에러가 발생하고, 원인 파악하기가 매우 힘들어질 것입니다.(실제로 그래 봤습니다.)

좀 더 들어가면, 이 clients.yml과 종합하는 yml을 연결하기 위한 python파일들이 존재합니다. 이 파이썬 파일들을 이용해서 clients.yml에 있는 값들을 종합하는 yml에 옮겨주고 합쳐진 yml을 통해 완전해진 값들을 가지고 고객사들의 DAG들을 생성할 수 있게 되는 것입니다.


고객사들의 DAG를 자동으로 생성해주는 방법에 대해서 궁금해지셨을 것 같습니다만, yaml글을 통해서 yaml을 한번 갖고 놀아보시고?! 다음 글을 기대해주시면 좋을 것 같습니다. 다음 글에서는 위에서 만든 yml파일과 종합하는 yml파일, 그리고 github action을 사용해서 Airflow의 DAG를 자동으로 만들어주고 배포하는 과정에 대해서 알아보겠습니다.

Author

SangHyub Lee, Jose

Posted on

2021-08-11

Updated on

2023-12-08

Licensed under

Comments