코알못

[kubernetes] ReplicaSet 란? 본문

ETC

[kubernetes] ReplicaSet 란?

코린이s 2023. 5. 20. 12:47
728x90

만약 Pod를 필요한 수 만큼 유지 할 수 있도록 관리(장애가 나서 Pod가 죽었을시 자동 복구) 해줄수 있는 기능이 있다면 얼마나 좋을까!?

ReplicaSet 오브젝트를 사용하면 된다!

ReplicaSet 의 경우 아래와 같은 구조를 가지며

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: blue-app-rs
  labels:          
    app: blue-app
spec:      
  selector:
    matchLabels:
      app: blue-app
  replicas: 3
  template:
    metadata:
      labels:
        app: blue-app
    spec:
      containers:
      - name: blue-app
       image: blue-app:1.0

각각 설명은 아래 표를 참고한다.

구분 내용
apiVersion Kubernetes API 버전
Kind 오브젝트 타입
metadata.name 오브젝트 이름
metadata.labels 오브젝트 조회시 사용할 라벨
spec 사용자가 원하는 스펙 정의
spec.selector.matchLabels Pod 선택 조건 (해당 라벨이 맞는 Pod만 관리)
spec.replicas 유지 되길 원하는 Pod 수
spec.template Pod 정보 (apiVersion, kind를 제외하고 기존 Pod 정의시 기입한 정보 입력)

이제 실제로 만들어 보자!

# replicaset.yaml 

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: blue-replicaset
spec:
  replicas: 3
  selector:
    matchLabels:
      app: blue-app
  template:
    metadata:
      labels:
        app: blue-app
    spec:
      containers:
      - name: blue-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: "50m"

해당 yaml 에 정의한대로 쿠버네티스 클러스터에 적용한다.

$ kubectl apply -f replicaset.yaml
replicaset.apps/blue-replicaset created

정상적으로 적용 되었는지 확인하기 위해  'get rs' 로 조회한다.

Desired는 원하는 파드수, Current 는 현재 파드수로 현재 3개의 파드가 준비(Ready) 된것을 볼 수 있으며 사용한 이미지 정보와 Label 정보가 같이 나온다.

$ kubectl get rs blue-replicaset -o wide
NAME              DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                   SELECTOR
blue-replicaset   3         3         3       18m   blue-app     yoonjeong/blue-app:1.0   app=blue-app

replicaSet에 의해 생성 된다고 하면 아래와 같이 임의의 문자가 붙는것을 알 수 있다.

$ kubectl get pod -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP           NODE                                           NOMINATED NODE   READINESS GATES
blue-replicaset-8zg9g   1/1     Running   0          18m   10.100.0.4   gke-corin-cluster-default-pool-d2d86113-w610   <none>           <none>
blue-replicaset-9426j   1/1     Running   0          18m   10.100.2.5   gke-corin-cluster-default-pool-d2d86113-zy02   <none>           <none>
blue-replicaset-bl5zq   1/1     Running   0          18m   10.100.3.9   gke-corin-cluster-default-pool-d2d86113-xq03   <none>           <none>

해당 ReplicaSet에 대해서 상세한 정보를 보기 위해 아래와 같이 'describe' 명령어를 이용한다!

event 부분을 보면 3개의 Pod 생성한것을 볼 수 있다.

$ kubectl describe rs blue-replicaset
Name:         blue-replicaset
Namespace:    default
Selector:     app=blue-app
Labels:       <none>
Annotations:  <none>
Replicas:     3 current / 3 desired
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=blue-app
  Containers:
   blue-app:
    Image:      yoonjeong/blue-app:1.0
    Port:       8080/TCP
    Host Port:  0/TCP
    Limits:
      cpu:     50m
      memory:  64Mi
    Environment:
      NODE_NAME:   (v1:spec.nodeName)
      NAMESPACE:   (v1:metadata.namespace)
      POD_IP:      (v1:status.podIP)
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From                   Message
  ----    ------            ----  ----                   -------
  Normal  SuccessfulCreate  23m   replicaset-controller  Created pod: blue-replicaset-bl5zq
  Normal  SuccessfulCreate  23m   replicaset-controller  Created pod: blue-replicaset-8zg9g
  Normal  SuccessfulCreate  23m   replicaset-controller  Created pod: blue-replicaset-9426j

 

