Kubernetes 기반의 기계학습 워크플로우를 간소화해주는 Kubeflow 의 Pipelines 를 생성할 때 YAML 파일을 사용합니다. YAML 파일을 쓸 때 들여쓰기나 대소문자에 신경을 써야 하므로, 아무래도 텍스트 편집기나 vmi 편집 기능을 쓰는 것보다는 Kubernetes 를 지원하는 IDE (Integrated Development Environment) 를 사용하는 것이 코딩을 쉽고 빠르게 할 수 있도록 도와주고 또 에러가 사전에 방지할 수 있어서 여러모로 좋습니다.  

 

이번 포스팅에서는 K8s 를 지원하는 프로그래밍 IDE 중에서도 무료로 사용할 수 있는 MS 의

  (1) Visual Studio Code 를 설치하고, 

  (2) Visual Studio Code 에 Kubernetes YAML 언어 지원 확장 팩을 설치하고 설정하고, 

  (3) Visual Studio Code 의 기능 소개

를 해보겠습니다. 

 

 

 (1) Visual Studio Code 를 설치

 

Visual Studio Code 의 홈페이지인 https://code.visualstudio.com/ 에 방문해서 자신이 사용하는 컴퓨터의 OS 에 맞게 VS Code 설치 파일을 다운로드 하여 설치(install)하면 됩니다.

 

저는 MacBook 을 사용하고 있으므로 'Download Mac Universal (Stable Build)' 를 다운로드 해서 설치했습니다. 

 

Visual Studio Code - Download

 

 

 

(2) Visual Studio Code 에 Kubernetes YAML 언어 지원 확장 팩을 설치하고 설정

 

Visual Studio Code 에 Kubernetes YAML 파일의 코드를 인식하고 지원할 수 있도록 Red Hat 에서 제공하는 YAML 확장 팩을 설치해보겠습니다. 

 

Visual Studio Code 의 제일 왼쪽 메뉴의 제일 밑에 있는 네모 모양 (4개의 네모)의 메뉴를 선택한 후 --> YAML 키워드로 검색해서 --> YAML Language Support by Red Hat, with built-in Kubernetes syntax support 를 선택 --> 설치 (install) 단추 클릭

 

의 순서로 K8s 언어 지원 확장 팩을 설치해 줍니다. 

 

Visual Studio Code - Extension YAML Install

 

 

YAML Red Hat 확장 팩을 설치 했으면, 좌측 YAML 의 톱니바퀴 모양의 설정 단추를 선택하고 --> '확장 설정' 을 선택합니다. 

 

Visual Studio Code - Configuration

 

스크롤바를 밑으로 쭉 내리다보면 'Yaml: Schemas' --> 'setting.json 에서 편집' 을 선택합니다. 

 

Visual Studio Code - YAML Schemas

 

아래의 'setting.json 에서 편집' 창이 비어있을 텐데요, Kubernetes 가 모든 YAML 파일("*.yaml")을 인식할 수 있도록 대괄호 {} 안에 JSON 파일에 입력해줍니다. 

 

Visual Studio Code - settings.json

{
    "yaml.schemas": { 
        "kubernetes": "*.yaml"
        },
}

 

 

'settings.json' 파일을 저장하고 닫은 다음에, --> Visual Studio Code 를 종료 --> Visual Studio Code 를 다시 시작 합니다. 이제부터 VS Code 에서 K8s 에서 인식하는 모든 YAML 언어지원이 사용가능해요. 

 

Visual Studio Code - Enabled

 

 

 

(3) Visual Studio Code 의 기능 소개

 

이제 Visual Studio Code 에서 YAML 언어를 선택해서 --> YAML 파일을 생성해보겠습니다. 

 

Visual Studio Code - Select Language YAML

 

 

왼쪽 메뉴바의 제일 위에 있는 '신규 생성' --> 탐색기에서 '신규 파일 +' 클릭 --> '신규 파일 이름 입력 (예: nginx.yaml)  

해줍니다. 

 

 

 

