3.5.2 조정 루프 (Reconciliation Loop)

앞서 우리는 쿠버네티스에서 사용자가 YAML과 같은 형식의 매니페스트 파일을 통해 시스템의 ‘원하는 상태(Desired State)’를 선언적으로 기술하고, 이를 kubectl이라는 도구를 통해 쿠버네티스 API 서버에 전달하는 방식으로 시스템과 상호작용한다는 것을 배웠습니다. 그렇다면, 우리가 이렇게 마치 소원을 빌 듯 원하는 상태를 선언하기만 하면, 쿠버네티스는 과연 어떻게, 그리고 어떤 내부적인 원리를 통해 그 마법과 같은 일들, 즉 우리가 선언한 상태를 현실로 만들고, 심지어 예기치 않은 문제가 발생하여 현재 상태가 틀어지더라도 그 선언된 상태를 꾸준히 유지하려고 끊임없이 노력하는 것일까요? 그 비밀의 핵심에는 바로 쿠버네티스 시스템 내부에서 마치 심장처럼 쉼 없이 박동하며 작동하는 매우 중요하고 근본적인 메커니즘, ‘조정 루프(Reconciliation Loop)’ 또는 때로는 ‘제어 루프(Control Loop)’라고 불리는 지능적인 자동화 엔진이 자리 잡고 있습니다.

조정 루프 (Reconciliation Loop)

이 ‘조정 루프’라는 개념을 정확히 이해하는 것은 쿠버네티스가 어떻게 그토록 강력한 자동화 능력, 스스로 문제를 해결하는 자가 치유(self-healing) 기능, 그리고 변화하는 요구에 맞춰 시스템의 규모를 유연하게 조절하는 확장성(scalability)을 제공할 수 있는지에 대한 근본적인 해답을 얻는 것과 같습니다. 이는 마치 고도로 훈련된 로봇 군단이 각자에게 주어진 임무를 지치지 않고, 실수 없이, 그리고 끊임없이 수행하며 전체 시스템을 항상 최적의 상태로 유지하려는 모습과도 유사하다고 할 수 있습니다. 이 조정 루프야말로 쿠버네티스를 단순한 ‘컨테이너 실행 도구’를 넘어, ‘지능형 분산 시스템 관리 플랫폼’으로 만들어주는 핵심적인 두뇌이자 심장이라고 할 수 있습니다.

쿠버네티스의 컨트롤 플레인(Control Plane), 즉 클러스터 전체를 지휘하고 관리하는 중앙 제어부 내부에는 다양한 종류의 특화된 ‘컨트롤러(Controller)’ 프로세스들이 항상 깨어 실행되고 있습니다. (컨트롤러에 대해서는 다음 3.5.3절에서 더 자세히 다룰 예정입니다.) 이 컨트롤러들은 각각 자신에게 할당된 특정 종류의 쿠버네티스 리소스(예: 파드, 디플로이먼트, 서비스, 노드 등)의 상태를 책임지고 관리하는 임무를 부여받습니다. 그리고 각 컨트롤러는 자신이 책임지고 있는 리소스에 대해 다음과 같은 세 가지 핵심적인 단계를 마치 하나의 무한 반복 루프(infinite loop)처럼, 끊임없이 그리고 지칠 줄 모르고 수행합니다. 이 반복적인 관찰, 비교, 그리고 실행의 과정을 바로 ‘조정 루프’라고 부릅니다.

3.5.2.1.관찰(Observe): 현재 시스템의 실제 상태를 면밀하고 지속적으로 주시하다.

조정 루프의 가장 첫 번째이자 가장 기본적인 단계는 바로 ‘관찰(Observe)’입니다. 이는 마치 유능한 의사가 환자의 상태를 정확히 진단하기 위해 먼저 환자의 다양한 생체 신호(체온, 맥박, 혈압 등)를 주의 깊게 측정하고 관찰하는 것과 같습니다. 올바른 조치를 취하기 위해서는 현재 상황에 대한 정확하고 시의적절한 정보가 필수적이기 때문입니다.

쿠버네티스에서 각 컨트롤러는 자신이 관리하도록 지정된 특정 종류의 리소스(예를 들어, 디플로이먼트 컨트롤러는 클러스터 내의 모든 디플로이먼트(Deployment) 오브젝트들을, 노드 컨트롤러는 모든 노드(Node) 오브젝트들을 책임집니다)에 대해, 쿠버네티스 API 서버를 통해 해당 리소스들의 ‘현재 상태(Current State)’ 또는 ‘실제 상태(Actual State)’를 지속적으로, 그리고 매우 반응적으로 감시하고 그 최신 정보를 수집합니다.

