목차
- 파드가 요청을 즉시 처리하지 못한다면?
- 레디니스 프로브
- 레디니스 프로브 유형
- 레디니스 프로브 동작
- 레디니스 프로브가 중요한 이유
- 파드에 레디니스 프로브 추가
- 실제 환경에서 수행해야 하는 기능
- 레디니스 프로브를 항상 정의
- 레디니스 프로브에 파드의 종료 코드를 포함하지 않기
파드가 요청을 즉시 처리하지 못한다면?
파드의 레이블이 서비스의 파드 셀렉터와 일치할 경우 파드가 서비스의 엔드포인트에 포함됩니다. 적절한 레이블을 가진 새 파드가 만들어지자마자 서비스의 일부가 돼 요청이 파드로 전달되기 시작합니다. 하지만 만약 그 파드가 즉시 요청을 처리할 준비가 돼 있지 않다면 어떻게 될까요?
파드는 구성에 시간이 걸리거나 데이터를 로드하는 데 시간이 필요할 수 있고, 첫 번째 사용자 요청이 너무 오래 걸리거나 사용자 경험에 영향을 미치는 것을 방지하고자 준비 절차를 수행해야 할 수도 있습니다. 이러한 경우 특히 이미 실행 중인 인스턴스가 요청을 적절하고 신속하게 처리할 수 있는 경우 파드가 요청을 즉시 받기 시작하는 것을 원하지 않을 수 있습니다. 완전히 준비될 때까지 기동 중인 파드에 요청을 전달하지 않는 것이 좋습니다.
레디니스 프로브
이전에 다루었던 라이브니스 프로브와 불안전한 컨테이너를 자동으로 다시 시작해 애플리케이션의 상태를 원활히 유지하는 방법을 배웠습니다. 쿠버네티스에서는 라이브니스 프로브와 비슷하게 파드에 레디니스 프로브(readiness probe)를 정의할 수 있습니다.
레디니스 프로브는 주기적으로 호출되며 특정 파드가 클라이언트 요청을 수신할 수 있는지를 결정합니다. 컨테이너의 레디니스 프로브가 성공을 반환하면 컨테이너가 요청을 수락할 준비가 됐다는 신호입니다.
준비가 됐다(being ready)라는 표시는 분명 각 컨테이너마다 다를 수 있습니다. 쿠버네티스는 컨테이너에서 실행되는 애플리케이션이 간단한 GET / 요청에 응답하는지 혹은 특정 URL 경로를 호출할 수 있는지 확인하거나 필요에 따라 애플리케이션이 준비됐는지 확인하기 위해 전체적인 항목을 검사하기도 합니다. 애플리케이션 특성에 따라 상세한 레디니스 프로브를 작성하는 것은 애플리케이션 개발자의 몫입니다.
레디니스 프로브 유형
라이브니스 프로브와 마찬가지로 세 가지 유형의 레디니스 프로브가 존재합니다.
- Exec 프로브
컨테이너의 상태를 프로세스의 종료 상태 코드로 결정합니다. - HTTP GET 프로브
HTTP GET 요청을 컨테이너로 보내고 응답의 HTTP 상태 코드를 보고 컨테이너가 준비됐는지 여부를 결정합니다. - TCP 소켓 프로브
컨테이너의 지정된 포트로 TCP 연결을 엽니다. 소켓이 연결되면 컨테이너가 준비된 것으로 간주합니다.
레디니스 프로브의 동작
컨테이너가 시작될 때 쿠버네티스는 첫 번째 레디니스 점검을 수행하기 전에 구성 가능한 시간이 경과하기를 기다리도록 구성할 수 있습니다. 그런 다음 주기적으로 프로브를 호출하고 레디니스 프로브의 결과에 따라 작동합니다. 파드가 준비되지 않았다고 하면 서비스에서 제거됩니다. 파드가 다시 준비되면 서비스에 다시 추가됩니다.
라이브니스 프로브와 달리 컨테이너가 준비 상태 점검에 실패하더라도 컨테이너가 종료되거나 다시 시작되지 않습니다. 이는 라이브니스 프로브와 레디니스 프로브 사이의 중요한 차이입니다. 라이브니스 프로브는 상태가 좋지 않은 컨테이너를 제거하고 새롭고 건강한 컨테이너로 교체해 파드의 상태를 정상으로 유지하는 반면, 레디니스 프로브는 요청을 처리할 준비가 된 파드의 컨테이너만 요청을 수신하도록 합니다. 이것은 컨테이너를 시작할 때 주로 필요하지만 컨테이너가 작동한 후에도 유용합니다.
다음 그림에서 볼 수 있듯이 레디니스 프로브가 실패하면 파드는 엔드포인트 오브젝트에서 제거됩니다. 서비스로 연결하는 클라이언트의 요청은 파드로 전달되지 않습니다. 파드의 레이블이 서비스의 레이블 셀렉터와 일치하지 않을 때와 같은 효과입니다.
레디니스 프로브가 중요한 이유
파드 그룹이 다른 파드에서 제공하는 서비스에 의존한다고 가정해봅시다. 프론트엔드 파드 중 하나에 연결 문제가 발생해 더 이상 데이터베이스에 연결할 수 없는 경우, 해당 시점에 파드가 해당 요청을 처리할 준비가 되지 않았다는 신호를 레디니스 프로브가 쿠버네티스에게 알리는 것이 현명할 수 있습니다.
다른 파드 인스턴스에 동일한 유형의 연결 문제가 발생하지 않는다면 정상적으로 요청을 처리할 수 있습니다. 레디니스 프로브를 사용하면 클라이언트가 정상 상태인 파드하고만 통신하고 시스템에 문제가 있다는 것을 절대 알아차릴 수 없습니다.
즉, 레디니스 프로브가 제대로 구성되어 있지 않으면, 클라이언트는 문제가 있는 파드와도 통신을 시도하고, 이로 인해 시스템 장애가 발생할 수 있습니다. 따라서 레디니스 프로브를 올바르게 구성하는 것이 중요합니다.
파드에 레디니스 프로브 추가
kubectl edit 명령어로 기존 레플리케이션 컨트롤러의 파드 템플릿에 프로브를 추가할 수 있습니다.
kubectl edit rc kubia
텍스트를 편집기에서 레플리케이션 컨트롤러 YAML이 열리면 파드 템플릿에 컨테이너 스펙을 찾고 spec.tamplate.spec.containers 아래의 첫 번째 컨테이너에 다음 레디니스 프로브 스펙을 추가합니다.
...
spec:
...
template:
...
spec:
containers:
- name: kubia
image: luksa/kubia
readinessProbe: > 파드의 각 컨테이너에 레디니스 프로브가 이런 방식으로 정의될 수 있습니다.
exec:
command:
- ls
- /var/ready
...
레디니스 프로브는 컨테이너 내부에서 ls /var/ready 명령어를 주기적으로 수행합니다. ls 명령어는 파일이 존재하는 종료 코드 0을 반환하고 그렇지 않으면 0이 아닌 값을 반환합니다. 파일이 있으면 레디니스 프로브가 성공하고 그렇지 않으면 실패합니다.
다소 이상할 수 있는 레디니스 프로브를 정의하는 이유는 문제의 파일을 생성하거나 제거해 그 결과를 바로 전환할 수 있기 때문입니다. 아직 파일이 없으므로 모든 파드가 준비되지 않았다고 보고해야 합니다. 그렇다고 무조건 그런 것은 아닙니다. 레플리케이션 컨트롤러에 대해 다룰 때에도 파드 템플릿을 변경해도 기존 파드에는 영향을 미치지 않습니다.
즉, 기존 파드는 여전히 레디니스 프로브가 정의돼 있지 않습니다. kubectl get pods로 파드를 조회하고 READY 열을 보면 확인할 수 있습니다. 파드를 삭제하면 레플리케이션 컨트롤러가 다시 파드를 생성합니다. 새 파드는 레디니스 점검에 실패하고 각각에 /var/ready 파일을 만들 때까지 서비스의 엔드포인트에 포함되지 않을 것입니다.
실제 환경에서 수행해야 하는 기능
실제 환경에서 레디니스 프로브는 애플리케이션이 클라이언트 요청을 수신할 수 있는지 여부에 따라 성공 또는 실패를 반환해야 합니다.
서비스에서 파드를 수동으로 제거하려면 수동으로 프로브의 스위치를 전환하는 대신 파드를 삭제하거나 파드 레이블을 변경해야 합니다. 수동으로 추가 및 제거를 한다면 파드와 서비스의 레이블 셀렉터에 enabled=ture 부분을 추가하면 생성되고 레이블을 제거하면 서비스에서 파드도 제거됩니다.
레디니스 프로브에서 알야할 2가지에 대해 알아보겠습니다.
- 레디니스 프로브를 항성 정의
파드에 레디니스 프로브를 추가하지 않으면 파드가 시작하는 즉시 서비스 엔드포인트가 됩니다. 애플리케이션이 수신 연결을 시작하는 데 너무 오래 걸리는 경우 클라이언트의 서비스 요청은 여전히 시작 단계로 수신 연결을 숫락할 준비가 되지 않은 상태에서 파드로 전달됩니다. 따라서 클라이언트는 "Connection refused" 유형의 에러를 보게 될 것입니다. 기본 URL에 HTTP 요청을 보내더라도 항상 레디니스 프로브를 정의하는 습관을 들여야합니다. - 레디니스 프로브에 파드의 종료 코드를 포함하지 않기
나머지 강조할 점은 파드의 라이프 사이클 마지막 단계에서 고려해야 하며 연결 오류가 발생한 클라이언트와 관련된 내용입니다. 파드가 종료할 때, 실행되는 애플리케이션은 종료 신호를 받자마자 연결 수락을 중단합니다. 그렇기 때문에 종료 절차가 시작되는 즉시 레디니스 프로브가 실행하도록 만들어 파드가 모든 서비스에서 확실하게 제거돼야 한다고 생각할 수 있습니다. 하지만 그건 필요하지 않습니다. 쿠버네티스는 파드를 삭제하자마자 모든 서비스에서 파드를 제거하기 때문입니다.
'Container > Kubernetes' 카테고리의 다른 글
[Kubernetes Volume] 1. 쿠버네티스 볼륨과 볼륨의 유형 (0) | 2023.04.12 |
---|---|
[Kubernetes Service] 7. 헤드리스 서비스란? (0) | 2023.04.11 |
[Kubernetes Service] 5. 인그레스로 통신 및 TLS로 보안 (0) | 2023.04.11 |
[Kubernetes Service] 4. 클라이언트 외부에 서비스 노출 (2) | 2023.04.11 |
[Kubernetes Service] 3. 클러스터 외부에 서비스 연결 (0) | 2023.04.10 |