Kubernetes 보안, 확장성, 안정성, 관찰 가능성 설계된 모던 앱 아키텍처의 예

Sprint 2.0에서 NGINX MARA(Modern Applications Reference Architecture)를 공개했을 때 NGINX의 설계 목표를 앞장서고 있었습니다. Kubernetes에서 실행되고 보안, 확장성, 안정성, 모니터링을 지원하도록 설계된 최신 애플리케이션 아키텍처의 예를 만들고 싶었습니다. 이 프로젝트는 시간 소모적인 통합 노력 없이 기능 구성 요소를 결합하는 “plug and play” 접근 방식을 사용하여 다양한 인프라에 배포할 수 있어야 했습니다.

Sprint 이후 몇 달 동안 로드맵을 진행해 왔습니다. 모든 프로젝트와 마찬가지로 NGINX는 성공과 실패의 몫을 가졌고 점점 더 많은 교훈을 얻으면서 MARA에 성공했습니다. 이러한 문제를 문서화하고 이러한 교훈을 염두에 두고 설계함으로써 다른 사람들이 동일한 문제를 겪지 않도록 할 수 있기를 바랍니다.

최근 프로젝트 디렉토리를 재구성하고 환경을 인스턴스화하고 파괴하는 프로세스를 변경하는 MARA 버전 1.0.0으로 이정표에 도달했습니다. 중복 코드를 제거하고 향후 추가 사항을 쉽게 수용할 수 있는 디렉토리 구조를 만들고 관리 스크립트를 표준화했습니다. 이 버전은 MARA의 역사에서 중요한 지점을 표시하기 때문에 진행 상황을 중단하고 커뮤니티에 다시 보고하고, 배운 더 중요한 교훈 중 일부를 기록하고, 앞으로의 로드맵에 대한 정보를 제공하고자 합니다.

목차

1. 원격 측정(Telemetry) – 메트릭(Metrics), 로깅 및 추적(Tracing)
2. 배포 옵션 – Kubeconfig
3. 파트너와의 협업
4. 지금까지 배운 교훈
5. 향후 계획

1. 원격 측정(Telemetry) – 메트릭(Metrics), 로깅 및 추적(Tracing)

MARA의 핵심 기여자는 대규모로 소프트웨어를 실행한 경험이 있으며 운영, 엔지니어링 및 관리 관점에서 서비스를 제공하는 데 필요한 사항을 이해하고 있습니다. 그들은 응용 프로그램이 오작동할 때 느끼는 침울한 느낌을 알고 있으며 문제가 무엇인지 정확하게 판단할 수 있는 쉬운 방법이 없습니다. DevOps 세계에서 순환하는 인용문은 문제를 간결하게 요약합니다. “Microservices 디버깅은 일련의 살인 미스터리를 푸는 것과 같습니다.”

이를 염두에 두고 단기 로드맵에서 관찰 가능성 추가를 최우선 과제로 삼았습니다. 이 컨텍스트에서 관찰 가능성에는 로그 관리, 메트릭 및 추적 데이터가 포함됩니다. 그러나 데이터를 수집하는 것만으로는 충분하지 않습니다. 데이터를 자세히 살펴보고 환경에서 일어나는 일에 대해 의미 있는 결정을 내릴 수 있어야 합니다.

추적 옵션을 탐색한 결과 원격 분석 데이터, 로그, 메트릭 및 추적의 전체 범위를 지원하기 때문에 OTEL(OpenTelemetry)을 선택하게 되었습니다. 우리는 OTEL 에이전트가 집계 및 내보내기를 위해 OTEL 수집기에 전달하기 전에 모든 추적 데이터를 수집, 처리 및 중복 제거하고 워크플로 끝에 시각화 시스템을 사용하여 데이터를 사용할 수 있도록 하는 구현을 구상했습니다. 이 접근 방식은 사용자에게 데이터 표시 및 분석을 위한 가장 광범위한 선택을 제공하는 동시에 OTEL 표준을 활용하여 초기 단계(수집, 집계 등)를 단순화합니다.

