
NGINX Ingress Controller 작동 방식
이 문서에서는 NGINX Ingress Controller 의 작동 방식을 설명합니다. 대상 고객은 다음과 같은 두 개의 주요 그룹으로 구성됩니다.
- 소프트웨어가 어떻게 작동하는지 알고 싶어하고 어떻게 실패할 수 있는지 더 잘 이해하고자 하는 운영자.
- 프로젝트에 기여하고자 하는 개발자들.
독자가 Pod, Deployment, Service 및 Endpoints와 같은 핵심 Kubernetes 개념에 익숙하다고 가정합니다.
목차
1. Ingress Controller란?
2. 높은 수준의 Ingress Controller
3. Ingress Controller Pod
3-1. IC Pod
3-2. NGINX Plus의 차이점
4. Ingress Controller 프로세스
4-1. 새로운 Ingress 리소스 처리
4-2. Ingress Controller 는 Kubernetes Controller 입니다.
5. Ingress Controller 프로세스 구성 요소
5-1. 리소스 Cache
5-2. Control Loop
6. Reloading NGINX
6-1. Reloading in General
6-2. IC Reloading
6-3. Ingress Controller가 NGINX를 Reload하는 경우
1. Ingress Controller란?
Ingress Controller는 클러스터 사용자가 생성한 Ingress 리소스에 따라 HTTP Load Balancer를 구성하는 Kubernetes 클러스터의 구성 요소입니다.
Ingress 리소스에 대한 자세한 내용은 Kubernetes 공식 문서를 참조하십시오.
이 문서는 NGINX 및 NGINX Plus 기능을 기반으로 구축된 Ingress Controller 또는 IC라고 하는 NGINX Ingress Controller에만 해당됩니다.
2. 높은 수준의 Ingress Controller
Ingress Controller(IC)에 대한 포괄적인 설명부터 시작하겠습니다. 다음 그림은 IC가 Kubernetes 클러스터에서 실행되는 두 개의 웹 애플리케이션을 인터넷의 클라이언트에 Expose 하는 방법의 예를 보여줍니다.

높은 수준의 IC
그림은 다음을 보여줍니다.
- Kubernetes 클러스터.
- Kubernetes API를 통해 클러스터를 사용하는 클러스터 사용자 관리자, 사용자 A 및 사용자 B.
- 해당 사용자가 배포한 애플리케이션 A 및 B에 연결하는 클라이언트 A 및 클라이언트 B.
- nginx-ingress Namespace의 Pod에 관리자가 배포하고 ConfigMap nginx-ingress를 통해 구성된 IC입니다. 단순화를 위해 하나의 IC Pod만 설명합니다. 그러나 관리자는 일반적으로 중복성을 위해 최소 2개의 Pod를 배포합니다. IC는 Kubernetes API를 사용하여 클러스터에서 생성된 최신 Ingress 리소스를 가져온 다음 해당 리소스에 따라 NGINX를 구성합니다.
- 사용자 A가 Namespace A에 배포한 두 개의 Pod가 있는 애플리케이션 A. 호스트
a.example.com
을 통해 애플리케이션을 클라이언트(클라이언트 A)에 노출하기 위해 사용자 A는 Ingress A를 생성합니다. - 사용자 B가 namespace B에 배포한 하나의 pod가 있는 애플리케이션 B. 호스트 b.example.com을 통해 애플리케이션을 클라이언트(클라이언트 B)에 Expose 하기 위해 사용자 B는 VirtualServer B를 생성합니다.
- IC Pod 앞에 있는 Public Endpoint입니다. 이는 일반적으로 TCP Load Balancer(Cloud, 소프트웨어 또는 하드웨어) 또는 이러한 Load Balancer와 NodePort 서비스의 조합입니다. 클라이언트 A와 B는 Public Endpoint를 통해 애플리케이션에 연결합니다.
노란색과 보라색 화살표는 클라이언트 트래픽과 관련된 연결을 나타내고 검은색 화살표는 Kubernetes API에 대한 액세스를 나타냅니다.
단순화를 위해 관리자와 사용자가 생성해야 하는 배포 및 서비스와 같은 많은 필수 Kubernetes 리소스는 표시되지 않습니다.
다음으로 IC Pod를 살펴보겠습니다.
3. Ingress Controller Pod
IC Pod는 다음을 포함하는 단일 컨테이너로 구성됩니다:
- IC 프로세스 – 클러스터에서 생성된 Ingress 및 기타 리소스에 따라 NGINX를 구성합니다.
- NGINX Master 프로세스 – NGINX Worker 프로세스를 제어합니다.
- NGINX Worker 프로세스 – 클라이언트 트래픽을 처리하고 트래픽을 Backend 애플리케이션으로 Load Balancing 합니다.
다음은 이러한 프로세스들이 외부 프로세스/Entity와 함께 어떻게 상호 작용하는 방식을 보여주는 아키텍처 다이어그램입니다.

