no image
Kubernetes with Docker Desktop 환경 설정
Motivation 맥북을 개발용 컴퓨터로 두고 나니 쿠버네티스를 돌리기에는 컴퓨터 사양이 너무 부족했습니다. 그래서 몇 달 전 10만원 언저리로 쿠버네티스용 윈도우 컴퓨터를 구매 후 kubeadm 통해 가상 머신 위에서 멀티 노트 클러스터를 구축하여 이래저래 잘 사용해왔습니다만 그만 클러스터가 복구 불가능할 정도로 망가져버리고 말았습니다. virtualbox로 가상머신 3대를 통해 노드 3대를 만들었는데, 가상 머신 이미지도 맛이 가버린 상황에서 다시 처음부터 설치를 하려니 도저히 손이 안가더라구요. 이럴꺼면 잘 좀 정리해놓을껄 싶은 순간이였습니다. 그런데 여기서 생각해보니, 굳이 여러 노드로 돌려야 하는지는 의문이 들더군요. 물론 업무를 한다면 여러 노드를 돌리는게 재현성이 훨씬 좋겠지만, 제가 쿠버..
2023.06.18
no image
gchr.io를 활용한 도커 이미지 관리
Motivation Docker Repository를 Container Registry로 잘 사용하고 있었으나 무료 플랜의 경우 해당 이미지를 Private으로 설정할 수 없음. ghcr(Github Container Registry)의 경우 Private 저장소를 500MB 까지 무료로 사용 가능 Public으로 관리할 수 있는 도커 이미지의 경우, Docker Repository를 활용해도 무방하나 ssh Token 혹은 Github Access Token등의 Credential이 포함된 경우 gchr을 통해 이미지를 관리하고자 함. 도커와 gchr 연동 먼저, gchr을 이미지 저장소로 활용하기 위해 Github Access Token을 발급받는다. 이는 본인 계정의 Settings > Develo..
2023.05.22
no image
[Kubeflow] pipeline
kubeflow란 💡 컨테이너 기반의 End-to-end ML 워크 플로우 관리 플랫폼 Kubeflow Pipeline의 구성 Experiment, Job, Run을 관리, 추적하고 실행할 수 있는 UI 파이프라인의 단계별 실행 스케쥴링을 위한 엔진 Python에서 파이프라인을 정의, 구축하기 위한 SDK SDK와 파이프라인의 실행을 위한 쥬피터 노트북 Pipeline의 지향점 쉬운 파이프라인 구성 쉬운 파이프라인 생성: Trial/ Experiement 컴포넌트들을 통해 다양한 기술 적용 가능 쉬운 재사용: 컨테이너 기반 구조 💡 간단하게 말해서 ML Pipeline이란, 워크플로우 컴포넌트를 통해 작업을 그래프 형태로 결합시킨 것! Pipeline의 실행 과정 파이프라인이 실행되면, 시스템은 각 단계..
2023.04.07
[Kubeflow] MLOps 개발환경 설정
구성 요소 제약 사항 kubernetes version >= 1.25 cpu >= 0.6 Storage >= 10GB Default Storage Class with dynamic provisioning 특히 default storage class를 생성하는 부분이 상당히 당황스러웠는데, minikube에서는 기본적으로 addon 형태로 달려있는 것을 확인할 있지만, kubeadm을 통해 만들어진 kubernetes 클러스터는 그렇지 않다. 직접 설정해줘야 한다. 이때 사용할 수 있는 대표적인 솔루션이 Rook과 Cephfs이다. CephFS is a distributed file system that provides scalable and reliable storage for files. It is a..
2023.04.07
error: parsing file '/var/lib/dpkg/updates/0001' near line 0: newline in field name `#padding'
문제 상황 sudo dpkg --configure -a 시에 다음과 같은 문제가 발생 error: parsing file '/var/lib/dpkg/updates/0001' near line 0: newline in field name `#padding'해결 # 백업 파일로 남겨두고 다시 시도 sudo mv /var/lib/dpkg/updates/0001 /var/lib/dpkg/updates/0001.X sudo dpkg --configure -a
2023.03.23
Could not get lock /var/lib/dpkg/lock-frontend
문제 상황 sudo apt-get install -y ca-certificates curl gnupg lsb-release E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable) E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?해결 sudo rm /var/lib/apt/lists/lock sudo rm /var/cache/apt/archives/lock sudo rm /var/lib/dpkg/lock* sudo dpkg --configure -a && su..
2023.03.23
sudo ubuntu-drivers autoinstall 오류
문제 상황 sudo ubuntu-drivers autoinstall Reading package lists... Done Building dependency tree Reading state information... Done Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to re..
2023.03.23
no image
쿠버네티스 패턴 (1장 개요)
소개글 본격적인 패턴 소개 이전에 클라우드 네이티브 애플리케이션을 지탱하는 쿠버네티스의 핵심 개념들을 설명한다. 구체적인 쿠버네티스 리소스를 통해 주로 쿠버네티스의 추상화 방식에 대해서 다루게 된다. DDD 도메인 주도 설계(Domain Driven Design)는 이를 사용하는 사람들의 영역 또는 지식의 영역을 중심으로 하는 소프트웨어 개발 철학이다. 과거의 많은 소프트웨어 설계에서는 객체가 가져야 할 데이터에 초점을 두어 객체를 설계하였다(데이터 주도 설계, Data Driven Design). 이러한 방식은 객체 자신이 포함하는 데이터를 조작하는 데에 있어서는 좀 더 용이할지 모르나, 실제 비즈니스 레벨에서 다뤄져야 하는 내용들이 코드 상에 반영되지 못하고, 소프트웨어와 현실 간의 괴리가 발생하는 ..
2022.11.15

Motivation

맥북을 개발용 컴퓨터로 두고 나니 쿠버네티스를 돌리기에는 컴퓨터 사양이 너무 부족했습니다. 그래서 몇 달 전 10만원 언저리로 쿠버네티스용 윈도우 컴퓨터를 구매 후 kubeadm 통해 가상 머신 위에서 멀티 노트 클러스터를 구축하여 이래저래 잘 사용해왔습니다만 그만 클러스터가 복구 불가능할 정도로 망가져버리고 말았습니다.

 

virtualbox로 가상머신 3대를 통해 노드 3대를 만들었는데, 가상 머신 이미지도 맛이 가버린 상황에서 다시 처음부터 설치를 하려니 도저히 손이 안가더라구요. 이럴꺼면 잘 좀 정리해놓을껄 싶은 순간이였습니다.

 

