mobile background
NGINX Ingress/Gateway Fabric 에서 구현가능한 기술 / 사용사례 소개 61
프로필 이미지
관리자
2025-01-17
조회 7

2023년 10월 25일, 미국 국립표준기술원(NIST)은 Kubernetes용 NGINX Ingress Controller에 영향을 미치는 3개의 CVE를 보고했습니다 .

  • CVE-2022-4886 – ingress-nginx 경로 정리는 directive를 통해 우회될 수 있음 log_format.
  • CVE-2023-5043 – ingress-nginx 주석 주입으로 인해 임의의 명령 실행이 발생합니다.
  • CVE-2023-5044 – nginx.ingress.kubernetes.io/permanent-redirect 주석을 통해 코드 주입이 발생합니다.


해당 보고서와 후속 출판물(긴급 : Kubernetes용 NGINX Ingress 컨트롤러에서 새로운 보안 결함 발견 )은 어떤 NGINX Ingress 컨트롤러가 실제로 영향을 받는지, 그리고 이러한 CVE에 설명된 취약점을 해결하는 데 누가 관여해야 하는지에 대한 혼란(및 여러 지원 문의)을 야기했습니다.

혼란은 완전히 이해할 수 있습니다. NGINX 기반 Ingress 컨트롤러가 두 개 이상 있다는 것을 알고 계셨나요? 시작으로, "NGINX Ingress Controller"라는 완전히 다른 두 프로젝트가 있습니다.


  • 커뮤니티 프로젝트 – GitHub의 kubernetes/ingress-nginx 리포지토리에서 발견된 이 Ingress 컨트롤러는 NGINX 오픈 소스 데이터 플레인을 기반으로 하지만 Kubernetes 커뮤니티에서 개발 및 유지 관리하고 있으며 문서는 GitHub에 호스팅됩니다 .
  • NGINX 프로젝트 – GitHub의 nginxinc/kubernetes -ingress repo 에서 찾을 수 있는 NGINX Ingress Controller는 F5 NGINX에서 개발 및 유지 관리하며 docs.nginx.com에 문서가 있습니다 . 이 공식 NGINX 프로젝트는 두 가지 버전으로 제공됩니다.
    • NGINX 오픈 소스 기반(무료 및 오픈 소스 옵션)
    • NGINX Plus 기반(상업용 옵션)

NGINX를 기반으로 하는 다른 Ingress 컨트롤러도 있는데, Kong이 있습니다. 다행히도, 이름은 쉽게 구별할 수 있습니다. 어떤 것을 사용하는지 잘 모르겠다면 실행 중인 Ingress 컨트롤러의 컨테이너 이미지를 확인한 다음 Docker 이미지 이름을 위에 나열된 리포와 비교하세요.

위에 설명된 취약점(CVE-2022-4886, CVE-2023-5043 및 CVE-2023-5044)은 커뮤니티 프로젝트 ( kubernetes/ingress-nginx )에만 적용됩니다. NGINX Ingress Controller( nginxinc/kubernetes-ingress , 오픈소스 및 상업용)에 대한 NGINX 프로젝트는 이러한 CVE의 영향을 받지 않습니다.



위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요



전문가에게 상담받기

프로필 이미지
관리자
2025-01-17
조회 12

당신은 현대적 앱 개발자입니다. 오픈 소스와 아마도 일부 상용 도구 모음을 사용하여 새로운 앱과 컨테이너를 작성, 테스트, 배포 및 관리합니다. 개발, 테스트, 스테이징 및 프로덕션 환경에서 이러한 컨테이너와 포드를 실행하기 위해 Kubernetes를 선택했습니다. 마이크로서비스의 아키텍처와 개념, Cloud Native Computing Foundation 및 기타 현대적 산업 표준을 도입했습니다.

이 여정에서 여러분은 쿠버네티스가 실제로 강력하다는 것을 알게 되었습니다. 하지만 여러분은 쿠버네티스가 얼마나 어렵고, 유연하지 않으며, 좌절스러울 수 있는지에 놀랐을 것입니다. 라우터, 방화벽, 로드 밸런서 및 기타 네트워크 장치에 대한 변경 사항과 업데이트를 구현하고 조정하는 것은 압도적일 수 있습니다. 특히 자체 데이터 센터에서는 더욱 그렇습니다! 개발자를 눈물 흘리게 만들기에 충분합니다.

이러한 과제를 어떻게 처리하는지는 Kubernetes를 어디서 어떻게 실행하는지(관리형 서비스 또는 온프레미스)와 많은 관련이 있습니다. 이 문서에서는 배포 선택이 사용 편의성에 영향을 미치는 주요 영역인 TCP 로드 밸런싱을 다룹니다.


관리형 Kubernetes를 사용한 TCP 부하 분산(일명 Easy Option)

Kubernetes용 퍼블릭 클라우드 공급자와 같은 관리형 서비스를 사용하면 지루한 네트워킹 작업의 대부분이 처리됩니다. 단 하나의 명령( kubectl apply -f loadbalancer.yaml) 으로 서비스 유형 LoadBalancer는 퍼블릭 IP, DNS 레코드 및 TCP 로드 밸런서를 제공합니다. 예를 들어, NGINX Ingress Controller가 포함된 포드에 트래픽을 분산하도록 Amazon Elastic Load Balancer를 구성하고 이 명령을 사용하면 백엔드가 변경될 때 걱정할 필요가 없습니다. 너무 쉽기 때문에 당연하게 여기실 겁니다!


온프레미스 Kubernetes를 사용한 TCP 부하 분산(일명 하드 옵션)

온프레미스 클러스터의 경우 완전히 다른 시나리오입니다. 귀하 또는 네트워킹 피어가 네트워킹 부분을 제공해야 합니다. "왜 사용자를 내 Kubernetes 앱으로 유도하는 것이 이렇게 어려울까?"라고 궁금해할 수 있습니다. 답은 간단하지만 약간 충격적입니다. 클러스터의 정문인 서비스 유형 LoadBalancer는 실제로 존재하지 않습니다.

클러스터 외부에 앱과 서비스를 노출하려면 네트워크 팀에서 티켓, 승인, 절차, 심지어 보안 검토까지 필요할 수 있습니다. 이 모든 것이 장비를 재구성하기 전에 필요합니다. 아니면 모든 것을 직접 해야 할 수도 있는데, 그러면 애플리케이션 제공 속도가 엄청나게 느려질 수 있습니다. 더 나쁜 것은 Kubernetes 서비스를 변경하지 않는 것입니다. NodePort 가 변경되면 트래픽이 차단될 수 있기 때문입니다! 그리고 사용자들이 500 오류를 얼마나 좋아하는지 우리 모두 알고 있습니다. 상사는 아마 더 싫어할 것입니다.


온프레미스 TCP 로드 밸런싱을 위한 더 나은 솔루션: Kubernetes용 NGINX 로드 밸런서

새로운 프로젝트인 Kubernetes용 NGINX 로드밸런서를 사용하면 "하드 옵션"을 "쉬운 옵션"으로 바꿀 수 있습니다 . 이 무료 프로젝트는 NGINX Ingress Controller를 감시하고 로드 밸런싱을 위해 구성된 외부 NGINX Plus 인스턴스를 자동으로 업데이트하는 Kubernetes 컨트롤러 입니다 . 매우 간단한 설계로 설치 및 작동이 간편합니다. 이 솔루션을 사용하면 온프레미스 환경에서 TCP 로드 밸런싱을 구현하여 새로운 앱과 서비스를 즉시 감지하고 트래픽에 사용할 수 있습니다. 직접 작업할 필요가 없습니다.


Architecture와 Flow

Kubernetes용 NGINX 로드밸런서는 Kubernetes 클러스터 내부에 있습니다. Kubernetes에 등록되어 nginx-ingress 서비스(NGINX Ingress Controller)를 감시합니다. 백엔드가 변경되면 Kubernetes용 NGINX 로드밸런서는 Worker IP와 NodePort TCP 포트 번호를 수집한 다음 NGINX Plus API를 통해 IP:ports를 NGINX Plus로 전송합니다 . NGINX 업스트림 서버는 로 업데이트되고 NGINX Plus는 트래픽을 올바른 업스트림 서버와 Kubernetes NodePorts로 로드밸런싱합니다. 추가 NGINX Plus 인스턴스를 추가하여 고가용성을no reload required 달성할 수 있습니다 .

NGINX 로드밸런서가 동작하는 다이어그램


Kubernetes용 NGINX 로드밸런서의 작동 스냅샷

아래 스크린샷에는 Kubernetes용 NGINX Loadbalancer가 배포되어 작업을 수행하는 모습을 보여주는 두 개의 창이 있습니다.

  1. 서비스 유형 – LoadBalancer(용 nginx-ingress)
  2. 외부 IP – NGINX Plus 서버에 연결
  3. 포트 - NodePort는 NGINX 업스트림 서버와 일치하는 443:30158에 매핑됩니다(NGINX Plus 실시간 대시보드 에 표시됨 )
  4. 로그 - Kubernetes용 NGINX 로드밸런서가 NGINX Plus로 데이터를 성공적으로 전송하고 있음을 나타냄

참고 : 이 예에서 Kubernetes 워커 노드는 10.1.1.8 및 10.1.1.10입니다.

Kubernetes용 NGINX Loadbalancer의 작동 스크린샷



위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요



전문가에게 상담받기

프로필 이미지
관리자
2025-01-17
조회 3

가동 중지 시간은 심각한 결과를 초래할 수 있습니다.

이러한 말은 대부분의 다른 산업보다 의료 기술 분야의 회사에 더 해당됩니다. 그들의 경우 "심각한 결과"에는 문자 그대로 사망이 포함될 수 있습니다. 우리는 최근에 의료 기록 보관을 펜과 종이에서 언제 어디서나 액세스할 수 있는 안전한 디지털 데이터로 전환하려는 회사의 기술 스택을 분석할 기회를 가졌습니다. 이러한 데이터는 환자 정보에서 치료 지침, 생물학적 마커, 의료 분석, 과거 기록 및 의료 팀 간에 공유되는 모든 것에 이르기까지 다양합니다.

처음부터 이 회사는 겉보기에 간단한 질문인 "케어 종사자가 실시간으로 데이터를 쉽게 기록하도록 어떻게 도울 수 있을까?"를 해결하고자 했습니다. 그러나 회사가 성장함에 따라 확장하고 데이터를 지속적으로 사용할 수 있게 해야 하는 필요성으로 인해 이 과제를 해결하는 것이 점점 더 복잡해졌습니다. 여기서는 이 회사의 기술 여정이 어떻게 Kubernetes 와 NGINX Ingress Controller를 도입하게 되었는지 설명합니다 .


기술 스택을 한눈에 보기

  • OS – 리눅스
  • 컨테이너 오케스트레이션 – Microsoft Azure Kubernetes Service
  • 네트워킹 – Kubernetes , NGINX Plus 기반 NGINX Ingress Controller
  • 소프트웨어 개발 언어/프레임워크 – .Net 
  • 모니터링, 관찰성 및 경고 – Prometheus
  • 모니터링 대시보드 – Grafana
  • 로깅 – Grafana Loki
  • 데이터베이스 – Azure SQL 서비스
  • 애플리케이션 서버 - Azure App Service , .Net
  • 메시징 및 스트리밍 – Azure Event Hubs
  • 캐싱 – Redis
  • 보안 – NGINX 앱 보호
  • 위치 및 인프라 – 2개의 가용성 영역, 2개의 Kubernetes 클러스터, 15~20개의 노드, 60~100개의 포드 
  • DevOps – Azure DevOps 서비스

NGINX가 해당 아키텍처에서 어떻게 적용되는지 살펴보겠습니다.

NGINX가 아키텍처에 어떻게 들어맞는지 다이어그램으로 표시

종이의 문제

정기적으로 환자 상태와 치료 정보를 수집하는 것은 의료 종사자의 핵심 임무입니다. 전통적으로 그들은 환자 정보를 종이에 기록했거나, 최근에는 노트북이나 태블릿에 기록했습니다. 몇 가지 심각한 단점이 있습니다.

  • 의료 종사자는 하루에 수십 명의 환자와 상호 작용할 수 있으므로 치료를 제공하는 동안 자세한 메모를 작성하는 것은 일반적으로 실용적이지 않습니다. 결과적으로 근로자는 교대 근무가 끝날 때 메모를 작성하게 됩니다. 그 시점에서 정신적, 신체적 피로로 인해 일반적인 의견만 기록하고 싶어집니다.
  • 근로자는 또한 환자 행동에 대한 세부 사항에 대한 기억에 의존해야 합니다. 부정확한 내용은 시간이 지남에 따라 정확하고 일관되게 문서화되면 더 큰 건강 문제의 진단을 용이하게 하는 패턴을 가릴 수 있습니다.
  • 종이 기록은 단일 부서 내의 부서 간에 쉽게 공유할 수 없으며, EMT, 응급실 직원, 보험 회사와 같은 다른 기관과는 더더욱 그렇습니다. 노트북이나 태블릿이 중앙 데이터 저장소나 클라우드에 연결되지 않은 경우 상황은 크게 나아지지 않습니다.

이러한 과제를 해결하기 위해 회사는 환자 정보에 액세스하고 약물 분배와 같은 일반적인 이벤트를 기록하기 위한 단축키를 제공하는 간소화된 데이터 기록 시스템을 만들었습니다. 이러한 액세스 및 사용의 용이성 덕분에 환자 상호작용을 발생하는 대로 실시간으로 기록할 수 있습니다.

모든 데이터는 회사에서 관리하는 클라우드 시스템에 저장되며, 앱은 다른 전자 의료 기록 시스템과 통합되어 거주자 행동에 대한 포괄적인 종단적 관점을 제공합니다. 이를 통해 간병인은 더 나은 치료 연속성을 제공하고, 안전한 과거 기록을 생성하며, 다른 의료 소프트웨어 시스템과 쉽게 공유할 수 있습니다.