3-1. IC Pod
간결함을 위해 프로세스 설명에서 접미사 프로세스를 생략했습니다.
다음 번호 목록은 각 연결의 유형을 중괄호로 묶어서 설명합니다.
- (HTTP) Prometheus는 IC가 노출하는 HTTP Endpoint를 통해 IC 및 NGINX Metrics 가져옵니다. 기본값:
9113/metrics
입니다. Note: IC에는 Prometheus가 필요하지 않으며, Endpoint를 끌 수 있습니다. - (HTTPS) IC는 Kubernetes API를 읽고 클러스터에 있는 최신 버전의 리소스를 가져오고 API에 기록하여 처리된 리소스의 상태를 업데이트하고 이벤트를 내보냅니다.
- (HTTP) Kubelet은 IC 준비 상태(기본값:
8081/nginx-ready
)를 조사하여 IC Pod가 준비된 것으로 간주합니다. - (File I/O) IC가 시작되면 파일 시스템에서 구성 생성에 필요한 구성 템플릿을 읽습니다. 템플릿은 컨테이너의 / 디렉토리에 있으며 확장자는
.tmpl
입니다. - (File I/O) IC는 컨테이너 런타임에서 수집된 Log를 stdout 및 stderr에 기록합니다.
- (File I/O) IC는 클러스터에서 생성된 리소스를 기반으로 NGINX 구성을 생성하고(리소스 목록은 Ingress Controller는 Kubernetes Controller입니다. 섹션 참조) 파일 시스템의
/etc/nginx
폴더에 씁니다. 구성 파일의 확장자는.conf
입니다. - (File I/O) IC는 Ingress 및 기타 리소스에서 참조하는 모든 TLS Secret의 TLS 인증서와 Key를 파일 시스템에 기록합니다.
- (HTTP) IC는
unix:/var/lib/nginx/nginx-status.sock
UNIX 소켓을 통해 NGINX metrics을 가져와 #1에서 사용된 Prometheus 형식으로 변환합니다. - (HTTP) 구성 Reload가 성공했다고 간주하기 위해, IC는 적어도 한 명의 NGINX Worker가 새로운 구성을 가지고 있는지 확인합니다. 이를 위해 IC는
unix:/var/lib/nginx/nginx-config-version.sock
UNIX 소켓을 통해 특정 Endpoint를 확인합니다. - (N/A) NGINX를 시작하기 위해 IC는 NGINX Master를 시작하는
nginx
명령을 실행합니다. - (Signal) NGINX를 Reload 하기 위해 IC는
nginx -s reload
명령을 실행하여 구성을 확인하고 Reload 신호를 NGINX master로 보냅니다. - (Signal) NGINX를 종료하기 위해 IC는 nginx -s quit 명령을 실행하여 NGINX Master에 정상적인 종료 신호를 보냅니다.
- (File I/O) NGINX Master는 컨테이너 런타임에서 수집된 Log를 stdout 및 stderr로 보냅니다.
- (File I/O) NGINX Master는 시작하거나 Reload 할 때 구성에서 참조되는 TLS 인증서 및 Key를 읽습니다.
- (File I/O) NGINX Master는 시작할 때 또는 Reload 하는 동안 구성 파일을 읽습니다.
- (Signal) NGINX Master는 NGINX Worker Lifecycle을 제어하여 새로운 구성으로 Worker를 생성하고 이전 구성으로 Worker를 종료합니다.
- (File I/O) NGINX Worker는 컨테이너 런타임에 수집되는 stdout 및 stderr에 Log를 씁니다.
- (UDP) NGINX Worker는 UNIX 소켓
/var/lib/nginx/nginx-syslog.sock
을 통해 Syslog 프로토콜을 통해 HTTP upstream 서버 응답 대기 시간 Log를 IC로 보냅니다. 그러면 IC가 Log를 분석하고 Prometheus Metrics으로 변환합니다. - (HTTP, HTTPS, TCP, UDP) 클라이언트는 포트80 및 443의 NGINX Worker와 GlobalConfiguration 리소스에 의해 Expose된 추가 포트로 트래픽을 보내고 받습니다.
- (HTTP, HTTPS, TCP, UDP) NGINX Worker는 Backend와 트래픽을 주고받습니다.
- (HTTP) 관리자는 NGINX Worker를 통해 포트 8080을 사용하여 NGINX stub_status에 연결할 수 있습니다. Note: 기본적으로 NGINX는
localhost
에서의 연결만 허용합니다.
3-2. NGINX Plus의 차이점
위의 다이어그램은 NGINX를 가진 IC를 나타낸다. IC는 또한 다음과 같은 중요한 차이점이 있는 NGINX Plus를 지원합니다.
- NGINX Plus를 구성하기 위해 Ingress Controller는 구성 Reload 및 NGINX Plus API를 사용합니다. 후자는 Ingress Controller가 Upstream의 Upstream 서버를 동적으로 변경할 수 있도록 합니다.
- Stub Status Metrics 대신 NGINX Plus API를 통해 사용할 수 있는 확장 Metrics이 사용됩니다.
- IC는 TLS 인증서와 Key 외에도
nginx.org/jwk
, 유형의 Secret에서 JWK를 작성하고 NGINX Worker가 이를 읽을 수 있습니다.
4. The Ingress Controller 프로세스
이 섹션에서는 다음을 포함한 IC 프로세스의 아키텍처를 다룹니다.
- IC가 사용자에 의해 생성된 새로운 Ingress 리소스를 처리하는 방법.
- IC의 작동 방식과 Kubernetes Controller의 관계에 대한 요약입니다.
- IC 프로세스의 다양한 구성 요소.
4-1. 새로운 Ingress 리소스 처리
다음 다이어그램은 IC가 새 Ingress 리소스를 처리하는 방법을 보여줍니다. 단순성을 위해 NGINX Master 및 Worker 프로세스를 단일 직사각형 NGINX로 나타냅니다. 또한 VirtualServer 및 VirtualServerRoute 리소스는 유사하게 처리됩니다.

