🥞 BE
home

Ch9. 레이블과 애너테이션

자원들의 메타데이터를 관리하는 데 사용
레이블: 셀럭터와 함께 특정 레이블이 있는 자원들을 선택할 때 주로 사용
→ 클러스터 안에서 사용자가 오브젝트 생성 시 해당 오브젝트를 구분하는 용도
사용자임의로 원하는 값 지정해 사용
애너테이션: 주석 성격의 메타데이터를 기록하는 데 사용
쿠버네티스 시스템에서 필요한 정보들 표시

레이블 (Label)

사용자가 클러스터 안에 오브젝트를 만들 때 메타데이터로 설정할 수 있음
생성된 후 수정 가능
키-값 쌍으로 구성
컨트롤러들이 관리할 파드를 구분할 수 있도록 함
쿠버네티스는 레이블만으로 관리 대상을 구분하므로 특정 컨트롤러가 만든 파드라도 레이블을 변경하면 인식할 수 없음
→ 컨트롤러와 파드를 느슨하게 결합하는 이런 특징 때문에 파드 관리 시 유연성이 있음

활용

서비스 운영
보통 서비스 운영 중 디버깅이 필요할 때 별도의 컨테이너를 실행해 확인하지만, 기존에 발생하던 증상이 재현되지 않아 문제를 확인하기 어려울 수 있음
→ 서비스에 영향 없이 이슈가 발생한 파드만을 따로 분리해 확인 가능
노드 구분
클러스터 안 노드들을 레이블로 구분한 다음, 특정 레이블이 있는 노드에만 자원을 할당해 실행
ex) SSD를 사용하는 노드에만 자원 할당

규칙

레이블의 키와 값 설정 시 다음 규칙을 준수해야 함
63글자를 넘지 않아야 함
시작과 끝 문자는 알파벳 대소문자 및 숫자여야 함
중간에는 대시(-), 밑줄(_), 점(.), 숫자 등이 올 수 있음
레이블의 키 이름 앞에 /로 구분해 접두어를 사용할 수 있음
ex) “kubernetes.io/”
보통 접두어가 있는 레이블의 키는 쿠버네티스 시스템에서 사용하는 레이블들
접두어는 DNS 하위 도메인 형식이어야 하고, 점(.)으로 구분할 수 있음

레이블 셀렉터 (Label selector)

사용자가 특정 레이블을 설정한 자원만 선택해 관리할 때 사용
1.
등호 기반 (equality-based)
같은지(=, ==) 다른지(!=)를 구분하는 연산자를 사용
# =와 ==는 같은 뜻 environment=develop release=stable environment=develop, release=stable
Python
복사
line1: 레이블의 가 environment인 것 중 이 develop인 것들을 선택
line2: 레이블의 가 release인 것 중 이 stable인 것들 선택
line3: 두 조건 모두 만족하는 경우에는 쉼표(,)로 연결
2.
집합 기반 (set-based)
여러 개 값을 조건으로 설정한 다음 해당 키가 있는 레이블값이 조건에 속하는지(in), 아닌지(notin) 확인
특정 레이블의 키가 존재(exists)하는지도 설정 가능
environment in (develop, stage) release notin (lastest, canary) gpu !gpu
Python
복사
line1: environment가 develop이거나 stage인 레이블 선택
line2: release가 lastest와 canary가 아닌 레이블 선택
line3: gpu라는 레이블 키가 있는 모든 레이블 선택 (값은 확인하지 않음)
line4: gpu라는 키가 없는 모든 레이블 선택
등호 기반과 집합 기반 방식을 섞어서 사용할 수 있음
environment=production, release notin (lastest, canary)

레이블 사용 예시

디플로이먼트와 서비스용 템플릿 여러 개를 사용
디플로이먼트용 - 4개 템플릿: deployment-label01.yaml, deployment-label02.yaml, deployment-label03.yaml, deployment-label04.yaml
레이블 관련 설정 외에는 같음
# deployment-label01.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-label01 labels: app: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app:nginx environment: develop release: beta spec: containers: - name: nginx image: nginx ports: - containerPort: 80
Python
복사
.spec.template.metadata.labels 하위 필드에 app, environment, release 3개의 레이블 키가 있음
app
environment
Release
deployment-label01.yaml
nginx
develop
beta
deployment-label02.yaml
nginx
production
beta
deployment-label03.yaml
nginx
develop
stable
deployment-label04.yaml
nginx
production
stable
서비스용 - 2개 템플릿: label-service01.yaml, label-service02.yaml
# label-service01.yaml apiVersion: v1 kind: Service metadata: name: label-develop-service # label-service02.yaml: label-stable-service로 설정 spec: type: ClusterIP selector: environment: develop ports: - protocol: TCP port: 80 targetPort: 80
Python
복사
.spec.selector.environment 필드 값을 develop으로 설정
kubectl apply -f . : 모든 파일을 한번에 클러스터에 적용
kubectl get pods -o wide : 어떤 IP를 갖고 파드가 만들어졌는지 확인
kubectl get svc -o wide : 서비스가 어떤 셀럭터를 갖고 만들어졌는지 확인
kubectl describe svc : 설정대로 서비스가 파드들을 선택했는지 서비스 전체의 현재 상태를 확인
kubectl get pods -l app=nginx
kubectl get pods -l environment=develop,release=stable
kubectl get pods -l "app=nginx,environment notin (develop)”
kubectl get pods -l release!=stable
⇒ 레이블을 선택하는 조건을 다양하게 혼합해서 사용할 수 있는 것이 쿠버네티스의 강력한 장점

