코알못

[kubernetes] 쿠버네티스 Label, Selector 실습 본문

ETC

[kubernetes] 쿠버네티스 Label, Selector 실습

코린이s 2023. 5. 7. 20:39

이번 시간에 두가지 실습을 진행해보도록 한다!

첫번째. Label, Selector 기본 명령어 연습

두번째. Selector로 선택하여 배포

이제 실습을 진행해보도록 하자!

첫번째. Label, Selector 기본 명령어 연습

테스트를 위해 우선 4개의 yaml 을 만들어본다..!

# rose-app.yaml

apiVersion: v1
kind: Pod
metadata:
  name: rose-app
  labels:
    group: nature
spec:
  containers:
  - name: rose-app
    image: yoonjeong/red-app:1.0
    ports:
    - containerPort: 8080
    env:
    - name: NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace
    - name: POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    resources:
      limits:
        memory: "64Mi"
        cpu: "100m"

# sky-app.yaml

apiVersion: v1
kind: Pod
metadata:
  name: sky-app
  labels:
    group: nature
spec:
  containers:
  - name: sky-app
    image: yoonjeong/blue-app:1.0
    ports:
    - containerPort: 8080
    env:
    - name: NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace
    - name: POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    resources:
      limits:
        memory: "64Mi"
        cpu: "100m"

# tree-app-1.yaml

apiVersion: v1
kind: Pod
metadata:
  name: tree-app-1
  labels:
    group: nature
spec:
  containers:
  - name: tree-app
    image: yoonjeong/green-app:1.0
    ports:
    - containerPort: 8081
    env:
    - name: NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace
    - name: POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    resources:
      limits:
        memory: "64Mi"
        cpu: "100m"

# tree-app-2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: tree-app-2
  labels:
    group: nature
spec:
  containers:
  - name: tree-app
    image: yoonjeong/green-app:1.0
    ports:
    - containerPort: 8081
    env:
    - name: NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace
    - name: POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    resources:
      limits:
        memory: "64Mi"
        cpu: "100m"

4개의 yaml 을 각각 배포해도 되며, 하나의 디렉토리에 yaml 을 모두 넣어두면 아래와 같이 편리하게 디렉토리 단위로 적용 가능하다.

저자의 경우 labelSelector 이라는 디렉토리에 4개의 yaml 파일을 모두 넣어 두고 해당 명령어를 호출 하였다.

% kubectl apply -f labelSelector
pod/hello-app created
pod/rose-app created
pod/sky-app created
pod/tree-app-1 created
pod/tree-app-2 created

--show-labels 옵션을 주어 label 을 확인 하면 정상적으로 추가 되어 있음을 확인 할 수 있다.

$ kubectl get pods --show-labels
NAME         READY   STATUS    RESTARTS      AGE    LABELS
hello-app    1/1     Running   0             8m6s   group=greeting
rose-app     1/1     Running   0             8m5s   group=nature
sky-app      1/1     Running   0             8m4s   group=nature
tree-app-1   1/1     Running   0             8m4s   group=nature
tree-app-2   1/1     Running   3 (31s ago)   93s    group=nature

-L 옵션을 주면 원하는 레이블의 키값을 칼럼 형식으로 볼 수 있으며 group 키값에 대한 레이블을 확인하면 아래와 같이 보기 좋게 나온다.

$ kubectl get pods -L group
NAME         READY   STATUS      RESTARTS      AGE     GROUP
hello-app    1/1     Running     0             8m19s   greeting
rose-app     1/1     Running     0             8m18s   nature
sky-app      1/1     Running     0             8m17s   nature
tree-app-1   1/1     Running     0             8m17s   nature
tree-app-2   0/1     OOMKilled   3 (44s ago)   106s    nature

이제 Label을 아래와 같이 추가 하도록 한다.

Label 은 띄어쓰기로 구분하여 한번에 다수의 Label을 추가 할 수 있다.

$ kubectl label pod hello-app version=v1
pod/hello-app labeled
$ kubectl label pod rose-app concept=flower element=rose position=bottom version=v1
pod/rose-app labeled
$ kubectl label pod sky-app concept=earth element=sky position=top version=v1
pod/sky-app labeled
$ kubectl label pod tree-app-1 concept=earth element=tree position=bottom version=v1
pod/tree-app-1 labeled
$ kubectl label pod tree-app-2 concept=earth element=tree position=bottom version=v1
pod/tree-app-2 labeled