우리는 두 단계로 구현을 구축했습니다.

1. 환경(environment)에서 OTEL 수집기를 관리하기 위해 Kubernetes용 OpenTelemetry Operator 배포

2. 추적(trace) 및 메트릭(metric)을 내보내는 Bank of Sirius 애플리케이션 계측

MARA의 원래 버전은 로깅을 위해 Elasticsearch와 Filebeat를 사용했고, Grafana Loki로 교체하는 것을 고려했지만 당분간 원래 선택을 유지하기로 했습니다. 지표 측면에서 우리는 처음에 사용했던 맞춤형 Prometheus 구성을 완전한 Prometheus 환경을 나타내는 커뮤니티 유지 kube-prometheus-stack Helm 차트로 교체하여 Prometheus 및 Grafana를 기반으로 한 원래 배포를 수정해야 한다는 것을 깨달았습니다. Grafana, 노드 내보내기, Kubernetes 환경 관리에 적합한 일련의 사전 구성된 대시보드 및 스크래핑 대상을 포함합니다. 여기에 NGINX Ingress Controller 및 Bank of Sirius 애플리케이션에 대한 몇 가지 추가 대시보드를 추가했습니다.

이것은 OTEL을 구현하는 데 필요한 엄청난 양의 작업에 대한 간략한 요약일 뿐입니다.

2. 배포 옵션 – Kubeconfig

MARA의 초기 버전에서는 Amazon Elastic Kubernetes Service(EKS)를 배포 환경으로 선택했습니다. 많은 사용자들이 비용상의 이유로 실험실이나 워크스테이션과 같이 리소스가 덜 필요한 “로컬” 환경에서 MARA를 실행하기를 원한다고 말했습니다. 이식성은 원래 프로젝트의 핵심 목표였으므로(지금도 마찬가지입니다), 이것이 우리가 그것을 달성할 수 있음을 증명할 기회였습니다. 작업을 더 쉽게 만들기 위해 몇 가지 최소 요구 사항을 충족하는 모든 Kubernetes 클러스터에서 실행할 수 있는 배포 절차를 설계하기로 결정했습니다.

첫 번째 단계로 Kubernetes 클러스터와 통신하기 위해 kubeconfig 파일을 읽는 새로운 Pulumi 프로젝트를 MARA에 추가했습니다. 이 프로젝트는 Pulumi Kubernetes 프로젝트와 인프라 프로젝트 사이에 있습니다(후자의 예는 AWS 및 DigitalOcean에 대한 프로젝트임). 실용적인 측면에서 kubeconfig 프로젝트를 생성하면 새로운 인프라 프로젝트를 통합하는 데 대한 장벽이 낮아집니다. 인프라 프로젝트가 kubeconfig 파일, 클러스터 이름 및 클러스터 컨텍스트를 kubeconfig 프로젝트에 전달할 수 있으면 나머지 MARA 배포 절차가 원활하게 작동합니다.

테스트를 위해 K3, Canonical MicroK8 및 minikube를 포함하여 CPU 및 메모리 요구 사항이 적은 설치하기 쉬운 여러 Kubernetes 배포를 사용했습니다. 배포판은 모두 2개의 CPU와 16GB RAM이 있는 Ubuntu 21.10을 실행하는 가상 머신(VM)에 배포되었습니다. 또한 모든 배포는 영구 볼륨 및 Kubernetes LoadBalancer 지원을 제공하도록 구성되었습니다.