그런데 여기서 생각해보니, 굳이 여러 노드로 돌려야 하는지는 의문이 들더군요. 물론 업무를 한다면 여러 노드를 돌리는게 재현성이 훨씬 좋겠지만, 제가 쿠버네티스를 윈도우에서 돌리는 이유는 결국 학습이니까요. 학습을 위해서라면 단일 노드 환경도 문제가 없겠다는 판단하에, minikube와 docker-desktop을 활용해야겠다는 결론을 내렸고 그 중에서 docker-desktop을 통해 상호작용이 가능한 docker-desktop 버전의 쿠버네티스를 사용해야겠다고 최종적인 방향을 정했습니다.

 

Docker Desktop 설치

먼저 Docker Desktop을 설치해야겠죠. Docker Desktop은 다음의 웹페이지에서 쉽게 설치가 가능합니다.

 

https://www.docker.com/products/docker-desktop

 

Download Docker Desktop | Docker

Docker Desktop is available to download for free on Mac, Windows, or Linux operating systems. Get started with Docker today!

www.docker.com

 

 

설치가 완료됐다면 이후 로그인 완료하시고 접속해주시면 되겠습니다.

 

Docker 실행 후 1시 방향의 톱니바퀴를 눌러주시면 Kubernetes 메뉴가 옆에 있습니다. Enable Kuberntes를 체크하고 Apply & Restart를 누르면 Kubernetes 설치가 진행됩니다.

 

 

설치하는데 생각보다 시간이 많이 걸리니 (제 경우 10분 걸렸습니다) 차분하게 완료가 될때까지 기다려주세요. 이후 정상적으로 설치가 완료되었다면 다음과 같이 쿠버네티스 아이콘이 활성화됩니다.

 

쿠버네티스 사용하기

쿠버네티스는 kubectl이라는 cli 명령어 인터페이스로 관리가 됩니다. 말 나온김에 쿠버네티스 구조를 살펴보면 다음과 같습니다.

 

출처:https://www.simplilearn.com/tutorials/kubernetes-tutorial/kubernetes-architecture

 

일반적으로 고가용성을 보장하는 쿠버네티스는 Multi-node 환경으로 구성이 되어 있습니다. 그림에서 볼 수 있는 것처럼 Master가 중앙에서 각 Worker들에게 명령을 내리는 구조이구요. 이때 kubectl은 Master에게 kubeapi server와 통신하며 본인의 요구사항을 전달하는 매개가 됩니다. 

 

쿠버네티스 구조를 설명하는 글은 아니기 때문에 해당 주제는 여기서 줄이도록 하고 계속해서 클러스터를 살펴보도록 하겠습니다.

 

간단히 몇 가지 명령어를 실행해보겠습니다.

 

# kubectl 의 버전 확인 
# Client 및 Server 의 버전을 확인할 수 있습니다. 
$> kubectl version --short
Client Version: v1.25.4
Kustomize Version: v4.5.7
Server Version: v1.25.4

# 클러스터 정보 확인 
# k8s의 컨트롤 패널의 정보를 가져올 수 있는 endpoint를 알려줍니다. 
# kubernetes.docker.internal 은 k8s 설치시 hosts 파일에 자동으로 등록된 정보입니다. 127.0.0.1 kubernetes.docker.internal
$> kubectl cluster-info
Kubernetes control plane is running at https://kubernetes.docker.internal:6443
CoreDNS is running at https://kubernetes.docker.internal:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

# 노드 정보 확인
$> kubectl get nodes
NAME             STATUS   ROLES           AGE     VERSION
docker-desktop   Ready    control-plane   9m10s   v1.25.4

 

만약 kubectl의 서버가 뜨지 않았다면, 가장 먼저 root 유저로 해당 명령어를 입력하지는 않았는지 확인해주시기 바랍니다. kubectl config 파일을 별도로 root 유저 쪽에도 설정해주지 않으셨다면, kubectl을 root 유저에서 실행해도 server에 요청이 전달이 되지 않았습니다.

 

그럼에도 문제가 된다면 Docker Desktop의 쿠버네티스가 정상적으로 설치되지 않았을 확률이 높습니다. 다양한 경우의 수가 있지만, 계속해서 문제가 된다면 대신 minikube를 활용해보시는 것을 추천드립니다. 

 

Kubernetes Dashboard 설치

물론 CLI만을 활용해서 쿠버네티스를 다루는 것도 좋지만, GUI를 통해서도 접근이 가능하다면 훨씬 훌륭하겠죠.

 

해당 글에서는 쿠버네티스 공식 문서에서 제공하는 웹 대시보드를 설치해보려고 합니다.

 

https://kubernetes.io/ko/docs/tasks/access-application-cluster/web-ui-dashboard/

 

 

쿠버네티스 대시보드를 배포하고 접속하기

웹 UI(쿠버네티스 대시보드)를 배포하고 접속한다.

kubernetes.io

 

설치는 쿠버네티스 공식 github에서 제공하는 yaml을 사용합니다.

 

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.4.0/aio/deploy/recommended.yaml

 

설치가 완료되었다면 다음의 명령어를 통해 확인해줍니다.

 

$> kubectl get deployment -n kubernetes-dashboard
NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
dashboard-metrics-scraper   1/1     1            1           44s
kubernetes-dashboard        1/1     1            1           45s

 

설치가 완료되었지만 대시보드에 접속하기 위해서는 proxy 설정이 필요합니다.

$> kubectl proxy

 

혹 쿠버네티스의 proxy가 생소하신 분들은 쿠버네티스의 공식 문서을 참조해보시는 것을 추천드립니다.

 

해당 문서에서는 다양한 쿠버네티스에서 활용되는 다양한 proxy를 설명하고 있으며, 우리가 활용하고자 하는 kubectl proxy에 대한 특징을 다음과 같이 설명합니다.

 

✅ 사용자의 데스크탑이나 파드 안에서 실행한다.
✅ 로컬 호스트 주소에서 쿠버네티스의 API 서버로 프락시한다.
✅ 클라이언트로 프락시는 HTTP를 사용한다.
✅ API 서버로 프락시는 HTTPS를 사용한다.
✅ API 서버를 찾는다.인증 헤더를 추가한다.

 

로컬 호스트의 주소를 쿠버네티스의 적절한 파드로 넘겨준다 정도로 이해하고 넘어가주시면 되겠습니다.

 

성공적으로 proxy가 동작한다면 다음의 주소로 접속해봅시다. 

 

http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login

 

문제가 없다면 다음과 같이 정상적으로 접속이 가능한 것을 확인할 수 있습니다.

 

 

