고기 대신 SW 한점/Public Cloud

Kubernets 구조, Yaml file 이해하기

지식한점 2023. 8. 4. 09:45
반응형

 

►Kubernetes 구조

쿠버네티스의 핵심 개념을 한 줄로 표현하자면, 계속해서 원하는 상태를 만들기 위해 현재 상태를 바꾸는 플랫폼입니다. 예를 들어 내가 원하는 컨테이너를 쿠버네티스에 알려주면 (Desired State) 쿠버네티스는 계속해서 Current State(현재상태) 를 체크합니다. 단순히 컨테이너 뿐만 아니라 네임스페이스나 네트워크, 스토리지 같은 부분도 동일하게 동작합니다.

 

 

 

 

 

쿠버네티스는 가장 먼저 클러스터 구조를 이해할 필요가 있습니다. 클러스터는 여러 대의 컴퓨터가 모여서 같은 목적으로 수행되는 컴퓨터들의 집합이라고 볼 수 있는데, 이때 클러스터 전체를 관리하는 컨트롤러로서 마스터가 존재하고, 컨테이너가 배포되는 물리적인 머신을 노드라고 하게 됩니다.

마스터에는 kube-api-server, kube-controller-manager, kube-scheduler, cloud-controller-manager, etcd 등의 컴포넌트가 실행됩니다. 상세한 내용은 아래와 같습니다.

► Master Node

 

 

kube-apiserver

kube-apiserver는 쿠버네티스 클러스터의 api를 사용할 수 있도록 하는 컨트롤 플레인 컴포넌트 입니다. 즉 api 서버는 쿠버네티스 프론트 엔드로서 클러스터로 온 요청이 유효한지 검증하고, api서버를 통해 다른 컴포넌트가 서로 필요한 정보를 주고받게 됩니다. 특히 etcd에는 api 서버만 접근할 수 있습니다.

 

etcd

etcd는 쿠버네티스에서 필요한 모든 데이터를 키-값 형태로 저장하는 저장하는 데이터베이스 역할을 합니다. etcd는 서버 하나당 프로세스 1개만 사용할 수 있는데, 보통 etcd 자체를 클러스터링 한 후 여러 개 마스터 서버에 분산해서 실행해 안정성을 보장하도록 합니다.

 

kube-scheduler

현재 클러스터 안에서 자원 할당이 가능한 노드 중 알맞은 노드를 선택해서 새로운 파드를 실행해주는 역할을 합니다. 처음 파드가 실행될 때 최소 할당되어야 하는 ram과 같은 설정들을 할 수 있는데, 이러한 조건에 맞추어 알맞은 노드에 파드를 실행시켜주는 자동화 작업해주게 됩니다.

 

kube-controller-manager

쿠버네티스의 파드들을 관리하는 컨트롤러입니다. 컨트롤러 각각은 논리적으로 개별 프로세스지만 복잡도를 줄이려고 모든 컨트롤러를 바이너리 파일로 컴파일해서 단일 프로세스로 실행합니다.

 

cloud-controller-manager

cloud-controller-manager는 쿠버네티스의 컨트롤러들을 클라우드 서비스와 연결해서 관리하는 컴포넌트입니다.

 

Work Node

kubelet

kubelet은 클러스터 안 모든 노드에서 실행되는 에이전트입니다. 파드스펙(PodSpec) 설정을 전달받아서 파드 컨테이너의 실행을 직접적으로 관리하고 해당 컨테이너가 정상적으로 실행되는지 헬스 체크를 진행합니다.

단, 노드 안에 있는 컨테이너라도 쿠버네티스를 통해서 만들어지지 않은 컨테이너는 관리하지 않습니다.

 

kube-proxy

쿠버네티스는 클러스터 안에서 별도의 가상 네트워크를 생성하고 관리하게 되는데, kube-proxy는 이런 가상 네트워크의 동작을 관리하는 컴포넌트입니다.

 

컨테이너 런타임

실제로 컨테이너를 실행시키는 컴포넌트입니다. 가장 많이 사용하는 런타임으로 Docker를 주로 사용합니다.

 

Node >  Pod  >  Container

pod

- K8S에서 컨테이너가 동작되는 기본자원을 PoD란 이름으로 정의함 

- pod안에 주로 한 개의 컨테이너만 위치하나 직접 종속된 한두개의 컨테이너를 더 둘 수도 있음

