728x90
반응형

Replication Controller

 

레플리케이션 컨트롤러 리소스란 쿠버네티스 리소스 중 하나로 포드가 항상 실행되도록 유지하게 하는 역할을 한다.

일단 레플리카 개념부터 이해해보자.

레플리카의 역할이란 예를 들어 두 개의 포드가 운영중이라고 하면 이 중 하나의 포드가 사용자의 실수 또는 노드의 장애로 실패 (삭제) 되었을 때 다른 포드를 바로 생성하여 두 개가 유지되도록 해주는 역할을 한다. 하나의 포드를 여러개 복사한 것을 복제본이라는 표현을 사용하는데 이런 복제본의 숫자가 항상 유지되도록 해주는 역할을 하는 것이 레플리카이다. 

 

아래는 그림으로 표현한 레플리카이다.

 

 

포드 A와 포드 B가 있는데 포드 A는 레플리카를 사용하지 않고 생성한 일반 포드이고 포드 B는 레플리카를 통해 생성한 포드이다. 이 두 포드가 실행되는 노드에 장애가 발생하였을 때 레플리카는 자신이 관리하는 포드에 문제가 생겼음을 감지하고 클러스터 내에 있는 다른 노드에 새로운 포드 B를 생성한다. 포드 A의 경우 레플리카가 관리하는 포드가 아니므로 삭제가 되어도 복구할 수 없다.

포드가 항상 실행상태로 유지되려면 레플리카의 영역내에서 실행되어야 한다. 그리고 당연한 얘기이겠지만 포드가 실패한 것을 레플리카가 어떻게 알 수 있냐인데 레플리카는 항상 자신이 관리하는 포드를 모니터링해서 자신이 원하는 포드의 수와 실행중인 포드의 수를 비교하여 일치하는지 확인한다.

 

쿠버네티스에서 레플리카를 실행하는 것이 레플리케이션컨트롤러이다. 현재는 레플리케이션 컨트롤러의 업그레이드 버전인 레플리카셋이 사용되며 라벨 셀렉터 부분에서 차이가 있으나 이 부분은 나중에 알아보고 레플리케이션 컨트롤러의 동작 과정 및 개념에 대해 알아보겠다.

 

 

레플리케이션 컨트롤러의 동작과정

 

레플리케이션 컨트롤러의 동작 과정을 알아보겠다.

 

  1. 레플리케이션 컨트롤러가 실행

  2. 자신이 가진 라벨셀렉터와 일치하는 라벨셀렉터를 가진 포드를 검색

  3. 검색된 포드의 수와 자신이 원하는 수의 포드의 수가 일치하는지 확인

  4. 원하는 수의 포드보다 더 많은 경우 실행 중인 포드 중 랜덤으로 지정하여 삭제함 (어떤 포드가 삭제될지는 알 수 없음, 다만 나중에 다른 글에서 설명하겠지만 종료 규칙을 지정하여 포드가 삭제되게 하도록 할 수 있다)

  5. 원하는 수보다 포드의 수가 적은 경우 정의된 템플릿대로 원하는 수와 일치하는만큼 포드를 실행함 (템플릿이란 레플리케이션 컨트롤러 매니페스트[yaml 파일] 에 정의된 내용)

  6. 이제 이 과정을 마쳤다면 다시 검색단계로 돌아가 지속적으로 위의 단계를 반복함

 

 

레플리케이션 컨트롤러에는 세 가지 요소가 있는데 아래와 같다.

 

1. 라벨 셀렉터 : 레플리케이션 컨트롤러 범위에 있는 포드를 결정

2. 복제본 수 : 실행하고 싶은 포드의 수

3. 포드 템플릿 : 새로운 포드 (복제본) 를 생성할 때 사용

레플리케이션 컨트롤러는 이렇게 세 가지의 요소를 가지고 있는데 이 요소들은 언제든 수정이 가능하다.

 

 

레플리케이션 컨트롤러의 생성 과정

 

 

그림 하나에 모든 설명이 들어가 있으므로 다른 설명은 생략하겠지만 항상 기억해둬야 할점은 포드를 생성하는 건 레플리케이션 컨트롤러가 아니라 Kubelet이다.