의사와 다른 전문가도 환자를 입원시키거나 다른 방식으로 환자와 교류할 때 이 플랫폼을 사용합니다. 환자와 함께 모든 시설로 이동하는 선호도와 개인적 필요 사항의 기록이 있습니다. 이를 사용하여 환자가 새로운 환경에서 편안함을 느끼도록 도울 수 있으며, 이는 회복 시간과 같은 결과를 개선합니다.

회사가 환자 데이터를 얼마나 오랫동안 보관해야 하는지에 대한 엄격한 법적 요구 사항이 있습니다. 이 회사의 개발자는 일반 클라우드 애플리케이션보다 훨씬 더 나은 가동 시간 SLA로 매우 높은 가용성을 제공하는 소프트웨어를 구축했습니다. 환자의 파일이 로드되지 않아서 구급차를 기다리게 하는 것은 선택 사항이 아닙니다.


차고에서 클라우드로, 그리고 쿠버네티스로의 여행

많은 스타트업과 마찬가지로 이 회사는 공동 창업자의 집에 있는 서버에서 최초의 개념 증명 애플리케이션을 실행하여 처음에 비용을 절감했습니다. 이 아이디어가 타당하다는 것이 분명해지자 회사는 데이터 센터에서 하드웨어를 관리하는 대신 인프라를 클라우드로 옮겼습니다. Microsoft 매장인 그들은 Azure를 선택했습니다. 초기 아키텍처는 Microsoft의 IIS 웹 서버를 실행하는 관리형 애플리케이션 제공 서비스인 Azure App Service의 기존 가상 머신(VM)에서 애플리케이션을 실행했습니다. 데이터 저장 및 검색을 위해 이 회사는 VM에서 실행되는 Microsoft의 SQL Server를 관리형 애플리케이션으로 사용하기로 했습니다.

클라우드에서 수년간 운영한 후, 회사는 빠르게 성장하고 확장의 어려움을 겪었습니다. 회사는 무한히 확장해야 했고, VM을 사용하면 수직이 느리고 비용이 많이 들기 때문에 수평이 아닌 수평으로 확장해야 했습니다. 이러한 요구 사항으로 인해 컨테이너화와 Kubernetes가 가능한 솔루션으로 자연스럽게 이어졌습니다. 컨테이너화를 지지하는 또 다른 요점은 회사 개발자가 중단 위험 없이 애플리케이션과 인프라에 대한 업데이트를 자주 제공해야 한다는 것입니다. 환자 기록이 여러 시간대에 걸쳐 지속적으로 추가되면서 고객이 결함으로 인해 즉시 영향을 받을 위험 없이 프로덕션에 변경 사항을 푸시할 자연스러운 다운타임이 없습니다.

회사의 논리적인 시작점은 Microsoft의 관리형 Kubernetes 오퍼링인 Azure Kubernetes Services(AKS)였습니다. 팀은 Kubernetes 모범 사례를 조사하고 AKS의 노드와 포드에서 실행되는 트래픽과 애플리케이션을 효과적으로 관리하기 위해 Kubernetes 클러스터 앞에서 실행되는 Ingress 컨트롤러가 필요 하다는 것을 깨달았습니다.


Traffic 경로는 유연하면서도 정확해야 합니다.

팀은 AKS의 기본 Ingress 컨트롤러를 테스트했지만, 트래픽 라우팅 기능이 회사 고객에게 필요한 방식으로 업데이트를 제공할 수 없다는 것을 발견했습니다. 환자 케어에 관해서는 모호함이나 상충되는 정보에 대한 여지가 없습니다. 예를 들어, 한 케어 종사자가 주황색 플래그를 보고 다른 케어 종사자가 같은 이벤트에 대해 빨간색 플래그를 보는 것은 용납할 수 없습니다. 따라서 주어진 조직의 모든 사용자는 동일한 버전의 앱을 사용해야 합니다. 이는 업그레이드와 관련하여 큰 과제입니다. 고객을 새 버전으로 전환할 자연스러운 시기가 없으므로 회사는 서버 및 네트워크 수준에서 규칙을 사용하여 다른 고객을 다른 앱 버전으로 라우팅할 방법이 필요했습니다.

이를 달성하기 위해 이 회사는 조직의 모든 사용자에게 동일한 백엔드 플랫폼을 실행하고 조직 내 인프라 계층에서 세분화된 다중 테넌시를 제공하지 않습니다. Kubernetes를 사용하면 자세한 트래픽 규칙과 함께 브라우저의 가상 네트워크 경로 및 쿠키를 사용하여 트래픽을 분할할 수 있습니다. 그러나 이 회사의 기술 팀은 AKS의 기본 Ingress 컨트롤러는 필요에 따라 고객 조직 또는 개별 사용자 수준에서 작동하는 규칙이 아닌 백분율 기준으로만 트래픽을 분할할 수 있다는 것을 발견했습니다.

기본 구성에서 NGINX Open Source를 기반으로 하는 NGINX Ingress Controller는 동일한 제한이 있으므로 회사는 세분화된 트래픽 제어를 지원하는 엔터프라이즈급 제품인 NGINX Plus를 기반으로 하는 보다 고급 NGINX Ingress Controller로 전환하기로 결정했습니다. 높은 수준의 유연성과 제어를 기반으로 Microsoft와 Kubernetes 커뮤니티의 NGINX Ingress Controller에서 권장 사항을 찾은 것은 선택을 확고히 하는 데 도움이 되었습니다. 이 구성은 포드 관리(클래식 트래픽 관리와 대조적으로)에 대한 회사의 요구 사항을 더 잘 지원하여 포드가 적절한 영역에서 실행되고 트래픽이 해당 서비스로 라우팅되도록 합니다. 때로는 트래픽이 내부적으로 라우팅되지만 대부분의 사용 사례에서는 관찰 가능성을 위해 NGINX Ingress Controller를 통해 다시 라우팅됩니다.


Here Be Dragons: 모니터링, 관찰성 및 애플리케이션 성능

NGINX Ingress Controller를 사용하면 기술팀이 개발자와 최종 사용자 경험을 완벽하게 제어할 수 있습니다. 사용자가 로그인하여 세션을 설정하면 즉시 새 버전으로 라우팅되거나 이전 버전으로 되돌릴 수 있습니다. 패치는 조직의 모든 사용자에게 동시에 거의 즉시 푸시될 수 있습니다. 소프트웨어는 클라우드 플랫폼 전반의 네트워킹에 대한 DNS 전파나 업데이트에 의존하지 않습니다.

NGINX Ingress Controller는 또한 회사의 세부적이고 지속적인 모니터링 요구 사항을 충족합니다. 애플리케이션 성능은 의료 분야에서 매우 중요합니다. 지연이나 가동 중지 시간은 특히 생사의 상황에서 성공적인 임상 치료를 방해할 수 있습니다. Kubernetes로 이전한 후, 고객들은 회사에서 알아차리지 못한 가동 중지 시간을 보고하기 시작했습니다. 회사는 곧 문제의 근원을 발견했습니다. Azure App Service는 샘플링된 데이터에 의존합니다. 샘플링은 평균 및 광범위한 추세에는 적합하지만 거부된 요청 및 누락된 리소스와 같은 사항은 완전히 놓칩니다. 또한 간병인이 체크인하고 환자 데이터를 기록할 때 일반적으로 30분마다 발생하는 사용량 급증도 표시하지 않습니다. 회사는 지연, 오류 소스, 잘못된 요청 및 사용할 수 없는 서비스에 대한 불완전한 그림만 얻었습니다.

문제는 거기서 끝나지 않았습니다. 기본적으로 Azure App Service는 저장된 데이터를 한 달 동안만 보존합니다. 많은 국가의 법률에서 요구하는 수십 년보다 훨씬 짧습니다. 더 오래 보존하기 위해 필요에 따라 데이터 저장소를 확장하는 것은 엄청나게 비쌌습니다. 게다가 Azure 솔루션은 Kubernetes 네트워킹 스택 내부를 볼 수 없습니다. NGINX Ingress Controller는 4계층과 7계층 트래픽을 처리할 때 인프라와 애플리케이션 매개변수를 모두 모니터링할 수 있습니다.

성능 모니터링 및 관찰성을 위해 이 회사는 Grafana 시각화 엔진 및 대시보드에 연결된 Prometheus 시계열 데이터베이스를 선택했습니다. Prometheus와 Grafana와의 통합은 NGINX 데이터 및 제어 평면에 미리 구워져 있으며, 기술 팀은 모든 트래픽을 Prometheus 및 Grafana 서버를 통해 전달하기 위해 작은 구성 변경만 하면 되었습니다. 이 정보는 또한 Grafana Loki 로깅 데이터베이스로 라우팅되어 로그를 분석하기 쉬워졌고 소프트웨어 팀이 시간이 지남에 따라 데이터를 더 잘 제어할 수 있게 되었습니다. 

이 구성은 또한 문제 해결 및 버그 수정을 위해 매우 빈번하고 방대한 양의 데이터 샘플링이 필요한 사고에 대비하여 미래를 보호합니다. 대부분의 대형 클라우드 회사에서 제공하는 애플리케이션 모니터링 시스템으로는 이러한 유형의 사고를 해결하는 데 비용이 많이 들 수 있지만 이 사용 사례에서 Prometheus, Grafana 및 Loki의 비용과 오버헤드는 최소입니다. 세 가지 모두 안정적인 오픈 소스 제품으로 일반적으로 초기 튜닝 후 패치만 하면 됩니다.


Routing 유지: 고가용성 및 보안에 집중

이 회사는 항상 가장 민감한 데이터 유형 중 하나를 보호하기 위한 보안과 필요할 때마다 앱을 사용할 수 있도록 하는 고가용성 에 중점을 두었습니다 . Kubernetes로 전환하면서 두 가지 용량을 모두 확장하기 위해 몇 가지 변경을 했습니다.

가장 높은 가용성을 위해 기술 팀은 단일 장애 지점 없이 완전한 중복성을 위해 액티브-액티브, 멀티 존, 멀티 지오 분산 인프라 설계를 구축합니다. 팀은 두 개의 다른 지리적 지역에 듀얼 쿠버네티스 클러스터가 있는 N+2 액티브-액티브 인프라를 유지 관리합니다. 각 지리적 지역 내에서 소프트웨어는 여러 데이터 센터에 걸쳐 다운타임 위험을 줄이고 인프라의 모든 계층에서 장애가 발생할 경우 적용 범위를 제공합니다. 친화성 및 반친화성 규칙은 사용자와 트래픽을 즉시 가동 중인 포드로 다시 라우팅하여 서비스 중단을 방지할 수 있습니다. 

보안을 위해 팀은 잘못된 요청과 악의적인 행위자로부터 보호하기 위해 웹 애플리케이션 방화벽 (WAF)을 배포합니다. OWASP Top 10 에 대한 보호 는 대부분 WAF에서 제공하는 기본 사항입니다. 앱을 만들 때 팀은 기본 Azure WAF와 ModSecurity를 포함한 여러 WAF를 조사했습니다. 결국 팀은 인라인 WAF와 분산 서비스 거부 (DDoS) 보호 기능이 있는 NGINX App Protect를 선택했습니다.

NGINX App Protect의 큰 장점은 NGINX Ingress Controller와 함께 배치되어 중복 지점을 제거하고 지연 시간을 줄이는 것입니다. 다른 WAF는 Kubernetes 환경 외부에 배치해야 하므로 지연 시간과 비용이 증가합니다. 아주 사소한 지연(요청당 1밀리초 추가)도 시간이 지남에 따라 빠르게 누적됩니다.


서프라이즈 사이드 퀘스트: 개발자를 위한 다운타임 없음

대부분의 애플리케이션 및 네트워킹 인프라에 대해 AKS로의 전환을 완료한 이 회사는 개발자 경험(DevEx)에서도 상당한 개선을 이루었습니다. 이제 개발자는 고객이 문제를 알아차리기 전에 거의 항상 문제를 발견합니다. 전환 이후 오류에 대한 지원 전화의 양이 약 80% 감소했습니다!

회사의 보안 및 애플리케이션 성능 팀은 자세한 Grafana 대시보드와 통합 알림을 갖추고 있어 여러 시스템을 확인하거나 다른 프로세스에서 오는 경고 텍스트 및 호출에 대한 트리거를 구현할 필요가 없습니다. 개발 및 DevOps 팀은 이제 코드 및 인프라 업데이트를 매일 또는 하루에 여러 번 제공하고 매우 세부적인 청록색 패턴을 사용할 수 있습니다. 이전에는 일주일에 한두 번 업데이트를 제공하고 사용량이 적은 시간대에 시간을 내야 했으며 이는 스트레스가 많은 제안이었습니다. 이제 코드는 준비되면 제공되고 개발자는 애플리케이션 동작을 관찰하여 영향을 직접 모니터링할 수 있습니다.

결과는 전반적으로 긍정적입니다. 소프트웨어 개발 속도가 빨라지고, 개발자의 사기가 향상되고, 생명이 더 많이 구해졌습니다.



위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요



전문가에게 상담받기

프로필 이미지
관리자
2025-01-17
조회 1

저희는 2023년 1월에 NGINX Ingress Controller 의 버전 3.0을 출시했으며, 여기에는 중요한 새로운 기능과 향상된 기능이 다수 포함되었습니다. 여러분께 특히 가치 있다고 생각되는 새로운 기능 중 하나는 NGINX Ingress Controller의 NGINX Plus 에디션에서 제공되는 Deep Service Insight입니다.