이 ‘관찰’ 과정은 단순히 주기적으로 정보를 폴링(polling)하는 소극적인 방식만을 의미하지 않습니다. 물론, 컨트롤러는 일정 주기로 자신이 관리하는 리소스의 상태를 API 서버에 질의하여 변경 사항이 있는지 확인할 수 있습니다. 하지만 더 중요하고 효율적인 방식은 바로 쿠버네티스 API 서버가 제공하는 ‘와치(watch)’ 메커니즘을 적극적으로 활용하는 것입니다. ‘와치’는 특정 리소스나 리소스 목록에 대한 변경 사항(예: 새로운 리소스 생성, 기존 리소스 수정, 리소스 삭제 등)이 발생했을 때, API 서버가 해당 변경 사항에 관심 있는 클라이언트(여기서는 컨트롤러)에게 실시간으로 이벤트 알림을 보내주는 기능입니다. 컨트롤러는 이 와치 기능을 통해, 마치 특정 주제에 대한 뉴스 구독을 신청한 것처럼, 자신이 관리하는 리소스에 어떤 변화가 생기면 즉시 그 사실을 통보받고 필요한 정보를 업데이트할 수 있습니다. 이는 불필요한 API 서버 부하를 줄이면서도 매우 신속하게 상태 변화에 대응할 수 있게 해주는 핵심 기술입니다.

예를 들어, 우리가 “특정 레이블(label)을 가진 Nginx 웹 서버 파드를 항상 3개 실행하라”고 정의한 레플리카셋(ReplicaSet) 오브젝트가 있다고 가정해 봅시다. 이 레플리카셋을 전담하여 관리하는 레플리카셋 컨트롤러는 다음과 같은 정보들을 API 서버로부터 지속적으로 관찰하고 업데이트 받습니다.

  • “이 레플리카셋이 관리해야 할 특정 레이블을 가진 파드들이 현재 클러스터 내에 정확히 몇 개나 실행 중인가?”
  • “각 파드의 현재 상세 상태(예: Pending – 생성 중, Running – 실행 중, Succeeded – 성공적으로 완료, Failed – 오류로 실패, Unknown – 상태 알 수 없음 등)는 어떠한가?”
  • “각 파드는 클러스터 내의 어떤 워커 노드에 할당되어 실행되고 있는가?”
  • “최근에 이 레플리카셋의 명세(spec 필드, 예를 들어 원하는 복제본 수)가 변경되지는 않았는가?”
  • “이 레플리카셋이 관리하는 파드 중 최근에 새로 생성되거나, 수정되거나, 또는 삭제된 파드는 없는가?”

이러한 정보들을 종합적으로, 그리고 거의 실시간으로 파악함으로써, 레플리카셋 컨트롤러는 자신이 관리하는 파드 그룹의 현재 상태에 대한 가장 정확하고 최신의 그림을 항상 머릿속에 그리고 있게 됩니다. 이는 마치 숙련된 항공 교통 관제사가 레이더 화면을 통해 자신이 담당하는 공역 내 모든 항공기의 현재 위치, 고도, 속도, 비행 경로 등을 꼼꼼하게, 그리고 실시간으로 파악하며 안전한 운항을 유도하려고 노력하는 것과 매우 유사하다고 할 수 있습니다.

여기서 매우 중요한 점은, 컨트롤러는 결코 현재 상태에 대해 안주하거나 과거의 정보를 바탕으로 섣부른 가정을 하지 않는다는 것입니다. 분산 시스템 환경에서는 언제든지 예기치 않은 변화가 발생할 수 있기 때문에, 컨트롤러는 항상 최신의 실제 관찰된 정보를 바탕으로 다음 단계의 판단과 조치를 내리려고 노력합니다. 이러한 지속적이고 반응적인 관찰이야말로 조정 루프가 효과적으로 작동하기 위한 가장 기본적인 전제 조건이며, 쿠버네티스가 그토록 역동적이고 회복탄력적인 시스템이 될 수 있는 비결 중 하나입니다.

3.5.2.2.차이 분석(Diff): 원하는 이상적인 모습과 냉정한 현실 사이의 간극을 정확히 측정하다.

