Kubernetes Lable & Selector & Annotation

신동수·2024년 5월 14일

K8S

목록 보기
12/19
post-thumbnail

Label과 Selector

Label

Label은 AWS의 태그와 유사한 개념이다.리소스의 이름은 Namespace에서 유일해야 했다. 반면 Label은 리소스에 1개 이상 설정할 수 있다.여러개의 리소스에 동일한 Label을 중복해서 붙일 수 있다.
Label을 붙여서 오브젝트의 특성을 식별하는 데 사용한다.

  • POD와 같은 Object에 첨부된 Key와 Value의 값이다.
  • 리소스를 논리적인 그룹으로 나누기 위해 붙이는 이름표이다.
  • Object의 특성을 식별하는 데 사용되어 사용자에게 중요하지만, 코어 시스템에 직접적인 의미는 없다.
  • Object의 하위 집합을 선택하고, 구성하는데 사용할 수 있다.
  • Object를 생성할 때에 붙이거나 생성 이후에 붙이거나 언제든지 수정이 가능하다.
  • Object마다 Key와 Value으로 Label을 정의할 수 있다. Object의 Key는 고유한 Value이어야 한다.

Selector

Object에 부여된 Label을 기반으로 검색할 수 있는 개념입니다. Label은 고유하지 않다. 따라서 많은 Object에 다양한 Label을 부여할 수 있다. 사용자는 Label Selector를 이용하여 Object를 식별할 수 있으며 Label Selector는 Kubernetes 코어 그룹에 속한다.
모든 컨트롤러가 같은 특징을 가지는데, 예를 들어 Replication Controller가 따로 존재하고 컨트롤러는 replica=3을 만들어달라고 요청받고 a=123이라는 label을 POD에 지정하면 마찬가지로 Controller는 a=123 LabelSelector를 갖게된다.
그리고 Controller는 이 Label이 달린 POD를 자신이 관리합니다는 사실을 인지하게 된다.

  • Label을 이용해 쿠버네티스 리소스를 필터링하고 원하는 리소스 집합을 구하기 위한 label query
  • Label을 이용해 쿠버네티스 리소스를 선택하는 방법(Label query)

label이 필요한 이유


실제 애플리케이션을 배포할 때 대부분의 사용자는 더 많은 파드를 실행하게 될 것이다. 파드 수가 증가함에 따라 파드를 부분 집합으로 분류할 필요가 있다.

예를 들어 여러 버전 혹은 릴리스 (안정, 베타, 카나리 등)가 동시에 실행되고 있다. 이로 인해 시스템에 수백 개 파드가 생길 수 있다. 파드를 정리하는 메커니즘이 없다면, 크고 이해하기 어려운 난장판이 될 것이다. 그림은 여러 개 레플리카를 실행하는 여러 마이크로서비스에 속해 있는 파드와 동일한 마이크로 서비스의 다른 릴리스에 속한 파드를 보여준다.

모든 개발자와 시스템 관리자는 어떤 파드가 어떤 것인지 쉽게 알 수 있도록 임의의 기준에 따라 작은 그룹으로 조직하는 방법이 필요하다. 각 파드에 대해 개별적으로 작업을 수행하기보다 특정 그룹에 속한 모든 파드에 관해 한 번에 작업하기를 원할 것 이다. 레이블을 통해 파드와 기타 다른 쿠버네티스 오브젝트의 조직화가 이뤄진다.

Label

apiVersion: v1
kind: Pod
metadata:
  name: label-pod-demo
  labels:
    name: my-pod
    rel: stable
    version: v1
    env: prod
spec:
  containers:
  - name: nginx
    image: nginx:1.14
    ports:
    - containerPort: 80

위 yaml 은 label 확인을 위한 yaml 이다.

Label 확인

# label 확인
$ kubectl get pod --show-labels
NAME             READY   STATUS    RESTARTS   AGE   LABELS
label-pod-demo   1/1     Running   0          29s   env=prod,name=my-pod,rel=stable,version=v1

# 특정 label을 가진 pod 확인
$ kubectl get pod -l env=prod
NAME             READY   STATUS    RESTARTS   AGE
label-pod-demo   1/1     Running   0          3m26s

# name label을 가진 pod 확인
$ kubectl get pod --show-labels -l name
NAME             READY   STATUS    RESTARTS   AGE   LABELS
cmdpod           1/1     Running   0          14m   name=login
label-pod-demo   1/1     Running   0          20m   env=prod,name=my-pod,rel=stable,version=v1

# label에 name이 login인 pod 확인
$ kubectl get pod --show-labels -l name=login
NAME     READY   STATUS    RESTARTS   AGE   LABELS
cmdpod   1/1     Running   0          14m   name=login

Label 추가, 변경, 삭제

# pod 생성
$ kubectl run cmdpod --image=nginx:1.14 --port=80
pod/cmdpod created

# label 추가
$ kubectl label pod cmdpod name=test
pod/cmdpod labeled

# label 확인
$ kubectl get pod --show-labels
NAME             READY   STATUS    RESTARTS   AGE     LABELS
cmdpod           1/1     Running   0          5m47s   name=test,run=cmdpod
label-pod-demo   1/1     Running   0          12m     env=prod,name=my-pod,rel=stable,version=v1

# label 변경
$ kubectl label pod cmdpod name=login --overwrite
pod/cmdpod labeled

