티스토리 뷰

728x90
반응형

레플리카셋(Replica Set): 일정 개수의 포드를 유지하는 컨트롤러

레플리카셋을 사용하는 이유

쿠버네티스의 기본 단위인 포드는 여러 개의 컨테이너를 추상화해 하나의 애플리케이션으로 동작하도록 만드는 컨테이너 묶음이다.

실제로 외부 사용자의 요청을 처리해야 하는 마이크로 서비스 구조의 포드라면 스웜 모드처럼 여러 개의 동일한 컨테이너를 생성한 뒤 외부 요청이 각 컨테이너에 적절히 분배될 수 있어야 한다.

image

쿠버네티스에서는 기본 단위가 포드이기 때문에 동일한 여러 개의 포드를 생성해 외부 요청을 각 포드에 분배하는 방식을 사용해야 한다.

apiVersion: v1
kind: Pod
metadata:
  name: my-nginx-pod-a
spec:
  containers:
  - name: my-nginx-container
    image: nginx:latest
    ports:
    - containerPort: 80
      protocol: TCP

---

apiVersion: v1
kind: Pod
metadata:
  name: my-nginx-pod-b
spec:
  containers:
  - name: my-nginx-container
    image: nginx:latest
    ports:
    - containerPort: 80
      protocol: TCP

그러나 여러 개의 포드를 직접 생성하는 방법은 여러 가지 이유로 적절하지 않다. 우선 동일한 포드의 개수가 많아질수록 일일이 정의하는 것은 매우 비효율적인 작업이다. 또한 포드가 어떠한 이유로든지 삭제되거나, 포드가 위치한 노드에 장애가 발생해 더 이상 포드에 접근하지 못하게 됐을 때 직접 포드를 삭제하고 다시 생성하지 않는 한 해당 포드는 다시 복구되지 않는다(kubectl get pods -o wide 명령어로 포드를 더 자세히 볼 수 있다).

이처럼 포드만 YAML 파일에 정의해 사용하는 방식은 여러 가지 한계점이 있다. 따라서 쿠버네티스에서 포드만 정의해 사용하는 경우는 거의 없의며, 이러한 한계점을 해결해주는 레플리카셋(replicaset)이라는 쿠버네티스 오브젝트를 함께 사용하는 것이 일반적이다. 레플리카셋이 수행하는 역할은 간단하게 이렇다.

  • 정해진 수의 동일한 포드가 항상 실행되도록 관리
  • 노드 장애 등의 이유로 포드를 사용할 수 없다면 다른 노드에서 포드를 다시 생성



레플리카셋 사용하기

# vi replicaset-nginx.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: replicaset-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-nginx-pods-label
  template:
    metadata:
      name: my-nginx-pod
      labels:
        app: my-nginx-pods-label
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

리소스의 고유한 이름은 포드뿐만 아니라 모든 쿠버네티스 오브젝트에서 설정할 수 있으며, 이 레플리카셋의 이름은 metadata의 name 항목에서 replicaset-nginx로 설정했다.

  • spec.replicas : 동일한 포드를 몇 개 유지시킬 것인가.
  • spec.template 아래의 내용들 : 포드를 생성할 때 사용할 템플릿을 정의. 이것만 가리켜서 포드 스펙, 포드 템플릿이라고 함.

레플리카셋을 생성해보자.

$ kubectl apply -f replicaset-nginx.yaml
$ kubectl get po
$ kubectl get rs

3개의 포드가 정상적으로 생성됌을 볼 수 있다. pods, replicasets 명령어를 줄여서 쓸 수 있는데 kubectl api-resources 명령어의 SHORTNAMES 항목에서 확인할 수 있다.

레플리카셋에 정의된 포드의 개수를 늘려 4개의 포드가 실행되게 해보자. kubectl edit, kubectl patch 등 여러 방법이 있지만, YAML 파일에서 숫자만 바꿔도 된다. 숫자를 바꾸고 kubectl apply 명령어로 적용해보면 created가 아닌 configured라는 문구가 출력되면서 새로운 리소스를 생성하지 않고 기존의 리소스를 수정한다. 즉, 1개의 포드가 추가로 생성될 것이다.

삭제하려면 kubectl delete -f, kubectl delete rs를 사용하면 된다.

$ kubectl delete rs replicaset-nginx
...


$ kubectl get po



레플리카셋의 동작 원리

레플리카셋을 삭제하면 포드 또한 삭제되기 때문에 레플리카셋은 포드와 연결된 것처럼 보이지만 실제로는 그렇지 않다. 오히려 느슨한 연결을 유지하고 있으며, 이러한 느슨한 연결은 포드와 레플리카셋의 정의 중 라벨 셀렉터(Label Selector)를 이용해 이뤄진다.

레플리카셋 yaml 파일에서 metadata 항목에서는 리소스의 부가적인 정보를 설정할 수 있다. 그 부가 정보 중에는 리소스의 고유한 이름뿐만 아니라 주석, 라벨 등도 포함된다. 특히 라벨은 포드 등의 쿠버네티스 리소스를 분류할 때 유용하게 사용할 수 있는 메타데이터이다.