Visual Studio Code 는 신규 생성 파일이 YAML 임을 인식하고는 apiVersion, kind, metadata, spec 을 알려주고, 들여쓰기라든지, dictionary / array 포맷도 알아서 해주고ㅡ Kubernetes  YAML 파일의 포맷에 맞추어서 적당한 명령어를 추천(Recommendation) 해줍니다. 이 기능은 편리하기도 하고, 휴먼 에러를 줄일 수 있어서 매우 유용합니다. 

 

Visual Studio Code - Recommendation

 

 

만약  Kubernetes YAML 코딩을 하다가 잘못된 부분이 있으면 에러 메시지를 팝업으로 띄워주고, 하단의 '문제 (problem)' 메뉴에도 에러가 있는 코드의 라인(예: line 10)과 문제(예: bad indentation of a mapping entry YAML [10, 5]) 의 에러 내용도 볼 수 있습니다. 이 기능은 디버깅을 할 때 매우 유용합니다. 

 

Visual Studio Code - Error Message

 

 

들여쓰기 에러를 바로잡아 주니 에러 메시지가 사라졌습니다. :-)

 

Visual Studio Code - Error Fixed

 

 

Visual Studio Code 의 왼쪽 하단에 '개요 (Outline)' 메뉴를 선택하면 아래와 같이 YAML 파일의 전체 구조(structure)를 한눈에 빠르게 살펴볼 수 있습니다. 

 

Visual Studio Code - Outline

 

 

터미널에서 방금 전에 새로 만든 nginx.yaml 파일을 cat 으로 열어서 살펴보면 아래와 같습니다. 물론 터미널에서 vim 에디터로도 YAML 파일을 만들고 수정할 수 있기는 합니다만, Visual Studio Code 의 편리한 기능들을 생각하면 역시 VS Code IDE 가 훨씬 매력적이긴 합니다. 

 

(base) lhongdon@Hongui-MacBookPro ~ % ls
Applications		Downloads		Music			VirtualBox VMs		minikf			seaborn-data
Desktop			Library			Pictures		examples		minikf-kubeconfig
Documents		Movies			Public			kubernetes		opt
(base) lhongdon@Hongui-MacBookPro ~ % cd kubernetes 
(base) lhongdon@Hongui-MacBookPro kubernetes % ls
nginx.yaml	pod.yml
(base) lhongdon@Hongui-MacBookPro kubernetes % 
(base) lhongdon@Hongui-MacBookPro kubernetes % 
(base) lhongdon@Hongui-MacBookPro kubernetes % cat nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-2
  labels:
    env: production
spec:
  containers:
    - name: nginx
      image: nginx
                                                                                                                                                             (base) lhongdon@Hongui-MacBookPro kubernetes %

 

 

이번 포스팅이 많은 도움이 되었기를 바랍니다. 

행복한 데이터 과학자 되세요~!  :-)

 

 

728x90
반응형
Posted by Rfriend
,

이전 포스팅에서 Python으로 JSON 데이터 읽고 쓰기, XML 데이터 읽고 쓰기에 대해서 소개한 적이 있습니다.  이번 포스팅에서는 Python의 PyYAML 라이브러리를 이용하여 YAML 파일을 파싱하여 파이썬 객체로 읽어오기, Python 객체를 YAML 파일로 쓰는 방법을 소개하겠습니다. 



YAML에 대한 Wikipedia의 소개를 먼저 살펴보겠습니다. 

YAML 은 "YAML Ain't Markup Language" 의 반복적인 약어(recursive acronym)로서, 인간이 읽을 수 있는 데이터 직렬화 언어(human-readable data-serialization language) 입니다. YAML 은 데이터가 저장되거나 전송되는 구성 파일(configuration file)과 애플리케이션에서 종종 사용됩니다. YAML은 XML 과 동일한 커뮤니케이션 애플리케이션을 대상으로 하지만 최소한의 구문을 가지고 있습니다. 

* source: https://en.wikipedia.org/wiki/YAML


