레플리케이션 & 컨트롤러

blackdog·2021년 10월 21일
0

book-k8s-in-action

목록 보기
3/3

파드를 수동으로 생성한다면 unmanaged 파드가 된다. unmanaged 파드는 노드에 장애가 발생해서 파드가 유실되더라도 새로운 파드로 대체되지 않는데, 레플리케이션 컨트롤러를 이용하면 파드를 안정적으로 유지할 수 있다.

4.1 파드를 안정적으로 유지하기

쿠버네티스를 사용하면 얻을 수 있는 주요 이점은 쿠버네티스에 컨테이너 목록을 제공하면 해당 컨테이너를 클러스터 어딘가에서 계속 실행되도록 할 수 있다는 것이다.

파드가 노드에 스케줄링되는 즉시, 해당 노드의 kubelet은 파드의 컨테이너를 실행하고 파드가 존재하는 한 컨테이너가 계속 실행되도록 한다. 그리고 컨테이너의 주 프로세스에 크래시가 발생하면 kubelet이 컨테이너를 다시 시작한다.
하지만 프로세스의 크래시 없이도 OOM 발생 등으로 프로세스는 실행되지만 정상적인 서비스가 불가능한 경우에도 애플리케이션을 다시 시작하는 방법이 있다.

4.1.1 라이브니스 프로브 소개

쿠버네티스는 liveness probe를 통해 컨테이너가 살아 있는지 확인할 수 있다. 파드의 스펙에 각 컨테이너의 라이브니스 프로브를 지정한다. 쿠버네티스틑 주기적으로 프로브를 실행하고, 실패할 경우 프로브를 다시 시작한다.

쿠버네티스는 세 가지 메커니즘을 사용해 컨테이너에 프로브를 실행한다.

  • HTTP GET 프로브 : HTTP GET 요청을 지정된 경로에 요청하고 응답이 오류코드를 나타내지 않는 경우 성공으로 간주
  • TCP 소켓 프로브 : 컨테이너의 지정된 포트에 TCP 연결을 시도한다. 연결에 성공하면 성공으로 간주
  • Exec 프로브 : 컨테이너 내의 임의의 명령을 실행하고 명령 종료 상태를 확인. 상태 코드가 0이면 성공으로 간주

4.1.2 HTTP 기반 라이브니스 프로브 생성

4.1.3 동작 중인 라이브니스 프로브 확인

  • kubectl get po [pod name] 으로 파드의 restart 여부, 종료 이유 등을 조회할 수 있다.
  • 이전 컨테이너의 종료 코드를 볼 수 있는데, 128 + x(프로세스에 전송된 시그널 번호) 이다.
  • 137의 경우 128 + SIGKILL 요청이 전송되어 프로세스가 종료 된 것을 알 수 있다.

4.1.4 라이브니스 프로브의 추가 속성 설정

  • 지연, 제한 시간, 기간 등을 둘 수 있다.
  • 지연(delay)이 0이면 컨테이너 시작된 후 바로 프로브를 실행한다.
  • 제한 시간(timeout)은 프로브 실행 후 응답을 받기 까지의 대기 시간이다.
  • 기간(period)는 프로브를 재시도 할 때 까지의 주기를 말한다.
  • 초기 지연(initialDelaySeconds)을 설정하지 않으면 컨테이너가 시작되자마자 프로브를 실행하는데, 대부분의 애플리케이션은 이 때 요청을 받을 준비가 되지 않기 때문에 실패로 간주될 수 있다. 그래서 초기 지연을 설정하는 것이 중요하다.

4.1.5 효과적인 라이브니스 프로브 생성

라이브니스 프로브가 확인해야 할 사항

  • 특정 URL 경로 (/health) 에 요청하도록 프로브를 구성해 애플리케이션에 실행 중인 모든 구성요소가 살아 있는지 확인하도록 구성할 수 있다.
  • 애플리케이션 내부만 체크하고, 외부 요인의 영향을 받지 않도록 해야 한다.
  • 문제의 원인이 DB에 있는 경우에도 프로브에서 실패를 받으면, 웹 서버 컨테이너를 재시작해도 문제가 해결되지 않기 때문이다.