라벨은 쿠버네티스 리소스의 부가적인 정보를 표현할 수 있을뿐만 아니라, 서로 다른 오브젝트가 서로를 찾아야 할 때 사용되기도 한다. 예를 들면 레플리카셋은 spec.selector.matchLabel에 정의된 라벨을 통해 생성해야 하는 포드를 찾는다. 즉, app: my-nginx-pods-label 라벨을 가지는 포드의 개수가 replicas 항목에 정의된 숫자인 3개와 일치하지 않으면 포드를 정의하는 포드 템플릿 항목의 내용으로 포드를 생성한다.

image

레플리카셋을 처음 생성했을 때는 my-nginx-pods-label 라벨을 가지는 포드가 존재하지 않기 때문에 template에 정의된 포드 설정으로 3개의 포드를 생성한다.

app: my-nginx-pods-label 라벨을 가지는 포드를 미리 생성해 놓은 다음, 위의 레플리카셋을 생성한다면 레플리카셋의 selector.matchLabel에 정의된 app: my-nginx-pods-label 라벨을 가지는 포드가 이미 1개 존재하기 때문에 template에 정의된 포드 설정을 통해 2개의 포드만이 생성될 것이다.

# vi nginx-pod-without-rs.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-nginx-pod
  labels:
    app: my-nginx-pods-label
spec:
  containers:
  - name: my-nginx-container
    image: nginx:latest
    ports:
    - containerPort: 80
$ kubectl apply -f nginx-pod-without-rs.yaml
pod/my-nginx-pod created

$ kubectl apply -f replicaset-nginx.yaml

$ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
my-nginx-pod             1/1     Running   0          26s
replicaset-nginx-qvrn4   1/1     Running   0          8s
replicaset-nginx-x98vj   1/1     Running   0          8s

참고

kubectl get pods 명령어에서 --show-labels로 label을 확인하거나, -l app & -l app=my-nginx-pods-labels로 app 전체 및 원하는 app을 확인할 수 있다.

$ kubectl get pods --show-labels
$ kubectl get pods -l app
$ kubectl get pods -l app=my-nginx-pods-labels

수동으로 생성한 포드를 삭제하면 해당 라벨을 가지는 포드의 개수가 2개가 되기 떄문에 새로운 포드 1개를 생성하게 된다.

$ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
replicaset-nginx-4sbs4   1/1     Running   1          39h
replicaset-nginx-kw876   1/1     Running   1          39h
replicaset-nginx-m72wt   1/1     Running   0          5s
$ kubectl delete pods replicaset-nginx-4sbs4
pod "replicaset-nginx-4sbs4" deleted
$ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
replicaset-nginx-kw876   1/1     Running   1          39h
replicaset-nginx-m72wt   1/1     Running   0          7m57s
replicaset-nginx-tgkq4   1/1     Running   0          15s

레플리카셋이 생성해 놓은 포드의 라벨을 edit 명령어로 포드 중 1개만 라벨만 지운뒤 저장하면 라벨을 가지는 포드가 2개가 됐으므로, 레플리카셋은 새로운 포드를 새롭게 하나 더 생성한다. 라벨을 삭제한 포드는 레플리카셋의 selector.matchLabel 항목의 값과 더 이상 일치하지 않으므로 레플리카셋에 의해 관리되지 않게된다. 레플리카셋 자체를 삭제하더라고 라벨을 없앤 이 포드는 삭제가지 않으며, 직접 수동으로 삭제해야한다.

$ kubectl edit pods replicaset-nginx-kw876(자신의 포드 name 중 한개)

labels: 
  app: my-nginx-pods-label
두문장 삭제

$ kubectl get pods --show-labels
NAME                     READY   STATUS    RESTARTS   AGE   LABELS
replicaset-nginx-f5bnt   1/1     Running   0          21m   app=my-nginx-pods-label
replicaset-nginx-kw876   1/1     Running   1          40h   <none>
replicaset-nginx-m72wt   1/1     Running   0          41m   app=my-nginx-pods-label
replicaset-nginx-tgkq4   1/1     Running   0          33m   app=my-nginx-pods-label

$ kubectl delete pods replicaset-nginx-kw876
pod "replicaset-nginx-kw876" deleted



레플리케이션 컨트롤러 vs 레플리카셋

이전 버전의 쿠버네티스에서는 레플리카셋이 아닌 레플리케이션 컨트롤러(Replication Controller)라는 오브젝트를 통해 포드의 개수를 유지했었다.

레플리카셋이 레플리케이션 컨트롤러와 다른 점 중 하나는 "표현식(matchExpression)" 기반의 라벨 셀렉터를 사용할 수 있다는 것. 예를 들어 레플리카셋의 yaml selector 항목은 다음과 같이 표현식으로 정의할 수도 있다.

...
selector: 
  matchExpressions:
    - key: app
      values: 
      - my-nginx-pods-label
      - your-nginx-pods-label
      operator: In
  template:
...

위의 예시는 키가 app인 라벨을 가지고 있는 포드들 중에서 values 항목에 정의된 값들이 존재(In)하는 포드들을 대상으로 하겠다는 의미이다. 따라서 app: my-nginx-pods-label, app: your-nginx-pods-label 라벨을 가지는 포드가 레플리카셋의 관리하에 놓이게된다.





출처
시작하세요! 도커/쿠버네티스(용찬호 저, 위키북스)
example

728x90
반응형
댓글
반응형
250x250
글 보관함
최근에 달린 댓글
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Total
Today
Yesterday
링크