대시보드가 성공적으로 동작하지만, 아쉽게도 대시보드가 쿠버네티스를 자동으로 추적하지는 못합니다. 때문에 추가적인 인증 과정을 거쳐 대시보드에 쿠버네티스를 등록해주는 과정이 필요합니다.

 

해당글에서는 토큰을 기반으로 하는 인증을 수행할 예정입니다. 이러한 인증 과정은 Bearer Authentication이라고 불리기도 합니다.

 

쿠버네티스에서 Bearer 토큰을 발급하기 위해서는 다음의 과정을 거쳐야 합니다.

 

먼저, 해당 토큰을 발급할 주체인 Service Account를 생성해줍시다.

 

생성을 위해서는 아래의 텍스트를 yaml 파일로 저장합니다. 

 

apiVersion: v1
kind: ServiceAccount
metadata:
  name: dashboard-admin
  namespace: kubernetes-dashboard

 

이후 적용하여 생성합니다. 파일 이름의 경우 유동적으로 설정해주시면 됩니다.

 

$> kubectl apply -f 0.svc.yaml
serviceaccount/admin-user created

 

생성이 완료되었다면, 앞서 생성한 Service Account에 권한을 부여해줘야 합니다.

 

쿠버네티스에서는 권한을 Role로 관리해주게 되는데, 이러한 Role을 부여해주는 행위를 Role Binding이라고 합니다.

 

아래의 yaml 파일은 쿠버네티스 클러스터에 대한 권한을 Service Account에게 부여해주는 스크립트입니다. 쿠버네티스에는 기본적으로 제공하는 여러 Role이 있으며 그중에서 Cluster Role은 Cluster에 대한 권한을 의미하는 특별한 의미의 Role 입니다. 그 중에서 우리는 cluster-admin이라는 역할을 앞서 생성한 Service Account에 부여해주려고 합니다.

 

마찬가지로 파일로 먼저 생성한 이후에 적용하여 생성해줍시다.

 

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dashboard-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: dashboard-admin.yaml
  namespace: kubernetes-dashboard

 

$> kubectl apply -f 1.cluster-role-binding.yaml
clusterrolebinding.rbac.authorization.k8s.io/dashboard-admin created

 

최종적으로 다음의 명령을 통해 Bearer Token을 발급받을 수 있습니다.

 

$> kubectl -n kubernetes-dashboard create token dashboard-admin

 

토큰이 발급되었다면 콘솔창에 출력된 긴 문자를 복사 후에 아까 띄워두었던 웹페이지에 붙여넣어 줍니다. 이후 아래의 화면이 띄게 되면 모든 설정이 완료되게 됩니다. 

 

 

아직은 클러스터 내에 아무런 앱이 떠 있지 않기 때문에 볼 수 있는게 없지만 배포 이후에는 다음의 대시보드 형태를 통해 클러스터 내의 리소스를 GUI 형태로 모니터링할 수 있게 됩니다.

 

 

k9s 설치하기

마지막으로 kubectl 대신 kubenetes를 더욱 쉽게 관리하도록 도와주는 k9s를 설치하고 해당 글을 마무리하려고 합니다.

 

설치 자체는 간단합니다.

 

제가 작업하는 리눅스(wsl)의 경우에는 다음의 명령을 통해 설치합니다. 명령어가 복잡해보이지만 사실 설치하고 압축 해제하는 것 말고는 없습니다.

 

curl -s -L https://github.com/derailed/k9s/releases/download/v0.26.7/k9s_Linux_x8
6_64.tar.gz -o k9s && tar -xvf k9s && chmod 755 k9s && rm LICENSE README.md  && sudo mv k9s /usr/local/bin

 

맥에서는 더욱 간단합니다. 패키지 관리자인 brew에 이미 k9s가 포함되어 있기 때문에 바로 설치가 가능합니다.

 

brew install k9s

 

최종적으로 설치가 완료되었다면 k9s를 실행해봅시다. 주의할 점은 root가 아닌 쿠버네티스 context가 존재하는 user에서 실행해주셔야 합니다.

 

다음의 명령어를 통해 실행해주시면 아래와 같은 텍스트 기반 GUI를 확인하실 수 있습니다.

 

k9s

Motivation

 

  • Docker Repository를 Container Registry로 잘 사용하고 있었으나 무료 플랜의 경우 해당 이미지를 Private으로 설정할 수 없음.

  • ghcr(Github Container Registry)의 경우 Private 저장소를 500MB 까지 무료로 사용 가능

  • Public으로 관리할 수 있는 도커 이미지의 경우, Docker Repository를 활용해도 무방하나 ssh Token 혹은 Github Access Token등의 Credential이 포함된 경우 gchr을 통해 이미지를 관리하고자 함.

 

도커와 gchr 연동

 

먼저, gchr을 이미지 저장소로 활용하기 위해 Github Access Token을 발급받는다.

 

이는 본인 계정의 Settings > Developer Settings에서 발급이 가능하다. 이때 허용해줘야 하는 권한에는 다음이 있다.

 

  1. read:packages

  2. write:packages

  3. delete:packages

 

토큰이 발급되었다면 이를 통해 docker login 명령어를 통해 gchr.io에 로그인 해야한다.

 

이는 다음과 같이 수행이 가능하다.

 

이때 username 부분에 본인의 Github username을, Access Token Value 부분에 앞서 발급받은 키를 넣어준다.

docker login ghcr.io -u username --password "Access Token Value"



또는 다음과 같이 로그인한다.

 

echo "Access Token Value" | docker login ghcr.io -u username --password-stdin

 


로그인이 완료되었다면 이제 앞서 생성한 도커 이미지를 gchr에 업로드해보자. 먼저 해당 이미지가 gchr에 push 되기 위해서는 해당 이미지에 대한 태그를 통해 이를 표현해줘야 한다.

 

이는 다음과 같이 수행한다.

 

username에 본인의 github username을, container-name:tag에 push 하고자 하는 적절한 로컬 이미지를 입력해주면 된다.

 

이때 “ghcr.io/username/container-name:tag”에서 마지막에 위치한 container-name:tag가 github에서 볼 수 있는 해당 이미지의 이름이 된다.

 

docker tag container-name:tag ghcr.io/username/container-name:tag

 


이제 gchr에 push만을 남겨두고 있다.

 

push는 기존 Docker Registry에서 사용하는 것과 동일하되, 앞서 지정한 태그를 활용한다.

 

docker push ghcr.io/username/container-name:tag

 


업로드된 이미지는 Github Package에서 확인이 가능하다.