Deep Service Insight는 로드 밸런서와 같은 라우팅 결정 시스템이 하나 이상의 Kubernetes 클러스터 앞에 있을 때 최적의 기능을 방해하는 제한 사항을 해결합니다. 즉, 시스템은 Ingress 컨트롤러 뒤의 클러스터에서 실행되는 개별 서비스의 상태에 대한 정보에 액세스할 수 없습니다. 이를 통해 트래픽을 정상적인 서비스가 있는 클러스터로만 라우팅하지 못하게 되어 사용자를 중단 및 오류(예:  404)  에 노출시킬 가능성이 있습니다 500.

Deep Service Insight는 NGINX Ingress Controller에서 수집한 백엔드 서비스 포드의 상태를 전용 엔드포인트에 노출하여 시스템에서 액세스하고 더 나은 라우팅 결정을 내리는 데 활용할 수 있도록 함으로써 이러한 문제를 해결합니다.

이 게시물에서는 Deep Service Insight가 해결하는 문제를 자세히 살펴보고, 몇 가지 일반적인 사용 사례에서 이 기능이 어떻게 작동하는지 설명하고, 이를 구성하는 방법을 보여드리겠습니다.


왜 Deep Service Insight가 필요한가요?

표준 Kubernetes 라이브니스, 준비성 및 시작 프로브는 클러스터에서 실행되는 백엔드 서비스에 대한 정보를 제공하지만 스택 전체에 걸쳐 더 나은 라우팅 결정을 내리는 데 필요한 통찰력을 제공하기에는 충분하지 않습니다. Kubernetes 배포가 복잡해지고 중단 없는 가동 시간에 대한 비즈니스 요구 사항이 더 시급해짐에 따라 올바른 정보가 부족하면 문제가 더 커집니다.

Kubernetes 환경을 확장할 때 가동 시간을 개선하기 위한 일반적인 접근 방식은 클러스터 앞에 로드 밸런서, DNS 관리자 및 기타 자동화된 결정 시스템을 배포하는 것입니다. 그러나 Ingress 컨트롤러의 작동 방식 때문에 Kubernetes 클러스터 앞에 있는 로드 밸런서는 일반적으로 클러스터에서 Ingress 컨트롤러 뒤에 있는 서비스에 대한 상태 정보에 액세스할 수 없습니다. Ingress 컨트롤러 포드 자체가 정상이고 트래픽을 수용하는지 여부만 확인할 수 있습니다.

반면 NGINX Ingress Controller는 서비스 상태에 대한 정보를 가지고 있습니다. 이미 HTTP , TCP , UDP 및 gRPC 서비스에 대한 주기적 수동 상태 검사를 보내고, 요청 응답성을 모니터링하고, 성공적인 응답 코드 및 기타 메트릭을 추적하여 클러스터의 업스트림 포드 상태를 모니터링합니다. 이 정보를 사용하여 일관되고 예측 가능한 사용자 경험을 제공하기 위해 서비스의 포드에 트래픽을 분산하는 방법을 결정합니다. 일반적으로 NGINX Ingress Controller는 백그라운드에서 이 모든 마법을 조용히 수행하고 있으며, 후드 아래에서 무슨 일이 일어나고 있는지 두 번 생각하지 않을 수도 있습니다. Deep Service Insight는 이 귀중한 정보를 "표면화"하여 스택의 다른 계층에서 보다 효과적으로 사용할 수 있도록 합니다.


심층적 서비스 통찰력은 어떻게 작동하나요?

Deep Service Insight는 NGINX VirtualServer 및 TransportServer 사용자 지정 리소스(각각 HTTP 및 TCP/UDP용)를 사용하여 배포하는 서비스에 사용할 수 있습니다. Deep Service Insight는 NGINX Plus API를 사용하여 Deep Service Insight에 고유한 전용 엔드포인트에서 백엔드 서비스의 개별 포드에 대한 NGINX Ingress Controller의 뷰를 공유합니다.

  • VirtualServer의 경우 – <IP_주소>  : <포트>  /probe/ <호스트 이름>
  • TransportServer의 경우 – <IP_주소>  : <포트>  /probe/ts/ <서비스_이름 >

어디

  • <IP_address>는 NGINX Ingress Controller에 속합니다.
  • <port> 는 Deep Service Insight 포트 번호(기본값 9114)입니다.
  • <hostname>spec.host 은 VirtualServer 리소스 필드에 정의된 서비스의 도메인 이름입니다.
  • <service_name>spec.upstreams.service 은 TransportServer 리소스의 필드에 정의된 서비스의 이름입니다.

출력에는 두 가지 유형의 정보가 포함됩니다.

  1. 호스트 이름 또는 서비스 이름에 대한 HTTP 상태 코드:

    • 200 OK – 적어도 하나의 포드가 건강합니다.
    • 418 I’m a teapot – 건강한 포드가 없습니다
    • 404 Not Found – 지정된 호스트 이름 또는 서비스 이름과 일치하는 포드가 없습니다.
  2. 지정된 호스트 이름 또는 서비스 이름에 대한 세 개의 카운터:

    • Total서비스 인스턴스(포드) 수
    • Up(건강한) 상태 의 포드 수
    • Unhealthy주 내 포드 수

다음은 서비스의 세 개의 Pod가 모두 정상인 예입니다.

HTTP/1.1 200 OKContent-Type: application/json; charset=utf-8
Date: Day, DD Mon YYYY hh:mm:ss TZ
Content-Length: 32
{"Total":3,"Up":3,"Unhealthy":0}

자세한 내용은 NGINX Ingress Controller 설명서를 참조하세요 .

활성 상태 검사를 구성하여 NGINX Ingress Controller가 포드가 정상인지 판단하는 데 사용하는 기준을 추가로 사용자 지정할 수 있습니다. 상태 검사가 전송되는 경로와 포트, 포드가 비정상으로 간주되기 위해 지정된 기간 내에 발생해야 하는 실패 검사 수, 예상 상태 코드, 연결 또는 응답 수신 시간 초과 등을 구성할 수 있습니다. VirtualServer 또는 TransportServerUpstream.Healthcheck 리소스 에 필드를 포함합니다 .


심층적인 서비스 통찰력을 위한 샘플 사용 사례

Deep Service Insight가 특히 가치 있는 사용 사례 중 하나는 로드 밸런서가 고가용성을 위해 두 클러스터에서 실행되는 서비스로 트래픽을 라우팅하는 경우입니다. 각 클러스터 내에서 NGINX Ingress Controller는 위에서 설명한 대로 업스트림 포드의 상태를 추적합니다. Deep Service Insight를 활성화하면 정상 및 비정상 업스트림 포드의 수에 대한 정보도 전용 엔드포인트에 노출됩니다. 라우팅 결정 시스템은 엔드포인트에 액세스하여 해당 정보를 사용하여 애플리케이션 트래픽을 비정상 포드에서 정상 포드로 전환할 수 있습니다.

이 다이어그램은 이 시나리오에서 Deep Service Insight가 작동하는 방식을 보여줍니다.

NGINX Ingress Controller가 전용 Deep Service Insight 엔드포인트에서 Kubernetes Pod 상태에 대한 정보를 제공하는 방식을 보여주는 다이어그램으로, 라우팅 결정 시스템이 이를 사용하여 Tea 서비스 Pod가 정상적이지 않은 클러스터에서 트래픽을 다른 곳으로 전환합니다.

고가용성 시나리오에서 클러스터에 대한 유지 관리를 수행할 때 Deep Service Insight를 활용할 수도 있습니다. 유지 관리를 수행하는 클러스터에서 서비스에 대한 포드 수를 0으로 줄이기만 하면 됩니다. 건강한 포드가 없는 경우 Deep Service Insight 엔드포인트에 자동으로 표시되고 라우팅 결정 시스템은 해당 정보를 사용하여 다른 클러스터의 건강한 포드로 트래픽을 전송합니다. NGINX Ingress Controller나 시스템에서 구성을 변경하지 않고도 효과적으로 자동 장애 조치를 받을 수 있으며, 고객은 서비스 중단을 경험하지 않습니다.


심층적인 서비스 통찰력 활성화

Deep Service Insight를 활성화하려면 -enable-service-insightKubernetes 매니페스트에 명령줄 인수를 포함하거나 Helm을 사용하는 경우 serviceInsight.create매개변수를 로 설정합니다 true.

사용자 환경에 맞게 엔드포인트를 조정하기 위해 포함할 수 있는 두 가지 선택적 인수가 있습니다.

  • -service-insight-listen-port <port> – Deep Service Insight 포트 번호를 기본값인 9114에서 변경합니다( <port>1024–65535 범위의 정수). Helm과 동등한 것이 매개 serviceInsight.port변수입니다.
  • -service-insight-tls-string <secret> – Deep Service Insight 엔드포인트의 TLS 종료를 위한 Kubernetes 비밀(TLS 인증서 및 키)( <secret>형식이 있는 문자열 <namespace>/<secret_name>). Helm과 동등한 것이 serviceInsight.secret매개변수입니다.


예: 카페 애플리케이션에 대한 심층적 서비스 통찰력 활성화

Deep Service Insight가 실제로 어떻게 활용되는지 확인하려면 NGINX Ingress Controller 설명서에서 예로 자주 사용되는 Cafe 애플리케이션 에서 이를 활성화하면 됩니다 .

  1. NGINX 사용자 정의 리소스를 지원하고 Deep Service Insight를 활성화하는 NGINX Ingress Controller의 NGINX Plus 버전을 설치합니다.

    • Helm을 사용하는 경우 serviceInsight.create매개변수를 .으로 설정합니다 true.
    • Kubernetes 매니페스트 (Deployment 또는 DaemonSet) 를 사용하는 경우 -enable-service-insight매니페스트 파일에 인수를 포함합니다.
  2. NGINX Ingress Controller가 실행 중인지 확인하세요.

    $ kubectl get pods -n nginx-ingressNAME                                          READY ...
    ingress-plus-nginx-ingress-6db8dc5c6d-cb5hp   1/1   ...  
    
        ...  STATUS   RESTARTS   AGE
        ...  Running   0          9d
  3. README 의 지침에 따라 Cafe 애플리케이션을 배포합니다 .
  4. NGINX VirtualServer 사용자 정의 리소스가 Cafe 애플리케이션에 배포되었는지 확인합니다(IP 주소는 읽기 쉽도록 생략).

    $ kubectl get vs NAME   STATE   HOST               IP    PORTS      AGE
    cafe   Valid   cafe.example.com   ...   [80,443]   7h1m
  5. cafe.example.com 에서 실행되는 Cafe 서비스에 대해 세 개의 업스트림 포드가 있는지 확인하세요 .

    $ kubectl get pods NAME                     READY   STATUS    RESTARTS   AGE
    coffee-87cf76b96-5b85h   1/1     Running   0          7h39m
    coffee-87cf76b96-lqjrp   1/1     Running   0          7h39m
    tea-55bc9d5586-9z26v     1/1     Running   0          111m
  6. Deep Service Insight 엔드포인트에 액세스하세요.

    $ curl -i <NIC_IP_address>:9114/probe/cafe.example.com

    응답 코드 는  200 OK서비스가 트래픽을 허용할 준비가 되었음을 나타냅니다(적어도 하나의 포드가 정상임). 이 경우 세 개의 포드가 모두 Up 상태입니다.

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Date: Day, DD Mon YYYY hh:mm:ss TZ
    Content-Length: 32
    {"Total":3,"Up":3,"Unhealthy":0}

    상태  418 I’m a teapot코드는 서비스를 사용할 수 없음(모든 Pod가 비정상적임)을 나타냅니다.

    HTTP/1.1 418 I'm a teapotContent-Type: application/json; charset=utf-8
    Date: Day, DD Mon YYYY hh:mm:ss TZ
    Content-Length: 32
    {"Total":3,"Up":0,"Unhealthy":3}

    상태 코드  404 Not Found는 지정된 호스트 이름에서 실행 중인 서비스가 없음을 나타냅니다.

    HTTP/1.1 404 Not FoundDate: Day, DD Mon YYYY hh:mm:ss TZ
    Content-Length: 0


위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요


전문가에게 상담받기

프로필 이미지
관리자
2025-01-17
조회 13

오늘날 기업에서 비용과 위험의 균형을 맞추는 것이 가장 중요합니다. 하지만 충분한 가시성이 없다면 리소스가 효과적으로 또는 일관되게 사용되고 있는지 알 수 없습니다.

쿠버네티스는 종종 일시적이고 가변적인 양의 클러스터 리소스를 소모하는 컨테이너화된 워크로드의 복잡한 배포를 가능하게 합니다. 이는 클라우드 환경이 쿠버네티스에 매우 적합한 이유입니다. 쿠버네티스는 피크 부하를 예상하여 과도하게 프로비저닝할 필요 없이 사용한 만큼만 비용을 지불하는 가격 모델을 제공하기 때문입니다. 물론 클라우드 공급업체는 이러한 편의성에 대해 프리미엄을 청구합니다. 비용 없이 퍼블릭 클라우드의 동적 로드 밸런싱을 잠금 해제할 수 있다면 어떨까요? 그리고 온프레미스 및 퍼블릭 클라우드 배포에 동일한 솔루션을 사용할 수 있다면 어떨까요?

이제 가능합니다. Kubecost와 NGINX는 Kubernetes 사용자가 수많은 배포에서 복잡성과 비용을 줄이는 데 도움을 줍니다. 이러한 솔루션을 함께 사용하면 최적의 성능과 해당 성능 및 관련 비용에 대한 궁극적인 가시성을 얻을 수 있습니다.

Kubecost의 통찰력을 통해 성능과 보안을 높이는 동시에 Kubernetes 배포 비용을 획기적으로 줄일 수 있습니다. Kubecost로 달성할 수 있는 것의 예는 다음과 같습니다.

  • 다른 지역의 스토리지 버킷으로 포드가 상당한 유출 트래픽을 생성하는 잘못된 구성을 식별합니다.
  • 비용을 절감하고 성능을 개선하기 위해 멀티 클러스터 Kubernetes 환경에서 로드 밸런서와 Ingress 컨트롤러 툴링을 통합합니다.
  • 컨테이너의 성능을 파악하여 위험 없이 비용을 절감할 수 있도록 컨테이너 크기를 올바르게 조정하세요.