이제 -L 옵션으로 추가한 레이블이 정상적으로 나오는지 확인한다.

$ kubectl get pods -L group,concept,position,version
NAME         READY   STATUS    RESTARTS   AGE   GROUP      CONCEPT   POSITION   VERSION
hello-app    1/1     Running   0          34s   greeting                        v1
rose-app     1/1     Running   0          33s   nature     flower    bottom     v1
sky-app      1/1     Running   0          32s   nature     earth     top        v1
tree-app-1   1/1     Running   0          31s   nature     earth     bottom     v1
tree-app-2   1/1     Running   0          31s   nature     earth     bottom     v1

이제 부터 selector를 통해 Pod를 조회하도록 하자! (아래 답을 보지 않고 조회 하면서 연습 해보도록 한다.)

1. group이 nature인 pod 조회

$ kubectl get pod --selector group=nature
NAME         READY   STATUS    RESTARTS   AGE
rose-app     1/1     Running   0          2m
sky-app      1/1     Running   0          119s
tree-app-1   1/1     Running   0          118s
tree-app-2   1/1     Running   0          118s

2. concept가 flower 또는 earth 인 pod 조회

 

$ kubectl get pod --selector 'concept in (flower,earth)'
NAME         READY   STATUS    RESTARTS   AGE
rose-app     1/1     Running   0          2m41s
sky-app      1/1     Running   0          2m40s
tree-app-1   1/1     Running   0          2m39s
tree-app-2   1/1     Running   0          2m39s

3. concept 라는 label이 없는 pod 조회

 

$ kubectl get pod --selector '!concept'
NAME        READY   STATUS    RESTARTS   AGE
hello-app   1/1     Running   0          3m

4. concept 가 earth 도 아니고 flower도 아닌 pod 조회 (concept가 없는 pod도 조회)

$ kubectl get pod --selector 'concept notin (earth,flower)'
NAME        READY   STATUS    RESTARTS   AGE
hello-app   1/1     Running   0          3m37s

5.  group이 nature 이고 position이 bottom인 pod 조회

$ kubectl get pod --selector 'group=nature,position=bottom'
NAME         READY   STATUS    RESTARTS   AGE
rose-app     1/1     Running   0          4m45s
tree-app-1   1/1     Running   0          4m43s
tree-app-2   1/1     Running   0          4m43s

6. group이 nature 이고 position이 top인 pod 조회

$ kubectl get pod --selector 'group=nature,position=top'
NAME      READY   STATUS    RESTARTS   AGE
sky-app   1/1     Running   0          5m3s

selector 를 통해 조회하는 연습은 충분하며 이제 label 을 변경 해보자!
아래와 같이 tree-app-1 파드의 concept label이 기존에는 tree 였으나 mountain으로 변경 하려 했으나 오류가 발생한다.

확인 해보면 이미 키가 있을때 변경 하려면 --overwrite를 사용 하라는 가이드가 나온다!

우리는 해당 옵션을 추가하여 변경 하도록 한다.

$ kubectl label pod tree-app-1 concept=mountain
error: 'concept' already has a value (earth), and --overwrite is false
$ kubectl label pod tree-app-1 concept=mountain --overwrite
pod/tree-app-1 labeled

확인 해보면 정상적으로 Label 이 변경 된것을 볼 수 있다.

$ kubectl get pod/tree-app-1 -L concept
NAME         READY   STATUS    RESTARTS   AGE     CONCEPT
tree-app-1   1/1     Running   0          9m16s   mountain

이제 Label 을 제거하는 실습을 진행해보자!

hello-app 파드의 version 레이블을 제거하기 위해서는 뒤에 '-' 를 불이면 되며 조회해보면 정상적으로 제거 된것을 볼 수 있다.

$ kubectl label pod hello-app version-
pod/hello-app labeled
$ kubectl get pod/hello-app -L version
NAME        READY   STATUS    RESTARTS   AGE   VERSION
hello-app   1/1     Running   0          10m

이제 첫번째 실습이 완료 되었으니 group 레이블이 있는 파드를 모두 제거한다.

$ kubectl delete pod -l group
pod "hello-app" deleted
pod "rose-app" deleted
pod "sky-app" deleted
pod "tree-app-1" deleted
pod "tree-app-2" deleted