조정 루프의 첫 번째 단계인 ‘관찰(Observe)’을 통해 컨트롤러가 자신이 관리하는 리소스의 현재 실제 상태(Current State)에 대한 가장 최신의 정확한 정보를 확보하고 나면, 이제 루프의 두 번째 핵심 단계인 ‘차이 분석(Difference Analysis 또는 간단히 Diff)’으로 넘어갑니다. 이 단계의 목적은 매우 명확합니다. 바로 앞서 관찰을 통해 파악한 ‘현재 시스템의 실제 모습’과, 사용자가 YAML 매니페스트 파일 등을 통해 쿠버네티스 API 서버에 이미 선언적으로 정의해 둔 ‘시스템이 최종적으로 도달해야 할 이상적인 모습, 즉 원하는 상태(Desired State)’ 또는 ‘기대하는 상태(Expected State)’를 매우 면밀하고 정확하게 비교하여, 그 둘 사이에 어떠한 불일치나 간극(difference 또는 delta)이 존재하는지를 정확하게 찾아내고 분석하는 것입니다.

이는 마치 의사가 환자의 현재 증상과 건강 상태(현재 상태)를 다양한 검사 결과를 통해 파악한 후, 의학적으로 가장 건강하고 이상적인 상태(원하는 상태)와 비교하여 어떤 부분이 얼마나 차이가 나는지, 즉 어떤 질병이나 문제가 있는지를 진단하는 과정과도 유사합니다. 또는, 노련한 항해사가 현재 배의 위치와 항로(현재 상태)를 해도와 나침반, GPS 등을 통해 파악한 후, 원래 계획했던 목적지와 항로(원하는 상태)로부터 얼마나 벗어나 있는지를 정확히 계산하는 과정에 비유할 수도 있습니다.

컨트롤러는 이 차이 분석을 수행하기 위해, 자신이 책임지고 있는 리소스의 ‘원하는 상태’ 정보를 API 서버로부터 가져옵니다. 이 ‘원하는 상태’는 보통 해당 리소스 오브젝트의 spec 필드에 상세하게 기술되어 있습니다. 그리고 이 spec 필드의 내용과, ‘관찰’ 단계를 통해 얻은 리소스의 ‘현재 상태'(보통 리소스 오브젝트의 status 필드나, 연관된 다른 리소스들의 실제 상태를 통해 파악됨)를 항목별로 꼼꼼하게 비교합니다.

앞서 우리가 예시로 들었던, “특정 레이블을 가진 Nginx 웹 서버 파드를 항상 3개 실행하라”고 정의된 레플리카셋(ReplicaSet)을 계속 사용해 봅시다. 이 레플리카셋을 관리하는 레플리카셋 컨트롤러는 다음과 같은 방식으로 차이 분석을 수행할 수 있습니다.

복제본 수(Number of Replicas) 비교:
  • 원하는 상태: 레플리카셋의 spec.replicas 필드에는 3이라는 값이 명시되어 있습니다. 즉, 사용자는 항상 3개의 파드가 실행되기를 원합니다.
  • 현재 상태: 컨트롤러가 ‘관찰’ 단계를 통해 현재 클러스터에서 해당 레플리카셋이 관리하는 레이블을 가진 파드의 실제 실행 개수를 확인합니다.
  • 차이 분석 결과:
    • 만약 현재 실행 중인 파드가 단 2개뿐이라면, 컨트롤러는 “원하는 상태(3개)와 현재 상태(2개) 간에 파드 1개가 부족하다”라는 명확한 차이를 인식하게 됩니다.
    • 반대로, 만약 어떤 이유로든 현재 4개의 파드가 실행 중이라면, 컨트롤러는 “파드 1개가 초과되었다”는 차이를 정확하게 감지할 것입니다.
    • 만약 정확히 3개의 파드가 실행 중이라면, 일단 수적인 측면에서는 차이가 없는 것으로 판단할 수 있습니다.

개별 파드의 건강 상태(Health Status) 비교 (더 정교한 컨트롤러의 경우):