NGINX는 당신에게 필요한 성능을 제공합니다

NGINX Ingress Controller는 가장 널리 사용되는 Ingress 기술 중 하나로, 지금까지 Docker Hub에서 10억 회 이상 풀을 달성했으며 , 프로덕션 환경에서 실행되는 고성능, 확장 가능 및 보안을 갖춘 최신 앱의 대명사입니다.

NGINX Ingress Controller는 Kubernetes 환경에서 NGINX Open Source 또는 NGINX Plus 인스턴스와 함께 실행됩니다. 표준 Kubernetes Ingress 리소스 와 NGINX 사용자 지정 리소스를 모니터링하여 Ingress 로드 밸런싱이 필요한 서비스에 대한 요청을 발견합니다. 그런 다음 NGINX Ingress Controller는 NGINX 또는 NGINX Plus를 자동으로 구성하여 이러한 서비스로 트래픽을 라우팅하고 로드 밸런싱합니다.

NGINX Ingress Controller는 API 게이트웨이, 로드 밸런서 및 Ingress 컨트롤러 기능을 결합하는 범용 도구로 사용하여 운영을 간소화하고 비용과 복잡성을 줄일 수 있습니다.


Kubecost가 네트워크 운영의 실제 비용을 공개합니다.

Kubecost는 Kubernetes 사용자에게 클러스터에서 각 컨테이너를 실행하는 데 드는 비용에 대한 가시성을 제공합니다. 여기에는 각 노드의 명백한 CPU, 메모리 및 스토리지 비용이 포함됩니다. 그러나 Kubecost는 이러한 기본 사항을 넘어 클라우드 공급자의 데이터 이탈 시 일반적으로 발생하는 포드당 네트워크 전송 비용을 공개합니다.

Kubecost가 올바른 작업 부하에 비용을 얼마나 정확하게 할당하는지를 결정하는 두 가지 구성 옵션이 있습니다.

첫 번째 옵션은 통합 클라우드 청구 입니다 . Kubecost는 트래픽을 처리한 노드와 관련된 네트워크 전송 비용을 포함하여 클라우드 공급자로부터 청구 데이터를 가져옵니다. Kubecost는 이 비용을 컨테이너 트래픽의 공유에 따라 해당 노드의 포드에 분배합니다.

보고된 총 네트워크 비용은 정확하지만 이 방법은 이상적이지 않습니다. 많은 포드의 경우 유일하게 중요한 트래픽은 자체 존(따라서 무료) 내에 있지만 Kubecost는 이러한 워크로드에 대한 네트워크 비용을 보여줍니다.

두 번째 옵션인 네트워크 비용 구성은 모든 트래픽의 소스와 목적지를 살펴봄으로써 클라우드 청구 통합의 이러한 한계를 해결합니다. Kubecost Allocations 대시보드는 네임스페이스, 레이블, 서비스와 같은 Kubernetes 개념과 팀, 제품, 프로젝트, 부서, 환경과 같은 조직 부문을 포함한 여러 범주에 걸친 지출 비율을 표시합니다.

지난 60일 동안의 누적 비용을 네임스페이스별로 분류하여 보여주는 Kubecost 할당 대시보드



위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요



전문가에게 상담받기


프로필 이미지
관리자
2025-01-17
조회 1


12팩터 앱 으로 알려진 가이드라인은 10년 이상 전에 처음 발표되었습니다. 그 이후로 거의 모든 의무적 관행이 웹 앱을 작성하고 배포하는 사실상의 표준 방식이 되었습니다. 그리고 앱이 구성되고 배포되는 방식이 변경된 상황에서도 여전히 적용 가능하지만, 어떤 경우에는 앱 을 개발하고 배포하기 위한 마이크로서비스 패턴에 관행이 어떻게 적용되는지 이해하기 위해 추가적인 뉘앙스가 필요합니다.

이 블로그는 환경에서 구성 저장의 요소 3에 초점을 맞추고 있으며 다음과 같이 설명합니다.

  • 구성은 배포 환경(12단계 앱이 배포 라고 부르는 ) 간에 달라지는 모든 것을 말합니다.
  • 구성은 앱 코드와 엄격하게 분리되어야 합니다. 그렇지 않으면 배포마다 어떻게 달라질 수 있겠습니까?
  • 구성 데이터는 환경 변수에 저장됩니다.

마이크로서비스로 이동하면서 이러한 지침을 여전히 준수할 수 있지만, 항상 12팩터 앱의 문자 그대로의 해석에 정확히 매핑되는 방식은 아닙니다. 환경 변수로 구성 데이터를 제공하는 것과 같은 일부 지침은 훌륭하게 이어집니다. 12팩터 앱의 핵심 원칙을 존중하는 다른 일반적인 마이크로서비스 관행은 이를 확장한 것과 더 비슷합니다. 이 게시물에서는 팩터 3의 관점에서 마이크로서비스의 구성 관리에 대한 세 가지 핵심 개념을 살펴보겠습니다.

  • 서비스 구성을 명확하게 정의하기
  • 구성이 서비스에 제공되는 방법
  • 서비스를 구성으로 사용 가능하게 만들기

주요 마이크로서비스 용어 및 개념

마이크로서비스에 맞게 Factor 3을 적용하는 것에 대한 논의에 들어가기 전에 몇 가지 핵심 용어와 개념을 이해하는 것이 도움이 됩니다.

  • 모놀리식 앱 아키텍처  – 앱 기능을 구성 요소 모듈로 분리하지만 모든 모듈을 단일 코드베이스에 포함하는 전통적인 아키텍처 모델입니다.
  • 마이크로서비스 앱 아키텍처  - 각각 잘 범위가 정해진 작업 세트(예: 인증, 알림 또는 결제 처리)를 수행하는 여러 개의 작은 구성 요소로 크고 복잡한 앱을 빌드하는 아키텍처 모델입니다. "마이크로서비스"는 작은 구성 요소 자체의 이름이기도 합니다. 실제로 일부 "마이크로서비스"는 실제로 매우 클 수 있습니다.
  • 서비스  – 시스템 내의 단일 애플리케이션이나 마이크로서비스를 지칭하는 일반적인 용어입니다.
  • 시스템  – 이 블로그의 맥락에서 조직이 제공하는 완전한 기능을 생성하기 위해 함께 모이는 마이크로서비스와 지원 인프라의 전체 세트입니다.
  • 아티팩트  – 테스트 및 빌드 파이프라인에서 생성된 객체입니다. 앱의 코드를 포함하는 Docker 이미지와 같이 여러 형태를 취할 수 있습니다.
  • 배포  - 스테이징, 통합 또는 프로덕션과 같은 환경에서 실행되는 아티팩트의 실행 중인 "인스턴스"입니다.

마이크로서비스 대 모놀리스

모놀리식 애플리케이션에서는 조직의 모든 팀이 동일한 애플리케이션과 주변 인프라에서 작업합니다. 모놀리식 앱은 일반적으로 문서상으로는 마이크로서비스보다 간단해 보이지만 조직이 마이크로서비스로 이동하기로 결정하는 데에는 몇 가지 일반적인 이유가 있습니다.

  • 팀 자율성  – 모놀리스에서 기능과 하위 시스템의 소유권을 정의하는 것은 까다로울 수 있습니다. 조직이 성장하고 성숙해짐에 따라 앱 기능에 대한 책임은 점점 더 많은 팀에 분산되는 경우가 많습니다. 이는 기능을 소유한 팀이 모놀리스의 모든 관련 하위 시스템을 소유하지 않기 때문에 팀 간에 종속성을 만듭니다.
  • "폭발 반경" 감소  - 대규모 애플리케이션을 하나의 단일 단위로 개발 및 배포하는 경우 하나의 하위 시스템에서 오류가 발생하면 전체 앱의 기능이 저하될 수 있습니다.
  • 기능을 독립적으로 확장  – 모놀리식 앱에서 단일 모듈만 부하가 많이 걸리더라도 조직은 시스템 장애나 성능 저하를 방지하기 위해 전체 앱의 여러 인스턴스를 배포해야 합니다.

물론 마이크로서비스에는 복잡성 증가, 관찰성 감소, 새로운 보안 모델 필요성 등 고유한 과제가 있습니다. 하지만 많은 조직, 특히 대규모 또는 빠르게 성장하는 조직은 고객에게 제공하는 경험에 대한 안정적이고 신뢰할 수 있는 기반을 구축하는 데 있어 팀에 더 많은 자율성과 유연성을 제공하기 위해 이러한 과제를 감수할 가치가 있다고 결정합니다.

마이크로서비스 아키텍처에 필요한 변경 사항

모놀리식 앱을 마이크로서비스로 리팩토링하는 경우 서비스는 다음을 수행해야 합니다.

  • 예측 가능한 방식으로 구성 변경 사항 수락
  • 예측 가능한 방식으로 더 넓은 시스템에 자신을 알리십시오.
  • 잘 문서화하세요

모놀리식 앱의 경우 프로세스의 작은 불일치와 공유된 가정에 대한 종속성은 중요하지 않습니다. 그러나 많은 개별 마이크로서비스의 경우 이러한 불일치와 가정은 많은 고통과 혼란을 초래할 수 있습니다. 마이크로서비스에서 변경해야 하는 많은 부분은 기술적으로 필요하지만 놀랍게도 많은 부분이 팀이 내부적으로 작업하고 다른 팀과 상호 작용하는 방식과 관련이 있습니다.

마이크로서비스 아키텍처를 적용한 주요 조직 변화는 다음과 같습니다.

  • 동일한 코드베이스에서 함께 작업하는 대신, 팀은 완전히 분리되어 각 팀이 하나 이상의 서비스에 대해 전적으로 책임을 집니다. 가장 일반적인 마이크로서비스 구현에서 팀은 또한 "교차 기능적"으로 재편됩니다. 즉, 다른 팀에 대한 최소한의 종속성으로 팀의 목표를 완료하는 데 필요한 모든 역량을 갖춘 멤버가 있다는 의미입니다.
  • 플랫폼 팀(시스템 전반의 상태를 담당)은 이제 단일 애플리케이션을 다루는 대신, 여러 팀이 소유한 여러 서비스를 조정해야 합니다.
  • 툴링 팀은 다양한 서비스 소유자 팀에 툴링과 지침을 제공하여 시스템을 안정적으로 유지하는 동시에 목표를 빠르게 달성할 수 있도록 지원해야 합니다.

모놀리식 및 마이크로서비스 앱의 개발자 팀 구성을 비교하는 다이어그램

서비스 구성을 명확하게 정의하기

팩터 3을 확장해야 하는 마이크로서비스 아키텍처의 한 영역은 구성을 포함한 서비스에 대한 특정 중요 정보를 명확하게 정의하고 다른 서비스와 최소한의 공유 컨텍스트를 가정해야 할 필요성과 관련이 있습니다. 팩터 3은 이를 직접 다루지는 않지만, 애플리케이션 기능에 기여하는 개별 마이크로서비스가 많은 경우 특히 중요합니다.

마이크로서비스 아키텍처의 서비스 소유자로서, 귀하의 팀은 시스템 전체에서 특정 역할을 하는 서비스를 소유합니다. 귀하의 서비스와 상호 작용하는 다른 팀은 귀하의 서비스 저장소에 액세스하여 코드와 문서를 읽고 기여해야 합니다.

게다가, 소프트웨어 개발 분야에서 팀 구성원이 자주 바뀌는 것은 불행한 현실입니다. 개발자가 회사에 들어오고 나가기 때문일 뿐만 아니라 내부 조직 개편 때문이기도 합니다. 또한 주어진 서비스에 대한 책임도 종종 팀 간에 이전됩니다.

이러한 현실에 비추어 볼 때, 귀하의 코드베이스와 문서는 매우 명확하고 일관성이 있어야 하며, 이는 다음을 통해 달성됩니다.

  • 각 구성 옵션의 목적을 명확하게 정의합니다.
  • 구성 값의 예상 형식을 명확하게 정의합니다.
  • 애플리케이션이 구성 값을 제공하도록 기대하는 방법을 명확하게 정의합니다.
  • 이 정보를 제한된 수의 파일에 기록합니다.

많은 애플리케이션 프레임워크는 필요한 구성을 정의하는 수단을 제공합니다. 예를 들어, convictNode.js 애플리케이션용 NPM 패키지는 단일 파일에 저장된 완전한 구성 "스키마"를 사용합니다. 이는 Node.js 앱이 실행하는 데 필요한 모든 구성에 대한 진실의 원천 역할을 합니다.

강력하고 쉽게 발견할 수 있는 스키마를 통해 팀원과 다른 사람들이 서비스를 자신 있게 사용할 수 있습니다.

구성이 서비스에 제공되는 방법

애플리케이션에 필요한 구성 값을 명확하게 정의했다면 배포된 마이크로서비스 애플리케이션이 구성을 가져오는 두 가지 기본 소스 간의 중요한 구별도 존중해야 합니다.

  • 구성 설정을 명시적으로 정의하고 애플리케이션 소스 코드와 함께 제공되는 배포 스크립트
  • 배포 시점에 외부 소스가 쿼리됨

배포 스크립트는 마이크로서비스 아키텍처에서 일반적인 코드 구성 패턴입니다. 12팩터 앱이 처음 공개된 이후로 새로운 것이기 때문에 필연적으로 12팩터 앱의 확장을 나타냅니다.

패턴: 애플리케이션 옆의 배포 및 인프라 구성

