자원들의 메타데이터를 관리하는 데 사용
•
레이블: 셀럭터와 함께 특정 레이블이 있는 자원들을 선택할 때 주로 사용
→ 클러스터 안에서 사용자가 오브젝트 생성 시 해당 오브젝트를 구분하는 용도
→ 사용자가 임의로 원하는 값 지정해 사용
•
애너테이션: 주석 성격의 메타데이터를 기록하는 데 사용
→ 쿠버네티스 시스템에서 필요한 정보들 표시
레이블 (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
◦
→ v0.1과 v0.2 앱 컨테이너를 번갈아 접속
⇒ 여러 개 디플로이먼트를 하나의 접속 주소로 묶어 v0.1과 v0.2를 동시에 서비스하는 것
deployment-v1.yaml으로 실행한 파드들이 기존 버전(v0.1), deployment-v2.yaml이 신규 버전(v0.2)을 배포한 것
⇒ 기존 버전과 신규 버전이 함께 존재하므로 카나리 형태의 배포임