IC process
새로운 Ingress 리소스 처리에는 다음 단계가 포함되며, 각 단계는 다이어그램에서 동일한 번호의 화살표에 해당합니다.
- 사용자가 새로운 Ingress 리소스를 만듭니다.
- IC 프로세스에는 클러스터에 있는 리소스 Cache가 있습니다. Cache는 Ingress와 같이 IC가 관심을 갖고 있는 리소스만 포함됩니다. Cache는 리소스 변경 사항을 관찰하여 Kubernetes API와 동기화 상태를 유지합니다.
- Cache에 새 Ingress 리소스가 있으면 변경된 리소스에 대해 Control loop에 알립니다.
- Control loop는 Cache에서 ingress 리소스의 최신 버전을 가져옵니다. Ingress 리소스는 TLS Secrets와 같은 다른 리소스를 참조하기 때문에 Control loop는 참조된 리소스의 최신 버전도 가져옵니다.
- Control Loop는 TLS Secrets에서 TLS 인증서 및 Key를 생성하고 파일 시스템에 기록합니다.
- Control Loop는 Ingress 리소스에 해당하는 NGINX 구성 파일을 생성 및 작성하고 파일 시스템에 작성합니다.
- Control Loop는 NGINX를 Reload 하고 NGINX가 성공적으로 Reload 될 때까지 기다립니다.
- NGINX는 TLS 인증서와 Key를 읽습니다.
- NGINX는 구성 파일을 읽습니다.
- Control Loop는 Ingress 리소스에 대한 이벤트를 내보내고 상태를 업데이트합니다. Reload에 실패하면 이벤트에 오류 메시지가 포함됩니다.
4-2. Ingress Controller 는 Kubernetes Controller 입니다.
이전 섹션의 예를 바탕으로 IC의 작동 방식을 일반화할 수 있습니다.
IC는 클러스터의 기존 리소스에 대한 변경 사항과 새로운 리소스를 지속적으로 처리합니다. 따라서 NGINX 구성은 클러스터의 리소스에 대해 최신 상태로 유지됩니다.
IC는 Kubernetes Controller의 예입니다. IC는 NGINX가 원하는 상태(Ingress 및 기타 리소스)에 따라 구성되도록 하는 Control Loop를 실행합니다.
원하는 상태는 다음과 같은 기본 제공 Kubernetes 리소스 및 사용자 정의 리소스(CR)에 집중되어 있습니다.
- Layer 7 Load balancing 구성:
- Ingresses
- VirtualServers (CR)
- VirtualServerRoutes (CR)
- Layer 7 정책:
- Policies (CR)
- Layer 4 load balancing 구성:
- TransportServers (CR)
- Service discovery:
- Services
- Endpoints
- Pods
- Secret 구성:
- Secrets
- Global 구성:
- ConfigMap (리소스 하나만)
- GlobalConfiguration (CR, 리소스 하나만)
IC는 일반적이지 않고 기본적으로 활성화되지 않은 추가 사용자 정의 리소스를 볼 수 있습니다.
- NGINX App Protect 리소스(APPolicies, APLogConfs, APUserSigs)
- IngressLink 리소스 (리소스 하나만)
다음 섹션에서는 IC 프로세스의 다양한 구성 요소를 살펴봅니다.
5. Ingress Controller 프로세스 구성 요소
이 섹션에서는 IC 프로세스의 구성 요소와 이러한 프로세스의 상호 작용 방식에 대해 설명합니다. 여기에는 다음이 포함됩니다.
- IC가 리소스 변경을 감시하는 방법.
- IC Control Loop의 주요 구성 요소.
- 이러한 구성 요소가 리소스 변경을 처리하는 방법.
- 변경 사항을 처리하는 데 중요한 몇 가지 추가 구성 요소.
IC는 GO로 작성되었으며 Kubernetes 용 GO 클라이언트에 크게 의존합니다. 다음 섹션에서는 필요한 경우 GitHub의 코드에 대한 링크를 포함합니다.
5-1. 리소스 Cache
새로운 Ingress 리소스 처리 섹션에서, 우리는 IC가 리소스의 변경을 감시함으로써 Kubernetes API와 동기화되는 클러스터의 Resource Cache를 가지고 있다고 언급했습니다. 또한 Cache가 업데이트되면 변경된 리소스에 대해 Control Loop에 알린다고 언급했습니다.
Cache는 실제로 정보 Informer의 집합입니다. 다음 다이어그램은 IC에서 리소스 변경 사항을 처리하는 방법을 보여줍니다.