최근 몇 년 동안 애플리케이션 코드와 동일한 저장소에 infrastructure (또는 이와 비슷한 이름의 변형) 라는 폴더를 두는 것이 일반적이 되었습니다 . 여기에는 일반적으로 다음이 포함됩니다.

  • 서비스가 의존하는 인프라를 설명하는 코드로서의 인프라( Terraform 이 일반적인 예)(예: 데이터베이스)
  • Helm 차트 및 Kubernetes 매니페스트 와 같은 컨테이너 오케스트레이션 시스템에 대한 구성
  • 애플리케이션 배포와 관련된 기타 파일

언뜻 보면 이는 구성과 코드를 엄격하게 분리해야 한다는 요소 3의 규정을 위반하는 것처럼 보일 수 있습니다.

사실, 애플리케이션 옆 에 배치하면 인프라 폴더가 실제로 규칙을 준수하는 동시에 마이크로서비스 환경에서 작업하는 팀에 중요한 귀중한 프로세스 개선을 가능하게 한다는 것을 의미합니다.

이 패턴의 장점은 다음과 같습니다.

  • 서비스를 소유한 팀은 서비스 배포와 서비스별 인프라(예: 데이터베이스)의 배포도 소유합니다.
  • 소유 팀은 이러한 요소에 대한 변경 사항이 개발 프로세스(코드 검토, CI)를 거치도록 할 수 있습니다.
  • 팀은 외부 팀에 작업을 맡기지 않고도 서비스와 지원 인프라의 배포 방식을 쉽게 변경할 수 있습니다.

이 패턴이 제공하는 이점은 개별 팀의 자율성을 강화하는 동시에 배포 및 구성 프로세스에 추가적인 엄격성이 적용된다는 것입니다.

어떤 유형의 구성이 어디에 적용됩니까?

실제로 인프라 폴더에 저장된 배포 스크립트를 사용하여 스크립트 자체에 명시적으로 정의된 구성과 배포 시점에 외부 소스에서 구성을 검색하는 작업을 모두 관리합니다. 이를 위해 서비스에 대한 배포 스크립트를 다음과 같이 사용합니다.

  1. 특정 구성 값을 직접 정의합니다
  2. 배포 스크립트를 실행하는 프로세스가 외부 소스에서 원하는 구성 값을 찾을 수 있는 위치를 정의합니다.

서비스의 특정 배포에 특화되어 있고 팀의 완전한 통제 하에 있는 구성 값은 인프라 폴더의 파일에 직접 지정할 수 있습니다. 예를 들어 앱에서 시작한 데이터베이스 쿼리가 실행될 수 있는 시간 제한과 같은 것이 있습니다. 이 값은 배포 파일을 수정하고 애플리케이션을 다시 배포하여 변경할 수 있습니다.

이 계획의 한 가지 이점은 이러한 구성에 대한 변경 사항이 반드시 코드 검토 및 자동화된 테스트를 거쳐야 하므로 잘못 구성된 값으로 인해 중단이 발생할 가능성이 줄어든다는 것입니다. 코드 검토를 거치는 값과 주어진 시간의 구성 키 값에 대한 변경 사항은 소스 제어 툴링의 기록에서 발견할 수 있습니다.

애플리케이션이 실행되는 데 필요하지만 팀의 제어를 받지 않는 값은 애플리케이션이 배포된 환경에서 제공해야 합니다. 예를 들어, 서비스가 종속된 다른 마이크로서비스에 연결하는 호스트 이름과 포트가 있습니다.

해당 서비스는 귀하의 팀이 소유하지 않으므로 포트 번호와 같은 값에 대해 가정할 수 없습니다. 이러한 값은 언제든지 변경될 수 있으며 변경 시 일부 중앙 구성 저장소에 등록해야 합니다. 해당 변경이 수동으로 이루어지든 자동 프로세스로 이루어지든 상관없습니다. 그런 다음 해당 값에 의존하는 애플리케이션에서 쿼리할 수 있습니다.

이러한 지침은 마이크로서비스 구성을 위한 두 가지 모범 사례로 요약할 수 있습니다.

마이크로서비스 구성에서는 하드코딩된 값이나 상호 합의된 값에 의존하지 마십시오.

배포 스크립트에서 특정 값(예: 서비스가 상호 작용하는 서비스의 위치)을 하드코딩하는 것이 가장 간단해 보일 수 있습니다. 실제로 그러한 유형의 구성을 하드코딩하는 것은 위험하며, 특히 서비스 위치가 일반적으로 자주 변경되는 현대 환경에서 더욱 그렇습니다. 그리고 두 번째 서비스를 소유하지 않은 경우 특히 위험합니다.

스크립트에서 서비스 위치를 업데이트하기 위해 자신의 근면함에 의지할 수 있다고 생각할 수도 있고, 더 나쁜 경우 위치가 변경될 때 소유팀이 알려줄 것이라고 생각할 수도 있습니다. 근면함은 스트레스가 많은 시기에 종종 미끄러지고, 인간의 엄격함에 의존하면 시스템이 경고 없이 실패할 위험이 있습니다.

마이크로서비스 구성에서 해야 할 일: 서비스에 "내 데이터베이스는 어디에 있습니까?"라고 묻게 하세요.

위치 정보가 하드코딩되어 있든 아니든, 애플리케이션은 특정 위치에 있는 중요한 인프라에 의존해서는 안 됩니다. 대신, 새로 배포된 서비스는 "내 데이터베이스는 어디에 있습니까?"와 같은 시스템 내의 일반적인 소스에 질문을 하고 해당 외부 리소스의 현재 위치에 대한 정확한 답변을 받아야 합니다. 모든 서비스가 배포될 때 시스템에 등록하면 훨씬 더 간단해집니다.

서비스를 구성으로 사용 가능하게 만들기

시스템이 "내 데이터베이스는 어디에 있나요?"와 "내가 사용하는 '서비스 X'는 어디에 있나요?"라는 질문에 대한 답을 제공해야 하는 것처럼, 서비스는 배포 방법에 대해 전혀 알지 못해도 다른 서비스가 쉽게 찾아서 통신할 수 있는 방식으로 시스템에 노출되어야 합니다.

마이크로서비스 아키텍처의 핵심 구성 관행은 서비스 검색입니다. 새로운 서비스 정보를 등록하고 다른 서비스에서 액세스할 때 해당 정보를 동적으로 업데이트하는 것입니다. 마이크로서비스에 서비스 검색이 필요한 이유를 설명한 후 NGINX Open Source와 Consul을 사용하여 이를 달성하는 방법의 예를 살펴보겠습니다.

서비스의 여러 인스턴스(배포)를 동시에 실행하는 것은 일반적인 관행입니다. 이를 통해 추가 트래픽을 처리할 수 있을 뿐만 아니라 새로운 배포를 시작하여 다운타임 없이 서비스를 업데이트할 수도 있습니다. 리버스 프록시 및 로드 밸런서 역할을 하는 NGINX와 같은 도구는 들어오는 트래픽을 처리하여 가장 적합한 인스턴스로 라우팅합니다. 이는 서비스에 의존하는 서비스가 NGINX에만 요청을 보내고 배포에 대해 아무것도 알 필요가 없기 때문에 좋은 패턴입니다.

예를 들어, NGINX 뒤에서 역방향 프록시 역할을 하는 messenger 라는 서비스의 단일 인스턴스가 있다고 가정해 보겠습니다 .

NGINX에 의해 역방향 프록시되는 '메신저' 마이크로서비스의 단일 인스턴스 다이어그램

이제 앱이 인기를 얻으면 어떨까요? 좋은 소식으로 여겨지지만, 트래픽이 증가했기 때문에 메신저 인스턴스가 많은 CPU를 소모하고 요청을 처리하는 데 시간이 더 오래 걸리는 반면 데이터베이스는 정상적으로 작동하는 것 같습니다. 이는 메신저 서비스 의 다른 인스턴스를 배포하면 문제를 해결할 수 있음을 나타냅니다 .

메신저 서비스 의 두 번째 인스턴스를 배포할 때 NGINX는 그것이 라이브 상태인지 어떻게 알고 트래픽을 보내기 시작합니까? NGINX 구성에 새 인스턴스를 수동으로 추가하는 것은 한 가지 접근 방식이지만, 더 많은 서비스가 확장되고 축소됨에 따라 빠르게 관리하기 어려워집니다.

일반적인 해결책은 Consul 과 같은 고가용성 서비스 레지스트리가 있는 시스템에서 서비스를 추적하는 것입니다 . 새로운 서비스 인스턴스는 배포될 때 Consul에 등록됩니다. Consul은 주기적으로 상태 검사를 보내 인스턴스의 상태를 모니터링합니다. 인스턴스가 상태 검사에 실패하면 사용 가능한 서비스 목록에서 제거됩니다.

NGINX에서 역방향 프록시를 사용하고 서비스 검색을 위해 Consul을 사용하는 '메신저' 마이크로서비스의 두 인스턴스 다이어그램

NGINX는 다양한 방법을 사용하여 Consul과 같은 레지스트리를 쿼리하고 그에 따라 라우팅을 조정할 수 있습니다. 리버스 프록시 또는 로드 밸런서 역할을 할 때 NGINX가 트래픽을 "업스트림" 서버로 라우팅한다는 점을 기억하세요. 다음과 같은 간단한 구성을 고려하세요.


# Define an upstream group called "messenger_service"
upstream messenger_service {
    server 172.18.0.7:4000;
    server 172.18.0.8:4000;
}