프로브를 가볍게 유지하기

  • 프로브가 너무 많은 연산 리소스를 사용하면 부담이 될 수 있다.
  • 비교적 자주 실행되지만 1초 내에 완료되야 할 것.
  • 나중에 파드의 CPU 사용량에 제한을 걸 수도 있는데 그 때 프로브가 무거우면 부담이 될 것.

프로브에 재시도 루프를 구현하지 마라

  • 프로브 자체가 재시도가 된다.
  • 프로브에 재시도 루프를 구현하면 중첩 반복이 됨.

라이브니스 프로브 요약

  • 컨테이너에 크래시가 발생하거나 프로브가 실패한 경우 쿠버네티스가 컨테이너를 재시작한다.
  • 이 작업은 파드를 호스팅하는 노드의 kubelet에서 수행한다.
  • 마스터에서 실행 중인 쿠버네티스 컨트롤플레인 구성 요소는 이 프로세스에 관여하지 않는다.
  • 노드 자체에 크래시가 발생하면 중단된 노드의 대체 파드를 생성하는 것은 컨트롤 플레인의 역할이다.
  • 직접 생성한 파드는 kubelet에서만 관리가 되는데 kubelet은 노드에서 실행되기 때문에 노드가 고장나면 아무것도 할 수 없다.

4.2 레플리케이션컨트롤러 소개

레플리케이션 컨트롤러는 파드가 항상 실행되도록 보장한다. 클러스터에서 노드나 파드가 사라진 경우, 사라진 파드를 감지해 교체 파드를 생성한다. 하지만 직접 생성한 unmanaged 파드는 노드 장애 발생 시 완전히 유실된다.

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

  • 실행 중인 파드 목록을 지속적으로 모니터링하고, 특정 "type"의 실제 파드 수가 의도하는 수와 일치하는지 항상 확인한다. 조건에 맞는 파드 수가 적게 실행되면 파드를 늘리고, 많이 실행되면 파드를 제거한다.
  • 여기서 말하는 "type"은 lable selector로 선택할 수 있는 속성을 말한다.

의도하는 수의 복제본보다 많은 복제본이 생기는 경우

  • 누군가 같은 유형의 파드를 수동으로 만든다.
  • 누군가 기존 파드의 "type"을 변경한다.
  • 누군가 의도하는 파드 수를 줄인다.

컨트롤러 조정 루프 소개

  • 레플리케이션컨트롤러의 역할은 정확한 수의 파드가 항상 레이블 셀렉터와 일치하는지 확인하는 것이다.

레플리케이션컨트롤러의 세 가지 요소 이해

  • 레이블 셀렉터 : manage할 파드를 결정
  • 레플리카 수 (replica count) : 실행할 파드의 의도하는(desired) 수 결정
  • 파드 템플릿은 새로운 파드 레플리카를 만들 때 사용
  • 이 요소들은 언제든 수정할 수 있지만 레플리카 수의 변경만 기존 파드에 영향을 미친다.

컨트롤러의 레이블 셀렉터 또는 파드 템플릿 변경의 영향 이해

  • 레이블 셀렉터를 변경하면 기존 파드는 컨트롤러의 범위를 벗어나므로 해당 파드에 대한 관리를 중지한다.
  • 파드를 생성한 이후에는 파드의 실제 내용에 대해서 신경쓰지 않는다.
  • 템플릿은 컨트롤러로 새 파드를 생성할 때만 영향을 미친다.

레플리케이션컨트롤러 사용 시 이점

  • 기존 파드가 사라지면 새 파드를 시작해서 파드가 항상 실행되도록 한다.
  • 클러스터 노드에 장애가 발생하면, 장애 발생 노드에서 실행되던 파드에 대한 교체 복제본이 생긴다.
  • 수동 또는 자동으로 파드를 쉽게 수평으로 확장할 수 있게 한다.

