코알못

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

ETC

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

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

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

첫번째. 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