[Kubeflow] pipeline

mydailylogs
|2023. 4. 7. 16:58

kubeflow란

💡 컨테이너 기반의 End-to-end ML 워크 플로우 관리 플랫폼


Kubeflow Pipeline의 구성

  • Experiment, Job, Run을 관리, 추적하고 실행할 수 있는 UI

  • 파이프라인의 단계별 실행 스케쥴링을 위한 엔진

  • Python에서 파이프라인을 정의, 구축하기 위한 SDK

  • SDK와 파이프라인의 실행을 위한 쥬피터 노트북


Pipeline의 지향점

  • 쉬운 파이프라인 구성

  • 쉬운 파이프라인 생성: Trial/ Experiement 컴포넌트들을 통해 다양한 기술 적용 가능

  • 쉬운 재사용: 컨테이너 기반 구조

💡 간단하게 말해서 ML Pipeline이란, 워크플로우 컴포넌트를 통해 작업을 그래프 형태로 결합시킨 것!


Pipeline의 실행 과정

  1. 파이프라인이 실행되면, 시스템은 각 단계에 맞는 쿠버네티스 파드를 실행시킨다.

  2. 해당 파드는 설정된 컨테이너를 실행시킨다.

  3. 마찬가지로 해당 컨테이너는 내부의 애플리케이션을 실행한다.

  4. 이후 스케쥴러에 따라, 순서대로 컨테이너들을 실행시키는 형태로 파이프라인이 진행된다.


Pipeline 수행 과정 이해

 

Python SDK: 파이프라인 DSL을 통해 컴포넌트를 작성

In Python, DSL stands for Domain Specific Language. A DSL is a programming language that is specialized for a particular domain, such as data analysis, scientific computing, or web development. Some popular DSLs in Python include NumPy for numerical computing, Pandas for data analysis, and Django for web development.

 

  • DSL Compiler: 파이썬 코드를 YAML(쿠버네티스 리소스 양식)로 변환한다.

  • Pipeline Service: 쿠버네티스 리소스 양식에서 파이프라인을 생성하기 위해 호출

  • Kubernetes resources: Pipeline Service가 쿠버네티스 API 서버를 호출하여, 파이프라인 실행을 위한 쿠버네티스 리소스를 생성

  • Orchestration controllers: 생성된 쿠버네티스 리소스에 정의된 파이프라인을 실행하기 위한 할당 가능한 파드를 지정하며 컨테이너를 실행

  • Artifact storage: 실행된 파드에선 Meta-data → mysql 서버에 담고, 그 외의 큰 사이즈의 정보 → Minio 서버나, 별도 지정된 클라우드 스토리지에 저장

  • Pipeline web server: 실행된 파이프라인은 웹 UI를 통해 모니터링 가능


Component ( From 모두의 MLOPS)

💡 컴포넌트는 Component ContentsComponent Wrapper로 구성되며, 하나의 컴포넌트는 Wrapper를 통해 파이프라인에 전달되며 정의된 컴퍼넌트 콘텐츠를 실행(execute)하고 아티팩트(artifacts)를 생산합니다.

 

[출처] 모두의 mlops


Component Content

컴포넌트는 총 3가지로 구성됩니다.


1. Environment

2. Python code with Config

3. Generates Artifacts

예시와 함께 살펴보면

import dill
import pandas as pd

from sklearn.svm import SVC

train_data = pd.read_csv(train_data_path)
train_target= pd.read_csv(train_target_path)

clf= SVC(
    kernel=kernel
)
clf.fit(train_data)

with open(model_path, mode="wb") as file_writer:
     dill.dump(clf, file_writer)


다음과 같이 컴포넌트 콘텐츠로 나눌 수 있습니다.

[출처] 모두의 mlops


Environment는 파이썬 코드에서 사용하는 패키지들을 import하는 부분입니다.

다음으로 Python Code w\ Config 에서는 주어진 Config를 이용해 실제로 학습을 수행합니다.

마지막으로 아티팩트를 저장하는 과정이 있습니다.

Component Wrapper

컴포넌트 래퍼는 컴포넌트 콘텐츠에 필요한 Config를 전달하고 실행시키는 작업을 합니다.

[출처] 모두의 mlops


Kubeflow에서는 컴포넌트 래퍼를 위의 train_svc_from_csv와 같이 함수의 형태로 정의합니다. 컴포넌트 래퍼가 콘텐츠를 감싸면 다음과 같이 됩니다.

[출처] 모두의 mlops

Artifacts

위의 설명에서 컴포넌트는 아티팩트(Artifacts)를 생성한다고 했습니다. 아티팩트란 evaluation result, log 등 어떤 형태로든 파일로 생성되는 것을 통틀어서 칭하는 용어입니다. 그 중 다음과 같은 값을 주로 작업하게 됩니다.

[출처] 모두의 mlops

  • Model: ML 모델
  • Data: 데이터는 전 처리된 피처, 모델의 예측 값 등을 포함
  • Metric
    • 동적 지표: 학습과 함께 변화하는 값 (Train loss)
    • 정적 지표: 최종적으로 모델을 평가하는 지표 (Accuracy)
  • etc
💡 "모델이란 파이썬 코드와 학습된 Weights와 Network 구조 그리고 이를 실행시키기 위한 환경이 모두 포함된 형태"
- 모두의 MLOps


다시 파이프라인으로 돌아오자면 …

[출처] 모두의 mlops

파이프라인은 컴포넌트의 집합과 컴포넌트를 실행시키는 순서도로 구성되어 있습니다. 이때 순서도는 방향이 없는 그래프(Undirected Graph)로 표현되며, 간단한 조건문을 포함할 수 있습니다.

 

Pipeline Config

[출처] 모두의 mlops

컴포넌트를 실행시키기 위해 Config가 필요합니다. 이때 파이프라인을 구성하는 컴포넌트의 Config들을 모아둔 것이 파이프라인 Config입니다.

Run

  • Config 까지 주어진다면 → 파이프라인 실행가능

  • 이때 실행된 파이프라인 명세를 Run이라고 부름 (명세의 인스턴스화)


Run은 파이프라인의 실행 단위로서 앞서 그래프 형태로 표현된 파이프라인의 명세를 순서대로 실행합니다.

파이프라인이 실행되면 각 컴포넌트가 아티팩트들을 생성합니다. Kubeflow pipeline에서는 Run 하나당 고유한 ID 를 생성하고, Run에서 생성되는 모든 아티팩트들을 저장합니다.