- pod에 적정한 스토리지, 네트워킹기능을 할당할 수 있고, 한 개의 PoD 안의 컨테이너들은 이를 공유함

 

오브젝트

쿠버네티스를 이해하기 위해 가장 중요한 부분이 오브젝트입니다. 가장 기본적인 구성단위가 되는 기본 오브젝트와(Basic Object)와, 기본 오브젝트를 생성하고 관리하는 추가적인 기능을 가진 컨트롤러(Controller)로 이루어집니다. 그리고 이러한 오브젝트의 스펙(설정)이외에 메타 정보들로 구성이 되게 됩니다.

 

오브젝트 스펙

오브젝트들은 모두 오브젝트의 특성을 기술한 오브젝트 스펙으로 기술됩니다. 오브젝트 스펙을 기술하기 위해서는 cli를 이용해 직접 명령어를 실행시키거나, yaml 파일이나 json과 같은 템플릿 형식으로 오브젝트 스펙을 정의할 수 있습니다.

 

※ 최근에는 거의 yaml파일을 이용해 기술하고 있습니다.

 

Namespace

네임스페이스는 하나의 쿠버네티스 클러스터 안의 논리적인 구분 단위입니다. pod나 service 등은 네임 스페이스 별로 생성이나 관리될 수 있고, 사용자의 권한 역시 네임 스페이스 별로 나눠서 부여할 수 있습니다.

 

예를 들어 하나의 클러스터 내에 개발 / 운영 / 테스트 환경과 같이 3개의 네임 스페이스로 나눠서 각각의 네임스페이스를 논리적으로 독립해서 운영할 수 있게 됩니다. 주의할 점은 방금 언급한 대로 논리적인 분리한 것이기 때문에 다른 네임스페이스간의 pod끼리도 통신이 가능하게 됩니다.

 

따라서 높은 수준의 분리 정책을 원할 경우에는 클러스터 자체를 분리하는 것을 권장합니다.

 


템플릿

쿠버네티스 클러스터의 오브젝트나 컨트롤러가 어떤 상태여야 하는지를 적용할 때 YAML 형식의 템플릿을 사용합니다. YAML은 문법이 간결하고 주석도 지원하기 때문에 가독성이 좋습니다.

 

YAML은 기본적으로 3가지 형식이 있는데, 가장 단순한 형태로는 Scalars가 있습니다. key-value로 이루어진 형식으로 stirng값과 number 값을 value로 가집니다

 

 

 

기본 오브젝트(Basic Object)

쿠버네티스에 의해 배포 및 관리되는 가장 기본적인 오브젝트로 Pod, Service Volume, Namespace 4가지가 있습니다.

 

 

► Kubernetes Configuration File (YAML format)

 

YAML은 사람이 읽을 수 있는 데이터 직렬화 언어로서, 구성 파일 작성에 자주 사용됩니다. YAML을 yet another markup language로 생각하는 사람도 있고, YAML ain’t markup language(재귀 약어)로 생각하는 사람도 있습니다. 후자는 YAML이 문서가 아닌 데이터용임을 강조하는 말입니다. 

 

YAML 구문

YAML 파일은 .yml 또는 .yaml 확장자를 사용하며 특정 구문 규칙을 따릅니다. 

YAML에는 Perl, C, XML, HTML, 기타 프로그래밍 언어에서 유래한 기능이 있습니다. 또한 YAML은 JSON의 상위 집합이므로 YAML에서 JSON 파일을 사용할 수 있습니다.

중괄호, 대괄호, 닫기 태그 또는 따옴표와 같은 통상적인 형식 기호는 없습니다. 또한 YAML 파일은 Python 스타일의 들여쓰기를 사용해 구조를 결정하고 중첩을 표시하므로 더 읽기 쉽습니다. 시스템 전반에서 이식성을 유지하기 위해 의도적으로 탭 문자를 허용하지 않으므로 문자 그대로의 공백 문자인 공백이 대신 사용됩니다. 