4.2.2 레플리케이션컨트롤러 생성

  • 템플릿의 파드 레이블은 레플리케이션컨트롤러의 레이블 셀렉터와 완전히 일치해야 한다.
  • 그렇지 않으면 새 파드를 무한히 생성할 수 있다.
  • 파드 셀렉터를 지정하지 않으면 쿠버네티스가 파드 템플릿에서 레이블을 자동으로 추출하여 자동 설정한다. 실수를 줄이고 yaml 파일을 간결하게 유지하는 방법이다.

4.2.3 레플리케이션컨트롤러 작동 확인

삭제된 파드에 관한 레플리케이션컨트롤러의 반응 확인

  • 생성된 파드 중 하나를 수동으로 삭제한다면 다른 파드를 생성한다.

컨트롤러가 새로운 파드를 생성한 원인 정확히 이해하기

  • 파드를 삭제하면 다른 파드를 생성했다.
  • 삭제 그 자체에 대한 대응이 아니라, 결과적인 상태에 대응하는 것이다.

노드 장애 대응

  • 예제에서는 파드 삭제에 대응하여 레플리케이션 컨트롤러가 대체 파드를 생성하는 것을 보았다.
  • 노드의 네트워크 연결을 끊게 된다면, 쿠버네티스는 노드의 장애를 감지하고 노드에 있던 파드의 대체 파드를 생성한다.

4.2.4 레플리케이션컨트롤러 범위 안팎으로 파드 이동하기

  • 레플리케이션컨트롤러는 레이블 셀렉터와 일치하는 파드만을 관리한다.
  • 파드의 레이블을 변경하면 컨트롤러의 범위에 제거하거나 추가할 수 있다.
  • 파드의 레이블을 변경하여 컨트롤러 범위에서 제거하면 unmanaged 파드가 된다.
  • 하지만 컨트롤러는 파드가 사라짐을 감지하고 다시 replica 수에 맞게 새로운 파드를 기동한다.

컨트롤러에서 파드를 제거하는 실제 사례

  • 특정 파드에서 작업을 하려는 경우 컨트롤러에서 빼낸 다음 작업을 하면 편하다.
  • 오류가 발생한 파드가 있으면 컨트롤러에서 빼내서 새로운 파드로 교체한 후, 오류 발생 파드를 디버깅 하거나 문제를 재연할 수 있다.

4.2.5 파드 템플릿 변경

  • 템플릿은 언제든 변경할 수 있으나, 템플릿 변경 이후에 생성되는 파드에 영향을 미친다.

4.2.6 수평 파드 스케일링

  • 파드 수를 늘리거나 줄이는 것은 컨트롤러 리소스의 replicas 필드 값을 변경하기만 하면 된다.

스케일링에 대한 선언적 접근 방법 이해

  • x개의 인스턴스가 실행되게 하고 싶다.
  • 항상 유지해야 하는 개수를 알려주고 거기에 맞추기 위한 동작을 한다.

4.2.7 레플리케이션컨트롤러 삭제

  • 레플리케이션컨트롤러를 삭제하면 파드도 삭제된다.
  • --cascade=false 옵션을 주면 컨트롤러만 삭제되고 파드는 unmanaged가 된다.
  • 이 옵션을 이용하면 컨트롤러만 교체할 수도 있겠다.

4.3 레플리카셋 사용하기

레플리케이션컨트롤러는 앞으로 레플리카셋으로 대체될 예정이다.

4.3.1 레플리카셋과 레플리케이션컨트롤러 비교

  • 두 개는 똑같이 동작하지만 레플리카 셋이 좀 더 풍부한 표현식을 사용하는 파드 셀렉터를 갖고 있다.
  • 레플리카 셋의 셀렉터는 특정 레이블이 없는 파드나, 특정 레이블의 키만 가지고 매칭시킬 수 있다.

4.3.2 레플리카셋 정의하기

4.3.3 레플리카셋 생성 및 검사

4.3.4 레플리카셋의 더욱 표현적인 레이블 셀렉터 사용하기

4.3.5 레플리카셋 정리