Recurring Run

  • 주기적으로 파이프라인을 실행하는 Run
  • 대표적으로 Cron 형태로 수행가능 → 배치성 작업이나 모니터링 작업에 적합
  • Run Trigger을 통해 관리


Run Trigger

Run의 실행여부를 결정하는데 활용 (일종의 Flag)

  • Periodic: 간격 기반의 스케쥴링 (Ex. 30분에 한번 실행)
  • Cron: cron 형태의 스케쥴링 (Cron 형태란)


Step

  • 파이프라인 상에서 하나의 컴포넌트의 실행
  • 중첩/분기되어 실행되기도 함


Experiment

  • 파이프라인을 실행하는 워크스페이스
  • 파이프라인 실행을 논리적으로 묶어주는 역할 (K8s의 NS와 유사)
  • 별도 지정하지 않는 한 default라는 Experiment (group)에서 Run이 실행


Pipeline SDK

💡 파이프라인 SDK는 파이썬 패키지로 구성되어 있으며, 크게 5가지의 영역으로 나뉘어져 있습니다.


kfp.compiler

  • 파이프라인 컴포넌트를 빌드하는 클래스와 메소들의 패키지


kfp.components

  • 파이프라인 컴포넌트들을 다루는 클래스와 메소드들의 패키지

kfp.dsl

  • domain-specific language

  • 파이썬 코드를 통해 파이프라인을 작성하기 위해 필요한 클래스와 메소드, 모듈들을 모아둔 패키지


kfp.Client


파이프라인 API와 통신하는 파이썬 클라이언트
라이브러리 패키지


kfp.containers


컨테이너 이미지관련 메소드와 클래스들의 패키지


SDK로 파이프라인 만들기


파이프라인은 DSL을 통해서 작성되며, 컴파일 과정을 거쳐 쿠버네티스 파이프라인 리소스로 변환되어 사용됩니다.


파이프라인은 2가지 방법으로 작성이 가능합니다.


ksp.dsl 내부의 ContainerOp
를 이용하여 생성


이때, 각 Step에서 필요한 테스크를 수행하는 애플리케이션이 미리 작성이 되어 있어야 하며, 해당 애플리케이션은 도커 이미지로 패키징되어 단독으로도 실행이 가능해야 합니다.


이때, 도커 이미지는 ContainerOp의 매개변수를 통해 지정됩니다.

classkfp.dsl.BaseOp(
        name: # 컴포넌트 이름
        image: # 컨테이너 이미지 이름
        Command: # StringOrStringList 컨테이너 실행 명령어
        arguments: # StringOrStringList 컨테이너 실행 인자값
        ...
)


이를 활용한 파이프라인 정의

from kfp import ds1

def echo_op():
    return ds1.ContainerOp(
            name='echo',
            image='library/bash:4.4.23',
            command=['sh', '-c'],
            arguments=['echo "Hello World"'],
    )

@dsl.pipeline(
    name='ContainerOp pipeine',
    description="..."
)
def hello_world_pipeline():
    echo_task = echo_op()


활용 예시 1 - 쥬피터 노트북

if __name__ == "__main__":
    kfp.compiler.Compiler().complie(hello_world_pipeline, 'containerop.pipeline.tar.gz')



활용 예시 2 - dsl-compile

$ dsl-compile --py container.py --output containerpop.pipeline.tar.gz


파이썬 함수를 통해 생성


생성 예시

import kfp.dsl as dsl

@dsl.pipeline (
    name='example_1',
    description='A simple pipeline'
)
def my_pipeline(a: int = 1 b: str = "default value"):
    print(a)
    print(b)


활용 예제

if __name__ == "__main__":
    import kfp.compiler as compiler
    compiler.Compiler().compile(my_pipeline, 'my_pipeline.pipeline.tar.gz')
   
구성 요소 제약 사항
kubernetes version >= 1.25
cpu >= 0.6
Storage >= 10GB
Default Storage Class with dynamic provisioning

 

특히 default storage class를 생성하는 부분이 상당히 당황스러웠는데, minikube에서는 기본적으로 addon 형태로 달려있는 것을 확인할 있지만, kubeadm을 통해 만들어진 kubernetes 클러스터는 그렇지 않다. 직접 설정해줘야 한다.

이때 사용할 수 있는 대표적인 솔루션이 Rook과 Cephfs이다.

CephFS is a distributed file system that provides scalable and reliable storage for files. It is a component of the larger Ceph storage system and can be used as a standalone file system or as part of a Ceph cluster. CephFS is designed to provide POSIX-compliant file system semantics and is highly available and fault-tolerant.

 

Rook has built-in support for Ceph, which means that it can be used to deploy and manage a Ceph cluster within a Kubernetes environment. This includes managing CephFS as a storage solution within the Kubernetes cluster. Rook abstracts the complexities of managing Ceph and exposes a simplified API for deploying and managing the storage system.

 

Rook integrates with CSI to provide a standard interface for integrating different storage systems with Kubernetes. Rook uses CSI drivers to manage different storage systems, such as Ceph or CockroachDB, within a Kubernetes environment. The CSI drivers provide a standard set of APIs that Rook can use to manage the storage systems, making it easier for users to deploy and manage different storage solutions within their Kubernetes environment.


요약하자면, ceph는 분산 파일 스토리지, Rook은 이를 오케스트레이션해주는 서비스이다. 이때, 쿠버네티스 내의 각기 다른 파일시스템(Ceph/CockroachDB 등)에 대해서 Rook은 CSI(Container Storage Interface)에서 제공하는 Interface를 통해 비교적 쉽게 제어가 가능하다는 장점이 있다고 한다.

 

Step 1 Install LVM

Ceph는 raw block device, partitions, LVM logical volumnes를 포함하여 다양한 종류의 block storage device를 사용할 수 있는데, 해당 문서에서는 이슈 발생을 최대한 피하기 위해 raw device에 LVM을 설치하는 방식으로 진행한다.

 

먼저 해당 머신에 ceph 구성에 활용될 수 있는 partiion이나 device가 있는지를 확인한다.

lsblk
lsblk -f

 


이떄 만약 FSTYPE 필드가 비어있지 않다면, 해당 장치 위에 파일 시스템이 있다는 것을 의미한다. 해당 문서에서는 _sdb_를 사용하여 Ceph를 구성하기로 한다.

 

sudo apt-get install -y lvm2

 

Step 2 - Install Rook

 

현재 가장 최신 버전인 1.11.1 버전을 설치

 

git clone --single-branch --branch v1.11.1 https://github.com/rook/rook.git

 

cd rook/deploy/examples
kubectl create -f crds.yaml -f common.yaml -f operator.yaml