단순히 파드의 개수만 일치한다고 해서 ‘원하는 상태’가 완벽하게 달성되었다고 보기는 어렵습니다. 예를 들어, 레플리카셋이 아닌 디플로이먼트(Deployment) 컨트롤러와 같이 더 고수준의 컨트롤러는 개별 파드의 ‘건강 상태’까지도 고려하여 차이를 분석할 수 있습니다.

  • 원하는 상태: 일반적으로 사용자는 모든 파드가 정상적으로 실행되고(예: Running 상태이면서, 정의된 경우 라이브니스 프로브(Liveness Probe)와 레디니스 프로브(Readiness Probe)를 통과한 상태) 사용자 요청을 처리할 준비가 되어 있기를 원합니다.
  • 현재 상태: 컨트롤러가 3개의 파드가 실행 중임을 확인했지만, 그중 하나의 파드가 Running 상태가 아니라 Failed 상태이거나, 또는 Running 상태이기는 하지만 레디니스 프로브에 계속 실패하여 실제로는 요청을 처리할 수 없는 상태로 관찰되었다고 가정해 봅시다.
  • 차이 분석 결과: 이 경우, 컨트롤러는 “실행 중인 파드의 수는 3개로 일치하지만, 건강한 파드의 수는 2개뿐이므로, 건강한 파드 1개가 부족하다” 또는 “특정 파드(예: my-nginx-pod-xyz)가 원하는 건강 상태가 아니다”라는 더 구체적인 차이를 인식하게 됩니다.
기타 명세(Spec) 항목과의 비교:

파드의 수나 건강 상태 외에도, 컨트롤러는 자신이 관리하는 리소스의 spec에 정의된 다른 중요한 항목들(예: 사용해야 할 컨테이너 이미지 버전, 환경 변수 설정, 볼륨 마운트 정보 등)과 현재 실행 중인 파드들의 실제 구성이 일치하는지 여부도 비교 분석할 수 있습니다. 만약 사용자가 디플로이먼트의 컨테이너 이미지를 새로운 버전으로 업데이트하도록 spec을 변경했다면, 컨트롤러는 현재 실행 중인 파드들이 아직 이전 버전의 이미지를 사용하고 있다는 차이를 감지할 것입니다.

이처럼 차이 분석 단계는 마치 건축가가 완공된 건물을 설계도면과 한 치의 오차도 없이 꼼꼼하게 대조하며, 어느 부분이 설계와 다르게 시공되었는지, 혹은 어느 부분에 예상치 못한 하자가 발생했는지를 정확하게 찾아내고 그 문제의 본질을 진단하는 과정과도 같습니다. 이 단계에서의 정확하고 상세한 진단(차이 분석 결과)이 있어야만, 다음 단계인 ‘실행(Act)’ 단계에서 올바르고 효과적인 조치를 취하여 시스템을 원하는 상태로 되돌릴 수 있기 때문입니다. 만약 차이 분석이 부정확하거나 피상적이라면, 엉뚱한 조치를 취하거나 문제의 근본 원인을 해결하지 못하고 임시방편적인 처방만 내리게 될 수도 있습니다. 따라서 컨트롤러는 이 차이 분석 단계를 매우 신중하고 정교하게 수행하도록 설계되어 있습니다. 이 과정은 쿠버네티스가 단순한 자동화 스크립트의 집합이 아니라, 마치 상황을 이해하고 판단하는 지능적인 시스템처럼 느껴지게 하는 핵심적인 이유 중 하나입니다.

3.5.2.3.실행(Act): 감지된 차이를 메우고 원하는 상태로 시스템을 이끌기 위한 구체적인 행동을 취하다.

조정 루프의 앞선 두 단계, 즉 ‘관찰(Observe)’을 통해 현재 시스템의 실제 상태를 정확히 파악하고, ‘차이 분석(Diff)’을 통해 이 실제 상태와 사용자가 선언한 ‘원하는 상태(Desired State)’ 사이의 불일치나 간극을 명확하게 진단하고 나면, 이제 컨트롤러는 루프의 마지막이자 가장 능동적인 단계인 ‘실행(Act)’ 단계로 진입합니다. 이 단계의 핵심 목표는 바로 앞서 감지된 차이를 효과적으로 해소하고, 현재 시스템의 상태를 사용자가 궁극적으로 정의한 원하는 상태로 점진적으로, 그리고 안전하게 수렴(converge)시키기 위한 필요한 모든 구체적인 조치(action)들을 자동으로, 그리고 지능적으로 수행하는 것입니다. 이는 마치 의사가 환자의 병을 정확히 진단한 후, 그 병을 치료하기 위한 적절한 처방(약물 투여, 수술 등)을 내리고 실행하는 과정과도 같습니다.

컨트롤러가 취하는 구체적인 조치의 내용은 당연히 앞선 ‘차이 분석’ 단계에서 어떤 종류의 불일치가 감지되었는지, 그리고 해당 컨트롤러가 어떤 종류의 리소스를 책임지고 있는지에 따라 달라집니다. 몇 가지 대표적인 예시 상황과 컨트롤러의 대응 방식을 살펴보겠습니다.

파드 복제본 수가 부족한 경우 (예: 레플리카셋 컨트롤러):