코멘트는 파운드 또는 해시 기호(#)로 식별할 수 있습니다. 코멘트는 코드의 의도를 설명해 주므로 코멘트를 사용하는 것은 항상 권장됩니다. YAML은 여러 줄의 코멘트를 지원하지 않으므로 각 줄의 맨 앞에는 파운드 문자가 와야 합니다.

YAML 초심자가 흔히 하는 질문은 "3개의 대시는 무엇을 뜻하나요?"입니다. 3개의 대시(---)는 문서의 시작을 알리는 데 사용되며, 각 문서의 끝에는 3개의 점(...)이 사용됩니다.  

YAML 파일의 매우 기본적인 예시는 다음과 같습니다.

#Comment: This is a supermarket list using YAML #Note that - character represents the list --- food: - vegetables: tomatoes #first list item - fruits: #second list item citrics: oranges tropical: bananas nuts: peanuts sweets: raisins

 

 

YAML 파일의 구조는 맵 또는 목록이며 들여쓰기와 키 값 정의 방식에 따라 계층 구조를 준수합니다. 맵 구조에서는 키-값 쌍을 연결할 수 있습니다. 각 키는 고유해야 하며 순서는 상관없습니다. Python 사전, 또는 Bash 스크립트의 변수 할당을 생각해 보세요.

YAML의 맵은 먼저 해결해야 닫을 수 있고, 그런 다음 새 맵이 생성됩니다. 들여쓰기 수준을 높이거나 이전 맵을 해결하고 인근 맵을 시작함으로써 새 맵을 생성할 수 있습니다.

목록의 값은 특정 순서로 나열되며, 목록 하나에 필요한 수의 항목을 포함할 수 있습니다. 목록 시퀀스는 대시(-) 및 공백으로 시작하며 들여쓰기로 상위 항목과 구분합니다. 여기서 시퀀스는 Python 목록 또는 Bash나 Perl의 어레이에 해당합니다. 목록을 맵에 포함할 수 있습니다.

위 예시에서 'vegetables' 및 'fruits'은 'food'이라는 이름을 가진 목록을 구성하는 항목들입니다.

또한 YAML은 스칼라를 포함할 수 있는데, 스칼라란 문자열, 정수, 날짜, 숫자 또는 부울 등의 값으로 사용할 수 있는 임의의 데이터(유니코드로 인코딩됨)를 말합니다.

YAML 파일을 생성할 때는 이러한 구문 규칙을 준수하고 파일이 유효한지 확인해야 합니다. 이를 위해 파일의 구문을 검증하는 애플리케이션인 린터(linter)를 사용할 수 있습니다. YAML 파일을 생성한 후 애플리케이션에 전달하기 전에 yamllint라는 커맨드로 유효성을 확인할 수 있습니다.

쿠버네티스용 YAML

쿠버네티스는 정의된 상태와 실제 상태를 기반으로 작동합니다. 쿠버네티스 오브젝트는 클러스터의 상태를 나타내며, 사용자가 바라는 워크로드 상태를 쿠버네티스에 알리는 역할을 합니다. YAML 파일을 사용해 포드, 오브젝트, 배포와 같은 쿠버네티스 리소스를 생성할 수 있습니다. 

쿠버네티스 오브젝트를 생성할 때는 원하는 오브젝트 상태를 정의하기 위한 사양을 포함해야 합니다. 쿠버네티스 API를 사용해 오브젝트를 생성할 수 있습니다. API에 대한 요청에는 오브젝트 사양이 JSON으로 포함됩니다. 하지만 대부분의 경우 필요한 정보를 kubectl에 YAML 파일로 제공하게 됩니다. Kubectl은 API 요청 시 이 파일을 YAML로 변환합니다.

일단 오브젝트가 생성 및 정의되고 나면 쿠버네티스가 작동하여 해당 오브젝트가 항상 존재하게 합니다. 

개발자 또는 시스템 관리자는 YAML 또는 JSON 파일을 사용하여 정의된 상태를 지정하고 쿠버네티스 API에 제출합니다. 쿠버네티스는 컨트롤러를 사용하여 새롭게 정의된 상태와 클러스터의 실제 상태 간 차이점을 분석합니다.

 

Cluster에 원하는 서비스를 Deploy 하는 것은 결국 이러한 파일을 만들어서 API-Server를 통해 파일에 기술한 정보대로 Master내의 etcd에 원하는 상태정보를 만들게 하는 것이다.

사람이 읽기 쉬운 데이터 직렬화 양식입니다.

💡 Syntax: strict indentation!(들여쓰기)

 

Fields of Kubernetes Definition File

  • apiVersion

오브젝트를 생성하기 위해 사용하고 있는 쿠버네티스 API 버전

  • kind

어떤 종류의 쿠버네티스 오브젝트 리소스인지 기술

  • metadata

오브젝트를 구별해줄 수 있는 데이터

name, label, namespace, annotations …

  • spec

오브젝트로 생성하고자 하는 리소스의 구체적인 정보

  • status

현재 오브젝트의 상태

쿠버네티스에 의해 자동으로 생성

 

오브젝트: 원하는 상태가 저장된 쿠버네티스 객체

 

🔎 apiVersion

 오브젝트를 생성하기 위해 사용하고 있는 쿠버네티스 API 버전

  • v1: 쿠버네티스에서 발행한 첫 stable release API

 대부분의 api 포함

 Pod, Namespace, Node, Service, …

  • apps/v1: 쿠버네티스의 common API 모음

 Deployment, RollingUpdate, ReplicaSet, …

  • rbac.authorization.k8s.io/v1

 쿠버네티스의 role-based access control이 가능한 function 정의

 ClusterRole, RoleBinding, Role, …

 

kind

 어떤 종류의 쿠버네티스 오브젝트 리소스인지 기술

  • Pod: 쿠버네티스에서 배포할 수 있는 가장 작은 컴퓨팅 단위
  • ReplicaSet: Pod의 replica 개수 유지를 보장하는 컨트롤러
  • Deployment: Pod와 ReplicaSet에 대한 업데이트를 가능하게 하는 컨트롤러
  •  

spec

 오브젝트로 생성하고자 하는 리소스의 구체적인 정보

 쿠버네티스 리소스마다 요구하는 spec 필드의 정보는 다를 수 있음

 ex) Deployment

