컨테이너화된 워크로드와 서비스를 관리하기 위한 이식성이 있고, 확장가능한 오픈소스 플랫폼
🤔 워크로드란? 비즈니스 가치를 창출하는 리소스 및 코드 모음
쿠버네티스가 유용해질 때 까지의 시장 변화를 알아보자.
쿠버네티스는 전통적인 (모든 것이 포함된) PaaS(Platform as a Service)가 아니다. 이는 컨테이너 수준에서 운영되며 (PaaS가 일반적으로 제공하는) 배포, 스케일링, 로드 밸런싱과 같은 기능을 제공한다.
Monolithic이 아니므로 기본 솔루션은 선택적으로 추가/제거 할 수 있다. 즉, 사용자의 선택권과 유연성을 지켜준다.
어플리케이션이 실행되고 있는 환경을 지속적으로 모니터링하고 문제 상황이 발생하면 (서버가 다운되는 등의) 이를 시스템이 자동으로 처리해준다면 참 편리할 것이다!
그리고 이를 가능하게 해주는 것이 쿠버네티스이다.
쿠버네티스는 분산 시스템을 탄력적으로 실행하기 위한 프레임 워크를 제공한다.
쿠버네티스가 제공하는 구체적인 기능은 다음과 같다.
❗️ 쿠버네티스 클러스터란 컨테이너화된 어플리케이션을 실행하는 "노드"라는 워커 머신의 집합이다. (모든 클러스트는 최소 한 개의 워커 노드를 가진다.)
컨테이너는 파드 내에 배치되고 노드에서 실행되는데, 이 때 노드는 클러스터에 따라 가상 또는 물리 머신 일 수 있다.
- 파드(Pod) : 쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위. 하나 이상의 컨테이너 그룹을 의미한다.
컨트롤 플레인은 워커 노드와 클러스터 내 파드를 관리한다.
컨트롤 플레인을 구성하는 컴포넌트는 다음과 같다
쿠버네티스 컨트롤 플레인의 핵심은 API 서버이다.
API 서버는 최종 사용자, 클러스터의 다른 부분, 외부 컴포넌트가 서로 통신할 수 있도록 HTTP API를 제공한다.
노드 컴포넌트는 동작 중인 파드를 유지시키고 쿠버네티스 런타임 환경을 제공하며, 모든 노드 상에서 동작한다.
애드온은 쿠버네티스 리소스(데몬셋, 디플로이먼트 등)를 이용해 클러스터 기능을 구현한다.
쿠버네티스 오브젝트란 쿠버네티스 시스템에서 영속성을 가지는 오브젝트로써 클러스터의 상태를 나타내기 위해 이용한다.
오브젝트를 생성함으로써, 클러스터의 워크로드를 어떤 형태로 보이고자 하는지 쿠버네티스 시스템에 효과적으로 전달 할 수 있다. 이것이 바로 의도한 상태가 되는 것이다.
쿠버네티스 오브젝트는 오브젝트의 구성을 결정해주는 두 개의 중첩된 오브젝트 필드를 포함하는데,
이다.
❗️ 쿠버네티스 컨트롤 플레인은 모든 오브젝트의 실제 상태를 사용자가 의도한 상태와 일치시키기 위해 끊임없이 능동적으로 관리한다.
쿠버네티스에서 오브젝트를 생성할 때는
을 제시해줘야만 한다.
대부분의 경우 정보를 .yaml 파일로 kubectl
에 제공하며 kubectl
은 API 요청이 이루어질 때, JSON 형식으로 정보를 변환시켜 준다.
Example :
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
apiVersion
: 이 오브젝트를 생성하기 위해 사용하고 있는 쿠버네티스 API 버전이 어떤 것인지kind
: 어떤 종류의 오브젝트를 생성하고자 하는지metadata
: name
, UID
, 선택적인 namaspace
를 포함. 오브젝트를 유일하게 구분지어 줄 데이터spec
: 오브젝트에 대해 의도한 상태 (정확한 포맷은 쿠버네티스 오브젝트마다 다르며 중첩된 필드를 포함한다.)예를 들어, 이름이 myapp-1234
인 파드는 동일한 네임스페이스에서 하나만 존재할 수 있지만, 이름이 동일한 myapp-1234
인 디플로이먼트는 각각 존재할 수 있다.
✔️ 이름
/api/v1/pods/some-name
과 같이, 리소스 URL에서 오브젝트를 가리키는 클라이언트 제공 문자열.
✔️ UID
오브젝트를 중복없이 식별하기 위해 쿠버네티스 시스템이 생성하는 문자열.
쿠버네티스 클러스터가 구동되는 전체 시간에 걸쳐 생성되는 모든 오브젝트는 기록상 유사한 오브젝트의 출현을 서로 구분하기 위해 고유한 UID를 갖는다.
쿠버네티스는 동일한 물리 클러스터를 기반으로 하는 여러 가상 클러스터를 지원하는데, 이런 가상 클러스터를 네임스페이스라고 한다.
네임스페이스는
❗️ NOTE 리소스쿼터
여러 사용자나 팀이 정해진 수의 노드로 클러스터를 공유할 때, 한 팀이 공정하게 분배된 리소스 이상의 리소스를 사용할 우려가 있다.
리소스 쿼터는 관리자가 이러한 문제를 해결하기 위해 제공되는 도구이다.
ref. https://kubernetes.io/ko/docs/concepts/policy/resource-quotas/
단, 모든 오브젝트가 네임스페이스에 속하는 것은 아니다.
대부분의 쿠버네티스 리소스는 네임스페이스에 속하나, 네임스페이스 리소스 자체는 이에 속하지 않는다. 노드나 persistence volume과 같은 저수준 리소스 또한 네임스페이스에 속하지 않는다.
레이블은 파드와 같은 오브젝트에 첨부된 키값 쌍으로써 오브젝트의 특성을 식별하는데 사용된다. (코어 시스템에 직접적인 의미는 없다.)
레이블을 이용해 느슨한 결합도로 조직 구조와 시스템 오브젝트를 매핑할 수 있으며, 클라이언트에 매핑 정보를 저장할 필요가 없다.
레이블은 오브젝트 생성 시 or 생성 이후에 붙이거나 수정이 가능하며 오브젝트마다 키-값으로 레이블을 정의할 수 있는데, 오브젝트의 키는 고유한 값이어야한다.
Example :
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
이름이나 UID와 다르게 레이블은 고유하지 않다. 일반적으로 많은 오브젝트는 같은 레이블을 가질 수 있다.
그럼 레이블을 통한 오브젝트 구분은 불가능한 것일까? 🤔 레이블 셀렉터를 사용하면 클라이언트와 사용자가 오브젝트를 식별할 수 있다.
API는 현재 두 종류의 셀렉터-일치성 기준, 집합성 기준-를 지원하는데, 이는 쉼표로 구분된 다양한 요구사항에 따라 만들 수 있다. (&&
연산자와 동일한 역할)
✔️ 일치성 기준 요건 : 일치성 기준 또는 불일치 기준의 요구사항으로 레이블의 키와 값의 필터링을 허용한다.
=
, ==
, !=
3가지 연산자만 허용한다.Example :
1) environment = production
2) tier != frontend
1) 키가 environment
이고, 값이 production
인 레이블을 포함하는 모든 리소스를 선택한다.
2) 키가 tier
이지만 값이 frontend
가 아닌 레이블을 포함하는 모든 리소스를 선택한다. (공백 포함)
쉼표를 통해 한 문장으로 environment = production, tier != frontend
로 표현하면 두 조건을 한꺼번에 필터링 할 수 있다.
✔️ 집합성 기준 요건 : 집합성 기준 레이블 요건에 따라 값 집합을 키로 필터링 할 수 있다.
in
, notin
, exists
(키 식별자만 해당) 3가지 연산자만 허용한다.Example :
1) environment in (production, qa)
2) tier notin (frontend, backend)
3) partition
4) !partition
1) 키가 environment
이고 값이 production
또는 qa
인 모든 리소스를 선택한다.
2) 키가 tier
이고 값이 frontend
와 backend
가 아닌 경우의 리소스를 선택한다. (공백 포함)
3) 값에 상관없이 키가 partition
인 레이블을 포함하는 모든 리소스를 선택한다.
4) 값에 상관없이 키가 partition
인 레이블을 포함하지 않는 모든 리소스를 선택한다.
임의의 비식별 메타데이터를 오브젝트에 첨부할 수 있으며, 도구 및 라이브라이와 같은 클라이언트에서 이 메타데이터를 검색할 수 있다.
"metadata": {
"annotations": {
"key1" : "value1",
"key2" : "value2"
}
}
레이블을 사용해 오브젝트를 선택하고, 특정 조건을 만족하는 오브젝트 컬렉션을 찾을 수 있는 것과 달리 어노테이션은 오브젝트를 식별하고 선택하는데 사용되지 않는다. 따라서 어노테이션의 메타데이터는 느슨한 규약을 가지고 있다.
(단, 레이블과 같이 키-값 맵이다.)
필드 셀렉터는 한 개 이상의 리소스 필드 값에 따라 쿠버네티스 리소스를 선택하기 위해 사용된다.
Example :
metadata.name=my-service
metadata.namespace!=default
status.phase=Pending
❗️ NOTE
필드 셀렉터는 본질적으로 리소스 필터이다. 기본적으로 적용되는 셀렉터나 필드는 없으며, 이는 명시된 종류의 모든 리소스가 선택됨을 암시한다.예를 들어
kubectl get pods
는kubectl get pods --field-selector ""
와 동일하다.
https://kubernetes.io/ko/docs/concepts/overview/working-with-objects/common-labels/
쿠버네티스는 플랫폼 서비스(PaaS)가 아니며 어플리케이션에 대해 공식적인 개념이 없거나 강요하지 않는다. 대신 어플리케이션은 비공식적이며 메타데이터로 설명된다. 어플리케이션에 포함된 정의는 유연하다.
메타데이터들은 권장되는 레이블이다. 어플리케이션을 보다 쉽게 관리할 수 있지만 코어 도구에는 사실상 필요하지 않은 요소이다.