이벤트만 상세적으로 보기 위해서는 아래와 같이 'get events'를 이용하며 생성순으로 정렬하도록 sortby를 사용한다.

스케쥴러에 해당 요청이 할당(successfully assigned) 되었고 파드가 생성(Create pod)된것을 볼 수 있다.

그 뒤에 이미지를 받고(pulling image, successfully pulled image) 컨테이너를 생성(created container) 하였다. 

$ kubectl get events --sort-by=.metadata.creationTimestamp
LAST SEEN   TYPE      REASON             OBJECT                       MESSAGE
27m         Normal    Scheduled          pod/blue-replicaset-9426j    Successfully assigned default/blue-replicaset-9426j to gke-corin-cluster-default-pool-d2d86113-zy02
27m         Normal    SuccessfulCreate   replicaset/blue-replicaset   Created pod: blue-replicaset-8zg9g
27m         Normal    SuccessfulCreate   replicaset/blue-replicaset   Created pod: blue-replicaset-bl5zq
27m         Normal    Scheduled          pod/blue-replicaset-bl5zq    Successfully assigned default/blue-replicaset-bl5zq to gke-corin-cluster-default-pool-d2d86113-xq03
27m         Normal    Scheduled          pod/blue-replicaset-8zg9g    Successfully assigned default/blue-replicaset-8zg9g to gke-corin-cluster-default-pool-d2d86113-w610
27m         Normal    SuccessfulCreate   replicaset/blue-replicaset   Created pod: blue-replicaset-9426j
27m         Warning   FailedMount        pod/blue-replicaset-bl5zq    MountVolume.SetUp failed for volume "kube-api-access-srvn8" : failed to sync configmap cache: timed out waiting for the condition
27m         Normal    Pulling            pod/blue-replicaset-9426j    Pulling image "yoonjeong/blue-app:1.0"
27m         Normal    Pulling            pod/blue-replicaset-8zg9g    Pulling image "yoonjeong/blue-app:1.0"
27m         Normal    Pulling            pod/blue-replicaset-bl5zq    Pulling image "yoonjeong/blue-app:1.0"
27m         Normal    Pulled             pod/blue-replicaset-9426j    Successfully pulled image "yoonjeong/blue-app:1.0" in 5.962148636s (5.962179977s including waiting)
27m         Normal    Created            pod/blue-replicaset-9426j    Created container blue-app
27m         Normal    Created            pod/blue-replicaset-8zg9g    Created container blue-app
27m         Normal    Pulled             pod/blue-replicaset-bl5zq    Successfully pulled image "yoonjeong/blue-app:1.0" in 5.151005347s (5.151035378s including waiting)
27m         Normal    Created            pod/blue-replicaset-bl5zq    Created container blue-app
27m         Normal    Pulled             pod/blue-replicaset-8zg9g    Successfully pulled image "yoonjeong/blue-app:1.0" in 5.509598313s (5.509661241s including waiting)
27m         Normal    Started            pod/blue-replicaset-8zg9g    Started container blue-app
27m         Normal    Started            pod/blue-replicaset-9426j    Started container blue-app
27m         Normal    Started            pod/blue-replicaset-bl5zq    Started container blue-app

이제 정상적으로 컨테이너가 동작하는지 테스트를 위해 로컬 포트를 포워딩 한다.

참고 사항으로 'port-forward' 의 경우 로드밸런싱은 되지 않으며 첫번째 파드에만 요청이 간다. 이는 오브젝트가 하나의 기능에만 집중하도록 만들어 졌기 때문이며 로드밸런싱 기능을 이용하고 싶다면 다른 오브젝트를 같이 사용하면 된다.

$ kubectl port-forward rs/blue-replicaset 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

해당 컨테이너로 요청을 보내면 정상적으로 데이터가 나오는것을 볼 수 있다.