이 프로세스에서 가장 어려운 부분은 프로젝트의 일부인 맞춤형 NGINX Ingress Controller에 사용되는 비공개 레지스트리로 작업하는 것이었습니다. (Mara를 배포할 때 NGINX 오픈소스 또는 NGINX Plus를 기반으로 하는 표준 NGINX Ingress Controller와 이 맞춤형 NGINX Ingress Controller를 사용할 수 있습니다.) Amazon Elastic Container Registry(ECR)에서 레지스트리 로직을 분리해야 한다는 것을 발견했습니다. ) 보다 플랫폼에 구애받지 않는 접근 방식에 찬성하여 현재 진행 중인 작업입니다. 또한 송신 주소의 호스트 이름을 가져오기 위한 로직이 AWS Elastic Load Balancing(ELB)에 매우 고유하며 다른 사용 사례에 적용하려면 다시 작성해야 한다는 것을 깨달았습니다.

MARA 관리 스크립트와 Pulumi 프로젝트는 현재 위에서 설명한 문제를 해결하기 위해 몇 가지 특정 논리를 사용합니다. 현재 Kubernetes 구성 기반 배포는 공식 NGINX 레지스트리의 NGINX Ingress Controller(NGINX 오픈소스 또는 NGINX Plus 기반)를 사용해야 합니다.

클라우드 기반 배포에 필요한 리소스를 제공하지 않는 로컬 배포를 수용하기 위해 MARA 구성 파일에 몇 가지 조정 매개변수를 추가했습니다. 대부분의 매개변수는 Elastic Stack의 다양한 구성 요소에 대해 요청된 복제본 수와 관련이 있습니다. 테스트가 진행됨에 따라 배포 환경의 리소스 제약 조건에 따라 MARA를 미세 조정하기 위한 추가 매개변수가 있을 것입니다.

이러한 변경 사항을 적용하면 K3, MicroK8 및 Minikube에 성공적으로 배포할 수 있으며 AKS(Azure Kubernetes Service), DigitalOcean, Google Kubernetes Engine, Linode 및 Rancher’s Harvester에서 논리를 성공적으로 테스트했습니다. 자세한 내용은 MARA 제공자 상태 페이지리소스 제약적인 MicroK8s 환경에서 MARA로 배포하는 모범사례를 참조하십시오.

3. 파트너와의 협업

우리의 파트너는 MARA와의 작업을 매우 수용하고 지지해 왔으며, 많은 사람들이 프로젝트에 대해 자세히 알아보기 위해 연락을 취하거나, 제품과 함께 이를 활용하는 방법을 묻거나, 기능을 추가할 수도 있습니다.

우리는 Pulumi를 사용 용이성과 Python 지원을 위해 MARA의 핵심 부분으로 선택했습니다. 후자는 큰 커뮤니티에서 MARA 코드를 쉽게 이해할 수 있는 인기 있는 언어입니다. 또한 Pulumi의 활기찬 커뮤니티와 프로젝트 참여는 MARA를 통해 달성하고자 하는 커뮤니티 참여의 모델이었습니다.

2021년 말, 우리는 NGINX Ingress Controller를 사용하여 MARA를 클라우드 모니터링 솔루션의 일부로 만들기 위해 Sumo Logic과 협력했습니다. 이것은 MARA가 플러그 가능하다는 우리의 주장을 시험할 기회였습니다. 문제는 MARA에서 Grafana, Prometheus 및 Elastic을 Sumo Logic 솔루션으로 대체하는 것이었습니다. 다른 배포에 사용하는 것과 동일한 논리를 사용하여 솔루션을 성공적으로 구축하고 Sumo Logic SaaS에 연결할 뿐만 아니라 환경에서 메트릭을 가져오도록 구성한 것을 기쁘게 생각합니다.

OpenTelemetry 작업의 일환으로 Lightstep과 협력하고 OTEL 수집기를 쉽게 재구성하여 추적 및 메트릭을 Lightstep의 SaaS 제품으로 내보낼 수 있습니다. 이것은 우리가 OTEL이 관측 가능성의 미래라고 굳게 믿기 때문에 우리가 더 조사하기를 열망하는 영역입니다.

4. 지금까지 배운 교훈