아래는 데이터가 저장되거나 전송되는 구성파일을 XML과 JSON, YAML으로 나타내서 비교한 예입니다. Python 들여쓰기(indentation) 형태로 해서 XML 이나 JSON 대비 Syntax 가 매우 간소해졌음을 알 수 있습니다. 




Python 에서 YAML 파일을 파싱하거나, 반대로 Python 객체를 YAML 파일로 내보낼 때는 PyYAML 라이브러리 (PyYAML is YAML parser and emitter for python)를 사용합니다. 이전에 XML이나 JSON을 다루었을 때와 PyYAML 라이브러리의 load(), dump() 함수 사용법은 비슷합니다. 





먼저, PyYAML 라이브러리가 설치되어 있지 않다면 명령 프롬프트에서 pip로 설치를 해주면 됩니다. 




  (1) YAML 파일을 파싱해서 Python 객체로 읽어오기: yaml.load()


예제로 사용한 YAML 파일은 아래처럼 'Vegetables' 키에 'Pepper', 'Tamato', 'Garlic' 을 값으로 가지는 YAML 파일(vegetables.yml)입니다. (Notepad++ 에디터에서 파일 형식을 YAML로 해서 작성하면 들여쓰기를 알아서 맞추어 줍니다. PyCharm 같은 프로그래밍 에디터를 사용해도 편리합니다.)



vegetables.yml


with open() 으로 'vegetables.yml' YAML 파일을 연 후에, yaml.load() 함수로 YAML 파일을 파싱하여 vegetables 라는 이름의 Python 객체로 저장하였습니다. Python 객체를 인쇄해보면 Key, Value (list) 로 구성된 Dictionary 로 YAML 파일을 파싱했음을 알 수 있습니다. 



import yaml


with open('vegetables.yml') as f:

    vegetables = yaml.load(f, Loader=yaml.FullLoader)

    print(vegetables)

 

{'Vegetables': ['Pepper', 'Tomato', 'Garlic']}




아래와 같이 Kubernetes의 deployment-definition.yaml 처럼 조금 복잡한 YAML 파일을 PyYAML 로 파싱해보면 List와 Nested Dictionary 로 구성된 Dictionary로 파싱합니다. 



k8s_deployment_yaml.yml




import yaml


with open('deployment-definition.yml') as f:

    deployment_def = yaml.load(f, Loader=yaml.FullLoader)


deployment_def

{'apiVersion': 'apps/v1',
 'kind': 'Deployment',
 'metadata': {'name': 'frontend',
  'labels': {'app': 'mywebsite', 'tier': 'frontend'}},
 'spec': {'replicas': 3,
  'template': {'metadata': {'name': 'myapp-pod', 'labels': {'app': 'myapp'}},
   'spec': {'containers': [{'name': 'nginx', 'image': 'nginx'}]}},
  'selector': {'matchLabels': {'app': 'myapp'}}}}





  (2) 여러개의 YAML 문서들을 파싱하여 읽어오기 : yaml.load_all()


YAML 문서를 구분할 때는 '---' 를 사용합니다. 아래는 'Fruits'와 'Vegetables' 의 두개의 YAML 문서를 '---'로 구분해서 하나의 YAML 파일로 만든 것입니다. 



예제 파일:

fruit-vegetable.yml



위의 (1)번에서는 1개의 YAML 문서를 yaml.load() 함수로 Python으로 읽어왔었다면, 이번의 (2)번에서는 '---'로 구분되어 있는 여러개의 YAML 문서를 yaml.load_all() 함수를 사용해서 Python 객체로 파싱하여 읽어오겠습니다. 



import yaml


with open('fruit-vegetable.yml') as f:

    

    fruits_vegetables = yaml.load_all(f, Loader=yaml.FullLoader)

    

    for fruit_vegetable in fruits_vegetables:

        print(fruit_vegetable)

 

{'Fruits': ['Blueberry', 'Apple', 'Orange']}
{'Vegetables': ['Pepper', 'Tomato', 'Garlic']}




  (3) 읽어온 YAML 파일을 정렬하기


