쿠버네티스 공식문서를 확인하며 레이블, 셀렉터, 파이널라이저에 대해서 기억해야 하는 부분을 기록한다.
레이블과 셀렉터
- 레이블은 파드와 같은 오브젝트에 첨부된 키와 값의 쌍이다.
- 오브젝트의 특성을 식별하는 데 사용되어 사용자에게는 중요하지만, 코어 시스템에 직접적인 의미는 없다.
- 레이블로 오브젝트의 하위 집합을 선택하고, 구성하는데 사용할 수 있다.
- 오브젝트를 생성할 때에 붙이거나 생성 이후에도 언제든지 수정이 가능하다.
- 오브젝트마다 미와 값으로 레이블을 정의할 수 있으며 키는 고유한 값이어야 한다.
- 레이블은 UI와 CLI에서 효율적인 쿼리를 사용하고 검색에 사용하기 적합하며, 식별되지 않는 정보는 애너테이션으로 기록해야 한다.
사용 동기
- 레이블을 사용하면 사용자가 느슨하게 결합한 방식으로 조직 구조와 시스템 오브젝트를 매핑할 수 있으며, 클라이언트에 매핑 정보를 저장할 필요가 없어진다.
- 서비스 배포와 배치 프로세싱 파이프라인은 흔히 다차원의 엔티티이며, 관리에 크로스-커팅 작업이 필요한 경우가 많은데 이 작업은 사용자보다는 인프라에 의해 결정된 엄격한 계층 표현인 캡슐화를 깨트린다.
- 아래의 예시는 일반적으로 사용하는 레이블이며, 사용자는 자신만의 규칙(convention)에 따라 자유롭게 개발할 수 있지만 오브젝트에 붙여진 레이블 키는 고유하다는 것을 기억해야 한다.
"release" : "stable", "release" : "canary"
"environment" : "dev", "environment" : "qa", "environment" : "production"
"tier" : "frontend", "tier" : "backend", "tier" : "cache"
"partition" : "customerA", "partition" : "customerB"
"track" : "daily", "track" : "weekly"
구문과 캐릭터 셋
- 레이블은 키와 값의 쌍으로 유효한 레이블 키에는 슬래시(
/)로 구분되는 선택한 접두사 이름이라는 2개의 세그먼트가 있다.
- 이름 세그먼트는 63자 미만으로 시작과 끝은 영숫자(
[a-z0-9A-Z])이며, 대시(-), 밑줄(_), 점(.)과 함께 사용할 수 있다.
- 접두사는 선택사항이며 접두사를 지정하는 경우 접두사는 DNS의 하위 도메인으로 해야하며, 점(
.)과 전체 253자 이하, 슬래시(/)로 구분되는 DNS 레이블이다.
- 접두사를 생략하면 키 레이블은 개인용으로 간주한다. 최종 사용자는 오브젝트에 자동화된 시스템 컴포넌트(예,
kube-scheduler, kube-controller-manager, kube-apiserver, kubectl 또는 다른 타사의 자동화 구성 요소)의 접두사를 지정해야 한다.
kubernetes.io/와 k8s.io/ 접두사는 쿠버네티스의 핵심 컴포넌트로 예약되어 있다.
- 유효한 레이블은 아래의 규칙을 지켜야 한다.
- 63자를 넘길 수 없으며 공백일 수 있다.
- 공백이 아니라면 시작과 끝은 영숫자로 구성되어야 한다.
- 영숫자, 대시(
-), 밑줄(_), 점(.)을 중간에 포함할 수 있다.
- 아래의 예시는 파드에
environment: production과 app: nginx두 개의 레이블이 있는 구성 파일이다.
apiVersion: v1
kind: Pod
metadata:
name: label-demo
labels:
environment: production
app: nginx
레이블 셀렉터
- 이름과 UID와 다르게 레이블은 고유하지 않으며 일반적으로 우리는 많은 오브젝트들이 같은 레이블을 가질 것으로 예상한다.
- 레이블 셀렉터를 통해 클라이언트와 사용자는 오브젝트를 식별할 수 있으며, 레이블 셀렉터는 쿠버네티스 코어 그룹의 기본이다.
- API는 현재 “일치성 기준”과 “집합성 기준”이라는 두 종류의 셀렉터를 지원하고 레이블 셀렉터는 쉼표로 구분된 다양한 요구사항에 따라 만들 수 있다. 다양한 요구사항이 있는 경우 쉼표 기호가 AND(
&&) 연산자로 구분되는 역할을 하도록 해야 한다.
- 비어있거나 지정되지 않은 셀렉터는 상황에 따라 달라지기 때문에 셀렉터를 사용하는 API 유형은 유효성과 의미를 문서화 해야 한다.
- 레플리카셋(ReplicaSet)과 같은 일부 API 유형에서 두 인스턴스의 레이블 셀렉터는 네임스페이스 내에서 겹치지 않아야 하며 그렇지 않은 경우 컨트롤러는 상충하는 명령으로 보고, 얼마나 많은 복제본이 필요한지 알 수 없다.
- 일치성 기준과 집합성 기준 조건 모드에 대해 논리적인 OR(
||)연산자가 없다. 필터 구문이 적절히 구성되어 있는지 확인해야 한다.
일치성 기준 요건
- “일치성 기준” 또는 “불일치 기준”의 요구사항으로 레이블의 키와 값의 필터링을 허용한다.
- 일치하는 오브젝트는 추가 레이블을 가질 수 있지만, 레이블의 명시된 제약 조건을 모두 만족해야 한다.
=, ==는 일치를 의미하며 !=는 불일치를 의미하며 세 개의 연산자면 허용되며 사용 예시는 아래와 같다.
environment = production
tier != frontend
- 전자는
environment를 키로 가지는 것과 production을 값으로 가지는 모든 리소스를 선택한다.
- 후자는
tier를 키로 가지며, 값을 공백으로 가지는 모든 리소스를 선택한다.
environment=production,tier!=frontend처럼 쉼표를 통해 한 문장으로 frontend를 제외한 production을 필터링할 수 있다.
- “일치성 기준 레이블 요건”에 대한 하나의 이용 시나리오는 파드가 노드를 선택하는 기준을 지정하는 것이다. 아래의 샘플 파드는
accelerator=nvidia-tesla-p100 레이블을 가진 노드를 선택한다.
apiVersion: v1
kind: Pod
metadata:
name: cuda-test
spec:
containers:
- name: cuda-test
image: "k8s.gcr.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1
nodeSelector:
accelerator: nvidia-tesla-p100
집합성 기준 요건
- “집합성 기준 레이블 요건”에 따라 값 집합을 키로 필터링할 수 있으며
in, notin, exists 세 개의 연산자를 지원한다. 사용법은 아래와 같다.
environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
- 1라인: 키가
environment이며 값이 production 또는 qa인 모든 리소스를 선택한다.
- 2라인: 키가
tier이고 값이 frontend와 backend를 가지는 리소스를 제외한 모든 리소스를 선택한다. 추가로 키로 tier를 가지고 값을 공백으로 가지는 모든 리소스를 선택한다.
- 3라인: 레이블의 값에 상관없이 키가
partition을 포함하는 모든 리소스를 선택한다.
- 4라인: 레이블의 값에 상관없이 키가
partition을 포함하지 않는 모든 리소스를 선택한다.
- 쉼표(
,)는 AND 연산자로 작동하기 때문에 partition,environment notin (qa)와 같이 사용하면 값과 상관없이 키가 partition또는 environment이고 값이 qa와 다른 리소스를 필터링할 수 있다.
- “집합성 기준 레이블 셀렉터”는 일반적으로
environment=production과 environment in (production)을 동일한 것으로 보고 !=과 notin을 같은 것으로 본다.
- “집합성 기준 요건”은 “일치성 기준 요건”과 조합하여 사용할 수 있다. (`partition in (customerA,customerB),environment!=qa)
API
LIST와 WATCH 필터링
- LIST와 WATCH 작업은 쿼리 파라미터를 사용해서 반환되는 오브젝트 집합을 필터링하기 위해 레이블 셀렉터를 지정할 수 있으며 아래와 같은 요건 모두 허용된다.
- 일치성 기준 요건:
?labelSelector=environment%3Dproduction,tier%3Dfrontend
- 집합성 기준 요건:
?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%frontend%29
- 두 가지 레이블 셀렉터 스타일은 모두 REST 클라이언트를 통해 선택된 리소스를 확인하거나 목록을 볼 수 있으며 아래처럼
kubectl로 apiserver를 대상으로 “일치성 기준”과 “집합성 기준” 셀렉터를 이용할 수 있다.
# 일치성 기준
kubectl get pods -l environment=production,tier=frontend
# 집합성 기준
kubectl get pods -l 'environment in (production),tier in (frontend)'
# OR 연산자
kubectl get pods -l 'environment in (production, qa)'
# exists 연산자
kubectl get pods -l 'environment,environment notin (frontend)'
API 오브젝트에서 참조 설정
services와 replicationcontrollers와 같은 일부 쿠버네티스 오브젝트는 레이블 셀렉터를 사용해서 파드와 같은 다른 리소스 집합을 선택한다.
서비스와 레플리케이션 컨트롤러
services에서 지정하는 파드 집합은 레이블 셀렉터로 정의한다. 마찬가지로 replicationcontrollers가 관리하는 파드의 오브젝트 그룹도 레이블 셀렉터로 정의한다.
- 서비스와 레플리케이션 컨트롤러의 레이블 셀렉터는
json 또는 yaml 파일에 매핑된 일치성 기준 요구사항의 셀렉터만 지원한다. 아래의 두 방식은 같은 결과를 가져온다.
"selector": {
"component" : "redis",
}
or
selector:
component: redis
세트-기반 요건을 지원하는 리소스
Job, Deployment, ReplicaSet 그리고 DaemonSet 같은 새로운 리소스들은 “집합성 기준”의 요건도 지원한다.
selector:
matchLabels:
component: redis
matchExpressions:
- {key: tier, operator: In, values: [cache]}
- {key: environment, operator: NotIn, values: [dev]}
matchLabels는 {key,value}의 쌍과 매칭된다.
matchLabels에 매칭된 단일 {key,value}는 matchExpressions의 요소와 같으며 key 필드는 “key”로, operator는 “In” 그리고 values에는 “value”만 나열되어 있다.
matchExpressions는 파드 셀렉터의 요건 목록이며 유효한 연산자에는 In, NotIn, Exists, DoNotExist가 있고 In, NotIn은 설정된 값이 있어야 한다.
matchLabels와 matchExpressions 모두 AND로 되어 있어 일치하기 위해서는 모든 요건을 만족해야 한다.
노드 셋 선택
- 레이블을 통해 선택하는 사용 사례 중 하나는 파드를 스케줄 할 수 있는 노드 셋을 제한하는 것이다.
애너테이션
- 쿠버네티스 애너테이션을 사용하여 임의의 비-식별 메타데이터를 오브젝트에 첨부할 수 있다. 도구 및 라이브러리와 같은 클라이언트는 이 메타데이터를 검색할 수 있다.
오브젝트에 메타데이터 첨부
- 레이블이나 애너테이션을 사용하여 쿠버네티스 오브젝트에 메타데이터를 첨부할 수 있다.
- 레이블을 사용하여 오브젝트를 선택하고, 특정 조건을 만족하는 오브젝트 컬렉션을 찾을 수 있다.
- 애너테이션은 오브젝트를 식별하고 선택하는데 사용되지 않는다.
- 애너테이션의 메타데이터는 작거나 크고, 구조적이거나 구조적이지 않을 수 있으며, 레이블에서 허용되지 않는 문자를 포함할 수 있다.
- 애너테이션은 아래처럼 레이블과 같은 형식의 키-값 매핑이다.
"metadata": {
"annotations": {
"key1" : "value1",
"key2" : "value2"
}
}
- 맵의 키와 값은 문자열이어야 하며 숫자, 불리언, 리스트 등의 다른 형식을 키나 값에 사용할 수 없다.
- 아래는 애너테이션에 기록할 수 있는 정보의 예시이다.
- 필드는 선언적 구성 계층에 의해 관리된다. 이러한 필드를 애너테이션으로 첨부하는 것은 클라이언트 또는 서버가 설정한 기본 값, 자동 생성된 필드, 그리고 오토사이징 또는 오토스케일링 시스템에 의해 설정된 필드와 구분된다.
- 빌드, 릴리즈, 또는 타임 스탬프, 릴리즈 ID, git 브랜치, PR 번호, 이미지 해시 및 레지스트리 주소와 같은 이미지 정보.
- 로깅, 모니터링, 분석 또는 감사 리포지토리에 대한 포인터.
- 디버깅 목적으로 사용될 수 있는 클라이언트 라이브러리 또는 도구 정보. (이름, 버전, 빌드 정보 등)
- 다른 생태계 구성 요소의 관련 오브젝트 URL과 같은 사용자 또는 도구/시스템 출처 정보.
- 경량 롤아웃 도구 메타데이터. (구성, 체크포인트 등)
- 책임자의 전화번호 또는 호출기 번호, 또는 팀 웹 사이트 같은 해당 정보를 찾을 수 있는 디렉터리 진입점.
- 행동을 수정하거나 비표준 기능을 수행하기 위한 최종 사용자의 지시 사항.
- 애너테이션을 사용하는 대신, 이 유형의 정보를 외부 데이터베이스 또는 디렉터리에 저장할 수 있지만, 이는 배포, 관리, 인트로스펙션(introspection)등을 위한 공유 클라이언트 라이브러리와 도구 생성을 훨씬 더 어렵게 만들 수 있다.
문법과 캐릭터 셋
- 애너테이션은 키/값 쌍이다.
- 유효한 애너테이션 키에는 두 개의 세그먼트가 있으며 두 개의 세그먼트는 선택적인 접두사와 이름이며, 슬래시(
/)로 구분된다.
- 이름 세그먼트는 필수이며, 시작과 끝은 영숫자(
[a-z0-9A-Z])여야 하며 63자 이내로 작성되어야 한다. 이름에는 -, _, . 3개의 특수문자가 사용될 수 있다.
- 접두사는 선택 사항이며, 접두사가 지정되는 경우에는 DNS의 서브도메인이어야 한다.
- 점(
.)으로 구분된 일련의 DNS 레이블은 총 253자 이내로 작성되어야 하며, 뒤에 슬래시(/)가 붙는다.
- 접두사가 생략되면, 애너테이션 키는 사용자에게 비공개로 간주된다.
- 최종 사용자 오브젝트에 애너테이션을 추가하는 자동화된 시스템 구성 요소(
kube-scheduler, kube-controller-manager, kube-apiserver, kubectl, 다른 써드파티 자동화)는 접두사를 지정해야 한다.
- 아래는
imageregistry: https://hub.docker.com/ 애너테이션이 있는 파드의 구성 파일 예시다.
apiVersion: v1
kind: Pod
metadata:
name: annotations-demo
annotations:
imageregistry: "https://hub.docker.com/"
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
소유자 및 종속 개체(Owners and Dependents)
- 쿠버네티스에서 일부 개체는 다른 개체를 소유한다.
- 레플리카세트는 파드 집합의 소유자이며 종속 객체는 소유자에게 종속된다.
- 소유권은 일부 리소스에서도 사용되는 레이블 과 셀렉터 메커니즘과는 다르다.
- 서비스는 레이블을 사용하여 컨트롤 플레인이
EndpointSlice 해당 서비스를 사용하게 되는 개체를 결정하게 할 수 있다.
- 레이블 외에도
EndpointSlice를 대신하여 관리되는 각 레이블에는 “소유자 참조”가 존재하며 “소유자 참조”는 쿠버네티스의 다른 부분이 제어하지 않는 개체를 방해하는 것을 방지하는데 도움된다.
개체 명세의 소유자 참조
- 종속 개체에는
metadata.ownerReferences와 같은 형태의 소유자 개체를 참조하기 위한 필드가 존재한다.
- 유효한 소유자 참조는 종속 개체와 동일한 네임스페이스 내의 개체 이름과 UID로 구성된다.
- ReplicaSets, DaemonSets, Deployments, Jobs 및 CronJobs, ReplicationController와 같은 다른 개체에 종속되는 개체는
metadata.ownerReferences 필드의 값이 자동으로 설정된다. 사용자는 이 값을 수동으로 변경할 수 있지만 일반적으로 쿠버네티스에게 권한을 허용하고 자동으로 설정되도록 한다.
- 종속 개체에는
ownderReferences.blockOwnerDeletion 불리언 값을 사용하고 특정 종속 항목이 소유자 개체를 삭제하지 못하도록 가비지 수집을 차단을 제어하는 필드가 있다.
- 쿠버네티스는 자동으로 이 값을
true로 설정하고 제어 장치 metadata.ownerReferences 필드의 값을 설정한다.
- admission controller는 소유자의 삭제 권한에 따라 종속 리소스에 대해 이 필드를 변경하기 위한 사용자 액세스를 제어한다. 이 제어는 권한이 없는 사용자가 소유자 개체 삭제를 지연하는 것을 방지한다.
- 상호 네임스페이스 소유자 참조는 설계상 허용되지 않는다. 네임스페이스에 종속 항목은 클러스터 범위 또는 네임스페이스 소유자를 지정할 수 있다.
- 네임스페이스 소유자는 종속 개체와 동일한 네임스페이스에 위치해야 하며, 그렇지 않은 경우 소유자 참조는 부재로 처리되어 모든 소유자가 부재인 것으로 확인되어 종속 개체는 삭제될 수 있다.
- 클러스터 범위의 종속 개체은 클러스터 범위 소유자만 지정할 수 있다. v1.20 이상 버전에서 클러스터 범위 종속 개체인 네임스페이스 종류를 소유자로 지정하면 확인할 수 없는 소유자 참조가 있는 것으로 처리되고 가비지 수집이 불가능해진다.
- v1.20 이상 버전에서 가비지 수집기가 유효하지 않은 교차 네임스페이스
ownerReference 또는 네임스페이스 종류를 참조하는 클러스터 범위 종속을 감지하면 유효하지 않은 종속이 ownerReference에 있다는 경고 이벤트가 보고된다.
소유권(Ownership)과 파이널라이저(Finalizers)
- 쿠버네티스에게 리소스를 삭제하도록 지시하면 API 서버에서 관리 컨트롤러가 리소스에 대한 파이널라이저(finalizer) 규칙을 처리할 수 있다. 종료자 클러스터가 올바르게 작동하는 데 필요할 수 있는 리소스가 실수로 삭제되는 것을 방지한다.
- 파드에서 아직 사용 중인
PersistentVolume을 삭제하려고 하면 파이널라이저가 있기 때문에 바로 종료되지 않는다. 쿠버네티스는 볼륨이 더 이상 파드에 바인딩되지 않은 상황이 될 때 해당 볼륨을 삭제한다.
- 쿠버네티스는 소유자 개체가 삭제될 때 종속 개체까지 삭제하기 위해서 소유자 리소스에 파이널라이저 추가한다.
- 포그라운드 삭제에서는 컨트롤러가 소유자를 삭제하기 전에
forground 종속 리소스도 삭제되도록 파이널라이저를 추가한다.
ownerReferences.blockOwnerDeletion=true와 같이 설정하는 경우 쿠버네티스는 orphan 컨트롤러가 소유자 개체를 삭제한 후 종속 리소스를 무시하도록 파이널라이저를 추가하게 된다.
파이널라이저
- 파이널라이저는 쿠버네티스가 오브젝트를 완전히 학제하기 이전, 삭제 표시를 위해 특정 조건이 만족될 때까지 대기하도록 알려주기 위한 네임스페이스에 속한 키(namespaced key)다.
- 파이널라이저는 삭제 완료된 오브젝트가 소유한 리소스를 정리하기 위해 컨트롤러에게 알린다.
- 파이널라이저를 가진 특정한 오브젝트를 쿠버네티스가 삭제하도록 지시할 때, 쿠버네티스 API는
.metadata.delationTimestamp을 덧붙여 삭제하도록 오브젝트에 표시하며, 202 상태코드(HTTP, Acceptesd)
- 대상 오브젝트가 terminating 상태를 유지하는 동안 컨트롤 플레인 또는 다른 컴포넌트는 하나의 파이널라이저에서 정의한 작업을 수행한다.
- 정의된 작업이 완료 후에, 그 컨트롤러는 대상 오브젝트로부터 연관된 파이널라이저를 삭제한다,
metadata.finalizers 필드가 비어 있을 때 쿠버네티스는 삭제가 완료된 것으로 간주하고 오브젝트를 삭제한다.
- 파이널라이저가 리소스들의 가비지 컬렉션을 제어하도록 할 수 있다. 하나의 파이널라이저를 컨트롤러가 대상 리소스를 삭제하기 전에 연관된 리소스들 또는 인프라를 정리하도록 정의 할 수 있다.
- 파이널라이저를 사용하면 리소스를 삭제하기 전 특정 정리 작업을 수행하도록 컨트롤러에 경고하여 리소스의 가비지 수집을 제어할 수 있다.
- 파이널라이저는 보통 실행할 코드를 지원하지 않는다. 대신 파이널라이저는 일반적으로 애너테이션과 비슷하게 특정 리소스에 대한 키들의 목록으로 일부 파이널라이저는 쿠버네티스가 자동으로 지정하지만 사용자가 직접 지정할 수도 있다.
파이널라이저의 작동 방식
- 매니페스트 파일을 사용해 리소스를 생성하면
metadata.finalizers 필드에 파이널라이저를 명시할 수 있다. 리소스를 삭제하려 할 때는 삭제 요청을 처리하는 API 서버가 finalizers 필드의 값을 인식하고 아래의 작업을 수행한다.
- 삭제를 시작한 시각과 함께
metadata.deletionTimestamp 필드를 추가하도록 오브젝트를 수정한다.
- 오브젝트의
metadata.finalizers 필드가 비워질 때까지 오브젝트가 제거되지 않도록 한다.
202 상태 코드를 리턴한다(Accepted)
- 파이널라이저를 관리하는 컨트롤러는
metadata.deletionTimestamp를 설정하는 오브젝트가 업데이트 되었음을 인지하여 오브젝트의 삭제가 요청되었음을 나타낸다.
- 컨트롤러는 해당 리소스에 지정된 파이널라이저의 요구사항을 충족하려 시도한다.
- 컨트롤러는 파이널라이저 조건이 충족될 때 마다 리소스의
finalizers 필드에서 해당 키(key)를 제거한다.
finalizers 필드가 비워지면 deletionTimestamp 필드가 설정된 오브젝트는 자동으로 삭제되며 파이널라이저를 사용하여 관리되지 않는 리소스가 삭제되지 않도록 할 수 있다.
- 파이널라이저의 일반적인 예시로
퍼시스턴트 볼륨(Persistent Volume) 오브젝트가 실수로 삭제되는 것을 방지하는 kubernetes.io/pv-protection가 있다.
- 파드가
퍼시스턴트 볼륨 오브젝트를 사용 중일 때 쿠버네티스는 pv-protection 파이널라이저를 추가한다.
퍼시스턴트 볼륨을 삭제하려 하면 Terminating 상태가 되지만 파이널라이저가 존재하기 때문에 삭제할 수 없다.
- 파드가
퍼시스턴트 볼륨의 사용을 중지하면 쿠버네티스가 pv-protection 파이널라이저를 해제하고 컨트롤러는 볼륨을 삭제한다.
소유자 참조, 레이블, 파이널라이저
- 레이블(Label)과 마찬가지로 쿠버네티스에서 소유자 참조(Owner reference)는 오브젝트 간의 관계를 설명하지만 다른 목적으로 사용된다.
- 컨트롤러가 파드와 같은 오브젝트를 관리할 때 레이블을 사용하여 관련 오브젝트의 그룹에 대한 변경 사항을 추적한다. 예를 들어 잡(Job)이 하나 이상의 파드를 생성하면 잡 컨트롤러는 해당 파드에 레이블을 적용하고 클러스터 내 동일한 레이블을 갖는 파드에 대한 변경 사항을 추적한다.
- 잡 컨트롤러는 이러한 파드에 “소유자 참조”도 추가하여 파드를 생성한 잡을 가리킨다.
- 이 파드가 실행될 때 잡을 삭제하면 쿠버네티스는 “사용자 참조(레이블 대신)”를 사용하여 클러스터 내 어떤 파드가 정리되어야 하는지 결정한다.
- 쿠버네티스는 또한 삭제 대상 리소스에 대한 소유자 참조를 식별할 때 파이널라이저를 처리한다.
- 경우에 따라 파이널라이저는 종속 오브젝트의 삭제를 차단할 수 있으며 이로 인해 대상 소유자 오브젝트가 완전히 삭제되지 않고 예상보다 오래 유지될 수 있다.
- 삭제가 차단된 경우 대상 소유자 및 종속 객체에 대한 파이널라이저와 소유자 참조를 확인해 원인을 해결해야 한다.
- 오브젝트가 삭제 상태에 있는 경우, 삭제를 계속하기위해 파이널라이저를 수동으로 제거하면 안된다.
- 일반적으로 파이널라이저는 특정한 목적을 가지고 리소스에 추가되기 때문에, 강제로 제거하면 클러스터에 문제가 발생할 수 있다.
- 파이널라이저의 목적을 이해하고 “일부 종속 객체를 수동으로 정리하는 것과 같은 방법으로 수행될 때”만 삭제를 수행해야 한다.
필드 셀렉터
- 필드 셀렉터는 한 개 이상의 리소스 필드 값에 따라 쿠버네티스 리소스를 선택하기 위해 사용된다. 필드 셀렉터 쿼리는 아래와 같은 형태를 가진다.
metadata.name=my-service
metadata.namespace!=default
status.phase=Pending
- 아래의
kubectl 커맨드는 status.phase 필드의 값이 Running인 모든 파드를 선택한다.
kubectl get pods --field-selector status.phase=Running
- 필드 셀렉터는 본질적으로 리소스 필터이며 기본적으로 적용되는 셀렉터나 필드는 없고 이것은 명시된 종류의 모든 리소스가 선택된다는 것을 의미한다. 아래 두 개의 쿼리는 같은 결과를 출력하게 된다.
kubectl get pods
kubectl get pods --field-selector ""
사용 가능한 필드
- 사용 가능한 필드는 쿠버네티스의 리소스 종류에 따라서 다르다.
- 모든 종류의 리소스는
metadata.name과 metadata.namespace필드 셀렉터를 사용할 수 있으며 사용할 수 없는 필드 셀렉터를 사용하면 아래와 같은 에러를 출력한다.
Error from server (BadRequest): Unable to find "ingresses" that match label selector "
사용 가능한 연산자
- 필드 셀렉터에서는
=, ==, != 연산자를 사용할 수 있으며 =와 ==는 동일한 의미로 사용된다. 아래의 커맨드는 default 네임스페이스에 속해있지 않은 모든 쿠버네티스 서비스를 선택한다.
kubectl get services --all-namespaces --field-selector metadata.namespace!=default
연계되는 셀렉터
- 레이블을 비롯한 다른 셀렉터처럼, 쉼표로 구분되는 목록을 통해 셀렉터를 연계해서 사용할 수 있다. 아래의 커맨드는
status.phase 필드가 Running이 아니고, spec.restartPolicy 필드가 Always인 모든 파드를 선택한다.
kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always
여러 개의 리소스 종류
- 필드 셀렉터를 여러 개의 리소스 종류에 걸쳐 사용할 수 있다. 아래의 커맨드는
default 네임스페이스에 속해있지 않은 모든 스테이트풀셋(StatefulSet)과 서비스를 선택한다.
kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default
권장 레이블
- kubectl과 대시보드와 같은 많은 도구들로 쿠버네티스 오브젝트를 시각화 하고 관리할 수 있다.
- 공통 레이블 셋은 모든 도구들이 이해할 수 있는 공통의 방식으로 오브젝트를 식별하고 도구들이 상호 운용적으로 작동할 수 있도록 한다.
- 권장 레이블은 지원 도구 외에도 쿼리한느 방식으로 애플리케이션을 식별하게 한다.
- 메타데이터는 “애플리케이션”의 개념을 중심으로 정리되며 쿠버네티스는 플랫폼 서비스(PaaS)가 아니며 애플리케이션에 대해 공식적인 개념이 없거나 강요하지 않는다.
- 애플리케이션은 비공식적이며 메타데이터로 설명되고 애플리케이션에 포함된 정의는 유연하다.
- 메타데이터들은 권장하는 레이블이다. 애플리케이션을 보다 쉽게 관리할 수 있지만 코어 도구에는 필요하지 않다.
- 메타데이터들은 권장하는 레이블이며 애플리케이션을 보다 쉽게 관리할 수 있지만 코어 도구에는 필요하지 않다.
- 공유 레이블과 주석에는 공통 접두사인
app.kubernetes.io가 있다.
- 접두사가 없는 레이블은 사용자가 개인적으로 사용할 수 있다. 공유 접두사는 공유 레이블이 사용자 정의 레이블을 방해하지 않도록 한다.
레이블
- 레이블을 최대한 활용하려면 모든 리소스 오브젝트에 적용해야 한다.
| 키 |
설명 |
예시 |
타입 |
| app.kubernetes.io/name |
애플리케이션 이름 |
mysql |
문자열 |
| app.kubernetes.io/instance |
애플리케이션의 인스턴스를 식별하는 고유한 이름 |
myslq-abcxzy |
문자열 |
| app.kubernetes.io/version |
애플리케이션의 현재 버전(예: a semantic version, revision hash 등.) |
5.7.21 |
문자열 |
| app.kubernetes.io/component |
아키텍처 내 구성요소 |
database |
문자열 |
| app.kubernetes.io/part-of |
이 애플리케이션의 전체 이름 |
wordpress |
문자열 |
| app.kubernetes.io/managed-by |
애플리케이션의 작동을 관리하는 데 사용되는 도구 |
helm |
문자열 |
| app.kubernetes.io/created-by |
이 리소스를 만든 컨트롤러/사용자 |
controller-manager |
문자열 |
| - 아래는 위의 레이블을 사용한 스테이트풀셋 오브젝트이다. |
|
|
|
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/component: database
app.kubernetes.io/part-of: wordpress
app.kubernetes.io/managed-by: helm
app.kubernetes.io/created-by: controller-manager
애플리케이션과 애플리케이션 인스턴스
- 애플리케이션은 동일한 쿠버네티스 클러스터에, 심지어 동일한 네임스페이스에도 한번 이상 설치될 수 있다.
예를 들어, 하나의 쿠버네티스 클러스터에 WordPress가 여러 번 설치되어 각각 서로 다른 웹사이트를 서비스할 수 있다.
- 애플리케이션의 이름과 애플리케이션 인스턴스 이름은 별도로 기록된다. 예를 들어, WordPress는 애플리케이션 이름으로
app/kubernetes.io/name이라는 레이블에 wordpress라는 값을 가지며, 애플리케이션 인스턴스 이름으로는 app.kubernetes.io/instance라는 레이블에 wordpress-abcxzy라는 값을 가진다.
- 이름과 인스턴스의 이름을 통해 정확한 식별이 가능하며, 모든 애플리케이션 인스턴스는 고유한 이름을 가져야 한다.
단순한 스테이트리스 서비스
Deployment와 Service오브젝트를 통해 배포된 단순한 스테이트리스 서비스의 경우를 살펴본다. 다음 두 식별자는 레이블을 가장 간단한 형태로 사용하는 방법을 나타낸다.
Deployment는 애플리케이션을 실행하는 파드를 감시하는 데 사용한다.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: myservice
app.kubernetes.io/instance: myservice-abcxzy
...
Service는 애플리케이션을 노출하기 위해 사용한다.
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: myservice
app.kubernetes.io/instance: myservice-abcxzy
...
데이터베이스가 있는 웹 애플리케이션
- Helm을 티용해서 데이터베이스(MySQL)을 이용하는 웹 애플리케이션(WordPress)을 설치한 것과 같이 좀 더 복잡한 애플리케이션을 고려할 수 있다.
- 아래의 식별자는 이 애플리케이션을 배포하는 데 사용하는 오브젝트의 시작을 보여준다.
- 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가 더 큰 범위의 애플리케이션에 포함되어 있는 것을 알게 된다.
참고 자료