4.4 데몬셋

각 노드에서 정확히 한 개의 파드만 실행하고 싶은 경우에 사용한다. 예를 들면, 로그 수집기와 리소스 모니터, kube-proxy 등의 프로세스가 있다.
쿠버네티스를 사용하지 않는 환경에서는 일반적으로 노드가 부팅되는 동안에 시스템 초기화 스트립트(init script)나 systemd 데몬을 통해 시작된다. 쿠버네티스에서도 systemd를 사용할 수 있지만 쿠버네티스가 제공하는 모든 기능을 사용하려면 데몬셋을 이용하는게 좋다.

4.4.1 데몬셋으로 모든 노드에 파드 실행하기

  • 모든 클러스터의 노드마다 파드를 하나만 실행하려면 데몬셋 오브젝트 생성이 필요
  • 파드 셀렉터와 일치하는 파드 하나가 각 노드에서 실행 중인지 체크
  • 새 노드가 클러스터에 추가되면 데몬셋은 새 파드 인스턴스를 새 노드에 배포한다.

4.4.2 데몬셋을 사용해 특정 노드에서만 파드를 샐행하기

  • 특정 노드에서만 실행하고 싶은 파드가 있을 것이다. (eg. ssd)
  • 노드 셀럭터를 지정하여 특정 노드에만 파드를 생성할 수 있다.

4.5 완료 가능한 단일 태스크를 수행하는 파드 실행

레플리케이션컨트롤러, 레플리카셋, 데몬셋은 완료되지 않는 지속적인 태스크를 수행한다. 이런 파드의 프로세스는 종료되면 다시 시작한다. 하지만 한 번 실행하면 완료 상태로 두고 다시 시작하지 않는 태스크도 필요하다. 이 때 Job을 사용한다.

4.5.1 잡 리소스 소개

  • 파드의 컨테이너 내부에서 실행 중인 프로세스가 성공적으로 완료되면 컨테이너를 다시 시작하지 않는 파드를 생성
  • 노드에 장애가 발생한 경우 해당 노드에 있던 잡이 관리하는 파드는 레플리카셋 파드와 같은 방식으로 다른 노드로 다시 스케줄링된다.
  • 프로세스 자체에 장애가 발생한 경우, 잡에서 컨테이너를 다시 시작할 것인지 설정할 수 있다.
  • 작업이 제대로 완료되는 것이 중요한 임시 작업에 유용하다.
  • unmanged 파드에 만들 수도 있지만 작업이 수행되는 동안 장애가 발생하거나 파드가 노드에서 제거되는 경우 수동 생성이 필요하다.
  • 한 번만 실행되야하는 task 관리도 노드 장애나 리스케쥴링이 되더라도 끝까지 쿠버네티스가 책임지고 해주는 것이다.

4.5.2 잡 리소스 정의

4.5.3 파드를 실행한 잡 보기

4.5.4 잡에서 여러 파드 인스턴스 실행하기

잡은 두 개 이상의 파드 인스턴스를 생성해 병렬 혹은 순차적으로 실행하도록 구성할 수 있다.

  • 순차 : completions
  • 병렬 : parallelism

4.5.5 잡 파드가 완료되는 데 걸리는 시간 제한하기

4.6 크론잡

잡을 특정 시간에 실행하거나, 주기적으로 실행해야 할 때 사용한다.

4.6.1 크론잡 생성하기

4.6.2 스케줄된 잡의 실행 방법 이해

  • 일반적인 상황에서 크론 잡은 스케쥴에 설정된 각 실행에 항상 하나의 잡만 실행한다.
  • 하지만 두 개의 잡이 동시에 생성되거나 생성되지 않을 수 있다.
  • 여러개가 동시에 실행되는 경우를 대비해서 멱등상을 가져야한다.
  • 생성되지 않는 경우를 대비해서 다은 번 잡 실행이 이전에 누락된 실행에서 완료했어야하는 작업을 수행하는지 확인해야 한다.
profile
검둥검둥 검둥개

0개의 댓글