앞서 우리가 계속 예시로 들었던 레플리카셋(ReplicaSet)을 다시 생각해 봅시다. 사용자가 spec.replicas: 3으로 설정하여 항상 3개의 Nginx 파드가 실행되기를 원한다고 선언했는데, 현재 클러스터에는 해당 레이블을 가진 파드가 단 2개만 실행 중이라는 ‘차이’가 감지되었다고 가정합니다. 이 경우, 레플리카셋 컨트롤러는 즉시 쿠버네티스 API 서버에 “이러이러한 명세(파드 템플릿에 정의된 내용)를 가진 새로운 파드 1개를 추가로 생성해 주십시오”라는 요청을 보낼 것입니다. 그러면 API 서버는 이 요청을 받아들여 새로운 파드 오브젝트를 생성하고, 이어서 쿠버네티스 스케줄러는 이 새로운 파드를 클러스터 내의 가용한 컴퓨팅 자원(CPU, 메모리 등)이 있는 가장 적합한 워커 노드에 배치(스케줄링)하여 실행되도록 할 것입니다. 이 과정을 통해 시스템은 다시 3개의 파드가 실행되는 ‘원하는 상태’로 돌아가게 됩니다.

파드 복제본 수가 초과된 경우 (예: 레플리카셋 컨트롤러):

반대로, 만약 어떤 이유로든(예: 사용자의 실수나 다른 시스템의 개입) 원하는 복제본 수(3개)보다 더 많은 4개의 파드가 실행 중이라고 판단되었다면, 레플리카셋 컨트롤러는 불필요하게 실행 중인 파드 중 하나를 안전하게 삭제하도록 API 서버에 지시하는 조치를 취할 것입니다. 이때 어떤 파드를 삭제할지는 컨트롤러의 내부 로직(예: 가장 최근에 생성된 파드, 특정 어노테이션이 없는 파드 등)에 따라 결정될 수 있으며, 삭제 과정 역시 파드 내 컨테이너에게 정상적인 종료(graceful shutdown)를 시도하는 방식으로 진행됩니다.

노드가 응답하지 않는 경우 (예: 노드 컨트롤러 및 관련 워크로드 컨트롤러):

만약 특정 워커 노드가 하드웨어 고장이나 네트워크 단절 등으로 인해 컨트롤 플레인과 더 이상 통신할 수 없는 상태(예: NotReady 또는 Unknown)로 감지되면, 노드 컨트롤러는 해당 노드에 특정 상태(예: NoSchedule 테인트(Taint))를 표시하여 더 이상 새로운 파드가 해당 노드에 스케줄링되지 않도록 조치합니다. 동시에, 해당 장애 노드에서 실행 중이던 중요한 파드들(예: 디플로이먼트에 의해 관리되는 파드)을 관리하던 각 워크로드 컨트롤러들은, 자신들이 유지해야 할 ‘원하는 파드 수’가 부족해졌음을 인지하고, 해당 파드들을 다른 건강한 워커 노드로 옮겨(재스케줄링하여) 다시 실행하려는 시도를 할 수 있습니다. (이때, 파드가 안전하게 다른 노드로 이전되기 위해서는 파드 축출(Pod Eviction)과 관련된 정책 및 타임아웃 설정, 그리고 파드 자체의 특성(예: 스테이트풀셋 여부, 로컬 볼륨 사용 여부 등)이 중요하게 고려됩니다.)

애플리케이션 버전 업데이트가 필요한 경우 (예: 디플로이먼트 컨트롤러):

사용자가 디플로이먼트 오브젝트의 spec.template.spec.containers[0].image 필드를 새로운 버전의 컨테이너 이미지로 변경하여 ‘원하는 상태’를 업데이트했다고 가정해 봅시다. 디플로이먼트 컨트롤러는 이 변경 사항을 감지하고, 현재 실행 중인 파드들이 아직 이전 버전의 이미지를 사용하고 있다는 ‘차이’를 인식합니다. 그러면 컨트롤러는 사전에 정의된 업데이트 전략(예: 롤링 업데이트)에 따라, 새로운 버전의 이미지를 사용하는 파드들을 점진적으로 생성하고, 이들이 정상적으로 실행되는 것을 확인한 후, 기존 버전의 파드들을 점진적으로 삭제하는 일련의 자동화된 조치를 수행하여 시스템을 새로운 ‘원하는 상태’로 안전하게 이전시킵니다.