server {
    listen 80;

    location /api {
        # Proxy HTTP traffic with paths starting with '/api' to the
        # 'upstream' block above. The default load-balancing algorithm, 
        # Round-Robin, alternates requests between the two servers 
        # in the block.
        proxy_pass http://messenger_service;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
}


기본적으로 NGINX는 트래픽을 라우팅하기 위해 각 메신저 인스턴스 의 정확한 IP 주소와 포트를 알아야 합니다 . 이 경우 172.18.0.7과 172.18.0.8 모두에서 포트 4000입니다.

여기서 Consul과 Consul 템플릿이 등장합니다. Consul 템플릿은 NGINX와 동일한 컨테이너에서 실행되며 서비스 레지스트리를 유지 관리하는 Consul 클라이언트와 통신합니다.

레지스트리 정보가 변경되면 Consul 템플릿은 올바른 IP 주소와 포트를 사용하여 NGINX 구성 파일의 새 버전을 생성하고, NGINX 구성 디렉토리에 쓰고, NGINX에 구성을 다시 로드하라고 지시합니다. NGINX가 구성을 다시 로드할 때 다운타임이 없으며 , 새 인스턴스는 다시 로드가 완료되는 즉시 트래픽을 수신하기 시작합니다.

이런 상황에서 NGINX와 같은 역방향 프록시를 사용하면 다른 서비스가 액세스할 수 있는 장소로 시스템에 등록할 수 있는 단일 터치 포인트가 있습니다. 귀하의 팀은 다른 서비스가 서비스 전체에 대한 액세스를 잃을까 봐 걱정할 필요 없이 개별 서비스 인스턴스를 관리할 수 있는 유연성을 갖습니다.




위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요



전문가에게 상담받기

프로필 이미지
관리자
2025-01-17
조회 1
견고한 Kubernetes 환경을 만들고 관리하려면 네트워크 및 애플리케이션 팀 간의 원활한 협업이 필요합니다. 하지만 이들의 우선순위와 작업 스타일은 보통 상당히 다르기 때문에 충돌이 발생하여 앱 개발이 느리고 배포가 지연되며 심지어 네트워크 다운타임까지 심각한 결과를 초래합니다.

두 팀이 공통의 목표를 향해 노력하는 성공만이 오늘날의 현대적 애플리케이션이 적절한 보안과 확장성을 갖추고 제때에 제공되도록 보장할 수 있습니다. 그렇다면 각 팀의 기술과 전문성을 활용하면서 그들이 협력하도록 돕는 방법은 무엇일까요?

저희의 백서 ' Get Me to the Cluster' 에서는 네트워크팀과 애플리케이션팀이 갈등 없이 각자의 강점을 결합할 수 있도록 Kubernetes 서비스에 대한 외부 액세스를 활성화하는 솔루션을 자세히 설명합니다.


Kubernetes 클러스터에서 앱을 노출하는 방법

이 솔루션은 특히 온프레미스에서 호스팅되는 Kubernetes 클러스터에 적합하며 , 노드는 베어 메탈 또는 기존 Linux 가상 머신(VM)에서 실행되고 표준 레이어 2 스위치와 레이어 3 라우터는 데이터 센터에서 통신을 위한 네트워킹을 제공합니다. 클라우드 호스팅 Kubernetes 클러스터에는 적용되지 않습니다. 클라우드 공급자는 데이터 센터의 핵심 네트워킹이나 관리되는 Kubernetes 환경의 네트워킹을 제어할 수 없기 때문입니다.

데이터 센터 내에서 호스팅되는 Kubernetes 클러스터의 다이어그램. 노드와 표준 2계층 스위치, 3계층 라우터가 데이터 센터의 통신을 위한 네트워킹을 제공합니다.

솔루션의 세부 사항을 살펴보기 전에 Kubernetes 클러스터에서 애플리케이션을 노출하는 다른 표준 방식이 온프레미스 배포에 적합하지 않은 이유를 살펴보겠습니다.

  • 서비스  – 동일한 앱을 실행하는 포드를 그룹화합니다. 이는 내부 포드 간 통신에 좋지만 클러스터 내부에서만 볼 수 있으므로 앱을 외부에 노출하는 데 도움이 되지 않습니다.
  • NodePort  – 클러스터의 모든 노드에서 특정 포트를 열고 해당 앱으로 트래픽을 전달합니다. 이렇게 하면 외부 사용자가 서비스에 액세스할 수 있지만 구성이 정적이고 잘 알려진 하위 포트 번호 대신 높은 번호의 TCP 포트를 사용하고 다른 앱과 포트 번호를 조정해야 하기 때문에 이상적이지 않습니다. 또한 여러 앱 간에 공통 TCP 포트를 공유할 수 없습니다.
  • LoadBalancer  – 각 노드에서 NodePort 정의를 사용하여 외부 세계에서 Kubernetes 노드로의 네트워크 경로를 만듭니다. AWS, Google Cloud Platform, Microsoft Azure 및 대부분의 다른 클라우드 공급자가 잘 작동하고  A서비스에 필요한 공용 IP 주소와 일치하는 DNS 레코드를 제공하는 쉽게 구성할 수 있는 기능으로 지원하기 때문에 클라우드 호스팅 Kubernetes에 적합합니다. 안타깝게도 온프레미스 클러스터에는 동일한 기능이 없습니다.


온프레미스 Kubernetes 클러스터에 대한 외부 사용자 액세스 활성화

그러면 클러스터 외부의 사용자에서 클러스터 내부의 포드로 흐르는 트래픽(북쪽에서 남쪽으로 트래픽)을 위해 특별히 설계된 Kubernetes Ingress 객체가 남습니다. Ingress는 클러스터에 대한 외부 HTTP/HTTPS 진입점을 만듭니다. 외부 사용자가 여러 서비스에 액세스할 수 있는 단일 IP 주소 또는 DNS 이름입니다. 이것이 바로 필요한 것입니다! Ingress 객체는 Ingress 컨트롤러에 의해 구현됩니다. 당사 솔루션에서는 NGINX Plus 기반의 엔터프라이즈급 F5 NGINX Ingress 컨트롤러입니다 .

솔루션의 또 다른 핵심 구성 요소가 레이어 3 라우팅 프로토콜인 Border Gateway Protocol  (BGP)이라는 사실에 놀라실지도 모릅니다. 하지만 훌륭한 솔루션은 복잡할 필요가 없습니다!

Get Me to the Cluster 에 설명된 솔루션은 실제로 4가지 구성 요소로 구성되어 있습니다.

  1. iBGP 네트워크  – 내부 BGP(iBGP)는 데이터 센터의 자율 시스템(AS) 내에서 라우팅 정보를 교환하는 데 사용되며 네트워크가 안정적이고 확장 가능한지 확인하는 데 도움이 됩니다. iBGP는 이미 대부분의 데이터 센터에서 네트워크 팀에서 지원하고 있습니다.
  2. Project Calico CNI 네트워킹  – Project Calico 는 온프레미스 데이터 센터의 환경을 유연하게 연결하고 트래픽 흐름에 대한 세부적인 제어를 제공하는 오픈소스 네트워킹 솔루션입니다. 우리는 BGP를 활성화한 Kubernetes 클러스터에서 네트워킹을 위해 Project Calico의 CNI 플러그인을 사용합니다. 이를 통해 포드에 할당된 IP 주소 풀을 제어할 수 있어 네트워킹 문제를 빠르게 식별하는 데 도움이 됩니다.
  3. NGINX Plus 기반 NGINX Ingress Controller  – NGINX Ingress Controller를 사용하면 포드의 서비스 엔드포인트 IP 주소를 보고 트래픽 처리를 중단하지 않고 업스트림 서비스 목록을 자동으로 재구성할 수 있습니다. 애플리케이션 팀은 또한 활성 상태 검사, mTLS, JWT 기반 인증을 포함하여 NGINX Plus의 여러 다른 엔터프라이즈급 Layer 7 HTTP 기능을 활용할 수 있습니다.
  4. NGINX Plus를 에지에서 리버스 프록시로 사용  – NGINX Plus는 Kubernetes 클러스터의 에지에서 리버스 프록시로 사용되어 데이터 센터의 스위치와 라우터와 Kubernetes 클러스터의 내부 네트워크 간의 경로를 제공합니다. 이는 Kubernetes LoadBalancer 객체를 대체하는 역할을 하며 BGP에 Quagga를 사용합니다.

이 다이어그램은 솔루션 아키텍처를 보여주며, 요청 처리 중에 데이터가 교환되는 순서가 아닌 솔루션 구성 요소가 통신하는 데 사용하는 프로토콜을 나타냅니다.

솔루션 구성 요소가 통신하는 데 사용하는 프로토콜을 나타내는 솔루션 아키텍처를 설명하는 다이어그램




위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요



전문가에게 상담받기

프로필 이미지
관리자
2025-01-17
조회 1


지금, 수백만 명의 Java 개발자가 애플리케이션 성능을 최적화하는 데 엄청난 시간과 노력을 투자하고 있습니다. 그들은 웹에서 모바일, AI/ML, 엣지에 이르기까지 클라우드 기반 비즈니스 요구 사항을 처리하고 있습니다. 그들이 직면한 가장 큰 장애물 중 하나는 Java와 Kubernetes 간의 호환성이 좋지 않다는 것입니다 . 간단한 수정조차도 개발자가 익숙하지 않은 런타임 환경과 프로그래밍 언어를 배우고 채택해야 하기 때문에 시간이 많이 걸립니다. 여기서 프로젝트를 스캐폴딩하면 시간과 골치 아픈 일을 줄일 수 있습니다.


스캐폴딩이란?

소프트웨어 개발에서 스캐폴딩은 프로그램을 개발하고 테스트하는 동안 임시 또는 일반 코드를 만드는 것을 말합니다. 덜 복잡한 예로는 런타임 오류를 테스트하는 코드를 추가하고 양식 채우기 페이지의 모형을 만드는 것이 있습니다. 이 모형 또는 스캐폴드는 최종 양식 채우기가 작동하는 방식으로 작동하지만 최종 버전과 다르게 보이거나 다른 코드를 사용할 수 있습니다. 어느 쪽이든 결과는 최종 시스템이나 프로젝트에 포함되도록 의도되지 않은 애플리케이션 기능의 임시 골격입니다.


NGINX를 사용한 스캐폴딩의 예

NGINX 오픈 소스를 레이어 7 데이터 플레인으로 사용할 때 개발자는 일반적으로 작업을 수행하기 위해 상당한 양의 스캐폴딩을 설정해야 합니다. 이 스캐폴딩에는 인증 및 인증서 관리 추가, 로깅 설정, 자동화 및 CI/CD 기능 연결 등이 포함될 수 있습니다. 우리는 NGINX 에코시스템에 대한 확장을 진행 중이므로 앱을 테스트하고 배포하는 데 필요한 모든 주요 요구 사항이 하나 이상의 고품질 오픈 소스 구성 요소로 충족됩니다. 자세한 내용은 블로그를 참조하세요 .


Java 프로젝트를 Kubernetes 네이티브 앱으로 스캐폴딩

NGINX Sprint 2022의 이 데모에서 Red Hat의 수석 수석 개발자 옹호자인 Daniel Oh는 Java 프로젝트를 처음부터 스캐폴딩한 다음 메모리 사용량이 매우 적고 시작 시간이 몇 밀리초에 불과한 Kubernetes 네이티브 애플리케이션으로 빌드하는 방법을 안내합니다.

또한 다니엘은 로컬 개발자가 내부 루프 개발에서 겪는 경험을 복제하는 방식으로 원격 쿠버네티스 환경에 이미 배포된 애플리케이션을 계속 테스트하고 디버깅하는 방법을 보여줍니다.




위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요



전문가에게 상담받기

프로필 이미지
관리자
2025-01-17
조회 1

애플리케이션 개발의 궁극적인 목표는 물론 앱을 인터넷에 노출하는 것입니다. 개발자에게 Kubernetes는 Ingress 컨트롤러를 애플리케이션에 대한 요청을 라우팅하는 메커니즘으로 제공함으로써 이 프로세스를 어느 정도 간소화합니다. 하지만 모든 것이 여러분이 원하는 만큼 셀프 서비스인 것은 아닙니다. 여전히 앱의 도메인 이름을 Ingress 컨트롤러의 IP 주소에 매핑하기 위한 DNS(Domain Name System)의 레코드와 HTTPS를 사용하여 연결을 보호하기 위한 TLS 인증서가 필요합니다. 대부분의 조직에서는 DNS나 TLS를 직접 소유하지 않으므로 이를 소유한 운영 그룹(또는 그룹들!)과 협력해야 합니다.

운영자에게는 반드시 쉬운 일은 아닙니다. 대부분의 조직에서 DNS 레코드를 업데이트해야 할 필요성은 매우 드물기 때문에 절차(비즈니스 규칙과 실제 기술 단계 모두)가 희소하거나 존재하지 않는 경향이 있습니다. 즉, DNS 레코드를 추가해야 할 때 먼저 설명서를 찾거나 동료에게 물어보거나(최악의 경우) 알아내야 합니다. 또한 회사 보안 규칙을 준수하고 방화벽에 대한 유입 태그가 올바르게 지정되었는지 확인해야 합니다.

다행히도 개발자와 운영자 모두의 삶을 더 편리하게 만들 수 있는 방법이 있습니다. 이 게시물에서는 운영자가 Kubernetes 배포를 구성하여 개발자가 Kubernetes 환경에서 DNS 레코드를 업데이트하고 TLS 인증서를 생성할 수 있도록 셀프 서비스를 활성화하는 방법을 보여줍니다. 인프라를 미리 구축하면 모든 필수 비즈니스 및 기술 요구 사항이 충족되고 있는지 확인할 수 있습니다.


개요 및 전제 조건

솔루션이 준비되면 개발자가 애플리케이션을 인터넷에 노출하기 위해 해야 할 일은 Kubernetes 설치에서 관리하는 도메인 내의 정규화된 도메인 이름(FQDN)을 포함하는 제공된 템플릿에 따라 Ingress 컨트롤러를 만드는 것뿐입니다. Kubernetes는 템플릿을 사용하여 Ingress 컨트롤러에 대한 IP 주소를 할당하고,  AFQDN을 IP 주소에 매핑하는 DNS 레코드를 만들고, FQDN에 대한 TLS 인증서를 생성하여 Ingress 컨트롤러에 추가합니다. 정리도 마찬가지로 쉽습니다. Ingress가 제거되면 DNS 레코드가 정리됩니다.

이 솔루션은 다음 기술을 활용합니다(아래에 설치 및 구성 지침 제공):

  • 쿠버네티스 .
  • 외부 DNS .
  • 인증서 관리자 .
  • 암호화합시다 .
  • F5 NGINX의 NGINX Ingress Controller는 NGINX Open Source 또는 NGINX Plus를 기반으로 합니다 . 이 솔루션은 Kubernetes 커뮤니티에서 유지 관리하는 NGINX Ingress Controller 와 호환되지 않습니다 . 두 프로젝트 간의 차이점에 대한 자세한 내용은 블로그를 참조하세요 .

솔루션을 구성하기 전에 다음이 필요합니다.

  • egress( ) 객체가 있는 Kubernetes 클라우드 설치 LoadBalancer. 솔루션은 Linode를 사용하지만 다른 클라우드 공급자도 작동합니다.
  • Cloudflare 에서 호스팅되는 도메인 이름입니다 . cert-manager 에 지원되는 DNS 공급자 중 하나 이고 ExternalDNS( 작성 당시 베타 버전 )를 지원하기 때문에 선택했습니다. 이 도메인을 프로덕션이나 기타 중요한 용도로 사용하지 않는 것이 좋습니다.
  • 무료 계층에 포함된 Cloudflare API에 액세스합니다.
  • Kubernetes를 설치하고 배포하기 위한 Helm입니다 .
  • kubectlKubernetes의 명령줄 인터페이스로서.
  • 선택적으로 Kubernetes와 상호 작용하는 보다 체계적인 방식을 제공하는 잘 구성된 유형적 사용자 인터페이스(TUI)인 K9s를 사용할 수 있습니다.

또한 Kubernetes에 대한 기본적인 이해(매니페스트 적용 방법, Helm 차트 사용 방법, kubectl출력을 보고 문제를 해결하기 위한 명령 실행 방법)가 있다고 가정합니다. Let's Encrypt의 기본 개념을 이해하는 것이 도움이 되지만 필수는 아닙니다. 개요는 블로그를 참조하세요. cert-manager가 어떻게 작동하는지 알 필요도 없지만 NGINX Ingress Controller에서 cert-manager(및 인증서 전반)가 어떻게 작동하는지 궁금하다면 최근 게시물인 Kubernetes 환경에서 인증서 관리 자동화를 참조하세요 .

우리는 macOS와 Linux에서 솔루션을 테스트했습니다. Linux 버전 2(WSL2)용 Windows Subsystem에서는 테스트하지 않았지만, 문제는 예상하지 않습니다.

참고: 이 솔루션은 프로덕션 용도가 아닌 개념 증명 샘플로 의도되었습니다. 특히 운영 및 보안에 대한 모든 모범 사례를 통합하지 않았습니다. 해당 주제에 대한 정보는 cert-manager 및 ExternalDNS 설명서를 참조하세요.


솔루션 배포

솔루션을 배포하려면 다음 섹션의 단계를 따르세요.

  • 소프트웨어 다운로드
  • NGINX Ingress Controller 배포
  • cert-manager 배포
  • ExternalDNS 배포
  • 샘플 애플리케이션 배포
  • 솔루션 검증

소프트웨어 다운로드
  1. Cloudflare API 토큰을 다운로드하세요 .
  2. NGINX Ingress Controller 저장소를 복제합니다.

    $ git clone https://github.com/nginxinc/kubernetes-ingress.gitCloning into 'kubernetes-ingress'...
    remote: Enumerating objects: 45176, done.
    remote: Counting objects: 100% (373/373), done.
    remote: Compressing objects: 100% (274/274), done.
    remote: Total 45176 (delta 173), reused 219 (delta 79), pack-reused 44803
    Receiving objects: 100% (45176/45176), 60.45 MiB | 26.81 MiB/s, done.
    Resolving deltas: 100% (26592/26592), done.
  3. Kubernetes 클러스터에 연결할 수 있는지 확인하세요.

    $ kubectl cluster-infoKubernetes control plane is running at https://ba35bacf-b072-4600-9a04-e04...6a3d.us-west-2.linodelke.net:443
    KubeDNS is running at https://ba35bacf-b072-4600-9a04-e04...6a3d.us-west-2.linodelke.net:443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
     
    To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.


NGINX Ingress Controller 배포

  1. Helm을 사용하여 NGINX Ingress Controller를 배포합니다. 세 가지 비표준 구성 옵션을 추가하고 있다는 점에 유의하세요 .

    • controller.enableCustomResources – Helm에 NGINX VirtualServer 및 VirtualServerRoute 사용자 정의 리소스를 생성하는 데 사용되는 사용자 정의 리소스 정의(CRD)를 설치하도록 지시합니다.
    • controller.enableCertManager – NGINX Ingress Controller를 구성하여 cert-manager 구성 요소와 통신합니다.
    • controller.enableExternalDNS – Ingress Controller를 구성하여 ExternalDNS 구성 요소와 통신하도록 합니다.
  2. $ helm install nginx-kic nginx-stable/nginx-ingress --namespace nginx-ingress  --set controller.enableCustomResources=true --create-namespace  --set controller.enableCertManager=true --set controller.enableExternalDNS=trueNAME: nginx-kic
    LAST DEPLOYED: Day Mon  DD hh:mm:ss YYYY
    NAMESPACE: nginx-ingress
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    The NGINX Ingress Controller has been installed.
  3. NGINX Ingress Controller가 실행 중인지 확인하고 EXTERNAL-IP필드의 값을 기록하세요. NGINX Ingress Controller의 IP 주소입니다(여기서는 www.xxx.yyy.zzz). 출력은 읽기 쉽도록 두 줄로 나뉩니다.

    $ kubectl get services --namespace nginx-ingressNAME                      TYPE           CLUSTER-IP      ...
    nginx-kic-nginx-ingress   LoadBalancer   10.128.152.88   ... 
    
       ... EXTERNAL-IP       PORT(S)                      AGE
       ... www.xxx.yyy.zzz   80:32457/TCP,443:31971/TCP   3h8m


cert-manager 배포

솔루션에서 cert-manager는 TLS 인증서를 얻을 때 DNS-01 챌린지 유형을 사용하는데 , 이를 위해서는 ClusterIssuer 리소스를 생성하는 동안 Cloudflare API 토큰을 제공해야 합니다 . 솔루션에서 API 토큰은 Kubernetes Secret 으로 제공됩니다 .

  1. Helm을 사용하여 cert-manager를 배포합니다 .

    $ helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.9.1  --set installCRDs=trueNAME: cert-manager
    LAST DEPLOYED: Day Mon  DD hh:mm:ss YYYY
    NAMESPACE: cert-manager
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    cert-manager v1.9.1 has been deployed successfully!
  2. Cloudflare API 토큰을 Kubernetes Secret으로 배포하고 다음을 대체합니다 <your-API-token>.

    $ kubectl apply -f - <<EOFapiVersion: v1
    kind: Secret
    metadata:
      name: Cloudflare-api-token-secret
      namespace: cert-manager
    type: Opaque
    stringData:
      api-token: "<your-API-token>"
    EOF
    secret/Cloudflare-api-token-secret created
  3. ClusterIssuer 객체를 생성하고 Cloudflare-api-token-secret토큰을 검색할 장소로 (이전 단계에서 정의됨)을 지정합니다. 원하시면 example-issuer필드 metadata.name(및 example-issuer-account-key필드 spec.acme.privateKeySecretRef.name)를 다른 이름으로 바꿀 수 있습니다.

    $ kubectl apply -f - <<EOFapiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: example-issuer
      namespace: cert-manager
    spec:
      acme:
        email: example@example.com
        server: https://acme-v02.api.letsencrypt.org/directory
        privateKeySecretRef:
          name: example-issuer-account-key
        solvers:
          - dns01:
              Cloudflare:
                apiTokenSecretRef:
                  name: Cloudflare-api-token-secret
                  key: api-token
    EOF
    clusterissuer.cert-manager.io/example-issuer created
  4. ClusterIssuer가 배포되고 준비되었는지 확인합니다(필드의 값 READY은 True).

    $ kubectl get clusterissuerNAME             READY   AGE
    example-issuer   True    3h9m


ExternalDNS 배포

cert-manager와 마찬가지로 ExternalDNS 프로젝트는 DNS를 관리하기 위해 Cloudflare API 토큰이 필요합니다. 두 프로젝트 모두에 동일한 토큰을 사용할 수 있지만 필수는 아닙니다.

  1. 프로젝트 간 통합을 활성화하기 위해 NGINX Ingress Controller에 대한 ExternalDNS CRD를 생성합니다.

    $ kubectl create -f ./kubernetes-ingress/deployments/common/crds/externaldns.nginx.org_dnsendpoints.yamlcustomresourcedefinition.apiextensions.k8s.io/dnsendpoints.externaldns.nginx.org created
  2. 외부 DNS 서비스( external-dns)를 만듭니다. 매니페스트가 꽤 길기 때문에 여기서는 두 부분으로 나눕니다. 첫 번째 부분은 계정, 역할 및 권한을 구성합니다.

    • DNS를 관리하기 위한 모든 쓰기 및 업데이트 작업을 관리 하는 ServiceAccount 객체를 생성합니다 external-dns.
    • external-dns필요한 권한을 정의하는 ClusterRole 개체( )를 생성합니다 .
    • ClusterRole을 ServiceAccount에 바인딩합니다.
  3. $ kubectl apply -f - <<EOFapiVersion: v1
    kind: ServiceAccount
    metadata:
      name: external-dns
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: external-dns
    rules:
    - apiGroups: [""]
      resources: ["services","endpoints","pods"]
      verbs: ["get","watch","list"]
    - apiGroups: ["extensions","networking.k8s.io"]
      resources: ["ingresses"]
      verbs: ["get","watch","list"]
    - apiGroups: ["externaldns.nginx.org"]
      resources: ["dnsendpoints"]
      verbs: ["get","watch","list"]
    - apiGroups: ["externaldns.nginx.org"]
      resources: ["dnsendpoints/status"]
      verbs: ["update"]
    - apiGroups: [""]
      resources: ["nodes"]
      verbs: ["list","watch"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: external-dns-viewer
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: external-dns
    subjects:
    - kind: ServiceAccount
      name: external-dns
      namespace: default
    EOF
    serviceaccount/external-dns created
    clusterrole.rbac.authorization.k8s.io/external-dns created
    clusterrolebinding.rbac.authorization.k8s.io/external-dns-viewer created

    매니페스트의 두 번째 부분은 ExternalDNS 배포를 생성합니다.

    • ExternalDNS가 도메인을 관리할 때 발생할 수 있는 손상 범위를 제한하는 도메인 필터를 만듭니다. 예를 들어, 프로덕션 환경의 변경을 방지하기 위해 스테이징 환경의 도메인 이름을 지정할 수 있습니다. 이 예에서는 . domain-filter으로 설정합니다 example.com.
    • CF_API_TOKEN환경 변수를 Cloudflare API 토큰으로 설정합니다 . 의 경우 실제 토큰이나 토큰을 포함하는 비밀을 대체합니다. 후자의 경우 환경 변수를 사용하여 비밀을 컨테이너에 프로젝션<your-API-token> 해야 합니다 .
    • FREE_TIER환경 변수를 설정합니다 "true"(유료 Cloudflare 구독이 없는 경우 해당).
  4. $  kubectl apply -f - <<EOF 
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: external-dns
    spec:
      strategy:
        type: Recreate
      selector:
        matchLabels:
          app: external-dns
      template:
        metadata:
          labels:
            app: external-dns
        spec:
          serviceAccountName: external-dns
          containers:
          - name: external-dns
            image: k8s.gcr.io/external-dns/external-dns:v0.12.0
            args:
            - --source=service
            - --source=ingress
            - --source=crd
            - --crd-source-apiversion=externaldns.nginx.org/v1
            - --crd-source-kind=DNSEndpoint
            - --domain-filter=example.com
            - --provider=Cloudflare
            env:
              - name: CF_API_TOKEN
                value: "<your-API-token>"
              - name: FREE_TIER
                value: "true"
    EOF
    serviceaccount/external-dns created
    clusterrole.rbac.authorization.k8s.io/external-dns created
    clusterrolebinding.rbac.authorization.k8s.io/external-dns-viewer created
    deployment.apps/external-dns created


샘플 애플리케이션 배포

테스트 목적으로 Cafe 라는 표준 NGINX Ingress Controller 샘플 애플리케이션을 사용합니다 .

  1. 카페 애플리케이션을 배포합니다.

    $ kubectl apply -f ./kubernetes-ingress/examples/ingress-resources/complete-example/cafe.yamldeployment.apps/coffee created
    service/coffee-svc created
    deployment.apps/tea created
    service/tea-svc created
  2. Cafe 애플리케이션에 NGINX Ingress Controller를 배포합니다. 다음 설정에 유의하세요.

    • kind: VirtualServer – 표준 Kubernetes Ingress 리소스가 아닌 NGINX VirtualServer 사용자 지정 리소스를 사용하고 있습니다.
    • spec.host – cafe.example.com배포하는 호스트의 이름으로 바꾸세요. 호스트는 ExternalDNS로 관리되는 도메인 내에 있어야 합니다.
    • spec.tls.cert-manager.cluster-issuer – 이 게시물에 지정된 값을 사용했다면 이것은 .입니다 . 필요한 경우 Deploy cert‑manager 의 3단계example-issuer 에서 선택한 이름을 대체합니다 .
    • spec.externalDNS.enable – 이 값은 trueExternalDNS에 DNS  A레코드를 생성하도록 지시합니다.
  3. 이 단계를 완료하는 데 걸리는 시간은 DNS 제공자에 따라 크게 달라집니다. Kubernetes는 제공자의 DNS API와 상호 작용하기 때문입니다.

    $ kubectl apply -f - <<EOFapiVersion: k8s.nginx.org/v1
    kind: VirtualServer
    metadata:
      name: cafe
    spec:
      host: cafe.example.com
      tls:
        secret: cafe-secret
        cert-manager:
          cluster-issuer: example-issuer
      externalDNS:
        enable: true
      upstreams:
      - name: tea
        service: tea-svc
        port: 80
      - name: coffee
        service: coffee-svc
        port: 80
      routes:
      - path: /tea
        action:
          pass: tea
      - path: /coffee
        action:
          pass: coffee
    EOF
    virtualserver.k8s.nginx.org/cafe created


솔루션 검증

  1. DNS  A레코드를 확인합니다. 특히 ANSWER SECTION블록에서 FQDN(여기서는 cafe.example.com)이 올바른 IP 주소( www.xxx.yyy.zzz)에 매핑되어 있는지 확인합니다.

    $ dig cafe.example.com 
    ; <<>> DiG 9.10.6 <<>> cafe.example.com
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22633
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
     
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 4096
    ;; QUESTION SECTION:
    ;cafe.example.com.        IN    A
     
    ;; ANSWER SECTION:
    cafe.example.com.    279    IN    A    www.xxx.yyy.zzz
     
    ;; Query time: 1 msec
    ;; SERVER: 2607:fb91:119b:4ac4:2e0:xxxx:fe1e:1359#53(2607:fb91:119b:4ac4:2e0:xxxx:fe1e:1359)
    ;; WHEN: Day Mon  DD hh:mm:ss TZ YYYY
    ;; MSG SIZE  rcvd: 67
  2. 인증서가 유효한지 확인하세요(필드의 값 READY이 True).

    $ kubectl get certificatesNAME          READY   SECRET        AGE
    cafe-secret   True    cafe-secret   8m51s
  3. 신청서에 접속할 수 있는지 확인하세요.

    $ curl https://cafe.example.com/coffeeServer address: 10.2.2.4:8080
    Server name: coffee-7c86d7d67c-lsfs6
    Date: DD/Mon/YYYY:hh:mm:ss +TZ-offset
    URI: /coffee
    Request ID: 91077575f19e6e735a91b9d06e9684cd
    $ curl https://cafe.example.com/tea
    Server address: 10.2.2.5:8080
    Server name: tea-5c457db9-ztpns
    Date: DD/Mon/YYYY:hh:mm:ss +TZ-offset
    URI: /tea
    Request ID: 2164c245a495d22c11e900aa0103b00f


개발자가 NGINX Ingress Controller를 배포하면 어떻게 되나요?

솔루션이 제자리에 놓이면 많은 일이 내부에서 일어납니다. 다이어그램은 개발자가 NGINX VirtualServer 사용자 지정 리소스로 NGINX Ingress Controller를 배포할 때 어떤 일이 일어나는지 보여줍니다. 일부 운영 세부 사항은 생략됩니다.

  1. 개발자는 NGINX CRD를 사용하여 VirtualServer 리소스를 배포합니다.
  2. Kubernetes는 NGINX Ingress Controller를 사용하여 VirtualServer를 생성합니다.
  3. NGINX Ingress Controller는 ExternalDNS를 호출하여 DNS  A레코드를 생성합니다.
  4. ExternalDNS는 ADNS에 레코드를 생성합니다.
  5. NGINX Ingress Controller가 cert-manager를 호출하여 TLS 인증서를 요청합니다.
  6. cert-manager는 DNS-01 챌린지 동안 사용할 DNS 레코드를 추가합니다.
  7. cert-manager 연락처 Let's Encrypt를 사용하여 도전을 완료하세요.
  8. Let's Encrypt는 DNS에 대한 도전을 검증합니다.
  9. Let's Encrypt가 TLS 인증서를 발급합니다
  10. cert-manager는 NGINX Ingress Controller에 TLS 인증서를 제공합니다.
  11. NGINX Ingress Controller는 TLS로 보안된 외부 요청을 애플리케이션 포드로 라우팅합니다.


문제 해결

Kubernetes의 복잡성과 우리가 사용하는 구성 요소를 감안할 때 포괄적인 문제 해결 가이드를 제공하기는 어렵습니다. 그럼에도 불구하고 문제를 파악하는 데 도움이 되는 몇 가지 기본 제안이 있습니다.

  • 배포된 객체의 구성을 검증하려면 kubectl get및 명령을 사용합니다 .kubectl describe
  • 해당 kubectl logs <component>명령을 사용하면 배포된 다양한 구성 요소에 대한 로그 파일을 볼 수 있습니다.
  • K9s를 사용하여 설치를 검사합니다. 소프트웨어는 문제를 노란색 또는 빨간색(심각도에 따라 다름)으로 강조 표시하고 객체에 대한 로그와 세부 정보에 액세스할 수 있는 인터페이스를 제공합니다.




위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요



전문가에게 상담받기

프로필 이미지
관리자
2025-01-17
조회 18

사용자가 찾을 수 없다면 애플리케이션은 목적을 달성할 수 없습니다. 도메인 이름 시스템(DNS)은 도메인 이름을 IP 주소로 변환하여 앱과 웹사이트를 "찾는" 인터넷 기술입니다. DNS는 너무나 널리 퍼져 있고 안정적이어서 대부분의 날은 그것에 대해 생각조차 하지 않습니다. 하지만 DNS 문제가 발생하면 모든 것이 중단됩니다. DNS가 작동하는지 확인하는 것은 현대 애플리케이션, 특히 서비스가 끊임없이 회전하고 중단되는 마이크로서비스 아키텍처에서 매우 중요합니다.

이전 게시물 에서 , 우리는 같은 클러스터에서 실행되는 애플리케이션( 마케팅 앱 의 unit-demo.marketing.net 과 엔지니어링 앱 의 unit-demo.engineering.net )에 해당하는 두 개의 하위 도메인에 대한 DNS 레코드를 정의하는 것에 대해 이야기했고, 같은 클러스터 진입점, 즉 클러스터의 NGINX Ingress Controller의 외부 IP 주소로 해결합니다. SNI(Server Name Indication) 라우팅은 사용자가 요청한 도메인 이름에 따라 적절한 애플리케이션에 대한 연결을 인증하고 라우팅하도록 NGINX Ingress Controller에 구성됩니다.

하지만 많은 조직에서는 해당 사용 사례를 확장하고 클라우드 제공자 지역에 분산될 수 있는 여러 Kubernetes 클러스터에 애플리케이션을 배포해야 합니다. 외부 트래픽이 새로운 클러스터 지역에 도달하려면 해당 지역으로 확인되는 DNS 영역을 만들어야 합니다.

과거에는 이 프로세스에서 타사 공급자(예: GoDaddy 또는 DNSExit)를 사용하여 도메인 레지스트리를 수동으로 만들고 호스트 레코드를 적절히 업데이트해야 했습니다. 이제 ExternalDNS Kubernetes 프로젝트는 Kubernetes 리소스를 퍼블릭 DNS 서버를 통해 검색할 수 있도록 하여 프로세스를 자동화합니다. 즉, Kubernetes API를 사용하여 DNS 공급자 목록을 구성합니다.

ExternalDNS와 NGINX Ingress Controller를 통합하면 DNS 레코드를 관리하여 ADNS 이름이 표준 Kubernetes Ingress 리소스 또는 NGINX VirtualServer 사용자 지정 리소스에 선언된 호스트 이름에서 파생되도록 할 수 있습니다. 개발자와 DevOps 팀은 CI/CD 파이프라인에서 이 통합을 활용하여 NetOps 팀(일반적으로 DNS를 소유함)을 포함하지 않고도 다양한 클러스터에서 애플리케이션을 자동으로 검색할 수 있습니다.

이 게시물에서는 GitHub 저장소 의 샘플 구성 파일을 사용하여 ExternalDNS를 NGINX Ingress Controller와 통합하는 방법을 보여드립니다 .


기본 아키텍처

NGINX Ingress Controller로 ExternalDNS를 구현하기 위해 개발자가 Kubernetes 앱을 외부에 노출하도록 Ingress 컨트롤러를 구성하는 기본 사례부터 시작합니다. 구성된 도메인 이름이 Kubernetes 클러스터의 공개 진입점으로 확인될 때까지 클라이언트는 앱에 연결할 수 없습니다.

NGINX Ingress Controller는 중개자 ExternalDNS Kubernetes 배포를 통해 DNS 공급자와 상호 작용하여 외부 DNS 레코드를 사용하여 Kubernetes 애플리케이션을 자동으로 검색할 수 있습니다. 다이어그램에서 검은색 선은 외부 사용자가 Kubernetes 클러스터에서 애플리케이션에 액세스하는 데이터 경로를 나타냅니다. 보라색 선은 앱 소유자가 NGINX Ingress Controller 구성에서 VirtualServer 리소스로 외부 DNS 레코드를 관리하고 External DNS가 DNS 공급자에 액세스하는 제어 경로를 나타냅니다.

ExternalDNS Kubernetes 배포가 DNS 공급자와 NGINX Ingress Controller와 상호 작용하는 방식을 다이어그램으로 보여줌


ExternalDNS와 NGINX Ingress Controller 통합

ExternalDNS와 NGINX Ingress Controller를 통합하려면 다음 섹션의 단계를 수행하세요.

  • 필수 조건
  • NGINX Ingress Controller 및 ExternalDNS 배포
  • NGINX Ingress 컨트롤러 구성


필수 조건

  1. 최소한 하나의 등록된 도메인을 만드세요. 아래 단계에서 이름을 대체하세요 . ( PCMag의<my‑domain> 이 가이드를 포함하여 도메인을 등록하는 방법에 대한 많은 기사가 있습니다 .)
  2. 매니페스트 또는 Helm 차트를 사용하여 NGINX Ingress Controller를 배포합니다 . 배포 사양에 다음 명령줄 인수 와 동일한 인수를 추가합니다 .

    • -enable-external-dns – ExternalDNS와 통합이 가능합니다.
    • -external-service=nginx-ingress – NGINX Ingress Controller에 DNS 공급자가 관리하는 레코드에 기록하기 위한 공개 진입점을 광고하라고 지시합니다 A. 공개 진입점의 호스트 이름은 외부 서비스로 확인됩니다 nginx-ingress.
  3. 온프레미스에서 Kubernetes 클러스터를 배포하는 경우 외부 로드 밸런서를 프로비저닝합니다. 무료 eBook Get Me to the Cluster 에서 BGP를 사용하여 외부 로드 밸런서로 NGINX를 배포하는 방법에 대한 지침을 제공합니다 . 또는 F5 BIG‑IP 또는 MetalLB를 사용할 수 있습니다 .
  4. 필요한 경우 ExternalDNS에서 지원하는 공급자 에서 DNS 영역을 만듭니다 . 이 명령은 샘플 배포에서 사용된 공급자인 Google Cloud DNS를 위한 것입니다.

    $ gcloud dns managed-zones create "external-dns-<my-domain>" --dns-name "external-dns.<my-domain>." --description "Zone automatically managed by ExternalDNS"


NGINX Ingress Controller 및 ExternalDNS 배포

  1. 샘플 배포를 위해 GitHub 저장소를 복제 하고 NGINX Ingress Controller를 배포합니다.

    $ git clone https://github.com/nginxinc/NGINX-Demos.git && cd NGINX-Demos/external-dns-nginx-ingress/ 
    $ kubectl apply -f nginx-ingress.yaml && kubectl apply -f loadbalancer.yaml
  2. ExternalDNS 배포 사양에서 다음 인수를 업데이트합니다( 샘플 배포의 경우 external-dns-gcloud.yaml 의 59~62행 ):

    • --domain-filter– 이전 섹션의 4단계  에서 생성된 도메인의 이름 (샘플 배포에서 ). 이 도메인만 사용되도록 기존 값을 모두 제거합니다.external-dns.<my-domain>
    • --provider – DNS 제공자(샘플 배포의 경우 googleGoogle DNS용)
    • --google-project– 샘플 배포에 사용하는 Google 프로젝트  의 이름 (Google 프로젝트가 두 개 이상인 경우에만 필수)
    • --txt-owner-id – 선택한 ID(샘플 배포에 고유함).
  3. 참고: ExternalDNS 배포 사양에 포함해야 하는 인수는 선택한 DNS 공급자에 따라 다를 수 있습니다. 다른 DNS 공급자가 있는 클러스터에 ExternalDNS를 배포하는 방법에 대한 자습서 목록은 ExternalDNS 설명서를 참조하세요 .

  4. 클러스터에 ExternalDNS를 배포하고 배포가 성공적으로 실행되는지 확인합니다(출력은 읽기 쉽도록 두 줄로 나누어 표시했습니다).

    $ kubectl apply -f external-dns-gcloud.yaml$ kubectl get pods -o wide
    NAME                                READY  STATUS    ...
    external-dns-4hrytf7f98f-ffuffjbf7  1/1    Running   ...
        ... RESTARTS   AGE
        ... 0          1m


NGINX Ingress 컨트롤러 구성

다음으로, 외부 연결을 Kubernetes 애플리케이션으로 라우팅하는 Ingress 부하 분산 규칙으로 VirtualServer 리소스를 구성합니다.

  1. app-virtual-server.yaml 에서 필드를 설정합니다 host(라인 6):

     6    host: ingress.external-dns.<my-domain>
    

    이 값과 external-dns-gcloud.yamldomain-filter 의 59번째 줄에 있는 값 (이전 섹션의 2단계 에서 설정 ) 간의 매핑은 DNS 레코드의 자동 업데이트를 가능하게 합니다.

  2. app-virtual-server.yaml을 적용 하고 VirtualServer가 올바르게 구성되었는지 확인합니다.

    $ kubectl apply -f app-secret.yaml && kubectl apply -f app-virtual-server.yaml
    $ kubectl get vs 
    NAME   STATE   HOST                              IP            
    cafe   Valid   ingress.external-dns.<my-domain>  34.168.X.Y
  3. DNS 유형 A레코드가 DNS 영역에 추가되었는지 확인합니다. 특히, 필드의 IP 주소는 이전 단계의 명령 출력의 필드 ( NGINX Ingress Controller를 노출하는 유형의 서비스의 외부 IP 주소 또는 온프레미스 배포의 동등한 주소) DATA와 일치 해야 합니다.IPkubectl get vsLoadBalancer

    $ gcloud dns record-sets list --zone external-dns-<my-domain> -name ingress.external-dns.<my-domain> --type ANAME                               TYPE     TTL     DATA
    ingress.external-dns.<my-domain>.  A        300     34.168.X.Y
  4. VirtualServer 호스트 이름을 로컬 머신에서 확인할 수 있는지 확인하려면 DNS 영역(이 경우)에 할당된 이름 서버를 가져옵니다 my-ns-domains.

    $ gcloud dns record-sets list --zone external-dns.<my-domain> --name external-dns.<my-domain>. --type NSNAME                        TYPE      TTL     DATA
    external-dns.<my-domain>.   NS        21600   my-ns-domains
    
    $ dig +short @my-ns-domains ingress.external-dns.<my-domain>
    34.168.X.Y
  5. 이전 단계에서 검색한 DNS 레코드를 등록된 도메인의 전용 네임 서버로 사용합니다. 이렇게 하면 등록된 도메인이 필수 조건 의 4단계 에서 만든 DNS 영역의 부모 영역으로 설정됩니다 .
  6. 이제 VirtualServer 호스트 이름에 글로벌 인터넷에 노출되었으므로 액세스할 수 있는지 확인하세요.

    $ curl -i --insecure https://ingress.external-dns.<my-domain>/teaHTTP/1.1 200 OK
    Server: nginx/1.23.0
    Date: Day, DD MM YYYY hh:mm:ss TZ
    Content-Type: text/plain
    Content-Length: 160
    Connection: keep-alive
    Expires: Day, DD MM YYYY hh:mm:ss TZ
    Cache-Control: no-cache


여러 Kubernetes 클러스터 확장

다이어그램에서 외부 DNS 레코드 생성을 자동화하고 이를 새 클러스터 진입점( Kubernetes Cluster 1 및 Kubernetes Cluster 2 )으로 확인하여 아키텍처를 빠르게 확장하고 여러 클러스터를 자동으로 검색할 수 있습니다. Deploy NGINX Ingress Controller and ExternalDNS 및 Configure NGINX Ingress Controller 의 지침을 반복합니다 .

외부 DNS 레코드 생성을 자동화하고 이를 새 클러스터 진입점으로 확인하는 다이어그램

CI/CD 파이프라인에서 Infrastructure-as-Code 도구를 사용하여 ExternalDNS 및 NGINX Ingress Controller를 사용하여 외부 트래픽에 새 클러스터를 생성하고 노출할 수도 있습니다. 또한 여러 DNS 영역 또는 검색이 활성화된 방식에 따라 여러 DNS 공급자를 관리할 수도 있습니다.

결론

생산성과 침해를 완화하는 보안 조치의 균형을 맞추는 것은 어려울 수 있습니다. DevOps 팀에 제한을 가하면 종종 DevOps 팀과 NetOps/SecOps 팀 간에 마찰이 발생합니다. 이상적인 균형은 각 조직마다 다르며, NGINX는 우선순위와 요구 사항을 준수하는 균형을 확립할 수 있는 유연성을 제공합니다.

과거에 앱 소유자는 NetOps 팀에 의존하여 애플리케이션을 외부 시스템에 연결했습니다. NGINX와 ExternalDNS 통합을 사용하면 개발자와 DevOps 팀이 스스로 발견 가능한 애플리케이션을 배포할 수 있어 혁신을 위한 출시 시간을 단축하는 데 도움이 됩니다.



위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요


전문가에게 상담받기