레플리케이션 컨트롤러는 스케줄러를 통해 노드의 Kubelet에게 포드를 생성하라고 전달을 할뿐이지 자신이 직접 생성하지 않는다.

 

 

레플리케이션 컨트롤러 생성 및 삭제

 

구성 요소들을 알아봤으니 레플리케이션 컨트롤러를 만드는 방법을 알아보자.

아래는 레플리케이션 컨트롤러를 생성하는 매니페스트 이다. 파일의 이름은 testrc.yaml 이라고 가정한다.

 

apiVersion: v1

kind: ReplicationController # 레플리케이션 컨트롤러 (RC) 의 매니페스트 정의

metadata:

    name: test # 레플리케이션 컨트롤러의 이름

spec:

    replicas: 3 # 원하는 포드 인스턴스 수

    selector: # 포드 셀렉터를 통해 RC가 관리하려는 포드를 결정

        app: web

    template: # 새 포드를 생성하는 포드 템플릿

        metadata:

            labels:

                app: web

        spec:

            containers:

                - name: nginx

                  image: nginx:latest

                  ports:

                    - containerPort: 8080

 

위의 매니페스트를 해석하면 RC (ReplicationController) 리소스를 생성하고 컨트롤러의 이름은 test 이며 app=web 이라는 라벨을 가진다. 이 컨트롤러는 항상 3개의 포드가 유지되도록 동작하며 생성할 포드의 템플릿에는 포드의 라벨, 컨테이너 이미지, 컨테이너 포트가 포함되어 있다.

 

위의 매니페스트를 실행하려면 아래의 명령을 실행한다.

 

# kubectl apply -f testrc.yaml

 

이 후 생성된 컨트롤러의 세부정보를 확인하려면 아래의 명령을 실행한다.

 

# kubectl describe rc test

 

여기서 rc는 레플리케이션 컨트롤러를 의미하며 test는 매니페스트 메타데이터에 정의한 이름이다.

 

생성 후 레플리케이션 컨트롤러를 삭제하면 실행중이던 포드들도 함께 삭제가 된다. 만약 레플리케이션 컨트롤러가 삭제되더라도 포드는 실행되기를 바란다면 삭제 명령에 옵션을 주면 포드는 삭제되지 않는다.

 

# kubectl delete rc test --cascade=false

 

해당 명령은 레플리케이션 컨트롤러만 삭제하고 포드는 유지할 수 있게한다. 

 

 

 

레플리케이션 컨트롤러와 레플리카 셋의 차이

 

예를 들어 포드 세개가 구동중이고 이 포드들의 라벨은 app=kubia 이다. 근데 이중 하나의 포드에 라벨을 추가하면 어떻게 될까?

# kubectl label pod kubia-OOOO app=foo --overwrite -> 포드에 라벨을 추가하는 옵션은 --overwrite 이다.

 

 

 

어차피 app=kubia를 가진 포드고 여기서 라벨 하나만 더 추가된다 하더라도 포함되어 있으니까 상관없지 않을까라는 생각을 하지만 레플리케이션 컨트롤러는 자신의 라벨과 포드의 라벨이 정확히 일치하지 않는다고 결정 내리고 기존 포드는 잃어버렸다(?) 라고 생각하여 새로운 포드를 추가한다. 이게 레플리케이션 컨트롤러의 단점이였다. 하지만 이 부분이 개선되서 나온것이 레플리카셋이다.

 

레플리카 셋은 레플리케이션 컨트롤러와 모든게 동일하지만 라벨 셀렉터에서 차이점이 생긴다. 위의 경우처럼 라벨이 정확히 일치하지 않는 포드가 있으면 레플리케이션 컨트롤러는 실패한 포드라고 생각을 하지만 레플리카 셋은 자신이 가진 라벨중 하나만 있어도 그 포드는 자신이 관리하는 포드라고 생각한다.

 

레플리카 셋은 레플리케이션 컨트롤러의 라벨 셀렉터를 개선하였다. 어떻게 개선하였냐면

 

레플리케이션 컨트롤러 : 라벨 env=dev 이면 포드의 라벨도 env=dev 이어야 한다. (무조건 정확히 일치해야함, 라벨이 더있거나 덜 있거나 문자가 다르면 안됨)