여기서 우리가 반드시 이해해야 할 매우 중요한 점은, 대부분의 경우 컨트롤러가 직접 하부 시스템(예: 특정 노드의 컨테이너 런타임에게 “이 컨테이너를 시작하라”고 직접 명령을 내리거나, 네트워크 장비의 설정을 직접 변경하는 것)에 명령을 내리는 것이 아니라는 사실입니다. 대신, 컨트롤러는 주로 쿠버네티스 API 서버를 통해 다른 쿠버네티스 리소스의 상태를 변경하거나(예: 파드 오브젝트의 특정 필드 값을 업데이트), 새로운 리소스 생성을 요청하거나(예: 새로운 파드 오브젝트 생성 요청), 또는 다른 핵심 쿠버네티스 컴포넌트(예: 스케줄러에게 파드 배치 요청, Kubelet에게 특정 파드 실행 지시 등)에게 필요한 작업을 수행하도록 요청하는 방식으로 간접적으로 조치를 취한다는 것입니다.

이는 쿠버네티스 시스템 전체의 일관성(consistency)과 API 중심 설계(API-centric design) 원칙을 유지하는 데 매우 중요합니다. 모든 상태 변경과 작업 요청은 중앙의 API 서버를 통해 이루어지므로, 시스템 전체의 상태를 추적하고 감사하기 용이하며, 다양한 컴포넌트들이 서로 느슨하게 결합(loosely coupled)되어 각자의 역할에만 집중할 수 있게 됩니다.

그리고 이러한 모든 조정 조치들은 사람의 직접적인 개입 없이 완전히 자동화된 방식으로, 그리고 시스템 전체의 안정성을 해치지 않으면서 항상 사용자가 정의한 ‘원하는 상태’를 향해 나아간다는 명확한 목표를 가지고 지능적으로 진행됩니다. 컨트롤러는 단순히 미리 짜인 스크립트를 반복 실행하는 것이 아니라, 현재 시스템의 상태를 끊임없이 관찰하고, 목표와의 차이를 분석하며, 그 차이를 메우기 위한 최적의 행동을 스스로 결정하고 실행하는 것입니다.

이처럼 “관찰(Observe) -> 차이 분석(Diff) -> 실행(Act)”으로 이어지는 이 조정 루프는 쿠버네티스 클러스터가 살아 숨 쉬는 동안, 마치 우리 몸속에서 생명 활동을 유지하기 위해 끊임없이 작동하는 항상성(homeostasis) 유지 메커니즘처럼, 각 컨트롤러에 의해 쉼 없이 그리고 지칠 줄 모르고 반복적으로 수행됩니다. 이는 마치 가정에 있는 잘 설계된 자동 온도 조절 장치(thermostat)가 실내 온도를 계속해서 측정하다가, 사용자가 설정한 희망 온도보다 현재 온도가 낮아지면 자동으로 난방 시스템을 켜서 온도를 높이고, 반대로 희망 온도보다 높아지면 난방을 끄거나 경우에 따라서는 냉방 시스템을 가동하여 항상 쾌적한 온도를 유지하려고 노력하는 것과 같은 매우 직관적이면서도 강력한 피드백 제어(feedback control) 원리라고 할 수 있습니다.

덕분에, 쿠버네티스 시스템은 외부 환경의 예기치 않은 방해(예: 특정 서버의 갑작스러운 하드웨어 장애, 네트워크의 일시적인 단절, 애플리케이션 버그로 인한 파드의 예기치 않은 충돌 등)나, 혹은 사용자에 의한 내부적인 의도된 변화(예: 애플리케이션의 복제본 수를 늘리거나 줄이는 설정 변경, 새로운 버전의 컨테이너 이미지를 사용하도록 업데이트하는 경우 등)에도 불구하고, 항상 사용자가 최종적으로 정의한 ‘원하는 상태’를 기억하고 그 상태를 안정적으로 유지하거나, 만약 현재 상태가 그 원하는 상태에서 벗어났다면 가능한 한 빨리, 그리고 안전하게 그 상태로 되돌아가기 위해 끊임없이 노력합니다. 이것이 바로 쿠버네티스가 그토록 강력한 자가 치유 능력, 자동화된 확장성, 그리고 예측 가능한 운영을 제공할 수 있는 핵심적인 비결이며, 우리가 쿠버네티스를 단순한 도구가 아닌 ‘지능형 플랫폼’이라고 부를 수 있는 이유입니다. 다음으로는 이 조정 루프를 실제로 구현하고 실행하는 주체인 ‘컨트롤러’에 대해 더 자세히 알아보겠습니다.