IC process components
- IC가 모니터링하는 모든 리소스 유형에 대해 Informer를 생성합니다. Informer에는 해당 유형의 리소스가 들어 있는 저장소가 포함됩니다. 저장소를 클러스터의 최신 리소스 버전과 동기화하기 위해 Informer는 해당 리소스 유형에 대한 Watch 및 List Kubernetes API를 호출합니다(다이어그램에서 화살표 1. Watch and List 참조).
- 클러스터에서 변경이 발생하면(예: 새 리소스가 생성됨) Informer는 해당 저장소를 업데이트하고 Handler를 호출합니다(화살표 2. Invoke).
- IC는 모든 Informer에 대한 핸들러를 등록합니다. 대부분의 경우 Handler는 작업 대기 열 요소에 리소스 유형과 해당 Namespace 및 이름이 포함된 Workqueue에 영향을 받는 리소스에 대한 항목을 만듭니다. (화살표 3 Put.)
- Workqueue는 항상 스스로를 비우려고 합니다. 앞에 요소가 있으면 큐는 해당 요소를 제거하고 Callback 함수를 호출하여 Controller로 보냅니다. (화살표 4. Send)
- Controller는 Control Loop 나타내는 IC의 주요 구성 요소입니다. Control Loop 섹션에서 구성 요소를 설명합니다. 지금은 Workqueue 요소를 처리하기 위해 Controller 구성 요소가 저장소에서 최신 버전의 리소스를 가져오고(화살표 5. Get) 리소스에 따라 NGINX를 재구성한다는 것을 아는 것으로 충분합니다(화살표 6. Reconfigure), 리소스 상태를 업데이트하고 Kubernetes API를 통해 이벤트를 방출합니다(화살표 7. Update status and emit event).
5-2. Control Loop
이 섹션에서는 Control Loop를 구성하는 IC의 주요 구성 요소에 대해 설명합니다.
- Controller
- IC Control Loop를 실행합니다.
- 정보 Informer, 핸들러, Workqueue 및 추가 도우미 구성요소를 인스턴스화합니다.
- 변경된 리소스를 처리하기 위해 Workqueue에 의해 호출되는 sync (다음 섹션 참조)을 포함합니다.
- 변경된 리소스를 Configurator에 전달하여 NGINX를 재구성합니다.
- Configurator
- Kubernetes 리소스를 기반으로 NGINX 구성 파일, TLS 및 인증서 Key, JWK를 생성합니다.
- Manager를 사용하여 생성된 파일을 작성하고 NGINX를 Reload 합니다.
- Manager
- NGINX의 Lifecycle를 제어합니다(시작, Reload, 종료). Reloading에 대한 자세한 내용은 Reloading NGINX를 참조하세요.
- 구성 파일, TLS Key 및 인증서, JWK를 관리합니다.
다음 다이어그램은 세 구성 요소가 상호 작용하는 방식을 보여 줍니다.