애너테이션

레이블과 마찬가지로 키-값 쌍으로 구성하며, 사용자가 설정 가능
쿠버네티스 시스템이 필요한 정보들을 담음
쿠버네티스 클라이언트라이브러리자원을 관리하는 데 활용
→ 애너테이션의 쿠버네티스 시스템이 인식할 수 있는 값을 사용

활용

인그레스에서 필요한 설정 정의
애너테이션으로 사용자가 직접 필요한 설정들을 정의 가능
메모 용도
릴리즈 정보, 로깅, 모니터링에 필요한 정보들

애너테이션 사용 예시

# annotation.yaml apiVersion: apps/v1 kind: Deployment metadata: name: annotation labels: app: nginx annotations: manager: "myadmin" contact: "010-0000-0000" release-version: "v1.0" spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app:nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80
Python
복사
kubectl describe deploy annotation : 실행 중인 디플로이먼트의 정보 확인

레이블을 이용한 카나리 배포

레이블의 다양한 활용 중 배포에 활용하는 방법
배포 방법에는 롤링업데이트, 블루/그린, 카나리(canary) 등 여러 방법이 있음
롤링업데이트
• 배포된 전체 파드를 한번에 교체하지 않고 일정 개수씩 교체하며 배포 • 디플로이먼트의 기본 배포 방법
블루/그린
• 기존에 실행된 파드 개수와 같은 개수의 신규 파드를 모두 실행한 후 신규 파드가 정상적으로 실행됐는지 확인 • 그 후 트래픽을 한번에 신규 파드 쪽으로 옮김
카나리
• 신규 파드를 배포할 때 한번에 앱 컨테이너 전체를 교체하지 않음 • 기존 버전을 유지한 채로 일부 버전만 신규 파드로 교체 • 이상이 없는지, 사용자 반응은 어떤지 확인할 때 유용
쿠버네티스의 기본 디플로이먼트는 디플로이먼트에 속한 파드들을 모두 교체하는 방식이므로 카나리 방법으로 배포하기에는 어려움이 있음
→ 레이블을 이용하면 쿠버네티스에서도 카나리 방법으로 배포할 수 있음

카나리 배포 방법

디플로이먼트 템플릿 2개
# deployment-v1.yaml apiVersion: apps/v1 kind: Deployment metadata: name: k8s-testapp labels: app: myapp # 앱 컨테이너 버전 표시 version: stable spec: replicas: 2 # 파드 개수 selector: matchLabels: app: myapp version: stable template: metadata: labels: app: myapp version: stable spec: containers: - name: testapp image: arisu1000/simple-container-app:v0.1 # 실행하는 앱 컨테이너가 다름 ports: - containerPort: 8080
Python
복사
# deployment-v2.yaml apiVersion: apps/v1 kind: Deployment metadata: name: k8s-testapp-canary labels: app: myapp version: canary spec: replicas: 1 selector: matchLabels: app: myapp version: canary template: metadata: labels: app: myapp version: canary spec: containers: - name: testapp image: arisu1000/simple-container-app:v0.2 ports: - containerPort: 8080
Python
복사
위 코드로 만들어지는 파드 각각은 컨테이너에 접속한 내역을 보여주는 간단한 앱 컨테이너
kubectl apply -f deployment-v1.yaml , kubectl apply -f deployment-v2.yaml : 버전이 다른 템플릿 2개를 클러스터에 적용해 파드 배포
파드에 접근하는 서비스 템플릿
# myapp-svc.yaml apiVersion: v1 kind: Service metadata: labels: app: myapp name: myapp-svc namespace: default spec: ports: - nodePort: 30880 # 30880 포트를 이용하는 NodePort 타입 서비스를 실행 port: 8080 protocol: TCP targetPort: 8080 selector: app: myapp # app이 myapp인 파드들 선택하게 함 -> 모두 이 서비스와 연결됨 type: NodePort
Python
복사
kubectl apply -f myapp-svc.yaml
curl localhost:30880 으로 컨테이너에 접속
→ v0.1과 v0.2 앱 컨테이너를 번갈아 접속
⇒ 여러 개 디플로이먼트를 하나의 접속 주소로 묶어 v0.1과 v0.2를 동시에 서비스하는 것
deployment-v1.yaml으로 실행한 파드들이 기존 버전(v0.1), deployment-v2.yaml이 신규 버전(v0.2)을 배포한 것
기존 버전과 신규 버전이 함께 존재하므로 카나리 형태의 배포임