CRD, ClusterRole과 RoleBinding이 생성되는 것을 볼 수 있다.

 

이후 Rook 클러스터를 생성해준다.

 

kubectl create -f cluster.yaml

 


성공이 되었는지 확인해주자.

 

kubectl get CephCluster -n rook-ceph


Step 3 - Provision Storage Class and make it default

 

ceph를 도입한 당초 목적이였던 Storage Class를 프로비저닝하고 이를 쿠버네티스의 default 스토리지로 설정하는 단계이다.

 

마찬가지로 앞서 Clone 해왔던 Rook의 저장소에서 다음의 주소에 있는 yaml 파일을 적용시켜 준다.

(Rook/deploy/examples/csi/rbd)

 

kubectl apply -f storageclass-test.yaml


storage 클래스가 생성되었다면, 이를 default로 설정해보자

kubectl patch sc rook-ceph-block -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

 

Step 4 - Install kustomize

그동안 3.2.0 버전의 kustomize를 고수해오던 kubeflow가 2023년 2월경부터 5.0.0 버전을 요구하기 시작했다. (sortOptions라는 새로운 필드를 사용하기 위해서라고 한다)

kustomize repo에 들어가서 머신에 적합한 압축파일을 받아준다.

kustomize 릴리즈

 

Releases · kubernetes-sigs/kustomize

Customization of kubernetes YAML configurations. Contribute to kubernetes-sigs/kustomize development by creating an account on GitHub.

github.com

 

wget https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv5.0.1/kustomize_v5.0.1_linux_amd64.tar.gz


압축 풀어주고

tar -xvf kustomize_v5.0.1_linux_amd64.tar.gz


PATH 경로로 옮겨주면 구성 완료

 

mv kustomize /usr/local/bin


버전 확인해주며 마무리

 

kustomize version

Step 5 - Install Kubeflow

 

쿠버네티스를 설치하는 방식에는 크게 두 가지가 있다.

 

1. Single-command installation of all components under apps and common

2. Multi-command, individual components installation for apps and common

2번의 경우 각각의 개별적인 구성 요소들을 독립적으로 설치하는 옵션이다. 해당 사이트에 들어간 이후 설명대로 복사 붙여넣기만 하면 된다. 다만, 상당히 귀찮은 것을 확인할 수 있다.

 

해당 문서에서 진행하고자 하는 것은 Single-command로 명령어 한줄로 manifest들을 적용하여 kubeflow의 모든 구성요소를 설치하는 옵션이다.

 

manifest를 일단 가져와서 준비해준다.

 

cd ~
git clone https://github.com/kubeflow/manifests.git
cd manifests

 


다음 명령어를 통해 설치를 진행한다.

 

while ! kustomize build example | awk '!/well-defined/' | kubectl apply -f -; do echo "Retrying to apply resources"; sleep 10; done

 


약 10분 가량의 시간이 흐르고 설치가 완료되었다.

 

Step 6 - Connect to your Kubeflow Cluster (Port-Forward)

 

설치가 완료되었다면, Pod이 완전히 다 뜨는 것을 확인 후에 다음 단계로 넘어가자

 

kubectl get pods -n cert-manager
kubectl get pods -n istio-system
kubectl get pods -n auth
kubectl get pods -n knative-eventing
kubectl get pods -n knative-serving
kubectl get pods -n kubeflow
kubectl get pods -n kubeflow-user-example-com

 

kubeflow에 접근하는 기본적인 방식은 Port-forwarding이며, 이를 통해 해당 kubernets 환경에 별도 요구사항 없이도 kubeflow와 유저 간의 연결이 가능해진다.

 

앞서 설치된 Istio의 ingressgateway를 port-forwarding하여 Local Port 8080을 Remote port 80(pod 쪽)로 연결한다.

 

이후 다음을 통해 Kubeflow Central Dashboard에 접속한다. 1. 브라우저를 열고 http://localhost:8080으로 접속한다. Dex login 화면이 보인다면 성공 2. default user credential로 로그인한다. default email 주소는 user@example.com이고 비밀번호는 12341234이다.

NodePort/LoadBalancer/Ingress를 사용하기 위해서는 HTTPS를 사용해야만 한다. 이는 kubeflow의 많은 web app들이 Secure Cookie를 사용하고 있기 때문이다.

문제 상황

sudo dpkg --configure -a 시에 다음과 같은 문제가 발생