Control Loop
Controller sync 메서드는 리소스 변경을 처리하기 위해 Workqueue에 의해 호출됩니다. 이 메서드는 리소스의 종류를 결정하고 적절한 동기화 메서드를 호출합니다(예: Ingress의 경우 SyncIngress).
다양한 동기화 방법이 모두 어떻게 작동하는지 보여주기보다는 가장 중요한 방법인 syncIngress 방법에 초점을 맞추고 아래 다이어그램에 표시된 것처럼 새 Ingress 리소스를 처리하는 방법을 살펴봅니다.

Controller Sync
- Workqueue Sync 메서드를 호출하고 변경된 리소스 종류와 Key를 포함하는 Workqueue 요소를 여기에 전달합니다(Key: “default/cafe-ingress”와 같은 리소스 namespace/name).
- Kind를 사용하여 Sync 메서드는 적절한 Sync 메서드를 호출하고 리소스 Key를 전달합니다. Ingress의 경우 해당 메서드는 SyncIngress입니다.
- SyncIngress는 Key를 사용하여 Ingress 저장에서 Ingress 리소스를 가져옵니다. 저장소는 리소스 Cache 섹션에서 언급한 대로 Ingress Informer에 의해 제어됩니다.
- SyncIngress는 구성의 AddOrUpdateIngress를 호출하여 Ingress를 전달합니다. 구성은 NGINX 구성으로 변환할 준비가 된 Load Balancing 구성 리소스 모음(Ingress, VirtualServers, VirtualServerRoutes, TransportServers)을 나타내는 구성 요소입니다(자세한 내용은 구성 섹션 참조). AddOrUpdateIngress는 NGINX 구성에 반영되어야 하는 ResourceChanges 목록을 반환합니다. 일반적으로 새 Ingress 리소스의 경우 구성은 단일 ResourceChange만 반환합니다.
- SyncIngress는 단일 Ingress ResourceChange를 처리하는 ProcessChanges를 호출합니다.
- ProcessChanges는 NGINX 구성을 생성하기 위해 원본 Ingress 리소스와 종속성(예: Endpoints 및 Secrets)을 포함하는 확장된 Ingress 리소스(IngressEx)를 생성합니다. 단순화를 위해 이 단계는 다이어그램에 표시하지 않습니다.
- ProcessChanges는 Configurator의 AddOrUpdateIngress를 호출하고 확장된 Ingress 리소스를 전달합니다.
- Configurator는 확장된 Ingress 리소스를 기반으로 NGINX 구성 파일을 생성한 후 다음을 수행합니다.
- 관리자의 CreateConfig()를 호출하여 Ingress 리소스에 대한 구성을 업데이트합니다.
- Manager의 Reload()를 호출하여 NGINX를 Reload합니다.
- Reload 상태는 Manager에서 ProcessChanges로 전파됩니다. 상태는 오류 메시지와 함께 성공 또는 실패입니다.
- ProcessChanges는 UpdateRegularIngressStatusAndEvent를 호출하여 Ingress 리소스의 상태를 업데이트하고 Reload 상태와 함께 이벤트를 내보냅니다. 둘 다 Kubernetes API에 대한 API 호출을 포함합니다.
Notes:
- 일부 세부 사항은 단순성을 위해 논의되지 않았습니다. 전체 그림을 원하면 소스 코드를 볼 수 있습니다.
- SyncVirtualServer, SyncVirtualServerRoute 및 SyncTransportServer 메서드는 SyncIngress와 유사합니다. 다른 동기화 방법은 다릅니다. 그러나 이러한 방법에는 일반적으로 영향을 받는 Ingress, VirtualServer 및 TransportServer 리소스를 찾고 구성을 다시 생성하는 작업이 포함됩니다.
- Workqueue에는 Sync 메서드를 동기화하는 Worker Thread가 하나만 있습니다. 이는 Control Loop가 한 번에 하나의 변경 사항만 처리한다는 것을 의미합니다.
도우미 구성 요소
변경 처리에 중요한 두 가지 추가 도우미 구성 요소인 Configuration 및 LocalSecretStore가 있습니다.
구성
구성은 Ingresses, VirtualServers, VirtualServerRoutes, TransportServers 및 GlobalConfiguration과 같은 IC Load Balancing 구성 리소스의 유효한 최신 상태를 유지합니다.
구성은 리소스에 대한 추가/업데이트 및 삭제 작업을 지원합니다. 구성에서 리소스를 추가/업데이트/삭제하면 다음 작업 수행됩니다.
- 체를 확인합니다(추가/업데이트).
- NGINX 구성으로 전파하는 데 필요한 영향을 받는 리소스에 대한 변경 사항을 계산하고 변경 사항을 호출자에게 반환합니다.
예를 들어 새 Ingress 리소스를 추가할 때 Configuration은 IC에서 해당 Ingress에 대한 구성을 NGINX 구성 파일에 추가하도록 요구하는 변경 사항을 반환합니다. 또 다른 예: 기존 Ingress 리소스를 무효화한 IC가 NGINX 구성 파일에서 해당 Ingress에 대한 구성을 제거하도록 요구하는 변경 사항을 반환합니다.
또한 구성에서 하나의 Ingress/VirtualServer/TransportServer(TLS Passthrough)만 특정 호스트(예: cafe.example.com)를 보유하고 하나의 TransportServer(TCP/UDP)만 특정 수신기(예: UDP의 포트 53)를 보유하도록 합니다. 이렇게 하면 NGINX 구성에서 호스트 또는 Listener 충돌이 발생하지 않습니다.
궁극적으로, IC는 파일 시스템의 NGINX 구성이 특정 시점의 구성에 있는 객체의 상태를 반영하도록 합니다.
LocalSecretStore
LocalSecretStore(SecretStore 인터페이스의)는 유효한 Secret 리소스를 보유하고 파일 시스템의 해당 파일을 동기화된 상태로 유지합니다. Secret은 TLS 인증서 및 Key(유형 kubernetes.io/tls
), CA(nginx.org/ca
), JWK(nginx.org/jwk
) 및 OIDC 공급자(nginx.org/oidc
)에 대한 클라이언트 비밀을 보관하는 데 사용됩니다.
Controller가 Ingress와 같은 구성 리소스에 대한 변경을 처리할 때 NGINX 구성을 생성하는 데 필요한 종속성을 포함하는 리소스의 확장 버전(예: Secrets)을 생성합니다. LocalSecretStore를 사용하면 Controller가 Secret Key (namespace/name)로 Secret에 대한 파일 시스템의 참조를 얻을 수 있습니다.
6. Reloading NGINX
다음 섹션에서는 일반적으로 NGINX를 Reloading 하고 Ingress Controller가 이를 구현하는 방법을 구체적으로 다룹니다.
6-1. Reloading in General
새 구성을 적용하려면 NGINX를 Reloading야 하며 다음 작업을 수행해야 합니다.
- 관리자가 NGINX Master 프로세스에 HUP(중단) 신호를 전송하여 Reload 합니다.
- master 프로세스는 이전 구성의 Worker 프로세스를 중지하고 새 구성으로 Worker 프로세스를 시작합니다.
- 관리자는 Reload가 성공적으로 완료되었는지 확인합니다.
Reloading 하는 방법에 대한 자세한 내용은 NGINX 설명서를 참조하십시오.
Reload하는 방법
NGINX Binary(nginx
)는 -s reload
옵션을 사용하여 Reload 작업을 지원합니다. 이 옵션을 실행할 때:
- 새 NGINX 구성의 유효성을 검사하고 잘못된 경우 종료되며 오류 메시지를 Stderr에 인쇄합니다.
- NGINX Master 프로세스로 HUP 신호를 전송하고 종료합니다.
또는 HUP 신호를 NGINX Master 프로세스에 직접 보낼 수 있습니다.
Reloading 성공 확인 방법
nginx -s reload
는 NGINX가 Reloading 될 때까지 기다리지 않습니다. 따라서 이를 확인하는 것은 관리자의 책임입니다. 몇 가지 옵션이 있습니다.
- Master 프로세스가 새로운 Worker 프로세스를 생성했는지 확인합니다. 예를 들어
ps
를 실행하거나/proc
파일 시스템을 읽습니다. - NGINX에 HTTP 요청을 보내고 새 Worker 프로세스가 응답하면 NGINX가 성공적으로 Reload 되었음을 알 수 있습니다. 참고: 여기에는 추가 NGINX 구성이 필요합니다. Reloading in the Ingress Controller 섹션을 참조하세요.
Reloading은 일반적으로 최소 200ms의 시간이 걸립니다. 시간은 구성 크기, TLS 인증서/Key 수, 활성화된 모듈, 구성 세부 정보 및 사용 가능한 CPU 리소스에 따라 다릅니다.
대부분의 경우 nginx -s reload
가 성공하면 Reload도 성공합니다. 드문 경우지만 Reload에 실패하면 NGINX Master가 오류 메시지를 오류 Log에 인쇄합니다.
예를 들어:
2022/07/09 00:56:42 [emerg] 1353#1353: limit_req "one" uses the "$remote_addr" key while previously it used the "$binary_remote_addr" key
작업은 정상적이며 Reloading은 NGINX에 의한 트래픽 손실로 이어지지 않습니다. 그러나 자주 Reload 하면 메모리 사용률이 높아지고 잠재적으로 OOM(Out-Of-Memory) 오류로 인해 NGINX가 중지되어 트래픽이 손실될 수 있습니다. 이 문제는 오래 지속되는 연결(예: Websockets, gRPC)을 사용하는 트래픽을 Proxy 하고 (2) 자주 Reload 하는 경우에 발생할 수 있습니다. 이 경우 여러 세대의 NGINX Worker 프로세스가 종료될 수 있습니다(이전 NGINX Worker는 시간 초과 후 이전 Worker를 강제로 종료하도록 worker_shutdown_timeout을 구성하지 않는 한 클라이언트 또는 Backend에 의해 모든 연결이 종료될 때까지 종료되지 않습니다). 결국 이러한 모든 Worker 프로세스는 시스템의 사용 가능한 메모리를 소진할 수 있습니다.
Reload하는 동안 이전 NGINX Worker 프로세스와 새 NGINX Worker 프로세스가 모두 공존하기 때문에 Reload하면 메모리 사용률이 최대 2배까지 급증할 수 있습니다. 사용 가능한 메모리가 부족하기 때문에 NGINX Master 프로세스가 새 Worker 프로세스를 생성하지 못할 수 있습니다.
6-2. IC Reloading
Ingress Controller는 NGINX를 Reload하여 구성 변경 사항을 적용합니다.
Reloading를 용이하게 하기 위해 Ingress Controller는 /configVersion
URI에 대한 구성 버전으로 응답하는 Unix 소켓 unix:/var/lib/nginx/nginx-config-version.sock
에서 수신하는 서버를 구성합니다. Ingress Controller는 구성을 /etc/nginx/config-version.conf
에 씁니다.
reload에는 여러 단계가 포함됩니다.
- Ingress Controller는 모든 Secrets을 포함하여 생성된 구성 파일을 업데이트합니다.
- Ingress Controller가
/etc/nginx/config-version.conf
의 구성 버전을 업데이트합니다. - Ingress Controller는
nginx -s reload
를 실행합니다. 명령이 실패하면 Ingress Controller가 오류를 기록하고 Reload가 실패한 것으로 간주합니다. - 명령이 성공하면 Ingress Controller는 HTTP 요청을
unix:/var/lib/nginx/nginx-config-version.sock
의 구성 버전 서버로 전송하여 구성 버전을 주기적으로 확인합니다. - Ingress Controller가 NGINX에서 반환된 올바른 구성 버전을 확인하면 Reload가 성공한 것으로 간주합니다. 구성 가능한 시간 초과 후 올바른 구성 버전이 표시되지 않으면(
-nginx-reload-timeout cli
인수 참조) Ingress Controller reload가 실패한 것으로 간주합니다.
현재 Reload가 성공하거나 실패할 때까지 구성 파일을 변경하거나 NGINX를 Reload 할 수 없도록 Reload 하는 동안 Ingress Control Loop이 중지됩니다.
6-3. Ingress Controller가 NGINX를 reload하는 경우
Ingress Controller는 Control Loop가 생성된 NGINX 구성에 영향을 미치는 변경을 처리할 때마다 NGINX를 Reload 합니다. 일반적으로 리소스가 변경될 때마다 Ingress Controller는 구성을 다시 생성하고 NGINX를 Reload 합니다. 리소스는 Ingress Controller가 모니터링하는 모든 유형일 수 있습니다. Ingress Controller는 Kubernetes Controller 섹션을 참조하세요.
다음과 같은 세 가지 특수한 경우가 있습니다.
- 시작. Ingress Controller가 시작되면 클러스터의 모든 리소스를 처리한 다음 NGINX를 Reload 합니다. 이렇게 하면 한 번만 Reloading 하여 “reload storm”이 생성되는 것을 방지할 수 있습니다.
- Batch 업데이트. Ingress Controller가 Kubernetes API에서 여러 동시 요청을 수신하면 작업 큐(Queue)가 비워질 때까지 NGINX Reload를 일시 중지합니다. 이렇게 하면 Reload 횟수를 줄여 일괄 업데이트의 영향을 최소화하고 OOM(Out of Memory) 오류 위험을 줄입니다.
- NGINX Plus. Ingress Controller가 NGINX Plus를 사용하는 경우 Endpoints 리소스 변경에 대해 NGINX Plus를 Reload 하지 않습니다. 이 경우 Ingress Controller는 NGINX Plus API를 사용하여 해당 Upstream을 업데이트하고 Reload를 건너뜁니다.