Kubernetes object
쿠버네티스 오브젝트 이해하기
- 쿠버네티스 오브젝트 는 쿠버네티스 시스템에서 영속성을 가지는 개체
- 쿠버네티스 오브젝트는 하나의 “의도를 담은 레코드"이다. 오브젝트를 생성하게 되면, 쿠버네티스 시스템은 그 오브젝트 생성을 보장하기 위해 지속적으로 작동
- 생성이든, 수정이든, 또는 삭제든 쿠버네티스 오브젝트를 동작시키려면, 쿠버네티스 API를 이용해야 한다. 예를 들어, kubectl 커맨드-라인 인터페이스를 이용할 때, CLI는 여러분 대신 필요한 쿠버네티스 API를 호출
오브젝트 명세(spec)와 상태(status)
- spec을 가진 오브젝트는 오브젝트를 생성할 때 리소스에 원하는 특징(의도한 상태)에 대한 설명을 제공해서 설정한다.
- status는 오브젝트의 현재 상태 를 기술하고, 쿠버네티스 컴포넌트에 의해 제공되고 업데이트
Writing kubernetes object
- 쿠버네티스 오브젝트 생성시 기본 정보와 상태를 적은 spec이 필요함
- API 요청 시 요청 내용 안에 JSON 정보 포함
- 대부분의 경우
.yaml
파일로kubectl
에 제공
.yaml
파일에 필요한 정보들
apiVersion
: 사용하는 쿠베 API 버전kind
: 어떤 종류의 오브젝트metadata
: 이름,UID
,namespace
등 오브젝트를 유일하게 구분지어줄 데이터spec
: 오브젝트에 의도할 상태
쿠버네티스 오브젝트 관리
kubectl
cmd 툴은 kubernetes 오브젝트를 생성하고 관리하기 위한 방법 제공
- 명령형 커맨드 (Imperactive commands)
- Imperactive object configuration (명령형 오브젝트 구성)
- Declarative object configuration (선언형 오브젝트 구성)
다음 중 하나의 기법만 사용하여 관리하여아한다
Imperactive commands
- 오브젝트를 대상으로 직접 동작시킴
- 일회성 작업을 위한 가장 단순한 방법
kubectl run nginx --image nginx
kubectl create deployment nginx --image nginx
장점
- 커맨드가 간단
- 단 한 단계만으로 클러스터 수정 가능
단점
- 변경 검토 프로세스와 통합 안됨
- 변경 audit trail 제공안됨
- 템플릿 제공 X
Imperactive object configuration
- 명령형 오브젝트 구성에서 kubectl 커맨드는 작업(생성, 교체 등), 선택적 플래그, 그리고 최소 하나의 파일 이름을 정의
kubectl create -f nginx.yaml
kubectl delete -f nginx.yaml -f redis.yaml
kubectl replace -f nginx.yaml
장점
- git 등 소스컨트롤시스템 사용 가능
- 푸시, audit trail 전에 검토하는 등의 프로세스와 통합 가능
- 새로운 오브젝트 생성을 위한 템플릿 제공
- (Declarative object configuration에 비해) 간결하고 이해가 쉬움
단점
- object scheme에 대한 이해 필요
- yaml 기록하는 추가 과정
- (Declarative object configuration에 비해) 디렉토리가 아니라 파일에만 효과가 좋음
Declarative object configurations
- 사용자는 로컬에 보관된 오브젝트 구성 파일을 대상으로 작동시키지만, 사용자는 파일에서 수행 할 작업을 정의하지 않는다
- 생성, 업데이트, 그리고 삭제 작업은 kubectl에 의해 오브젝트 마다 자동으로 감지
예시) configs
디렉토리 내 모든 object config 파일을 처리
kubectl diff -f configs/
kubectl apply -f configs/
장점
- 직접 변경된 사항은 파일로 병합되지 않아도 유지된다.
- 디렉토리의 작업 및 오브젝트별 작업 (생성, 패치, 삭제)의 자동 감지를 더 잘 지원
단점
- 예상치 못한 결과를 디버깅하고 이해하기 어려움
- diff를 사용한 부분 업데이트는 복잡한 패치 작업을 일으킴
실질적으로 helm을 사용한다면 위 기법들을 사용할 일은 딱히 없게 된다. 그래도 기본적으로 저런 방식을 알아두어야 helm - kubernetes 간의 연결고리를 더 명확하게 파악할 수 있을듯하다.
오브젝트 이름과 ID
- 각 오브젝트는 해당 리소스에 대해 고유한 이름을 가지고 있다. (pod에서는 중복 이름 사용 불가, pod/deployment는 같은 이름 사용 가능)
- 전체 클러스터에 걸쳐 고유 UID를 가지고 있다.
- label, annotation은 unique하지 않아도 됨
이름
- 동일한 물리 클러스터에서 다중 가상 클러스터를 지원하기 위해 사용하는 추상화
- 리소스의 이름은 Namespance 내에서는 유일해야함
- DNS subdomain, DNS label, 경로 세그멘트 이름이 필요하고 각각의 제약이 있다. 이 문서에서 확인 가능.
Namespace
Kubernetes는 물리 클러스터를 기반으로 여러 가상 클러스터를 제공하는데, 이를 "Namespace"라고 한다.
- Namespace는 여러 팀, 프로젝트에 걸쳐 사용자가 많은 환경에서 사용하도록 만들어짐
- 클러스터 자원을 여러 사용자 사이에서 나누는 방법
네임스페이스 다루기
$ kubectl get namespace
NAME STATUS AGE
default Active 21d
kube-node-lease Active 21d
kube-public Active 21d
kube-system Active 21d
default
: 다른 네임스페이스가 없는 오브젝트를 위한 기본 네임스페이스kube-system
: 쿠버네티스 시스템에서 생성한 오브젝트를 위한 네임스페이스kube-public
: 이 네임스페이스는 자동으로 생성되며 모든 사용자(인증되지 않은 사용자 포함)가 읽기 권한으로 접근
현재 요청에 네임스페이스를 사용하려면 --namespace
플래그 사용
모든 오브젝트가 네임스페이스에 속하지는 않는다
- 대부분의 Kubernetes 리소스 (Pod, service, replicationController ...)는 네임스페이스에 속한다
- 네임스페이스 자체는 속하지 않음. Node 등 low-level resource도 속하지 않음
# In namespace
kubectl api-resource --namespaced=true
# without namespace
kubectl api-resource --namespaced=false
레이블과 셀렉터
Label
은 pod 등 object에 첨부된 key-value 쌍- 코어 시스템에 직접적인 의미는 없다. (사용자가 식별하기 위해서)
- 언제든지 수정이 가능
사용 동기
- label을 사용하면 사용자가 느슨한 방식으로 구조와 시스템 오브젝트를 매핑할 수 있다
- 예시 (예시를 따를 필요 없이 자유롭게 개발 가능)
- "release" : "stable", "release" : "canary"
- "environment" : "dev", "environment" : "qa", "environment" : "production"
Label selector
이름, UID와 다르게 Label은 unique하지 않음
label selector를 object 식별 가능
OR
연산자는 따로 없다.,
(쉼표)로 연결되면AND
의 의미Equality-based requirement
(일치성 기준 요건)=
,==
,!=
연산자environment = production tier != frontend
- 위의 내용을 선택하려면
environment=production,tier!=frontend
로 쉼표를 통해 한 문장으로 사용하면 된다.
Set-based requirement
(집합성 기준 요건)in
,notin
,exists
연산자environment in (production, qa) tier notin (frontend, backend) partition !partition
- 위 내용을 선택하려면
partition in (customerA, customerB),environment!=qa
API
- List, Watch api 모두 label selector를 지정할 수 있다. (api를 직접 사용할 일은 없겠지만...)
kubectl
에서는 아래와 같이 사용
kubectl get pods -l environment=production,tier=frontend
kubectl get pods -l 'environment in (production), tier in (frontend)'
kubectl get pods -l 'environment in (production, qa)'
kubectl get pods -l 'environment,environment notin (frontend)'
Annotation
kubernetes annotation을 사용하여 비식별된 메타데이터를 오브젝트에 첨부 가능하다.
오브젝트에 메타데이터 첨부
- 앞에 나온 label은 object를 선택하고 조건을 만족하는 object들을 선택할 수 있게 해주었다.
- 반면 annotation은 object를 식별이나 선택하지 못한다.
- 다양한 정보를 기록 가능
- annotation 대신 외부 데이터베이스를 사용할 수도 있지만 더 복잡하고 어려움.
Field Selector (필드 셀렉터)
필드 셀렉터는 resource field 값에 따라 resource를 선택하기 위해 사용
metadata.name=my-service
metadata.namespace!=default
status.phase=Pending
아래와 같이 사용
kubectl get pods --field-selector status.phase=Running
사용 가능한 필드는 리소스 종류마다 다르다.
metadata.name
,metadata.namespace
사용 가능=
,==
,!=
연산자 사용 가능
kubectl get services --all-namespaces --field-selector metadata.namespace!=default
- 다른 셀렉터처럼
,
(쉼표)로 chain 사용 가능
kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always
- 여러 리소스 종류에 걸쳐서 사용 가능하다.
kubectl get statuefulsets,services --all-namespaces --field-selector metadata.namespace!=default
label 셀렉터도 마찬가지지만 많은 리소스를 사용하고 관리하는 게 아니라면 딱히 selector를 사용할 일이 있을까 싶은 생각이 든다.. 특히 kubernetes 관리자가 아니라 제한된 클러스터에 제한된 권한을 가진 사용자라면...
권장 레이블
공통 레이블 셋은 kubectl, dashboard 등 모든 도구들이 이해할 수 있는 공통의 방식으로 오브젝트를 식별 가능하게 해준다.
메타데이터는
application
개념을 중심으로 정리- Kubernetes는 Paas(Platform service)가 아니며 애플리케이션에 대해 공식적인 개념이 없음
- 코어 도구에는 필요하지 않지만 application을 쉽게 관리하게 해줌
공유 레이블/주석에는 공통 접두사인
app.kubernetes.io
가 있음레이블을 최대한 활용하려면 모든 리소스 오브젝트에 적용해야한다.
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app.kubernetes.io/name: mysql
app.kubernetes.io/instance: wordpress-abcxzy
app.kubernetes.io/version: "5.7.21"
app.kubernetes.io/component: database
app.kubernetes.io/part-of: wordpress
app.kubernetes.io/managed-by: helm
예시
simple stateless service
deployment
, service
오브젝트를 통해 배포된 stateless 서비스의 경우
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: myservice
app.kubernetes.io/instance: myservice-abcxzy
...
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: myservice
app.kubernetes.io/instance: myservice-abcxzy
...
deployment, service가 같은 name, instance 라벨을 가짐
데이터베이스가 있는 웹 애플리케이션
WordPress를 배포하는데 다음과 같이 Deployment 로 시작한다.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: wordpress
app.kubernetes.io/instance: wordpress-abcxzy
app.kubernetes.io/version: "4.9.4"
app.kubernetes.io/managed-by: helm
app.kubernetes.io/component: server
app.kubernetes.io/part-of: wordpress
...
Service 는 애플리케이션을 노출하기 위해 사용한다.
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: wordpress
app.kubernetes.io/instance: wordpress-abcxzy
app.kubernetes.io/version: "4.9.4"
app.kubernetes.io/managed-by: helm
app.kubernetes.io/component: server
app.kubernetes.io/part-of: wordpress
...
MySQL은 StatefulSet 에 MySQL의 소속과 상위 애플리케이션에 대한 메타데이터가 포함되어 노출된다.
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app.kubernetes.io/name: mysql
app.kubernetes.io/instance: mysql-abcxzy
app.kubernetes.io/version: "5.7.21"
app.kubernetes.io/managed-by: helm
app.kubernetes.io/component: database
app.kubernetes.io/part-of: wordpress
...
Service 는 WordPress의 일부로 MySQL을 노출하는데 이용한다.
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: mysql
app.kubernetes.io/instance: mysql-abcxzy
app.kubernetes.io/version: "5.7.21"
app.kubernetes.io/managed-by: helm
app.kubernetes.io/component: database
app.kubernetes.io/part-of: wordpress
...
MySQL StatefulSet 과 Service 로 MySQL과 WordPress가 더 큰 범위의 애플리케이션에 포함되어 있는 것을 알게 된다
'backend > kubernetes docs' 카테고리의 다른 글
kubernetes docs - Container (0) | 2020.05.22 |
---|---|
kubernetes docs: 클러스터 아키텍쳐 - 컨트롤러 (controller) (0) | 2020.05.18 |
Kubernetes docs: Cluster Architecture - Node (0) | 2020.05.17 |
쿠버네티스 기본 개념 (kubernetes conecpt) (0) | 2020.05.14 |
k8s 문서 - 튜토리얼; 쿠버네티스 기초 학습 (0) | 2020.05.13 |