두번째. Selector로 선택하여 배포

이번 실습에서는 node 에 Label을 붙여 원하는 Label 에 해당하는 노드에 파드를 배포하도록 한다!

우선 노드 Name을 확인하기 위해 노드를 조회한다.

$ kubectl get node
NAME                                           STATUS   ROLES    AGE   VERSION
gke-corin-cluster-default-pool-d2d86113-3m94   Ready    <none>   22h   v1.25.7-gke.1000
gke-corin-cluster-default-pool-d2d86113-l47c   Ready    <none>   22h   v1.25.7-gke.1000
gke-corin-cluster-default-pool-d2d86113-q40b   Ready    <none>   22h   v1.25.7-gke.1000

label 명령어를 통해 두개의 노드에 soil(토양) 레이블 값이 moist(촉촉한)인 Label을 추가한다. 

$ kubectl label node gke-corin-cluster-default-pool-d2d86113-3m94 gke-corin-cluster-default-pool-d2d86113-q40b soil=moist
node/gke-corin-cluster-default-pool-d2d86113-3m94 labeled
node/gke-corin-cluster-default-pool-d2d86113-q40b labeled

이제 남은 하나의 노드에는 soil 레이블값이 dry(건조한)인 Label을 추가한다.

$ kubectl label node gke-corin-cluster-default-pool-d2d86113-l47c soil=dry
node/gke-corin-cluster-default-pool-d2d86113-l47c labeled

정상적으로 Label이 추가 되었는지 확인하면 정상적으로 추가 된것을 볼 수 있다.

$ kubectl get node -L soil
NAME                                           STATUS   ROLES    AGE   VERSION            SOIL
gke-corin-cluster-default-pool-d2d86113-3m94   Ready    <none>   22h   v1.25.7-gke.1000   moist
gke-corin-cluster-default-pool-d2d86113-l47c   Ready    <none>   22h   v1.25.7-gke.1000   dry
gke-corin-cluster-default-pool-d2d86113-q40b   Ready    <none>   22h   v1.25.7-gke.1000   moist

테스트를 위해 for 문을 돌려 green-app 파드를 5개 생성하며 --overrides 옵션에서 nodeSelector(노드 선택)로 Label soil이 moist 인 노드에만 배포 하도록 한다. 

$ for i in {1..5};
for> do kubectl run tree-app-$i \
for> --labels="element=tree" \
for> --image=yoonjeong/green-app:1.0 \
for> --port=8081 \
for> --overrides='{ "spec": { "nodeSelector": {"soil": "moist"} } }';
for> done
pod/tree-app-1 created
pod/tree-app-2 created
pod/tree-app-3 created
pod/tree-app-4 created
pod/tree-app-5 created

생성된 5개의 파드를 -o wide 옵션을 주어 상세적으로 보면 Label soil가 moist인 노드에만 파드가 생성 된 것을 볼 수 있다. 

$ kubectl get pods -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP            NODE                                           NOMINATED NODE   READINESS GATES
tree-app-1   1/1     Running   0          28s   10.100.0.21   gke-corin-cluster-default-pool-d2d86113-3m94   <none>           <none>
tree-app-2   1/1     Running   0          27s   10.100.0.22   gke-corin-cluster-default-pool-d2d86113-3m94   <none>           <none>
tree-app-3   1/1     Running   0          27s   10.100.1.15   gke-corin-cluster-default-pool-d2d86113-q40b   <none>           <none>
tree-app-4   1/1     Running   0          26s   10.100.1.16   gke-corin-cluster-default-pool-d2d86113-q40b   <none>           <none>
tree-app-5   1/1     Running   0          25s   10.100.0.23   gke-corin-cluster-default-pool-d2d86113-3m94   <none>           <none>

위에서는 yaml 이 아닌 run 으로 바로 생성하기 위해 --overrides를 사용 했으나 yaml 로 정의 한다면 아래와 같이 spec.nodeSelector 를 이용하면 된다.

apiVersion: v1
..
spec:
  nodeSelector:
  	soil: moist
  containers:
  - name:
..

이제 실습이 완료 되었으니 element가 tree인 파드를 제거한다!

$ kubectl delete pod -l element=tree
pod "tree-app-1" deleted
pod "tree-app-2" deleted
pod "tree-app-3" deleted
pod "tree-app-4" deleted
pod "tree-app-5" deleted

끝!

728x90
Comments