- selector: matchLabels와 동일한 label값을 가진 리소스를 선택

- replicas: 리소스를 몇 개의 복제본으로 생성할지

- template: 해당 오브젝트의 구체적인 형식

- metadata: 생성할 리소스의 기본 정보

- spec: 생성할 리소스(ex. Pod)의 구체적인 스펙 정보

 

 

status

쿠버네티스에 의해서 자동으로 생성

의도하는 상태(desired status)와 현재 상태(actual status)를 꾸준히 비교하고 업데이트

# desired status: 사용자가 배포하고자 하는 쿠버네티스 오브젝트에 대해 원하는 상태, yaml 파일을 이용하거나 run/create 과 같은 명령어를 이용하여 명시

# actual status: 해당 쿠버네티스 오브젝트의 실제 상태

 

이 두 상태가 일치하지 않을 경우, 쿠버네티스는 의도하는 상태(desired status)로 바꾸기 위한 관리 시작

 

Compare desired status and actual status, Kubernetes detect problem and create replica as soon as possible (1 -> 2)
예를 들어 Replica가 의 counts가 2개인데 Status에 1로 되어 있으면 2로 변경되게 됩니다.

 

etcd에 쿠버네티스의 모든 구성 요소의 현재 status를 저장하고 있음 (key-value storage)

 

 

Labels & Selectors 기본 정의

 

 

  • Label (식별 데이터)

쿠버네티스 오브젝트를 식별하기 위한 key/value 쌍의 메타 정보

쿠버네티스 리소스를 논리적인 그룹으로 나누기 위해 붙이는 이름표 (모든 오브젝트에 붙일 수 있다)

 

  • Selector

Label을 이용해 쿠버네티스 리소스를 필터링하고 원하는 리소스 집합을 구하기 위한 label query

ex) show me all the objects which has label where env: prod

 

 

ex) show me all the objects which has label where env: dev

 

사용 예시

  1. 클러스터에서 서로 다른 팀의 수백 개 pod 중, 주문 트래픽을 주문 pod으로 배달 트래픽을 배달 pod으로 라우팅 해야 할 때
  2. 배달 트래픽이 증가되는 상황에서 클러스터에서 실행 중인 배달 관련 Pod들을 수평 확장해야 할 때

 

  • Annotation

비-식별 메타데이터를 의미

따라서, 레이블과는 다르게 어노테이션을 통해 검색이나 리소스 간의 연결을 할 수는 없음 

👉 사용 예시

  어노테이션은 단순하게 메타데이터(리소스에 대한 정보)를 저장하는 용도로 사용

반응형