# label 확인
$ kubectl get pod --show-labels
NAME             READY   STATUS    RESTARTS   AGE     LABELS
cmdpod           1/1     Running   0          8m24s   name=login,run=cmdpod
label-pod-demo   1/1     Running   0          14m     env=prod,name=my-pod,rel=stable,version=v1

# label 삭제
$ kubectl label pod cmdpod run-
pod/cmdpod unlabeled

# label 확인
$ kubectl get pod --show-labels
NAME             READY   STATUS    RESTARTS   AGE   LABELS
cmdpod           1/1     Running   0          10m   name=login
label-pod-demo   1/1     Running   0          16m   env=prod,name=my-pod,rel=stable,version=v1

Selector

# selector를 통한 pod 확인
$ kubectl get pod --selector name
NAME             READY   STATUS    RESTARTS   AGE
cmdpod           1/1     Running   0          19m
label-pod-demo   1/1     Running   0          26m

# 조건을 통한 pod 확인
$ kubectl get pod --selector name=login
NAME     READY   STATUS    RESTARTS   AGE
cmdpod   1/1     Running   0          20m

# 연산자를 통한 확인
$ kubectl get pod --selector name!=login
NAME             READY   STATUS    RESTARTS   AGE
label-pod-demo   1/1     Running   0          27m

label query: key=value
kubectl get 명령어와 함께 Selector 사용한다.

Node Label

Worker Node의 특성(ex.하드웨어 스펙)을 Label로 설정

$ kubectl label nodes <노드 이름> key=value
  • 노드를 선택해서 파드 배치 가능
    • 각 노드의 스펙이 다른 경우 파드에 적합한 노드를 선택하여 배치

Node Label이 필요한 이유


만약 딥러닝이 돌아가는 컨테이너를 갖는 파드를 gpu가 있는 노드를 선택하여 배치해야 한다면 해당 스펙에 충족하는 노드에 파드가 배치가 되어야 한다. 이러한 조건을 위해서는 Node Label 이 필요하다.

Node Label 관리

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeselector
spec:
  nodeSelector:
    gpu: "true"
    disk: ssd
  containers:
  - name: nginx
    image: nginx:1.14
    ports:
    - containerPort: 80

.spec.nodeSelector에 key, value 형태로 지정을 해주면 된다. (단, Worker Node에 미리 label을 생성이나 변경을 해야한다.)

명령어 정리

#전체 노드 Label 보기
$ kubectl get nodes --show-labels

# 특정 Label 갖는 노드 보기
$ kubectl get nodes --selector <label_name>
$ kubectl get nodes -L <label_name>

# Label 생성 및 변경
$ kubectl label node <name> key=value
$ kubectl label node <name> key=value --overwrite

# Label 복수 할당
$ kubectl label node <name> key=value key=value

# Label 제거
$ kubectl label node <name> key-

Annotation

파드 및 다른 오브젝트들은 Label 외에 Annotations를 가질 수 있다.
Annotation은 키-값 쌍으로 레이블과 거의 비슷하지만, 식별 정보를 갖지 않는다.
레이블은 오브젝트를 묶는 데 사용할 수 있지만, 어노테이션은 그렇게 할 수 없다.

레이블 대신 어노테이션을 사용하는 이유

Annotations은 훨씬 더 많은 정보를 보유할 수 있다.
이 정보들은 주로 tools들에서 사용되는 정보들이다.
특정 Annotation은 Kubernetes에 의해서 자동으로 Object에 추가가 되지만, 나머지 어노테이션은 사용자가 직접 추가한다.

사용 예시

파드나 다른 API 오브젝트에 설명을 추가해놓으면, 클러스터를 사용하는 모든 사람이 개별 오브젝트에 관한 정보를 신속하게 찾아볼 수 있다.

# 예시
  annotations:
    builder: "ds (sds38839184@gmail.com)"
    buildDate: "20240514"
    imageRegistry: https://hub.docker.com/
    
# 예시
  annotations:
    kubernetes.io/change-cause: version 1.15

실습

apiVersion: v1
kind: Pod
metadata:
  name: pod-annotation
  annotations:
    builder: "ds (sds38839184@gmail.com)"
    buildDate: "20240514"
    imageRegistry: https://hub.docker.com/
spec:
  containers:
  - name: nginx
    image: nginx:1.14
    ports:
    - containerPort: 80

annotations항목에서 필요한 정보를 key, value 형태로 정의하였다.

$ kubectl create -f annotation.yaml
pod/pod-annotation created

$ kubectl describe pod pod-annotation
Name:             pod-annotation
Namespace:        default
Priority:         0
Service Account:  default
Node:             w1-k8s/192.168.1.101
Start Time:       Tue, 14 May 2024 13:54:45 +0900
Labels:           <none>
Annotations:      buildDate: 20240514
                  builder: ds (sds38839184@gmail.com)
                  cni.projectcalico.org/podIP: 172.16.221.145/32
                  cni.projectcalico.org/podIPs: 172.16.221.145/32
                  imageRegistry: https://hub.docker.com/

(중략)
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  41s   default-scheduler  Successfully assigned default/pod-annotation to w1-k8s
  Normal  Pulled     40s   kubelet            Container image "nginx:1.14" already present on machine
  Normal  Created    40s   kubelet            Created container nginx
  Normal  Started    40s   kubelet            Started container nginx

관리를 위해 필요한 정보를 기록할 용도로 릴리즈 정보와 같은 내용을 describe 명령어를 통해 쉽게 확인할 수도 있다.

profile
조금씩 성장하는 DevOps 엔지니어가 되겠습니다. 😄

0개의 댓글