지금까지 배운 가장 큰 교훈은 모듈식 접근 방식의 지혜입니다. Sumo Logic과의 작업은 MARA 구성 요소를 성공적으로 혼합하고 일치시킬 수 있음을 보여줍니다. 우리는 OTEL을 환경에 보다 완전히 통합함에 따라 추가 확인을 기대합니다. 우리는 이전에 Elasticsearch를 로그 관리 환경으로 Grafana Loki로 교체하는 것을 고려하고 있다고 언급했는데, 이는 스택의 리소스 풋프린트를 줄이기 때문입니다. 그렇긴 하지만, 우리는 모든 것을 마이크로서비스로 만들어 극단적으로 가기보다는 “실용적인 모듈화”를 옹호합니다. 예를 들어, 많은 애플리케이션의 로그를 처리할 수 있는 전문 서비스를 갖는 것이 합리적이지만 로그 수집, 저장 및 시각화를 위해 별도의 마이크로서비스가 필요하다는 것은 덜 분명합니다.

또한 관련 매개변수를 생략하는 것보다 구성에 명시적으로 포함하여 기본값을 설정하는 것이 도움이 된다는 것을 배웠습니다. 이것은 두 가지 면에서 관리자에게 편리합니다. 기본값을 기억할 필요가 없으며 구성의 올바른 위치에 올바른 구문으로 이미 표시되는 매개변수를 수정하기만 하면 쉽게 변경할 수 있습니다.

우리가 배운 또 다른 고통스러운 교훈은 일부 솔루션이 최고여서가 아니라 설치가 가장 쉽거나 최고의 튜토리얼이 있기 때문에 인기가 있다는 것입니다. 이것이 바로 설계 과정에서 가정에 의문을 제기하고 동료와 상의하는 것이 중요한 이유입니다. 열린 의사 소통의 문화는 문제를 조기에 식별하고 수정하는 데 큰 도움이 됩니다.

즉, 여러 경우에 우리는 효과가 있었지만 우리를 궁지에 몰아넣거나 다른 문제를 일으키는 논리를 구현했습니다. 예를 들어, Pulumi를 통해 애플리케이션 배포를 시작했을 때 Pulumi 변환을 사용하여 변수를 업데이트하는 ConfigMaps용 YAML 매니페스트를 사용했습니다. 이것은 효과가 있었지만 몇 가지 이유로 이상적이지 않았습니다. 그 중 가장 적은 것은 유지 관리 가능성이었습니다. 다음 반복에서는 kube2pulumi를 사용하여 매니페스트를 Pulumi 코드로 변환한 다음 ConfigMap을 빌드하는 데 사용할 수 있도록 하여 코드의 가독성과 유지 관리성을 개선했습니다.

병합이 배포 YAML에 잘못된 설정을 삽입했을 때 또 다른 수업이 시작되었습니다. 우리는 코드가 구문상 올바르고 우리가 원하는 대로 수행되었는지 확인하기 위해 YAML의 많은 부분을 다시 작성하고 신중하게 검토해야 했습니다. 답답하고 시간이 많이 걸리는 프로세스입니다. 향후 문제를 방지하기 위해 이제 GitHub 푸시 프로세스 중에 일반 YAML 및 Kubernetes 관련 린팅 및 유효성 검사를 모두 자동화했습니다.