$ curl localhost:8080/sky
<!DOCTYPE html>
<htm1>
<head>
    <title>Pod Networking - Blue App</title>
    <style>
        body {
            background-color: lightskyblue;
        }
        .kubernetes {
            margin: 10px 0;
            padding: 10px;
            border: 2px solid black;
        }
    </style>
</head>
<body>
    <h1>Blue App</h1>
    <section class="content">Sky is Blue.</section>
    <section class="kubernetes">
        <p>
            <span>Pod IP: </span><span id="podIp">10.100.2.5</span>
        </p>
        <p>
            <span>Node: </span><span id="node">gke-corin-cluster-default-pool-d2d86113-zy02</span>
        </p>
        <p>
            <span>Namespace: </span><span id="node">default</span>
        </p>
    </section>
</body>
</html>

이제 테스트를 마쳤으니 생성한 오브젝트를 제거 한다.

$ kubectl delete rs --all
replicaset.apps "blue-replicaset" deleted

 

만약에 ReplicaSet 에 정의한 라벨이 포함된 Pod가 생성 되어있는 상태에서  replicaset를 생성하면 어떻게 될까?

두번째 실습을 통해 알아보자!

우선 ReplicaSet 에 정의한 라벨이 포함된 Pod를 하나 생성하기 위해 'app=blue-app' 라벨이 포함된 yaml 파일을 만들고

# blue-app.yaml

apiVersion: v1
kind: Pod
metadata:
  name: blue-app
  labels:
    app: blue-app
spec:
  containers:
  - name: blue-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: "50m"

클러스터에 적용한다.

$ kubectl apply -f ../pod/blue-app.yaml
pod/blue-app created

파드가 정상적으로 생성됨을 알 수 있다.

$ kubectl get pod
NAME       READY   STATUS    RESTARTS   AGE
blue-app   1/1     Running   0          28s

이제 첫번째 실습했던 ReplicaSet 관련 yaml 파일을 생성한다.

$ kubectl apply -f replicaset.yaml
replicaset.apps/blue-replicaset created

파드를 조회해보면 replicaSet으로 생성된 파드는 세개가 아닌 두개이다.

blue-app Pod의 라벨이 ReplicaSet에 정의한 Label과 일치하여 ReplicaSet 관리 범주에 들어가

파드 하나가 이미 생성 되어 있으므로 두개만 생성 된 것이다.

$ kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
blue-app                1/1     Running   0          76s
blue-replicaset-5xn9b   1/1     Running   0          13s
blue-replicaset-rggrj   1/1     Running   0          13s

ReplicaSet 이 정말 두개 생성한것이 맞는지 보기위해  'describe' 로 조회하며 'Created Pod'가 이벤트가 두번 일어난것으로 보아 두개 생성한것이 맞다.

$ kubectl describe rs blue-replicaset
Name:         blue-replicaset
Namespace:    default
Selector:     app=blue-app
Labels:       <none>
Annotations:  <none>
Replicas:     3 current / 3 desired
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=blue-app
  Containers:
   blue-app:
    Image:      yoonjeong/blue-app:1.0
    Port:       8080/TCP
    Host Port:  0/TCP
    Limits:
      cpu:     50m
      memory:  64Mi
    Environment:
      NODE_NAME:   (v1:spec.nodeName)
      NAMESPACE:   (v1:metadata.namespace)
      POD_IP:      (v1:status.podIP)
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From                   Message
  ----    ------            ----  ----                   -------
  Normal  SuccessfulCreate  106s  replicaset-controller  Created pod: blue-replicaset-rggrj
  Normal  SuccessfulCreate  106s  replicaset-controller  Created pod: blue-replicaset-5xn9b

이를 통해 관련없는 pod 가 엮일 수 있기 때문에 Pod Selector 설계의 중요성을 알 수 있었다.

이제 실습을 종료 하며 아래와 같이 모든 오브젝트를 제거 한다.

$ kubectl delete rs/blue-replicaset
replicaset.apps "blue-replicaset" deleted

파드 확인하면 정상적으로 제거 됨을 확인 할 수 있다.

$ kubectl get pod
No resources found in default namespace.

끝!

728x90
Comments