아래와 같이 자동차 브랜드, 가격 쌍으로 이우러진 cars.yml YAML 파일을 Python 객체로 파싱해서 읽어올 때 Key 기준, Value 기준으로 각각 정렬을 해보겠습니다. (Dictionary 정렬 방법 사용)



cars.yml


(3-1) 읽어온 YAML 파일을 Key 기준으로 정렬하기 (sorting by Key)

    : 방법 1) yaml.dump(object, sort_keys=True) 



import yaml


with open('cars.yml') as f:

    

    cars_original = yaml.load(f, Loader=yaml.FullLoader)

    print(cars_original)

    

    print("---------------------")

    

    # sorting by Key

    cars_sorted = yaml.dump(cars_original, sort_keys=True)

    print(cars_sorted)

 

{'hyundai': 45000, 'tesla': 65000, 'chevrolet': 42000, 'audi': 51000, 'mercedesbenz': 80000}
---------------------
audi: 51000
chevrolet: 42000
hyundai: 45000
mercedesbenz: 80000
tesla: 65000



  : 방법 2) sorted(object.items()) 메소드 사용 



import yaml


with open('cars.yml') as f:

    

    cars_original = yaml.load(f, Loader=yaml.FullLoader)

    print(cars_original)

    

    print("---------------------")

    # sort by key in ascending order

    for key, value in sorted(cars_original.items()):

        print(key, ':', value


{'hyundai': 45000, 'tesla': 65000, 'chevrolet': 42000, 'audi': 51000, 'mercedesbenz': 80000}
---------------------
audi : 51000
chevrolet : 42000
hyundai : 45000
mercedesbenz : 80000
tesla : 65000

 



(3-2) Key 값의 역순으로 정렬 (sorting in reverse order): sorted(object.items(), reverse=True)



import yaml


with open('cars.yml') as f:

    cars_original = yaml.load(f, Loader=yaml.FullLoader)

    print(cars_original)

    

    print("---------------------")

    

    # sorting by key in reverse order

    for key, value in sorted(cars_original.items(), reverse=True):

        print(key, ':', value)


tesla : 65000
mercedesbenz : 80000
hyundai : 45000
chevrolet : 42000
audi : 51000




(3-3) 읽어온 YAML 파일을 Value 기준으로 정렬하기 (sorting by Value)



import yaml


with open('cars.yml') as f:

    cars_original = yaml.load(f, Loader=yaml.FullLoader)

    print(cars_original)

    

    print("---------------------")

    # sorting by value in ascending order

    for key, value in sorted(cars_original.items(), key = lambda item: item[1]):

        print(key, ':', value)


{'hyundai': 45000, 'tesla': 65000, 'chevrolet': 42000, 'audi': 51000, 'mercedesbenz': 80000}
---------------------
chevrolet : 42000
hyundai : 45000
audi : 51000
tesla : 65000
mercedesbenz : 80000




  (4) Python 객체를 YAML stream으로 직렬화 하기: yaml.dump()


Key, Value 쌍으로 이루어진 Python Dictionary를 yaml.dump() 메소드를 사용해서 YAML stream으로 직렬화해보겠습니다. 



import yaml


fruits = {'fruits': ['blueberry', 'apple', 'orange']}


# serialize a Python object into YAML stream

fruits_serialized_yaml = yaml.dump(fruits)

print(fruits_serialized_yaml)

 

fruits:
- blueberry
- apple
- orange




  (5) Python 객체를 YAML 파일로 쓰기: with open('w') as f: yaml.dump()


위의 (4)번에서 소개한, YAML stream으로 직렬화하는 yaml.dump() 메소드에 with open('w') 함수를 같이 사용해서 이번에는 YAML file 에 쓰기('w')를 해보겠습니다. 



import yaml


fruits = {'fruits': ['blueberry', 'apple', 'orange']}


with open('fruits.yaml', 'w') as f:

    yaml.dump(fruits, f)




많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. 



728x90
반응형
Posted by Rfriend
,