마지막으로, 메인 라인 분기가 항상 실행 가능하도록 하는 것이 처음부터 우리의 목표였습니다. 새로운 프로젝트를 체크 아웃하고 메인 라인에서 메인테이너가 도입한 문제를 해결해야 할 때 답답합니다. 불행히도 Bank of Sirius 하위 모듈의 다음 예를 포함하여 몇 번 실패했습니다.

  • URL 체계를 ssh://에서 https://로 변경하는 것을 실수로 잊었습니다. 이것은 우리 모두에게 ssh를 사용하여 GitHub에 연결하기 때문에 문제가 되지 않았습니다. 그러나 GitHub용 SSH 키가 없는 사용자는 하위 모듈을 초기화하려고 할 때 오류 메시지가 범람했습니다.
  • 관리 스크립트의 한 릴리스에는 우리의 시스템과 마찬가지로 모든 사람의 시스템에 설치될 것이라고 잘못 가정한 공통 패키지에 대한 종속성이 있었습니다.
  • 시작 논리를 다시 작성하는 동안 하위 모듈 소스를 확인하는 것을 잊었습니다. 하위 모듈에는 Bank of Sirius를 배포하는 데 필요한 매니페스트가 포함되어 있으며, 불행히도 이러한 매니페스트를 사용할 수 없을 때 발생하는 오류 및 경고는 근본 원인을 발견하기 전에 이상한 동작을 디버깅하는 데 며칠에 걸친 여정을 시작하기에 충분히 모호했습니다.

5. 향후 계획

NGINX Ingress Controller 빌드, 레지스트리 푸시, ingress hostname/IP address 로직의 리팩토링을 포함하여 향후 몇 달 간의 개발에 대한 큰 계획이 있습니다.

MARA의 모든 스탠드업에서 우리가 알아차린 한 가지는 NGINX Ingress Controller에 대한 스캔과 공격을 얼마나 빨리 보기 시작한다는 것입니다. 이로 인해 NGINX Ingress Controller와 NGINX App Protect WAF를 MARA에 통합하기 시작했습니다. 이는 App Protect에서 생성된 로깅을 가장 잘 관리하는 방법을 결정해야 하는 도전과 기회를 제공합니다.

앞으로 몇 달 동안 계획하고 있는 또 다른 변경 사항은 모든 모듈이 Pulumi와 Kubernetes가 아닌 Kubernetes에서 비밀을 가져오도록 하는 것입니다. 이는 모든 모듈이 공통 비밀 저장소를 사용하고 관리자에게 비밀이 채워지는 방식을 제어할 수 있음을 의미합니다. 우리는 사용자가 선택한 저장소에서 비밀을 읽고 해당 Kubernetes 비밀을 생성하는 새 모듈을 작성 중입니다.

MARA에는 현재 Bank of Sirius를 포크한 원래 Bank of Anthos 앱과 함께 제공되는 Locust 기반 도구의 업그레이드 및 약간 수정된 버전인 부하 생성 도구가 포함되어 있습니다. 우리가 작성하고 있는 새로운 테스트 도구인 Cicada Swarm은 로드를 생성할 뿐만 아니라 메트릭이 설정한 임계값을 초과할 때 추적하고 보고하므로 클라우드에서 소프트웨어 제품의 신속한 성능 테스트를 위한 프레임워크가 됩니다. 병렬화 기술을 사용하여 필요한 신뢰 수준, 더 높은 정밀도, 사용자 지정 가능한 회귀 분석으로 테스트 결과를 제공하여 CI/CD 파이프라인에서 빌드의 성공 또는 실패를 결정합니다.

마지막으로, 부하 테스트의 영향을 측정하는 방법에 대해 이야기하지 않고는 부하 테스트를 언급할 수 없으며, 이는 원격 분석으로 돌아갑니다. 우리는 OpenTelemetry의 잠재력에 대해 기쁘게 생각하며 곧 더 포괄적인 구현이 이루어지기를 바랍니다. 완전한 구현 없이도 우리의 목표는 테스트를 실행하고, 그 영향을 측정하고, 데이터가 알려주는 내용에 대해 운영상의 결정을 내리는 것입니다.

항상 그렇듯이 pull 요청, 문제 및 의견을 환영합니다. MARA의 목표는 커뮤니티가 함께 협력하여 다양한 잠재적 솔루션을 논의하고, 시도하고, 테스트하고, 반복하도록 영감을 주어 최신 애플리케이션을 배포하고 관리하는 최선의 방법에 대한 이해를 높이는 것입니다.

NGINX의 목표는 MARA를 가능한 한 많은 Kubernetes 사용자에게 최대한 유용하게 만드는 것입니다.