레플리카 셋 : 라벨 env=dev 이고 포드의 라벨이 env=dev, env=stg, env= 과 같이 있다하면 env=* 형식으로 자신이 가진 라벨 키와 같은 라벨키를 가진 포드를 모두 포함할 수 있다.

 

하나의 예를 더 들어서 설명하겠다.

 

Replication Controller Label : env=dev

ReplicaSet Label : env=prd

Pod Label : env=dev, env=prd

 

이렇게 라벨을 가진 경우 레플리케이션 컨트롤러는 포드가 두개의 라벨을 가진건지 두 개의 포드가 각자 하나씩 라벨을 가진 건지 알지 못한다. 포드에 있는 라벨 중 하나만 일치하고 다른 하나는 인식하지 못하는 라벨이기 때문에 자신이 관리하는 포드라고 지정할 수도 없다.

반면 레플리카셋은 포드의 두개의 라벨이 있고 그 라벨의 키가 자신이 가진 키와 동일하다면 하나의 포드가 두개의 라벨을 가진것을 알 수 있으며 자신이 관리하는 포드라고 알 수 있다.

 

이런 라벨 셀렉터를 정의하는 조건절도 있으며 매니페스트를 통해 어떻게 하는지 알아보겠다.

 

apiVersion: apps/v1

kind: ReplicaSet

metadata:

    name: test

spec:

    replicas: 3

    selector:

        matchExpressions: # 이 셀렉터는 포드에 "env" 키가 있는 라벨을 포함해야 함

            - key: env

             operator: In

             values:

                - stg # 라벨의 값은 stg이여야 함

    template:

        metadata:

            labels:

                env: stg

        spec:

            containers:

            - name: nginx

              image: nginx:latest

 

matchExpressions로 라벨 셀렉터에 표현식을 추가할 수 있다 (키, 연산자, 가능한 값)

 

연산자에는 네 가지의 연산자가 있다.

  • In : 라벨의 값이 지정된 값 중 하나와 일치해야함

  • NotIn : 라벨의 값이 지정된 값과 일치해서는 안됨

  • Exists : 포드에는 지정된 키가 있는 라벨이 포함돼야함 (값은 중요하지 않음), 이 연산자를 사용할 때 값 필드를 지정하면 안됨

  • DoesNotExist : 포드에는 지정된 키가 있는 라벨을 포함하면 안됨, values 속성을 지정하면 안되고 여러 표현식을 지정하면 셀렉터가 포드와 일치하도록 모든 표현식이 true로 평가돼야 함

 

 

테스트했던 내용

 

만약 두개의 레플리카셋이 있고 하나의 포드가 두 레플리카셋이 가진 라벨과 모두 일치한다면 어찌될까?

 

1번 Replicaset-1 : env=dev

2번 Replicaset-2 : env=prd

Pod : env=dev, env=prd

 

위 처럼 포드는 두 개의 레플리카셋이 관리하는 라벨을 모두 가지고 있다.

 

이런 경우에는 포드는 자신을 생성한 레플리카셋 (Replicaset-1) 의 관리만 받는다. 포드는 1번 레플리카의 관리 포드이므로 2번 레플리카에서는 관리할 수 없다.

만약 이 상태에서 1번 레플리카셋을 삭제한다면 포드는 함께 삭제되었는지 아니면 2번 레플리카 셋에 포함되었는지 기억이 나진 않는다.

다만 어찌됬든 1번 레플리카셋과 함께 삭제되던가 2번 레플리카셋에 포함되서 원하는 수를 넘으므로 삭제되던가 결국은 사라진다. 2번 레플리카셋에 포함되면 랜덤으로 사라짐 (동작 과정 보면 알수 있음)

반응형

'Kubernetes' 카테고리의 다른 글

Kubernetes Ingress  (0) 2019.09.19
Kubernetes Service  (0) 2019.09.17
Kubernetes Monitoring - Version1  (0) 2019.09.17
Kubernetes HorizontalPodAutoscaler  (0) 2019.08.31
Kubernetes Pod DaemonSet  (0) 2019.08.30

+ Recent posts