error: parsing file '/var/lib/dpkg/updates/0001' near line 0: newline in field name `#padding'

해결

# 백업 파일로 남겨두고 다시 시도 
sudo mv /var/lib/dpkg/updates/0001 /var/lib/dpkg/updates/0001.X

sudo dpkg --configure -a

'DevOps' 카테고리의 다른 글

[Kubeflow] pipeline  (0) 2023.04.07
[Kubeflow] MLOps 개발환경 설정  (0) 2023.04.07
Could not get lock /var/lib/dpkg/lock-frontend  (0) 2023.03.23
sudo ubuntu-drivers autoinstall 오류  (0) 2023.03.23
쿠버네티스 패턴 (1장 개요)  (1) 2022.11.15

문제 상황

sudo apt-get install -y ca-certificates curl gnupg lsb-release

E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?

해결

sudo rm /var/lib/apt/lists/lock
sudo rm /var/cache/apt/archives/lock
sudo rm /var/lib/dpkg/lock*

sudo dpkg --configure -a  && sudo apt update

문제 상황

sudo ubuntu-drivers autoinstall

Reading package lists... Done
Building dependency tree
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:
The following packages have unmet dependencies:
 virtualbox-guest-dkms-hwe : Conflicts: virtualbox-guest-dkms

충돌로 인해 정상적으로 설치가 되지 않는 상황이다.

sudo apt-get remove virtualbox-guest-dkms virtualbox-guest-dkms-hwe

두 패키지를 삭제를 하면 문제가 해결될 줄 알았으나, 문제는 해결되지 않는다.

해결

sudo apt-get install virtualbox-guest-dkms

해당 패키지를 설치해주고, 원래 명령어를 실행하면 이제야 정상적으로 설치가 완료됌을 볼 수 있다.

sudo ubuntu-drivers autoinstall
...
The following packages will be REMOVED:
  virtualbox-guest-dkms
The following NEW packages will be installed:
  virtualbox-guest-dkms-hwe
0 upgraded, 1 newly installed, 1 to remove and 65 not upgraded.
...
DKMS: install completed.

또한 내부적으로 의존성을 자동으로 해결하는 것을 볼 수 있다.

쿠버네티스 패턴 (1장 개요)

mydailylogs
|2022. 11. 15. 07:24

소개글

본격적인 패턴 소개 이전에 클라우드 네이티브 애플리케이션을 지탱하는 쿠버네티스의 핵심 개념들을 설명한다. 구체적인 쿠버네티스 리소스를 통해 주로 쿠버네티스의 추상화 방식에 대해서 다루게 된다.

DDD

도메인 주도 설계(Domain Driven Design)는 이를 사용하는 사람들의 영역 또는 지식의 영역을 중심으로 하는 소프트웨어 개발 철학이다. 과거의 많은 소프트웨어 설계에서는 객체가 가져야 할 데이터에 초점을 두어 객체를 설계하였다(데이터 주도 설계, Data Driven Design). 이러한 방식은 객체 자신이 포함하는 데이터를 조작하는 데에 있어서는 좀 더 용이할지 모르나, 실제 비즈니스 레벨에서 다뤄져야 하는 내용들이 코드 상에 반영되지 못하고, 소프트웨어와 현실 간의 괴리가 발생하는 경우가 많았다. 또한 설계 시에 협력을 고려하지 않았기에, 이 후 수정이 발생하는 경우 많은 비효율이 발생한다. 해당 객체의 의미가 무엇이고 어디에 사용되는지 본인 조차 모르는 경우가 종종 발생한다.

DDD는 이러한 괴리를 해소하기는 데에 초점을 둔다. DDD에서는 해당 소프트웨어가 사용될 실제 비즈니스 영역에서부터 출발한 설계를 지향한다. 이때의 도메인은 실제 세계에서 사건이 발생하는 집합 정도로 생각할 수 있을 것 같다. 즉, DDD는 현실에서 출발한 여러 도메인들의 상호작용을 객체 지향적인 언어로 풀어낸다고 이해할 수 있을 거 같다.

바운디드 컨텍스트 (Domain Driven Design):

  • DDD의 중심 패턴. 컨텍스트를 적절하게 식별 및 분리를 통해 마이크로서비스로 전환할 수 있다.
  • OOP에서 하나의 객체에 넣을 기능의 범위를 고민하듯, 하나의 컨텍스트 내부에도 어느 정도의 기능을 넣을지 고민해야 한다.
  • 앞서, 데이터 주도 설계가 객체들을 Public하게, 즉 누구나 접근 가능하게 열어 놓았다면 DDD에서는 Bounded Context를 통해 실제 해당 도메인 내에서만 객체들이 상호작용할 수 있도록 설계한다. 이를 서비스 관점에서 바라보게 되면 MSA를 의미하게 된다.

해당 교재에서는 가볍게 이러한 주제가 있다는 정도로 소개하고 넘어가지만, DDD는 MSA를 지탱하는 주요한 개념이기 향후 DDD를 본격적으로 공부하여 포스팅할 계획을 세우고 있다.

클라우드 네이티브의 단계

책에서는 현대 MSA 환경의 추상화 레벨을 다음과 같이 표현한다. 

Level 0: 코드 레벨
변수와 메소드, 인스턴스화하기로 결정한 클래스 등을 의미한다.

Level 1: 도메인 주도 설계
실제 비즈니스에 최대한 가깝게 설계하도록 소프트웨어를 설계하는 일종의 방법론.
비즈니스 경계 (바운디드 컨텍스트), 트랜젝션 경계(애그리깃), 사용하기 쉬운 인터페이스, 풍부한 API 등이 고려된다.

Level 2: 마이크로서비스 아키텍처 방식
분산 애플리케이션 설계 원칙을 고려하여 소프트웨어 아키텍처를 구성한다.
스케일(scale out/up), 회복성(resiliency) 등이 충족된다.

Level 3: 쿠버네티스 패턴(컨테이너)
컨테이너를 통한 애플리케이션 패키징과 실행이 가능해짐에 따라, 대규모의 컨테이너 기반 마이크로서비스 자동화가 요구된다.
쿠버네티스는 컨테이너 오케스트레이션 도구이자 클라우드 네이티브 플랫폼으로서 컨테이너 환경에서의 자동화와 컨테이너를 다루기 위한 다양한 방법을 제시한다. 해당 교재의 주제이기도 하다.

분산 기본 요소

앞서 언급하였듯 MSA는 DDD로부터 출발한다. DDD가 객체를 도메인 별로 나누었다면, MSA는 DDD에서 객체 대신 서비스를 넣었다고 생각할 수 있겠다. 

*로컬 기본 요소(in-process): Java 또는 JVM에서 제공하는 빌딩 블록 요소 
*분산 기본 요소: 클라우드 네이티브 환경에서의 빌딩 블록 요소 (해당 교재에선 쿠버네티스와 같다고 고려)

개념 로컬 기본 요소 분산 기본 요소
캡슐화 동작 클래스 컨테이너 이미지
인스턴스화 동작 객체 컨테이너
재사용 단위 .jar 파일 컨테이너 이미지
컴포지션(Composition) 클래스 A가 클래스 B를 포함 사이드카 패턴
상속 클래스 A가 클래스 B를 확장 'FROM 부모 이미지' 로 만든 컨테이너 이미지
배포 단위 .jar/.war/.ear 파드
빌드 타임 / 런타임 격리 모듈, 패키지, 클래스 네임스페이스, 파드, 컨테이너
초기화 필요 조건 생성자 초기화 컨테이너
초기화 직후 트리고 Init 메소드 postStart
삭제 직전 트리거 Destroy 메소드 preStop
정리(Clenup) 절차 finalize(), 셧다운 훅 Defer 컨테이너 (아직 구현 X)
비동기 & 병렬 실행 ThreadPoolExcutor, ForkJoinPool
주기적 작업 Timer, ScheduledExecutorService 크론잡
백그라운드 작업 데몬 스레드 데몬셋
설정 관리 System.getenv(), Properties 컨피그맵, 시크릿

짚고 넘어가야할 것은

분산 기본 요소와 객체 지향 방식의 로컬 기본 요소는 직접적으로 비교하거나 대체가 일반적으로 불가능하다.
애초에 추상화 레벨이 다르기에 두 개념 간의 기본 요소가 직접적으로 겹친다고는 할 수 없다.

 

컨테이너와 파드

쿠버네티스를 배우기 시작하는 입장에서 컨테이너와 파드 간의 차이만큼 혼동되는 개념도 없다. 해당 파트는 본격적으로 쿠버네티스 패턴에 들어가기 이전에 쿠버네티스 기본 요소를 정확히 이해하자는 데에 목적을 둔다.

컨테이너는 다음의 특징을 갖는다.

  • 쿠버네티스 기반 클라우드 네이티브 애플리케이션의 빌딩 블록 (패키징 및 격리를 제공하는 단위로 기능)
  • 컨테이너 이미지: 인스턴스화 이전의 클래스와 유사하다.
  • 클래스의 확장 및 수정이 이뤄지듯, 컨테이너 이미지의 버저닝(versioning)을 통한 확장과 수정이 가능하다.
  • 하나의 문제를 해결하는 기능 단위이며 독립적인 릴리스 주기를 갖는다.
  • 독립된 런타임과 배포를 제공한다.
  • 대부분의 경우, 1 마이크로서비스 = 1 컨테이너 이미지 이다.

파드는 다음의 특징을 갖는다.

  • 컨테이너 그룹의 수명주기를 관리하기 위한 분산 기본 요소
  • 컨테이너 그룹의 스케줄링과 배포, 격리된 런타임에 대한 최소 단위
  • 파드 냉부의 모든 컨테이너는 같은 호스트에 스케쥴링
  • 파일 시스템, 네트워크 자원, 프로세스 네임스페이스 등을 공유

위의 이유로 인해 파드 내에서는 파일 시스템 / 로컬 호스트 / IPC 등을 통해 컨테이너 간의 상호작용이 가능해진다.

즉, 쿠버네티스 내에서 애플리케이션이 스케쥴링되는 최소 단위는 파드이고, 그 내부에서 실제 실행되는 이미지는 컨테이너라고 이해할 수 있다.

서비스

쿠버네티스를 이루는 가장 주요한 특징 중의 하나는 HA를 위해서 파드가 언제든지 죽고 다시 시작될 수 있다는 점이다. 때문에 기존의 하드웨어에서 이뤄지는 네트워킹과 쿠버네티스에서 이뤄지는 네트워킹은 달라야 한다. 이를 가능하게 해주는 것이 바로 쿠버네티스의 기본 리소스 중 하나인 서비스이다.

주요한 서비스 요소로는 Cluster IP / Node Port / Load Balancer 등이 있으며, 엄밀하게 말해서 앞서 설명한 서비스의 역할을 수행하는 자원은 이 중 Cluster IP이다. ClusterIP 파드들이 클러스터 내부의 다른 리소스들과 통할 수 있도록 해주는 가상의 클러스터 전용 IP다. 이 유형의 서비스는 <ClusterIP>로 들어온 클러스터 내부 트래픽을 해당 파드의 <파드IP>:<targetPort>로 넘겨주도록 동작하므로, 오직 클러스터 내부에서만 접근 가능하게 된다. 

요약하자면 다음과 같다.

  • 언제나 삭제되고 변경될 수 있다는 파드의 특성을 고려한 네트워킹 리소스
  • 파드의 주소는 애플리케이션 실행 중에도 변경 가능하다.
  • 예를 들어, 클러스터의 노드에 문제가 생기면, 파드는 정책에 따라 다른 노드로 옮겨간다.  스케줄링된 노드가 변경됨에 따라 파드의 IP 주소도 변경된다.
  • 대신 서비스에서는 고정 불변한 IP 주소와 포트를 제공한다.
  • 서비스는 실제 파드의 IP 주소에 접근하지 않고도, 파드와 연결을 유지할 수 있는 방법을 제공한다.
  • 즉, 서비스의 가장 기본적인 역할은 특정 파드의 IP 주소와 포트로의 진입점 역할을 수행하는 것이다.

레이블 애노테이션

쿠버네티스를 사용해봤다면 레이블을 통해 클러스터 내에 배포를 해본 경험이 있을 것이다. 레이블 셀렉터와 레이블을 통해 쿠버네티스 리소스들이 어떤 도메인으로 묶이는지를 구분한다고 이해하는 것은 그리 어렵지 않다. 다만, 레이블과 상당히 유사하지만 다른 역할을 수행하는 애노테이션이라는 요소가 있다. 해당 섹션에서는 두 주제 간의 차이를 비교해보고자 한다.

먼저 레이블을 요약하자면 다음과 같다.

  • Key: Value 쌍의 Map 형태로 구성됨
  • 마이크로서비스로 넘어오면서, 하나의 애플리케이션 레벨로 수행하는 핵심 아티팩트 개념이 사라짐
  • 그럼에도 특정 서비스들이 하나의 애플리케이션에 속함을 표현할 경우가 발생 -> 레이블의 활용
  • 레이블을 통해 하나의 논리적 단위로 관리 가능, 객체 간의 매칭과 쿼리 시에 활용
  • 스케쥴러에서는 요구사항에 맞는 노드에 파드를 배치하기 위해, 레이블을 통해 파드들을 분산시키기도하고, 단일 노드에 위치시키기도 함.

이어서 애노테이션을 요약하자면 다음과 같다.

  • Key: Value 쌍의 Map 형태로 구성됨
  • 사람보다는 기계를 위한 용도
  • 검색 불가능한 메타데이터를 지정하는데 활용
  • 주로 다양한 도구나 라이브러리와의 상호작용을 위해 객체에 추가적인 메타데이터를 추가하는 용도

즉 두 요소의 차이를 다음과 같이 이해할 수 있겠다.

  1. 특정 자원에 동작을 수행하거나 쿼리를 수행 -> Label
  2. 기계가 인식하는 메타에이터 추가 -> Annotation

네임 스페이스

쿠버네티스 클러스터를 논리적 자원 풀로 나누는 데 활용되는 쿠버네티스 기본 리소스이다. 사실 네임스페이스라는 개념은 쿠버네티스의 고유한 개념은 아니고, 리눅스의 cgroup을 통해 관리되는 네임스페이스로부터 출발한다. 이때 네임스페이스를 통해 격리된 환경들은 멀티 테넌시 환경으로 활용될 수 있다. 해당 클러스터 내의 네임스페이스의 이름은 겹치지 않아야 하며, 이는 노드나 PersistentVolume과 같은 기본 요소도 마찬가지이다. 

이때, 주의해야할 점은 네임스페이스가 클러스터 자원에 대해서 논리적인 영역을 제공하긴 하지만, 하나의 자원이 다른 자원에 접근하는 것을 막을 수는 없다는 점이다. 파드의 IP를 무슨 이유에서인지 알고 있다면 이를 통해 내가 가진 프로필과 다른 네임스페이스에 대해서도 접근이 가능하다.

이후 2장에서 소개될 
ResourceQuota를 통해 네임스페이스 당 자원 소모량을 제한할 수 있다.