지금, 수백만 명의 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 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
애플리케이션 개발의 궁극적인 목표는 물론 앱을 인터넷에 노출하는 것입니다. 개발자에게 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 설명서를 참조하세요.
$ 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 배포
Helm을 사용하여 NGINX Ingress Controller를 배포합니다. 세 가지 비표준 구성 옵션을 추가하고 있다는 점에 유의하세요 .
controller.enableCustomResources – Helm에 NGINX VirtualServer 및 VirtualServerRoute 사용자 정의 리소스를 생성하는 데 사용되는 사용자 정의 리소스 정의(CRD)를 설치하도록 지시합니다.
controller.enableCertManager – NGINX Ingress Controller를 구성하여 cert-manager 구성 요소와 통신합니다.
controller.enableExternalDNS – Ingress Controller를 구성하여 ExternalDNS 구성 요소와 통신하도록 합니다.
$ 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.
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 으로 제공됩니다 .
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!
Cloudflare API 토큰을 Kubernetes Secret으로 배포하고 다음을 대체합니다 <your-API-token>.
ClusterIssuer 객체를 생성하고 Cloudflare-api-token-secret토큰을 검색할 장소로 (이전 단계에서 정의됨)을 지정합니다. 원하시면 example-issuer필드 metadata.name(및 example-issuer-account-key필드 spec.acme.privateKeySecretRef.name)를 다른 이름으로 바꿀 수 있습니다.
ExternalDNS가 도메인을 관리할 때 발생할 수 있는 손상 범위를 제한하는 도메인 필터를 만듭니다. 예를 들어, 프로덕션 환경의 변경을 방지하기 위해 스테이징 환경의 도메인 이름을 지정할 수 있습니다. 이 예에서는 . domain-filter으로 설정합니다 example.com.
CF_API_TOKEN환경 변수를 Cloudflare API 토큰으로 설정합니다 . 의 경우 실제 토큰이나 토큰을 포함하는 비밀을 대체합니다. 후자의 경우 환경 변수를 사용하여 비밀을 컨테이너에 프로젝션<your-API-token> 해야 합니다 .
FREE_TIER환경 변수를 설정합니다 "true"(유료 Cloudflare 구독이 없는 경우 해당).
테스트 목적으로 Cafe 라는 표준 NGINX Ingress Controller 샘플 애플리케이션을 사용합니다 .
카페 애플리케이션을 배포합니다.
$ 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
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레코드를 생성하도록 지시합니다.
이 단계를 완료하는 데 걸리는 시간은 DNS 제공자에 따라 크게 달라집니다. Kubernetes는 제공자의 DNS API와 상호 작용하기 때문입니다.
사용자가 찾을 수 없다면 애플리케이션은 목적을 달성할 수 없습니다. 도메인 이름 시스템(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와 NGINX Ingress Controller 통합
ExternalDNS와 NGINX Ingress Controller를 통합하려면 다음 섹션의 단계를 수행하세요.
필수 조건
NGINX Ingress Controller 및 ExternalDNS 배포
NGINX Ingress 컨트롤러 구성
필수 조건
최소한 하나의 등록된 도메인을 만드세요. 아래 단계에서 이름을 대체하세요 . ( PCMag의<my‑domain> 이 가이드를 포함하여 도메인을 등록하는 방법에 대한 많은 기사가 있습니다 .)
매니페스트 또는 Helm 차트를 사용하여 NGINX Ingress Controller를 배포합니다 . 배포 사양에 다음 명령줄 인수 와 동일한 인수를 추가합니다 .
-enable-external-dns – ExternalDNS와 통합이 가능합니다.
-external-service=nginx-ingress – NGINX Ingress Controller에 DNS 공급자가 관리하는 레코드에 기록하기 위한 공개 진입점을 광고하라고 지시합니다 A. 공개 진입점의 호스트 이름은 외부 서비스로 확인됩니다 nginx-ingress.
온프레미스에서 Kubernetes 클러스터를 배포하는 경우 외부 로드 밸런서를 프로비저닝합니다. 무료 eBook Get Me to the Cluster 에서 BGP를 사용하여 외부 로드 밸런서로 NGINX를 배포하는 방법에 대한 지침을 제공합니다 . 또는 F5 BIG‑IP 또는 MetalLB를 사용할 수 있습니다 .
필요한 경우 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 배포
샘플 배포를 위해 GitHub 저장소를 복제 하고 NGINX Ingress Controller를 배포합니다.
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(샘플 배포에 고유함).
참고: ExternalDNS 배포 사양에 포함해야 하는 인수는 선택한 DNS 공급자에 따라 다를 수 있습니다. 다른 DNS 공급자가 있는 클러스터에 ExternalDNS를 배포하는 방법에 대한 자습서 목록은 ExternalDNS 설명서를 참조하세요 .
클러스터에 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 리소스를 구성합니다.
app-virtual-server.yaml 에서 필드를 설정합니다 host(라인 6):
6 host: ingress.external-dns.<my-domain>
이 값과 external-dns-gcloud.yamldomain-filter 의 59번째 줄에 있는 값 (이전 섹션의 2단계 에서 설정 ) 간의 매핑은 DNS 레코드의 자동 업데이트를 가능하게 합니다.
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
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
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
이전 단계에서 검색한 DNS 레코드를 등록된 도메인의 전용 네임 서버로 사용합니다. 이렇게 하면 등록된 도메인이 필수 조건 의 4단계 에서 만든 DNS 영역의 부모 영역으로 설정됩니다 .
이제 VirtualServer 호스트 이름에 글로벌 인터넷에 노출되었으므로 액세스할 수 있는지 확인하세요.
다이어그램에서 외부 DNS 레코드 생성을 자동화하고 이를 새 클러스터 진입점( Kubernetes Cluster 1 및 Kubernetes Cluster 2 )으로 확인하여 아키텍처를 빠르게 확장하고 여러 클러스터를 자동으로 검색할 수 있습니다. Deploy NGINX Ingress Controller and ExternalDNS 및 Configure NGINX Ingress Controller 의 지침을 반복합니다 .
CI/CD 파이프라인에서 Infrastructure-as-Code 도구를 사용하여 ExternalDNS 및 NGINX Ingress Controller를 사용하여 외부 트래픽에 새 클러스터를 생성하고 노출할 수도 있습니다. 또한 여러 DNS 영역 또는 검색이 활성화된 방식에 따라 여러 DNS 공급자를 관리할 수도 있습니다.
결론
생산성과 침해를 완화하는 보안 조치의 균형을 맞추는 것은 어려울 수 있습니다. DevOps 팀에 제한을 가하면 종종 DevOps 팀과 NetOps/SecOps 팀 간에 마찰이 발생합니다. 이상적인 균형은 각 조직마다 다르며, NGINX는 우선순위와 요구 사항을 준수하는 균형을 확립할 수 있는 유연성을 제공합니다.
과거에 앱 소유자는 NetOps 팀에 의존하여 애플리케이션을 외부 시스템에 연결했습니다. NGINX와 ExternalDNS 통합을 사용하면 개발자와 DevOps 팀이 스스로 발견 가능한 애플리케이션을 배포할 수 있어 혁신을 위한 출시 시간을 단축하는 데 도움이 됩니다.
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
유효한 SSL/TLS 인증서는 현대 애플리케이션 환경의 핵심 요구 사항입니다. 안타깝게도 애플리케이션을 배포할 때 인증서(또는 인증서) 갱신을 관리하는 것은 종종 뒷전으로 밀려납니다. 인증서는 수명이 제한되어 있으며 DigiCert 인증서의 경우 약 13개월 에서 Let's Encrypt 인증서의 경우 90일 까지 다양합니다 . 안전한 액세스를 유지하려면 이러한 인증서는 만료되기 전에 갱신/재발급해야 합니다. 대부분 운영팀의 업무량이 많기 때문에 인증서 갱신이 간과되는 경우가 종종 있으며, 인증서가 만료 날짜에 가까워지거나 더 나쁜 경우 만료되면 혼란이 발생합니다.
이렇게 될 필요는 없습니다. 약간의 계획과 준비로 인증서 관리를 자동화하고 간소화할 수 있습니다. 여기서는 세 가지 기술을 사용하는 Kubernetes 솔루션을 살펴보겠습니다.
Jetstack의 인증 관리자
Let’s Encrypt
NGINX Ingress 컨트롤러
이 블로그에서는 엔드포인트에 고유하고 자동으로 갱신되고 업데이트된 인증서를 제공하여 인증서 관리를 간소화하는 방법을 알아봅니다.
Kubernetes 환경의 인증서
기술적인 세부 사항을 살펴보기 전에 용어를 정의해야 합니다. "TLS 인증서"라는 용어는 Ingress 컨트롤러에서 HTTPS 연결을 활성화하는 데 필요한 두 가지 구성 요소를 말합니다.
인증서
개인 키
인증서와 개인 키는 모두 Let's Encrypt 에서 발급합니다 . TLS 인증서가 작동하는 방식에 대한 전체 설명은 DigiCert의 게시물 How TLS/SSL Certificates Work를 참조하세요 .
쿠버네티스에서 이 두 구성 요소는 Secrets 로 저장됩니다. NGINX Ingress Controller 및 cert-manager 와 같은 쿠버네티스 워크로드는 이러한 Secrets를 쓰고 읽을 수 있으며, 쿠버네티스 설치에 액세스할 수 있는 사용자도 이를 관리할 수 있습니다.
cert-manager 소개
cert -manager 프로젝트는 Kubernetes 및 OpenShift와 함께 작동하는 인증서 컨트롤러입니다. Kubernetes에 배포하면 cert-manager는 Ingress 컨트롤러에 필요한 인증서를 자동으로 발급하고 유효하고 최신 상태인지 확인합니다. 또한 인증서의 만료 날짜를 추적하고 구성된 시간 간격으로 갱신을 시도합니다. 수많은 공개 및 비공개 발급자와 함께 작동하지만 Let's Encrypt와의 통합을 보여드리겠습니다.
두 가지 도전 유형
Let's Encrypt를 사용하면 모든 인증서 관리가 자동으로 처리됩니다. 이는 많은 편의성을 제공하지만, 다음과 같은 문제도 제기합니다. 이 서비스는 사용자가 문제의 정규화된 도메인 이름(FQDN)을 소유하고 있는지 어떻게 보장합니까?
이 문제는 챌린지를 사용하여 해결되는데 , 챌린지는 특정 도메인의 DNS 레코드에 액세스할 수 있는 사람만 제공할 수 있는 확인 요청에 답해야 합니다. 챌린지는 다음 두 가지 형태 중 하나를 취합니다.
HTTP-01 : 이 챌린지는 인증서를 발급하는 FQDN에 대한 DNS 레코드가 있으면 답변할 수 있습니다. 예를 들어, 서버가 IP www.xxx.yyy.zzz 에 있고 FQDN이 cert.example.com인 경우 챌린지 메커니즘은 www.xxx.yyy.zzz 의 서버에 토큰을 노출하고 Let's Encrypt 서버는 cert.example.com을 통해 해당 토큰에 도달하려고 시도합니다. 성공하면 챌린지가 통과되고 인증서가 발급됩니다.
HTTP-01은 DNS 공급자에 직접 액세스할 필요가 없으므로 인증서를 생성하는 가장 간단한 방법입니다. 이 유형의 챌린지는 항상 포트 80(HTTP)을 통해 수행됩니다. HTTP-01 챌린지를 사용할 때 cert-manager는 Ingress 컨트롤러를 활용하여 챌린지 토큰을 제공합니다.
DNS-01 : 이 챌린지는 토큰이 있는 DNS TXT 레코드를 생성한 다음 발급자가 이를 확인합니다. 토큰이 인식되면 해당 도메인의 소유권을 증명한 것이며 이제 해당 레코드에 대한 인증서를 발급할 수 있습니다. HTTP-01 챌린지와 달리 DNS-01 챌린지를 사용할 때 FQDN은 서버의 IP 주소로 확인할 필요가 없습니다(존재하지 않아도 됩니다). 또한 DNS-01은 포트 80이 차단된 경우에 사용할 수 있습니다. 이러한 사용 편의성의 단점은 cert-manager 설치에 API 토큰을 통해 DNS 인프라에 대한 액세스를 제공해야 한다는 필요성입니다.
인그레스 컨트롤러
Ingress 컨트롤러는 클러스터 외부에서 트래픽을 가져오고, 내부 Pod (하나 이상의 컨테이너 그룹)로 로드 밸런싱하고, 이탈 트래픽을 관리하는 Kubernetes용 전문 서비스입니다. 또한 Ingress 컨트롤러는 Kubernetes API를 통해 제어되며 Pod가 추가, 제거 또는 실패할 때 로드 밸런싱 구성을 모니터링하고 업데이트합니다.
Ingress 컨트롤러에 대해 자세히 알아보려면 다음 블로그를 읽어보세요.
쿠버네티스 네트워킹 101
Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress 컨트롤러 옵션
아래 예에서는 F5 NGINX가 개발하고 유지 관리하는 NGINX Ingress Controller를 사용하겠습니다.
인증서 관리 예제
이러한 예에서는 테스트할 수 있는 작동하는 Kubernetes 설치가 있고 설치가 외부 IP 주소(Kubernetes LoadBalancer 개체)를 할당할 수 있다고 가정합니다. 또한 포트 80과 포트 443(HTTP-01 챌린지 사용 시) 또는 포트 443(DNS-01 챌린지 사용 시)에서 트래픽을 수신할 수 있다고 가정합니다. 이러한 예는 Mac OS X를 사용하여 설명하지만 Linux 또는 WSL에서도 사용할 수 있습니다.
또한 A 레코드를 조정할 수 있는 DNS 공급자와 FQDN이 필요합니다. HTTP-01 챌린지를 사용하는 경우 A 레코드를 추가하는 기능만 있으면 됩니다(또는 사용자를 위해 추가되도록 하면 됩니다). DNS-01 챌린지를 사용하는 경우 지원되는 DNS 공급자 또는 지원되는 웹훅 공급자 에 대한 API 액세스가 필요합니다 .
NGINX Ingress Controller 배포
가장 쉬운 방법은 Helm을 통해 배포하는 것입니다 . 이 배포를 통해 Kubernetes Ingress와 NGINX Virtual Server CRD를 모두 사용할 수 있습니다.
NGINX 저장소를 추가합니다.
$ helm repo add nginx-stable https://helm.nginx.com/stable "nginx-stable" has been added to your repositories
저장소를 업데이트합니다.
$ helm repo update Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "nginx-stable" chart repository
Update Complete. ⎈Happy Helming!⎈
Ingress 컨트롤러를 배포합니다.
$ helm install nginx-kic nginx-stable/nginx-ingress \ --namespace nginx-ingress --set controller.enableCustomResources=true \
--create-namespace --set controller.enableCertManager=true
NAME: nginx-kic
LAST DEPLOYED: Thu Sep 1 15:58:15 2022
NAMESPACE: nginx-ingress
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The NGINX Ingress Controller has been installed.
배포를 확인하고 Ingress 컨트롤러에 대한 egress의 IP 주소를 검색합니다. 유효한 IP 주소 없이는 계속할 수 없습니다.
$ kubectl get deployments --namespace nginx-ingress NAME READY UP-TO-DATE AVAILABLE AGE
nginx-kic-nginx-ingress 1/1 1 1 23s
$ kubectl get services --namespace nginx-ingress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-kic-nginx-ingress LoadBalancer 10.128.60.190 www.xxx.yyy.zzz 80:31526/TCP,443:32058/TCP 30s
DNS A 레코드 추가
여기서의 프로세스는 귀하의 DNS 공급자에 따라 달라집니다. 이 DNS 이름은 Let's Encrypt 서버에서 확인할 수 있어야 하며, 레코드가 전파될 때까지 기다려야 작동할 수 있습니다. 이에 대한 자세한 내용은 SiteGround 문서 DNS 전파란 무엇이며 왜 그렇게 오래 걸리는가? 를 참조하세요.
선택한 FQDN을 확인할 수 있으면 다음 단계로 넘어갈 준비가 된 것입니다.
$ host cert.example.com cert.example.com has address www.xxx.yyy.zzz
cert-manager 배포
다음 단계는 cert-manager의 최신 버전을 배포하는 것입니다. 다시 말하지만, 우리는 배포에 Helm을 사용할 것입니다.
Helm 저장소를 추가합니다.
$ helm repo add jetstack https://charts.jetstack.io "jetstack" has been added to your repositories
저장소를 업데이트합니다.
$ helm repo update Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "nginx-stable" chart repository
...Successfully got an update from the "jetstack" chart repository
Update Complete. ⎈Happy Helming!⎈
cert-manager를 배포합니다.
$ helm install cert-manager jetstack/cert-manager \ --namespace cert-manager --create-namespace \
--version v1.9.1 --set installCRDs=true
NAME: cert-manager
LAST DEPLOYED: Thu Sep 1 16:01:52 2022
NAMESPACE: cert-manager
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
cert-manager v1.9.1 has been deployed successfully!
In order to begin issuing certificates, you will need to set up a ClusterIssuer
or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).
More information on the different types of issuers and how to configure them
can be found in our documentation:
https://cert-manager.io/docs/configuration/
For information on how to configure cert-manager to automatically provision
Certificates for Ingress resources, take a look at the `ingress-shim`
documentation:
https://cert-manager.io/docs/usage/ingress/
배포를 검증합니다.
$ kubectl get deployments --namespace cert-manager NAME READY UP-TO-DATE AVAILABLE AGE
cert-manager 1/1 1 1 4m30s
cert-manager-cainjector 1/1 1 1 4m30s
cert-manager-webhook 1/1 1 1 4m30s
NGINX Cafe 예제 배포
우리는 NGINX Cafe 예제를 사용하여 백엔드 배포 및 서비스를 제공할 것입니다. 이것은 NGINX에서 제공하는 설명서 내에서 사용되는 일반적인 예제입니다. 우리는 이것의 일부로 Ingress를 배포하지 않을 것입니다.
예제 디렉토리로 변경합니다. 이 디렉토리에는 Ingress 컨트롤러의 다양한 구성을 보여주는 여러 예제가 들어 있습니다. 우리는 complete-example 디렉토리에 제공된 예제를 사용하고 있습니다.
$ cd ./kubernetes-ingress/examples/ingress-resources/complete-example
NGINX Cafe 예제를 배포합니다.
$ kubectl apply -f ./cafe.yaml
deployment.apps/coffee created
service/coffee-svc created
deployment.apps/tea created
service/tea-svc created
get 명령을 사용하여 배포 및 서비스를 검증합니다 . Pod가 , 서비스가 로 표시되는지 kubectl확인해야 합니다 . 아래 예는 찾고 있는 것의 대표적인 샘플을 보여줍니다. 이 서비스는 NGINX Cafe 예와 동일한 네임스페이스(기본값)에서 실행되는 시스템 서비스입니다.READYrunningkubernetes
$ kubectl get deployments,services --namespace default NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/coffee 2/2 2 2 69s
deployment.apps/tea 3/3 3 3 68s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/coffee-svc ClusterIP 10.128.154.225 <none> 80/TCP 68s
service/kubernetes ClusterIP 10.128.0.1 <none> 443/TCP 29m
service/tea-svc ClusterIP 10.128.96.145 <none> 80/TCP 68s
ClusterIssuer 배포
cert-manager 내에서 ClusterIssuer를 사용하여 인증서를 발급할 수 있습니다. 이는 모든 네임스페이스에서 참조할 수 있고 정의된 인증서 발급 기관이 있는 모든 인증서 요청에서 사용할 수 있는 클러스터 범위 개체입니다. 이 예에서 Let's Encrypt 인증서에 대한 모든 인증서 요청은 이 ClusterIssuer에서 처리할 수 있습니다.
선택한 챌린지 유형에 대한 ClusterIssuer를 배포합니다. 이 게시물의 범위를 벗어나지만 ClusterIssuer에서 여러 개의 리졸버(선택자 필드에 따라 선택)를 지정할 수 있는 고급 구성 옵션 이 있습니다.
ACME 챌린지 기본 사항
ACME(Automated Certificate Management Environment) 프로토콜은 도메인 이름을 소유하고 있으므로 Let's Encrypt 인증서를 발급받을 수 있는지 확인하는 데 사용됩니다. 이 챌린지의 경우 전달해야 하는 매개변수는 다음과 같습니다.
metadata.name : Kubernetes 설치 내에서 고유해야 하는 ClusterIssuer 이름입니다. 이 이름은 나중에 인증서를 발급할 때 예제에서 사용됩니다.
spec.acme.email : 이것은 인증서를 생성하기 위해 Let's Encrypt에 등록하는 이메일 주소입니다. 이것은 귀하의 이메일이어야 합니다.
spec.acme.privateKeySecretRef : 개인 키를 저장하는 데 사용할 Kubernetes 비밀의 이름입니다.
spec.acme.solvers : 그대로 두어야 합니다. 여기에는 사용하는 챌린지 유형(ACME에서 부르는 대로 솔버)(HTTP-01 또는 DNS-01)과 이를 적용할 Ingress 클래스(이 경우 nginx)가 기록됩니다.
HTTP-01 사용
이 예제에서는 HTTP-01 챌린지를 사용하여 도메인 소유권을 증명하고 인증서를 수신하기 위해 ClusterIssuer를 설정하는 방법을 보여줍니다.
$ kubectl get clusterissuer NAME READY AGE
prod-issuer True 34s
DNS-01 사용
이 예제에서는 DNS-01 챌린지를 사용하여 도메인 소유권을 인증하는 ClusterIssuer를 설정하는 방법을 보여줍니다. DNS 공급자에 따라 토큰을 저장하기 위해 Kubernetes Secret을 사용해야 할 가능성이 높습니다. 이 예제에서는 Cloudflare를 사용합니다 . namespace 사용에 유의하세요. cert-manager 네임스페이스에 배포된 cert-manager 애플리케이션은 Secret에 액세스할 수 있어야 합니다.
이 예시에서는 계정에서 만들 수 있는 Cloudflare API 토큰이 필요합니다 . 이는 아래의 <API Token> 줄에 입력해야 합니다. Cloudflare를 사용하지 않는 경우 공급자의 설명서를 따라야 합니다 .
이 구성의 핵심 부분은 "true"로 metadata.annotations설정하는 곳 입니다 acme.cert-manager.io/http01-edit-in-place. 이 값은 필수이며 챌린지가 제공되는 방식을 조정합니다. 자세한 내용은 지원되는 주석 문서를 참조하세요. 이는 마스터/미니언 설정을 사용하여 처리할 수도 있습니다 .
이는 spec.ingressClassName우리가 설치하여 사용할 NGINX Ingress 컨트롤러를 말합니다.
Kubernetes spec.tls.secretSecret 리소스는 Let's Encrypt에서 인증서가 발급될 때 반환되는 인증서 키를 저장합니다.
우리의 호스트 이름은 및 cert.example.com에 대해 지정됩니다 . 이것은 우리의 ClusterIssuer가 인증서를 발급한 호스트 이름입니다.spec.tls.hostsspec.rules.host
이 spec.rules.http섹션은 경로와 해당 경로에서 요청을 처리할 백엔드 서비스를 정의합니다. 예를 들어, .에 대한 트래픽은 /tea.의 포트 80으로 전송됩니다 tea-svc.
설치에 맞게 위의 매니페스트를 수정하세요. 최소한 spec.rules.host및 spec.tls.hosts값을 변경하는 것이 포함되지만 구성의 모든 매개변수를 검토해야 합니다.
매니페스트를 적용합니다.
$ kubectl apply -f ./cafe-virtual-server.yaml virtualserver.k8s.nginx.org/cafe created
인증서가 발급될 때까지 기다리세요. READY 필드에 대한 "True" 값을 찾고 있습니다.
$ kubectl get certificates NAME READY SECRET AGE
certificate.cert-manager.io/cafe-secret True cafe-secret 37m
NGINX 가상 서버/가상 경로 사용
NGINX CRD를 사용하는 경우 다음 배포 YAML을 사용하여 Ingress를 구성해야 합니다.
실제 인증서와 키를 보고 싶다면 다음 명령을 실행하면 됩니다. (참고: 이는 Kubernetes Secrets의 약점을 보여줍니다. 즉, 필요한 액세스 권한이 있는 사람은 누구나 읽을 수 있습니다.)
$ kubectl get secret cafe-secret -o yaml
Ingress 테스트
인증서를 테스트합니다. 여기서는 원하는 방법을 사용할 수 있습니다. 아래 예에서는 cURL을 사용합니다 . 성공은 서버 이름, 서버의 내부 주소, 날짜, 선택한 URI(경로)(커피 또는 차) 및 요청 ID를 포함하는 이전에 표시된 것과 유사한 블록으로 표시됩니다. 실패는 HTTP 오류 코드의 형태를 띠며, 대부분 400 또는 301입니다.
$ curl https://cert.example.com/tea
Server address: 10.2.0.6:8080
Server name: tea-5c457db9-l4pvq
Date: 02/Sep/2022:15:21:06 +0000
URI: /tea
Request ID: d736db9f696423c6212ffc70cd7ebecf
$ curl https://cert.example.com/coffee
Server address: 10.2.2.6:8080
Server name: coffee-7c86d7d67c-kjddk
Date: 02/Sep/2022:15:21:10 +0000
URI: /coffee
Request ID: 4ea3aa1c87d2f1d80a706dde91f31d54
인증서 갱신
처음에 우리는 이 접근 방식이 인증서 갱신을 관리할 필요성을 없앨 것이라고 약속했습니다. 하지만 아직 그 방법을 설명하지 못했습니다. 왜 그럴까요? 이는 cert-manager의 핵심 내장 부분이기 때문입니다. 이 자동 프로세스에서 cert-manager가 인증서가 없거나 만료되었거나 만료까지 15일 이내이거나 사용자가 CLI를 통해 새 인증서를 요청하는 경우 새 인증서가 자동으로 요청됩니다 . 이보다 더 쉬운 일은 없습니다.
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
사이버 보안 공격의 정교함과 수는 기하급수적으로 증가하고 있으며, 온프레미스, 하이브리드 및 멀티 클라우드 Kubernetes 환경에 배포된 앱에 대한 상당한 노출 위험을 발생시키고 있습니다. 기존 보안 모델은 경계 기반이며, 환경의 보안 경계 내에 위치하는 경우 사용자가 신뢰할 수 있고(그리고 사용자 간의 통신이 안전하다고) 가정합니다. 오늘날의 분산 환경에서 경계 내부의 안전 지대라는 개념은 더 이상 존재하지 않습니다. 환경 "내부"에서 발생하는 통신은 외부 위협만큼 위험할 수 있습니다.
이 블로그에서는 Kubernetes 인프라를 보호하기 위해 Zero Trust 모델을 도입하는 이점과 NGINX가 보안 태세를 개선하는 데 어떻게 도움이 될 수 있는지 알아봅니다.
제로 트러스트란 무엇인가요?
Zero Trust 는 위치가 아닌 신원에 기반한 보안 모델입니다. 이는 요청자가 사내, 원격 또는 클라우드에 있는 것처럼 보이는지 여부에 관계없이 애플리케이션, 데이터 및 장치에 대한 액세스 요청이 공격일 수 있다고 가정합니다.
Zero Trust의 세 가지 핵심 원칙(절대 신뢰하지 말고, 항상 확인하고, 지속적으로 모니터링)을 구현하기 위해 모든 사용자, 서비스, 애플리케이션 및 기기는 지속적으로 인증 및 권한 부여 증명을 제시해야 합니다. 시간 제한 권한은 동적 액세스 정책과 최소 권한 기준에 따라 부여됩니다.
모든 통신은 암호화되고 모든 당사자를 인증하고 동적 액세스 정책에 따라 권한을 부여하는 정책 결정/시행 지점(PDP/PEP)을 통해 라우팅됩니다. 또한 감사, 모니터링, 보고 및 자동화 기능이 보안 위험을 분석, 평가 및 완화하기 위해 마련되어 있습니다.
Zero Trust가 보안 태세를 개선하는 방법
Zero Trust는 여러 가지 방법으로 보안 태세를 개선합니다.
승인되지 않은 활동을 자동으로 차단합니다
노출된 공격 표면을 줄이기 위해 액세스 제어를 시행합니다.
행동 이상 및 침해 지표 감지
액세스 시간을 제한하는 실시간 최소 권한 정책을 정의합니다.
진행 중인 공격을 차단하기 위해 지속적으로 신원을 인증하고 검증합니다.
Zero Trust는 Kubernetes 환경에서 실행되는 최신 클라우드 네이티브 앱에 특히 중요합니다. 느슨하게 결합되고 이식 가능한 분산 앱과 서비스는 컨테이너화되어 위치 기반 보안이 옵션이 아닌 하이브리드, 멀티 클라우드 환경에서 실행됩니다. 보안은 필연적으로 ID 및 권한의 지속적인 검증, 종단 간 암호화 및 모니터링에 달려 있습니다.
제로 트러스트 보안을 달성하는 방법
Zero Trust 원칙을 충족하려면 Kubernetes 환경에서 사용자, 애플리케이션, 서비스에 대한 인증, 권한 부여, 액세스 제어, 정책, 암호화, 모니터링, 감사와 같은 중요한 보안 기능을 제공해야 합니다.
이를 달성할 수 있는 한 가지 가능한 방법은 앱 자체에 보안을 구축하는 것입니다. 그러나 이는 개발자가 신뢰 설정 및 확인, 사용자 ID 및 인증서 관리, 모든 통신 암호화 및 복호화 등을 위한 여러 보안 절차를 구현해야 함을 의미합니다. 또한 TLS 및 Single Sign‑on(SSO)과 같은 타사 기술을 이해하고 통합해야 합니다. 이 모든 것이 이미 복잡한 Kubernetes 배포에 복잡성을 더할 뿐만 아니라 개발자가 집중해야 하는(그리고 원하는!) 것, 즉 앱의 비즈니스 기능을 최적화하는 데 방해가 됩니다.
당황하지 마세요. 더 나은 방법이 있습니다. 보안 및 기타 비기능적 요구 사항을 Kubernetes 인프라로 오프로드하세요! Ingress 컨트롤러 및 서비스 메시와 같은 Kubernetes 클러스터용 연결 도구는 사용자 또는 다른 앱이나 서비스에서 시작된 모든 앱 및 서비스 간 통신을 위한 PDP 및 PEP를 제공할 수 있습니다. 즉, 핵심 비즈니스 전문 지식과 기능에 집중하면서 앱을 더 빠르고 쉽게 제공할 수 있습니다.
F5 NGINX가 어떻게 도움이 될 수 있는지
다음 다이어그램에서 알 수 있듯이, 안전한 Kubernetes 연결을 위한 NGINX 솔루션에는 온프레미스, 하이브리드, 멀티 클라우드 등 모든 환경에서 사용자, 분산 애플리케이션, 마이크로서비스, API를 규모에 맞게, 종단 간 성공적으로 보호하는 데 필요한 모든 인프라 독립적 인 구성 요소와 도구가 포함되어 있습니다. 세계에서 가장 인기 있는 데이터 플레인으로 구동되는 이 솔루션은 다음을 결합합니다.
Kubernetes용 Ingress 컨트롤러이자 타사 ID 및 SSO 공급자와 통합되는 PDP/PEP인 NGINX Ingress Controller . NGINX Plus를 기반으로 하는 NGINX Ingress Controller는 고급 연결, 모니터링 및 가시성, 인증 및 SSO를 처리하고 API 게이트웨이 역할을 합니다.
NGINX Service Mesh는 가볍고 턴키 방식의 개발자 친화적 서비스 메시로 Kubernetes 클러스터 내에서 서비스 연결을 보호합니다. 각 Kubernetes 서비스와 함께 배치된 PDP/PEP 역할을 하는 엔터프라이즈급 사이드카는 NGINX Plus를 기반으로 합니다.
F5의 시장을 선도하는 보안 기술을 기반으로 구축된 최신 앱과 API의 전체적인 보호를 위한 NGINX App Protect . 배포 시나리오의 유연성과 최적의 리소스 활용을 위해 모듈식 접근 방식을 사용합니다.
NGINX App Protect WAF – OWASP Top 10을 보호하고 PCI DDS 규정 준수를 제공하는 강력하고 가벼운 WAF
NGINX App Protect DoS – 클라우드와 아키텍처 전반에 걸쳐 일관되고 적응적인 보호를 제공하는 동작형 DoS 탐지 및 완화
NGINX 솔루션을 사용하면 다음이 가능합니다.
릴리스 속도를 늦추거나 성능을 저하시키지 않고 분산 환경 전반에 강력한 보안 제어를 통합합니다.
지속적인 인증, 신원 검증, 동작 이상 감지를 통해 진행 중인 공격을 자동으로 차단합니다.
여러 팀에 걸쳐 실시간 최소 권한 정책, 세분화된 액세스 제어, 종단 간 암호화 및 거버넌스를 구현합니다.
통합적이고 강력한 WAF 및 앱 수준 DoS 방어 기능을 통해 코드에서 고객에게 앱을 안전하게 제공하세요.
세부적인 실시간 및 과거 지표를 통해 Kubernetes 환경의 보안 태세를 지속적으로 평가하고 개선합니다.
기술 통합을 통해 보안 사용자-서비스 및 서비스-서비스 간 통신 의 배포 및 관리를 간소화합니다.
NGINX로 포괄적인 Zero Trust 보안 구현
조직이 확장됨에 따라 앱의 기능에 국한되지 않은 요구 사항(예: Zero Trust 보안 기능)을 애플리케이션 계층에서 오프로드하는 것이 중요해집니다. 위에서 설명한 대로 이를 통해 개발자는 앱 전체에서 보안 로직을 빌드, 유지 관리 및 복제하는 부담에서 벗어날 수 있습니다. 대신 플랫폼 수준에서 보안 기술을 쉽게 활용할 수 있습니다. NGINX는 NGINX Ingress Controller를 사용하여 클러스터 가장자리에서 Kubernetes에 대한 중앙 집중식 보안 정책 시행을 제공하고 NGINX Service Mesh를 사용하여 클러스터 내에서 Kubernetes에 대한 중앙 집중식 보안 정책 시행을 제공합니다. 앱 보안 요구 사항에 따라 가장자리 또는 클러스터 내에 배포된 NGINX App Protect WAF 및 DoS를 사용하여 정교한 사이버 공격으로부터 고급 애플리케이션 보호 기능을 추가할 수 있습니다.
Kubernetes 배포에 포괄적인 Zero Trust 보안을 구현하는 데 필요한 기능이 NGINX 솔루션에 어떻게 포함되어 있는지 자세히 살펴보겠습니다.
인증 및 권한 부여
Zero Trust 보안의 핵심 원칙 중 하나는 모든 기기, 사용자, 서비스 및 요청이 인증되고 승인된다는 것입니다. 인증은 신원을 확인하는 프로세스입니다. 즉, 통신에 참여하는 각 당사자가 주장하는 대로인지 확인하는 프로세스입니다. 승인은 당사자가 리소스 또는 기능에 대한 액세스 권한이 있는지 확인하는 프로세스입니다.
이 원칙을 해결하기 위해 NGINX 솔루션은 HTTP 기본 인증 , JSON 웹 토큰(JWT) , Okta 및 Azure Active Directory(AD)와 같은 ID 공급자와의 통합을 통한 OpenID Connect를 포함하여 인증 및 권한 부여를 구현하기 위한 여러 옵션을 제공합니다. NGINX 솔루션은 또한 서비스에 보안 ID를 발급합니다(애플리케이션 사용자에게 인증서 형태의 ID가 발급되는 것과 매우 유사). 이를 통해 Kubernetes 클러스터에서 작업을 수행하도록 인증 및 권한 부여를 받을 수 있습니다. 워크로드 ID를 처리하는 것 외에도 NGINX 솔루션은 PKI(공개 키 인프라) 및 인증 기관과의 기본 제공 통합을 통해 인증서 관리를 자동화합니다.
NGINX Ingress Controller는 이미 클러스터에 들어오는 모든 요청을 면밀히 조사하여 적절한 서비스로 라우팅하기 때문에 중앙에서 사용자를 인증하고 권한을 부여하는 데 가장 효율적인 위치이며, 일부 시나리오에서는 서비스를 인증하는 데도 가장 효율적인 위치입니다.
자세한 내용은 블로그에서 Okta와 NGINX Ingress Controller를 사용하여 Kubernetes에 대한 OpenID Connect 인증 구현을 읽어보세요.
데이터 암호화 및 무결성
또 다른 Zero Trust 원칙은 모든 통신이 보안되어야 한다는 것입니다. 즉, 참여자가 어디에 있든 기밀성과 무결성이 유지되어야 합니다. 데이터는 승인되지 않은 당사자가 읽거나 전송 중에 수정되어서는 안 됩니다. 이 원칙을 충족하기 위해 NGINX 솔루션은 사용자-서비스 통신에는 SSL/TLS 암호화를 사용하고 서비스-서비스 통신 에는 상호 TLS(mTLS) 인증 및 암호화를 사용합니다 .
앱 아키텍처가 Kubernetes 클러스터 내에서 서비스 간 통신을 포함하지 않는 경우 NGINX Ingress Controller가 데이터 무결성 요구 사항을 충족하기에 충분할 수 있습니다. 두 가지 기본 옵션이 있습니다.
TLS Passthrough를 사용하면 NGINX Ingress Controller는 SSL/TLS로 암호화된 연결을 서비스에 직접 라우팅하여 암호를 해독하거나 SSL/TLS 인증서나 키에 액세스할 필요가 없습니다.
SSL/TLS 종료를 사용하면 NGINX Ingress Controller가 역방향 프록시 역할을 하여 요청자와의 TLS 연결을 종료한 다음 mTLS 또는 서비스 측 SSL/TLS를 사용하여 Kubernetes 서비스(백엔드 및 업스트림 서버)에 대한 새로운 연결을 암호화합니다.
아키텍처에 클러스터 내에서 서비스 간 통신이 포함되는 경우 데이터 무결성을 위해 NGINX Ingress Controller와 NGINX Service Mesh가 모두 필요합니다. NGINX Service Mesh는 특정 서비스만 서로 통신할 수 있도록 보장하고 mTLS를 사용하여 이를 인증하고 통신을 암호화합니다. NGINX Service Mesh를 사용하여 mTLS를 "제로 터치" 방식으로 구현할 수 있으므로 개발자는 인증서를 사용하여 애플리케이션을 개조하거나 상호 인증이 수행되고 있다는 것을 알 필요가 없습니다.
Kubernetes 클러스터에서 통신을 보호하는 방법에 대한 자세한 내용은 블로그의 NGINX 서비스 메시의 mTLS 아키텍처를 참조하세요.
접근 제어 및 접근 정책
액세스 제어는 Zero Trust 모델의 또 다른 중요한 요소입니다. Kubernetes는 역할 기반 액세스 제어(RBAC)를 사용하여 다양한 사용자에게 제공되는 리소스와 작업을 규제합니다. 이는 사용자 또는 사용자 그룹이 클러스터의 Kubernetes 객체 또는 네임스페이스와 상호 작용할 수 있는 방법을 결정합니다.
NGINX Kubernetes 연결 솔루션은 조직의 보안 정책과 쉽게 일치할 수 있도록 RBAC를 지원합니다. RBAC를 사용하면 사용자는 IT 티켓을 제출하고 처리될 때까지 기다리지 않고도 업무를 수행하는 데 필요한 기능에 대한 게이트형 액세스를 얻을 수 있습니다. RBAC가 없으면 사용자는 필요하지 않거나 권한이 없는 권한을 얻을 수 있으며, 권한이 오용되면 취약성이 발생할 수 있습니다.
NGINX Ingress Controller로 RBAC를 구성하면 조직의 애플리케이션 개발 및 제공 환경에서 다양한 역할에 맞게 권한을 조정하여 여러 사람과 팀의 액세스를 제어할 수 있습니다. 세분화된 액세스 관리 도구를 통해 여러 팀에서 셀프 서비스와 거버넌스를 수행할 수 있습니다.
NGINX Ingress Controller로 RBAC를 활용하는 방법을 알아보려면 DevNetwork, NGINX Ingress Controller를 사용한 고급 Kubernetes 배포에 대한 웨비나를 시청하세요 . 13:50부터 전문가가 보안, 셀프서비스 및 멀티테넌시를 위해 RBAC와 리소스 할당을 활용하는 방법을 설명합니다.
관찰 가능성
감사, 모니터링, 로깅, 추적 및 보고는 Zero Trust 환경에서 핵심 요소입니다. Kubernetes 애플리케이션 인프라의 상태에 대해 더 많은 정보를 수집하고 더 효과적으로 상관 관계를 분석하고 평가할수록 보안 태세를 강화할 수 있습니다.
아마도 Kubernetes 배포에서 모니터링 도구를 이미 사용하고 있을 것이고, 또 다른 도구가 필요하지 않을 것입니다. 클러스터 내부에서 무슨 일이 일어나고 있는지 전체적으로 파악할 수 있도록, JSON을 허용하고 OpenTelemetry , Grafana 및 Prometheus 와 같은 인기 있는 도구와 미리 빌드된 통합을 제공하는 모든 타사 도구에 메트릭을 쉽게 내보낼 수 있도록 NGINX Plus API 를 계측했습니다. 심층 추적을 통해 앱 연결에 대한 타겟팅된 통찰력을 얻을 수 있으므로 요청이 종단 간에 처리되는 방식을 이해할 수 있습니다 . NGINX Ingress Controller는 클러스터와 외부 클라이언트 간의 연결에 대한 통찰력을 제공하는 반면, NGINX Service Mesh는 클러스터 내의 컨테이너화된 마이크로서비스 기반 앱과 서비스 간의 연결을 다룹니다.
WAF 및 DoS 보호
NGINX App Protect를 사용하면 OWASP Top 10 및 Layer 7 서비스 거부(DoS) 공격 과 같은 위협으로부터 분산 애플리케이션을 보호하여 보안을 더욱 강화할 수 있습니다 . 엔드투엔드 NGINX 보안 연결 솔루션 의 필수 구성 요소인 NGINX App Protect는 기본적인 시그니처를 훨씬 넘어서 가장 진보된 위협으로부터 민첩하고 앱 중심의 보안을 제공합니다. F5의 선도적이고 신뢰할 수 있는 보안 전문 지식을 활용하며 릴리스 속도와 성능을 저하시키지 않습니다. 보안 원격 측정을 타사 분석 및 가시성 솔루션으로 쉽게 전달할 수 있으며, 높은 신뢰도 시그니처와 자동화된 동작 분석으로 거짓 양성을 줄입니다.
NGINX App Protect의 모듈식 설계는 필요에 따라 동일하거나 다른 인스턴스에 WAF와 DoS 보호 중 하나 또는 둘 다를 배포할 수 있음을 의미합니다. 예를 들어, 클러스터 가장자리에 NGINX Ingress Controller를 사용하여 배포하기로 결정할 수 있으며, 이는 전체 단일 클러스터에서 일관된 세분화된 보호를 제공하는 데 이상적입니다. 대신 클러스터의 여러 앱에 대한 앱별 정책이 필요한 경우 서비스 또는 포드 수준에서 WAF 및/또는 DoS 보호를 배포할 수 있습니다.
WAF와 DoS 보호 기능을 구축하는 방법에 대한 자세한 내용은 블로그에서 보다 안전한 앱을 위해 보안 도구를 좌측으로 전환을 읽어보세요.
Kubernetes를 위한 NGINX Zero Trust 보안 솔루션 시작하기
Kubernetes 여정의 시작에 있는 사용자이든 오랫동안 Kubernetes를 운영 환경에서 사용해 온 고급 사용자이든, NGINX는 사용자의 요구 사항을 충족하고 보안 태세를 개선하는 데 필요한 포괄적인 도구와 빌딩 블록 세트를 제공합니다
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
조직이 확장됨에 따라 Kubernetes의 개발 및 운영 워크플로는 더욱 복잡해집니다. 각 팀이 자체 클러스터를 갖는 것보다 팀이 Kubernetes 클러스터와 리소스를 공유하는 것이 일반적으로 더 비용 효율적이며 더 안전할 수 있습니다. 그러나 팀이 안전하고 보안적인 방식으로 리소스를 공유하지 않거나 해커가 구성을 악용하는 경우 배포에 심각한 손상이 발생할 수 있습니다.
네트워크 및 리소스 수준에서의 멀티 테넌시 관행과 네임스페이스 격리는 팀이 Kubernetes 리소스를 안전하게 공유하는 데 도움이 됩니다. 또한 테넌트별로 애플리케이션을 격리하여 침해 규모를 크게 줄일 수도 있습니다. 이 방법은 특정 팀이 소유한 애플리케이션의 하위 섹션만 손상될 수 있고 다른 기능을 제공하는 시스템은 그대로 유지되므로 복원력을 높이는 데 도움이 됩니다.
NGINX Ingress Controller는 여러 멀티 테넌시 모델을 지원하지만, 우리는 두 가지 주요 패턴을 봅니다. 인프라 서비스 공급자 패턴은 일반적으로 물리적 격리가 있는 여러 NGINX Ingress Controller 배포를 포함하는 반면, 엔터프라이즈 패턴은 일반적으로 네임스페이스 격리가 있는 공유 NGINX Ingress Controller 배포를 사용합니다. 이 섹션에서는 엔터프라이즈 패턴을 심층적으로 살펴봅니다. 여러 NGINX Ingress Controller를 실행하는 방법에 대한 자세한 내용은 설명서를 참조 하세요 .
NGINX Ingress Controller를 사용한 위임
NGINX Ingress Controller는 표준 Kubernetes Ingress 리소스와 사용자 지정 NGINX Ingress 리소스를 모두 지원하여 보다 정교한 트래픽 관리와 여러 팀에 대한 구성 제어 위임을 모두 가능하게 합니다. 사용자 지정 리소스는 VirtualServer, VirtualServerRoute , GlobalConfiguration , TransportServer 및 Policy 입니다 .
NGINX Ingress Controller를 사용하면 클러스터 관리자는 VirtualServer 리소스를 사용하여 외부 트래픽을 백엔드 애플리케이션으로 라우팅하는 Ingress 도메인(호스트 이름) 규칙을 프로비저닝하고 VirtualServerRoute 리소스를 사용하여 특정 URL의 관리를 애플리케이션 소유자와 DevOps 팀에 위임할 수 있습니다.
Kubernetes 클러스터에서 다중 테넌시를 구현할 때 선택할 수 있는 두 가지 모델이 있습니다. 전체 셀프 서비스 및 제한된 셀프 서비스입니다 .
전체 셀프 서비스 구현
전체 셀프 서비스 모델에서 관리자는 NGINX Ingress Controller 구성의 일상적인 변경에 관여하지 않습니다. 관리자는 NGINX Ingress Controller와 배포를 외부에 노출하는 Kubernetes Service를 배포하는 것에만 책임이 있습니다 . 그런 다음 개발자는 관리자를 포함하지 않고 할당된 네임스페이스 내에서 애플리케이션을 배포합니다. 개발자는 TLS 비밀을 관리하고, 도메인 이름에 대한 부하 분산 구성을 정의하고, VirtualServer 또는 표준 Ingress 리소스를 생성하여 애플리케이션을 노출할 책임이 있습니다.
이 모델을 설명하기 위해 다음 다이어그램에 나와 있는 것처럼 두 개의 하위 도메인 과 를 사용하여 샘플 bookinfo 애플리케이션(원래 Istio에서 생성)을 복제합니다. 관리자가 네임스페이스(녹색으로 강조 표시됨)에 NGINX Ingress Controller를 설치하고 배포하면 DevA(분홍색) 팀과 DevB(보라색) 팀이 자체 VirtualServer 리소스를 만들고 네임스페이스( 각각 및 ) 내에서 격리된 애플리케이션을 배포합니다 .a.bookinfo.comb.bookinfo.comnginx-ingressAB
DevA 팀과 DevB 팀은 도메인에 대한 Ingress 규칙을 설정하여 외부 연결을 해당 애플리케이션으로 라우팅합니다.
a.bookinfo.comTeam DevA는 네임스페이스 의 도메인 에 대한 애플리케이션을 노출하기 위해 다음 VirtualServer 리소스 개체를 적용합니다 A.
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: bookinfo
namespace: A
spec:
host: a.bookinfo.com
upstreams:
- name: productpageA
service: productpageA
port: 9080
routes:
- path: /
action:
pass: productpageA
view rawfull-self-service-vs-a.yaml hosted with ❤ by GitHub
b.bookinfo.com마찬가지로, DevB 팀은 네임스페이스 의 도메인 에 대한 애플리케이션을 노출하기 위해 다음 VirtualServer 리소스를 적용합니다 B.
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: bookinfo
namespace: B
spec:
host: b.bookinfo.com
upstreams:
- name: productpageB
service: productpageB
port: 9080
routes:
- path: /
action:
pass: productpageB
view rawfull-self-service-vs-b.yaml hosted with ❤ by GitHub
제한된 셀프 서비스 구현
제한된 셀프 서비스 모델에서 관리자는 클러스터에 들어오는 트래픽을 적절한 네임스페이스로 라우팅하도록 VirtualServer 리소스를 구성하지만, 네임스페이스의 애플리케이션 구성을 담당 개발 팀에 위임합니다. 이러한 각 팀은 VirtualServer 리소스에서 인스턴스화된 애플리케이션 하위 경로에 대해서만 책임을 지고 VirtualServerRoute 리소스를 사용하여 트래픽 규칙을 정의하고 네임스페이스 내에서 애플리케이션 하위 경로를 노출합니다.
다이어그램에 표시된 것처럼 클러스터 관리자는 nginx-ingress네임스페이스(녹색으로 강조 표시됨)에 NGINX Ingress Controller를 설치 및 배포하고 VirtualServerRoute 리소스 정의를 참조하는 경로 기반 규칙을 설정하는 VirtualServer 리소스를 정의합니다.
/productpage-A이 VirtualServer 리소스 정의는 두 개의 하위 경로에 대한 VirtualServerRoute 리소스 정의를 참조하는 두 개의 경로 기반 규칙을 설정합니다 /productpage-B.
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: example
spec:
host: bookinfo.example.com
routes:
- path: /productpage-A
route: A/ingress
- path: /productpage-B
route: B/ingress
view rawrestricted-self-service-vs.yaml hosted with ❤ by GitHub
네임스페이스AB 의 앱을 담당하는 개발자 팀은 VirtualServerRoute 리소스를 정의하여 네임스페이스 내의 애플리케이션 하위 경로를 노출합니다. 팀은 네임스페이스별로 격리 되고 관리자가 프로비저닝한 VirtualServer 리소스에서 설정한 애플리케이션 하위 경로를 배포하는 것으로 제한됩니다.
Team DevA(다이어그램의 분홍색)는 관리자가 설정한 애플리케이션 하위 경로 규칙을 노출하기 위해 다음 VirtualServerRoute 리소스를 적용합니다 /productpage-A.
apiVersion: k8s.nginx.org/v1
kind: VirtualServerRoute
metadata:
name: ingress
namespace: A
spec:
host: bookinfo.example.com
upstreams:
- name: productpageA
service: productpageA-svc
port: 9080
subroutes:
- path: /productpage-A
action:
pass: productpageA
view rawrestricted-self-service-vsr-a.yaml hosted with ❤ by GitHub
Team DevB(보라색)는 관리자가 설정한 애플리케이션 하위 경로 규칙을 노출하기 위해 다음 VirtualServerRoute 리소스를 적용합니다 /productpage-B.
apiVersion: k8s.nginx.org/v1
kind: VirtualServerRoute
metadata:
name: ingress
namespace: B
spec:
host: bookinfo.example.com
upstreams:
- name: productpageB
service: productpageB-svc
port: 9080
subroutes:
- path: /productpage-B
action:
pass: productpageB
view rawrestricted-self-service-vsr-b.yaml hosted with ❤ by GitHub
VirtualServer 및 VirtualServerRoute 리소스에서 구성할 수 있는 기능에 대한 자세한 내용은 NGINX Ingress Controller 설명서를 참조하세요 .
참고: 병합 가능한 Ingress 유형을 사용하여 크로스 네임스페이스 라우팅을 구성할 수 있지만 제한된 셀프 서비스 위임 모델에서는 이 접근 방식에 VirtualServer 및 VirtualServerRoute 리소스와 비교할 때 세 가지 단점이 있습니다.
보안성이 낮습니다.
Kubernetes 배포가 점점 더 크고 복잡해짐에 따라 병합 가능한 Ingress 유형은 개발자가 네임스페이스 내에서 호스트 이름에 대한 Ingress 규칙을 설정하는 것을 방해하지 않기 때문에 실수로 수정될 가능성이 커집니다.
VirtualServer 및 VirtualServerRoute 리소스와 달리 병합 가능한 Ingress 유형은 기본("마스터") Ingress 리소스가 "미니언" Ingress 리소스의 경로를 제어할 수 있도록 하지 않습니다.
제한된 셀프 서비스 모델에서 Kubernetes RBAC 활용
Kubernetes 역할 기반 액세스 제어(RBAC)를 사용하면 사용자에게 할당된 역할에 따라 네임스페이스 및 NGINX Ingress 리소스에 대한 사용자 액세스를 규제할 수 있습니다.
예를 들어, 제한된 셀프 서비스 모델에서 특별한 권한이 있는 관리자만 VirtualServer 리소스에 안전하게 액세스할 수 있습니다. 해당 리소스는 Kubernetes 클러스터의 진입점을 정의하기 때문에 오용하면 시스템 전체가 중단될 수 있습니다.
개발자는 VirtualServerRoute 리소스를 사용하여 자신이 소유한 애플리케이션 경로에 대한 Ingress 규칙을 구성하므로 관리자는 개발자가 해당 리소스만 만들 수 있도록 하는 RBAC 정책을 설정합니다. 개발자 액세스를 더욱 규제해야 하는 경우 해당 권한을 특정 네임스페이스로 제한할 수도 있습니다.
완전한 셀프 서비스 모델에서 개발자는 VirtualServer 리소스에 안전하게 액세스할 수 있지만, 관리자가 해당 권한을 특정 네임스페이스로 제한할 수도 있습니다.
RBAC 권한 부여에 대한 자세한 내용은 Kubernetes 설명서를 참조하세요 .
정책 추가
NGINX 정책 리소스는 분산 팀이 멀티 테넌시 배포에서 Kubernetes를 구성할 수 있도록 하는 또 다른 도구입니다. 정책 리소스는 OAuth 및 OpenID Connect (OIDC)를 사용한 인증, 속도 제한 및 웹 애플리케이션 방화벽(WAF)과 같은 기능을 활성화합니다. 정책 리소스는 VirtualServer 및 VirtualServerRoute 리소스에서 참조되어 Ingress 구성에서 적용됩니다.
예를 들어, 클러스터에서 ID 관리를 담당하는 팀은 Okta를 OIDC ID 공급자(IdP)로 사용하여 다음과 같이 JSON 웹 토큰 (JWT) 또는 OIDC 정책을 정의할 수 있습니다.
NetOps 및 DevOps 팀은 이 예와 같이 VirtualServer 또는 VirtualServerRoute 리소스를 사용하여 해당 정책을 참조할 수 있습니다.
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: bookinfo-vs
spec:
host: bookinfo.example.com
tls:
secret: bookinfo-secret
upstreams:
- name: backend
service: productpage
port: 9080
routes:
- path: /
policies:
- name: okta-oidc-policy
action:
pass: backend
view rawoidc-vs.yaml hosted with ❤ by GitHub
NGINX Policy, VirtualServer 및 VirtualServerRoute 리소스를 함께 사용하면 관리자가 구성을 다른 팀에 쉽게 위임할 수 있는 분산 구성 아키텍처가 가능합니다. 팀은 네임스페이스 전반에 걸쳐 모듈을 조립하고 안전하고 확장 가능하며 관리하기 쉬운 방식으로 정교한 사용 사례로 NGINX Ingress Controller를 구성할 수 있습니다.
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
NGINX Ingress Controller는 HTTP 트래픽과 함께 TCP 및 UDP 트래픽의 부하를 분산하므로 다음을 포함하여 해당 프로토콜을 기반으로 하는 다양한 앱과 유틸리티의 트래픽을 관리하는 데 사용할 수 있습니다.
MySQL, LDAP 및 MQTT – 많은 인기 있는 애플리케이션에서 사용되는 TCP 기반 앱
DNS, syslog 및 RADIUS – 에지 장치 및 비트랜잭션 애플리케이션에서 사용되는 UDP 기반 유틸리티
NGINX Ingress Controller를 사용한 TCP 및 UDP 로드 밸런싱은 다음과 같은 상황에서 Kubernetes 애플리케이션에 네트워크 트래픽을 분산하는 데도 효과적인 솔루션입니다.
NGINX Ingress Controller가 아닌 엔드투엔드 암호화(EE2E)를 사용하고 애플리케이션이 암호화 및 복호화를 처리하도록 합니다.
TCP 또는 UDP 기반 애플리케이션의 경우 고성능 로드 밸런싱이 필요합니다.
기존 네트워크(TCP/UDP) 로드 밸런서를 Kubernetes 환경으로 마이그레이션할 때 변경 사항을 최소화하려고 합니다.
NGINX Ingress Controller에는 TCP/UDP 부하 분산을 지원하는 두 개의 NGINX Ingress 리소스가 함께 제공됩니다.
GlobalConfiguration 리소스는 일반적으로 클러스터 관리자가 DevOps 팀에서 사용할 수 있는 TCP/UDP 포트( listeners)를 지정하는 데 사용됩니다. 각 NGINX Ingress Controller 배포에는 GlobalConfiguration 리소스가 하나만 있을 수 있습니다.
TransportServer 리소스는 일반적으로 DevOps 팀이 애플리케이션에 대한 TCP/UDP 부하 분산을 구성하는 데 사용됩니다. NGINX Ingress Controller는 관리자가 GlobalConfiguration 리소스에서 인스턴스화한 포트에서만 수신합니다. 이를 통해 포트 간 충돌을 방지하고 DevOps 팀이 관리자가 미리 결정한 안전한 포트만 공개 외부 서비스에 노출하도록 하여 보안 계층을 추가로 제공합니다.
다음 다이어그램은 GlobalConfiguration 및 TransportServer 리소스에 대한 샘플 사용 사례를 보여줍니다. gc.yaml 에서 클러스터 관리자는 GlobalConfiguration 리소스에서 TCP 및 UDP 리스너를 정의합니다. ts.yaml 에서 DevOps 엔지니어는 MySQL 배포로 트래픽을 라우팅하는 TransportServer 리소스에서 TCP 리스너를 참조합니다.
gc.yaml 의 GlobalConfiguration 리소스는 두 개의 리스너를 정의합니다. syslog 서비스에 연결하기 위한 포트 514의 UDP 리스너와 MySQL 서비스에 연결하기 위한 포트 5353의 TCP 리스너입니다.
apiVersion: k8s.nginx.org/v1alpha1
kind: GlobalConfiguration
metadata:
name: nginx-configuration
namespace: nginx-ingress
spec:
listeners:
- name: syslog-udp
port: 541
protocol: UDP
- name: mysql-tcp
port: 5353
protocol: TCP
view rawgc.yaml hosted with ❤ by GitHub
ts.yaml 의 TransportServer 리소스의 6~8행은 gc.yaml 에 이름( mysql-tcp) 으로 정의된 TCP 리스너를 참조하고 , 9~14행은 TCP 트래픽을 업스트림으로 보내는 라우팅 규칙을 정의합니다 mysql-db.
apiVersion: k8s.nginx.org/v1alpha1
kind: TransportServer
metadata:
name: mysql-tcp
spec:
listener:
name: mysql-tcp
protocol: TCP
upstreams:
- name: mysql-db
service: mysql
port: 3306
action:
pass: mysql-db
view rawts.yaml hosted with ❤ by GitHub
rawdata_content_schema이 예에서 DevOps 엔지니어는 MySQL 클라이언트를 사용하여 구성이 제대로 작동하는지 확인합니다. 이는 MySQL 배포 내 데이터베이스 의 테이블 목록이 포함된 출력을 통해 확인됩니다 .
$ echo “SHOW TABLES” | mysql –h <external_IP_address> -P <port> -u <user> –p rawdata_content_schema Enter Password: <password>
Tables_in_rawdata_content_schema
authors
posts
UDP 트래픽을 위한 TransportServer 리소스는 비슷하게 구성됩니다. 전체 예제는 GitHub의 NGINX Ingress Controller repo에서 Basic TCP/UDP Load Balancing을 참조하세요. 고급 NGINX 사용자는 repo의 Support for TCP/UDP Load Balancingstream-snippets 예제 에서 볼 수 있듯이 ConfigMap 키를 사용하여 기본 NGINX 구성으로 TransportServer 리소스를 확장할 수 있습니다 .
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
2021년 8월 Sprint 2.0에서 NGINX Modern Applications Reference Architecture (MARA)를 공개했을 때 우리는 디자인 목표를 솔직하게 밝혔습니다. 우리는 Kubernetes에서 실행되고 보안, 확장성, 안정성, 모니터링 및 내성을 지원하도록 설계된 최신 애플리케이션 아키텍처의 예를 만들고 싶었습니다. 이 프로젝트는 시간 소모적인 통합 노력 없이 기능적 구성 요소를 결합하는 "플러그 앤 플레이" 방식으로 다양한 인프라에 배포할 수 있어야 했습니다.
Sprint 이후 몇 달 동안 우리는 로드맵을 추진해 왔습니다. 다른 프로젝트와 마찬가지로 우리는 성공과 실패를 겪었고, MARA에 성공 사례를 녹여냈으며, 배운 교훈 목록도 계속 늘렸습니다. 이러한 문제를 문서화하고 이러한 교훈을 염두에 두고 설계함으로써 다른 사람들이 같은 문제에 부딪히지 않도록 할 수 있기를 바랍니다.
우리는 최근 MARA 버전 1.0.0 으로 이정표에 도달했습니다 . 이 버전은 프로젝트 디렉토리를 재구성하고 환경을 인스턴스화하고 파괴하는 프로세스를 변경합니다. 중복된 코드를 제거하고, 향후 추가 사항을 쉽게 수용할 수 있는 디렉토리 구조를 만들고, 관리 스크립트를 표준화했습니다. 이 버전은 MARA의 역사에서 중요한 지점을 나타내므로, 우리는 잠시 멈추어 커뮤니티에 진행 상황을 보고하고, 더 중요한 교훈 중 일부라고 생각되는 것을 기록하고, 앞으로의 로드맵에 대한 정보를 제공하고자 했습니다.
원격 측정 – 메트릭, 로깅 및 추적
MARA의 핵심 기여자들은 대규모로 소프트웨어를 실행한 경험이 있으며 운영, 엔지니어링 및 관리 관점에서 서비스를 제공하는 데 필요한 사항을 이해합니다. 그들은 애플리케이션이 제대로 작동하지 않고 문제가 무엇인지 정확히 파악할 수 있는 쉬운 방법이 없을 때 느끼는 침울함을 알고 있습니다. DevOps 세계에 떠도는 인용문은 이 문제를 간결하게 요약합니다. "마이크로서비스 디버깅은 일련의 살인 미스터리를 푸는 것과 같습니다."
이를 염두에 두고, 우리는 단기 로드맵에서 관찰 가능성 추가를 최우선 순위로 삼았습니다. 이 맥락에서 관찰 가능성에는 로그 관리, 메트릭 및 추적 데이터가 포함됩니다. 그러나 데이터 수집만으로는 충분하지 않습니다. 데이터를 파헤치고 환경에서 무슨 일이 일어나고 있는지에 대한 의미 있는 결정을 내릴 수 있어야 합니다.
추적 옵션에 대한 우리의 탐색은 원격 측정 데이터, 로그, 메트릭 및 추적의 전체 범위를 지원하기 때문에 OpenTelemetry (OTEL)로 이어졌습니다. 우리는 OTEL 에이전트가 모든 추적 데이터를 수집, 처리 및 중복 제거한 다음 OTEL 수집기에 전달하여 집계하고 내보내는 구현을 구상했으며, 워크플로 끝에 시각화 시스템을 사용하여 데이터를 사용 가능하게 만들었습니다. 이 접근 방식은 사용자에게 데이터를 표시하고 분석하기 위한 가장 광범위한 선택권을 제공하는 동시에 OTEL 표준을 활용하여 초기 단계(수집, 집계 등)를 간소화합니다.
우리는 두 단계로 구현을 구축했습니다.
환경에서 OTEL 수집기를 관리하기 위해 Kubernetes용 OpenTelemetry Operator를 배포합니다 .
Bank of Sirius 애플리케이션을 도구화하여 추적 및 메트릭을 방출합니다.
MARA의 원래 버전은 로깅을 위해 Filebeat 와 함께 Elasticsearch를 사용했고, Grafana Loki 로 대체하는 것을 고려했지만 , 당장은 원래의 선택을 유지하기로 했습니다. 지표 측면에서, 우리는 처음에 사용했던 맞춤형 Prometheus 구성을 커뮤니티에서 유지 관리하는 kube-prometheus-stack Helm 차트로 대체하여 Prometheus 와 Grafana 에 기반한 원래 배포를 수정해야 한다는 것을 깨달았습니다. 이 차트는 Grafana, 노드 내보내기 , Kubernetes 환경을 관리하는 데 적합한 일련의 미리 구성된 대시보드 및 스크래핑 대상을 포함한 완전한 Prometheus 환경을 구성합니다. 여기에 F5 NGINX Ingress Controller 와 Bank of Sirius 애플리케이션 에 대한 몇 가지 추가 대시보드를 추가했습니다 .
이는 OTEL을 구현하는 데 필요한 엄청난 양의 작업에 대한 간략한 요약일 뿐입니다. 다른 사람들이 같은 가파른 학습 곡선을 오르는 수고를 덜어주기 위해, 저희는 블로그의 Integrating OpenTelemetry into the Modern Apps Reference Architecture – A Progress Report 에서 전체 프로세스를 문서화했습니다 .
배포 옵션 – Kubeconfig
MARA의 초기 버전에서 우리는 배포 환경으로 Amazon Elastic Kubernetes Service (EKS)를 선택했습니다. 그 이후로 많은 사용자가 비용상의 이유로 랩이나 워크스테이션과 같이 리소스가 덜 필요한 "로컬" 환경에서 MARA를 실행하고 싶다고 말했습니다. 이식성은 원래 프로젝트의 핵심 목표였고(지금도 그렇습니다) 이것이 우리가 그것을 달성할 수 있다는 것을 증명할 기회였습니다. 작업을 더 쉽게 하기 위해 우리는 최소 요구 사항을 충족하는 모든 Kubernetes 클러스터에서 실행할 수 있는 배포 절차를 설계하기로 결정했습니다.
첫 번째 단계로, 우리는 Kubernetes 클러스터와 통신하기 위해 kubeconfig 파일을 읽는 새로운 Pulumi 프로젝트를 MARA에 추가했습니다. 이 프로젝트는 Pulumi Kubernetes 프로젝트와 인프라 프로젝트(후자의 예로는 AWS와 Digital Ocean 프로젝트) 사이에 있습니다. 실제적으로 kubeconfig 프로젝트를 만들면 새로운 인프라 프로젝트를 통합하는 데 대한 장벽이 낮아집니다. 인프라 프로젝트가 kubeconfig 파일, 클러스터 이름, 클러스터 컨텍스트를 kubeconfig 프로젝트에 전달할 수 있다면 MARA 배포 절차의 나머지 부분은 원활하게 작동합니다.
테스트를 위해 K3s , Canonical MicroK8s , minikube를 포함하여 CPU와 메모리 요구 사항이 작은 설치하기 쉬운 Kubernetes 배포판을 여러 개 사용했습니다. 배포판은 모두 2개의 CPU 와 16GB RAM이 있는 Ubuntu 21.10을 실행하는 가상 머신(VM)에 배포되었습니다 . 또한 모든 배포판은 영구 볼륨과 Kubernetes LoadBalancer 지원을 제공하도록 구성되었습니다.
이 프로세스에서 가장 어려운 부분은 프로젝트의 일부인 맞춤형 NGINX Ingress Controller에 사용되는 개인 레지스트리로 작업하는 것이었습니다. (Mara를 배포할 때는 NGINX Open Source 또는 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 Open Source 또는 NGINX Plus 기반)를 사용해야 합니다.
클라우드 기반 배포에 필요한 리소스를 제공하지 않는 로컬 배포를 수용하기 위해 MARA 구성 파일에 여러 튜닝 매개변수를 추가했습니다. 대부분의 매개변수는 Elastic Stack 의 다양한 구성 요소에 대해 요청된 복제본 수와 관련이 있습니다 . 테스트가 진행됨에 따라 배포 환경의 리소스 제약 조건에 따라 MARA를 미세 조정하기 위한 추가 매개변수가 있을 것입니다.
이러한 변경 사항을 적용하면 K3s, MicroK8s 및 Minikube에 성공적으로 배포할 수 있으며 Azure Kubernetes Service (AKS), Digital Ocean , Google Kubernetes Engine , Linode 및 Rancher's Harvester 에서 로직을 성공적으로 테스트했습니다 . 자세한 내용은 MARA Provider Status 페이지 와 블로그의 MARA: Now Running on a Workstation Near You를 참조하세요.
파트너와의 협력
저희 파트너들은 MARA와의 협력에 대해 매우 수용적이고 지지적이었습니다. 그들 중 많은 사람들이 이 프로젝트에 대해 자세히 알아보고, 자사 제품에 이를 어떻게 활용할 수 있는지, 심지어 기능을 어떻게 추가할 수 있는지 문의해왔습니다.
우리는 MARA의 핵심 부분으로 Pulumi를 선택했는데 , 사용하기 쉽고 Python을 지원하기 때문입니다. Python은 매우 인기 있는 언어이기 때문에 MARA 코드를 대규모 커뮤니티에서 쉽게 이해할 수 있습니다. 또한 Pulumi의 활기찬 커뮤니티와 프로젝트 참여는 MARA를 통해 이루고자 하는 커뮤니티 참여의 모델이었습니다.
2021년 후반에 우리는 Sumo Logic 과 협력하여 MARA를 NGINX Ingress Controller를 사용한 클라우드 모니터링 솔루션 의 일부로 만들었습니다 . 이것은 MARA가 플러그 가능하다는 우리의 주장을 시험할 기회였습니다. 과제는 MARA에서 Sumo Logic 솔루션을 Grafana, Prometheus, Elastic으로 대체하는 것이었습니다. 우리는 다른 배포에 사용하는 것과 동일한 로직을 사용하여 솔루션을 성공적으로 구축하고 Sumo Logic SaaS에 연결할 뿐만 아니라 환경에서 메트릭을 가져오도록 구성하게 되어 기뻤습니다.
OpenTelemetry와의 작업의 일환으로 Lightstep 과 협업하여 OTEL 수집기를 쉽게 재구성하여 추적 및 메트릭을 Lightstep의 SaaS 오퍼링으로 내보낼 수 있었습니다. 이는 OTEL이 관찰 가능성의 미래라고 굳게 믿기 때문에 더 조사하고 싶은 분야입니다.
지금까지 얻은 교훈
지금까지 우리가 얻은 가장 큰 교훈은 모듈식 접근 방식의 지혜입니다. Sumo Logic과의 작업은 MARA 구성 요소를 성공적으로 혼합하고 일치시킬 수 있음을 보여줍니다. OTEL을 환경에 더욱 완벽하게 통합함에 따라 추가 확인을 기대합니다. 이전에 Elasticsearch를 Grafana Loki로 로그 관리 환경으로 대체하는 것을 고려하고 있다고 언급했는데, 이는 스택의 리소스 사용량을 줄이기 때문입니다. 그럼에도 불구하고 모든 것을 마이크로서비스로 만들어 극단적인 방향으로 가는 것보다는 "실용적인 모듈성"을 옹호합니다. 예를 들어, 많은 애플리케이션의 로그를 처리할 수 있는 전문화된 서비스를 갖는 것이 합리적이지만 로그 수집, 저장 및 시각화를 위해 별도의 마이크로서비스가 필요하다는 것은 덜 분명합니다.
또한 관련 매개변수를 생략하는 것보다 구성에 명시적으로 포함시켜 기본값을 설정하는 것이 도움이 된다는 것을 알게 되었습니다. 이는 관리자에게 두 가지 면에서 편리합니다. 기본값을 기억할 필요가 없고 구성의 올바른 위치에 올바른 구문으로 이미 나타나는 매개변수를 수정하기만 하면 쉽게 변경할 수 있습니다.
우리가 얻은 또 다른 고통스러운 교훈은 일부 솔루션이 최고이기 때문이 아니라 설치하기 가장 쉽거나 튜토리얼이 가장 좋기 때문에 인기가 있다는 것입니다. 이것이 설계 과정에서 가정에 의문을 제기하고 동료와 상의하는 것이 매우 중요한 이유입니다. 개방적인 의사소통 문화는 문제를 일찍 식별하고 해결하는 데 큰 도움이 됩니다.
그럼에도 불구하고, 우리는 여러 차례에 걸쳐 작동했지만 우리를 궁지에 몰거나 다른 문제를 일으킨 로직을 구현했습니다. 예를 들어, Pulumi를 통해 애플리케이션을 배포하기 시작했을 때, 우리는 ConfigMaps 에 YAML 매니페스트를 사용하여 Pulumi 변환을 통해 변수를 업데이트했습니다. 이는 효과가 있었지만, 여러 가지 이유로 이상적이지 않았습니다. 그 중 가장 중요한 이유는 유지 관리성이었습니다. 다음 반복에서 우리는 kube2pulumi를 사용하여 매니페스트를 Pulumi 코드로 변환하여 ConfigMaps를 빌드하는 데 사용할 수 있도록 함으로써 코드의 가독성과 유지 관리성을 개선했습니다 .
또 다른 교훈은 병합이 배포 YAML에 잘못된 설정을 삽입했을 때 시작되었습니다. 우리는 YAML의 큰 부분을 다시 작성하고 신중하게 검토하여 코드가 구문적으로 올바르고 원하는 대로 작동하는지 확인해야 했는데, 이는 좌절스럽고 시간이 많이 걸리는 과정이었습니다. 향후 문제를 피하기 위해 이제 GitHub 푸시 프로세스 중에 일반 YAML과 Kubernetes 특정 린팅 및 검증을 모두 자동화 했습니다 .
마지막으로, 처음부터 우리의 목표는 메인라인 브랜치가 항상 실행 가능하도록 하는 것이었습니다. 새로운 프로젝트를 체크아웃하고 메인라인에서 관리자가 도입한 문제를 해결해야 할 때는 좌절스럽습니다. 안타깝게도, 우리는 이 부분에서 몇 번 실패했는데, 여기에는 Bank of Sirius 하위 모듈의 예도 포함됩니다.
우리는 실수로 URL 스킴을 ssh:// 에서 https:// 로 바꾸는 것을 잊었습니다 . 이것은 우리에게 문제가 되지 않았습니다. 왜냐하면 우리 모두가 sshGitHub에 연결하곤 했기 때문입니다. 그러나 GitHub의 SSH 키가 없는 사용자는 하위 모듈을 초기화하려고 했을 때 오류 메시지에 휩싸였습니다.
관리 스크립트의 한 릴리스에는 모든 사람의 컴퓨터에 설치되어 있기 때문에 우리 컴퓨터에도 설치되어 있을 것이라고 잘못 가정한 공통 패키지에 대한 종속성이 있었습니다.
우리는 시작 로직을 다시 작성하는 동안 하위 모듈 소스에 대한 검사를 넣는 것을 잊었습니다. 하위 모듈에는 Bank of Sirius를 배포하는 데 필요한 매니페스트가 포함되어 있으며, 불행히도 이러한 매니페스트를 사용할 수 없을 때 발생하는 오류와 경고는 우리가 근본 원인을 발견하기 전에 이상한 동작을 디버깅하는 며칠간의 오디세이를 시작하기에 충분히 모호했습니다.
다음은 무엇인가
저희는 향후 몇 달 동안 NGINX Ingress Controller 빌드 리팩토링, 레지스트리 푸시, Ingress 호스트 이름/IP 주소 로직을 포함한 대규모 개발을 계획하고 있습니다.
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의 잠재력에 대해 기대하고 있으며, 곧 더 포괄적인 구현을 구현할 수 있기를 바랍니다. 전체 구현이 없더라도, 우리의 목표는 테스트를 실행하고, 영향을 측정하고, 데이터가 알려주는 내용에 대한 운영 결정을 내리는 것입니다.
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
NGINX Modern Apps Reference Architecture (MARA) 프로젝트를 시작했을 때 , 우리는 이미 플랫폼에 익숙했고 부서 예산으로 비용을 지불할 수 있었기 때문에 AWS를 IaaS 공급자로 선택했습니다. 물론 모든 사람이 같은 경험이나 예산을 가지고 있는 것은 아니며, 여러분 중 많은 분들이 K3s , Canonical MicroK8s , minikube 와 같은 Kubernetes 배포판을 사용하여 로컬에서(랩 기반 환경 또는 워크스테이션에서) MARA를 실행할 수 있는 옵션을 제공해 달라고 요청했습니다 .
여러분의 의견을 듣고, 오늘 MicroK8s에서 MARA를 테스트 했으며, 여러분이 직접 배포할 수 있도록 지침을 제공하게 되어 기쁩니다!
왜 우리는 테스트를 위해 MicroK8s를 선택했을까요? 그것은 MARA에 필요한 DNS, 스토리지, 이탈 기능을 낮은 메모리 Foot-Print로 배포하기 쉬운 모델로 제공하기 때문입니다. MicroK8s를 사용하면 테스트 시나리오를 쉽고 반복적으로 반복하여 합리적인 수준의 성능을 제공하는 배포에 대한 최소 요구 사항을 결정할 수 있습니다.
이 작업이 다른 Kubernetes 배포판의 테스트를 용이하게 할 것으로 기대합니다. 다양한 배포판의 현재 상태에 대한 정보는 GitHub repo를 참조하세요 . 목록에 포함시키고 싶은 선호하는 배포판이 있으면 포크하고 테스트하고 풀 리퀘스트를 생성하세요!
리소스 제약 처리
MARA를 로컬로 실행하는 데 가장 큰 제약은 메모리와 CPU입니다. 예비 테스트 중에 메모리 고갈과 관련된 문제의 대부분이 Elasticsearch와 관련이 있다는 것을 발견했습니다. Kibana는 매우 적은 양의 메모리( 16GB 미만 )가 있는 구성에서는 거의 사용할 수 없습니다. 이 문제를 해결하기 위해 MARA 구성 파일에 전체 Elasticsearch 배포에 일반적으로 있는 중복 보호 기능을 제거하는 설정을 제공했습니다. 이로 인해 실패 모드 수가 늘어나지만 리소스가 제한된 환경에서는 필요한 트레이드오프 입니다.
CPU에 대한 제약은 샘플 Bank of Sirius 애플리케이션 에 부과되는 부하량과 직접 연결됩니다 . MARA 배포에는 Bank of Sirius에 부하를 생성하는 Locust가 포함되어 있으며 , 사용자 수와 새 사용자의 생성 속도에 대한 사용자 제어 설정이 있습니다.
Bank of Sirius의 부하를 늘리면 나머지 시스템에도 영향을 미칩니다. 사용자 Response 속도가 너무 높으면 MARA 성능이 저하되어 구성 요소가 충돌하거나 멈출 가능성이 높습니다. 이러한 동작을 일으키는 값은 사용 가능한 CPU에 따라 다르지만 요구 사항 에 지정된 용량 이상을 사용하여 최대 64명의 사용자와 한 번에 16명의 사용자로 생성된 부하를 처리할 수 있는 배포를 기대할 수 있습니다.
MicroK8s에 MARA 배포
이제 배경 지식을 갖추었으니, MicroK8s에서 MARA를 선보일 준비가 되었습니다!
요구 사항
root최소한 Ubuntu 20.04(Focal) 이상 을 실행하는 시스템(베어메탈 Linux 서버, 가상화 또는 클라우드)에 액세스 :
20GB 디스크
16GB 메모리
4개의 CPU와 동일
MARA에 필요한 모든 라이브러리와 바이너리가 있는 로컬 시스템의 Python 3 가상 환경. Python 3이 아직 설치되지 않았다면 다음 명령을 실행합니다.
MicroK8s의 통합 MetalLB 로드 밸런서가 NGINX Ingress Controller egress에 할당할 최소 하나의 무료 IPv4 주소 . 로컬호스트를 통해 Bank of Sirius 애플리케이션에 액세스하는 경우 사용 가능한 개인 ( RFC 1918 호환) 주소가 허용됩니다. 예를 들어 네트워크가 192.168.100.0/24인 경우 10.10.10.10과 같은 주소를 사용할 수 있습니다.
Pulumi 계정과 액세스 토큰. 아직 없다면 Deploy MARA 의 1단계 에서 만들게 됩니다 .
Pulumi에서는 상태 파일을 S3 호환 객체 저장소나 로컬 파일 시스템에 저장할 수 있지만 MARA에서는 작성 시점에 이를 지원하지 않습니다. 이 제한은 MARA 또는 Pulumi의 향후 릴리스에서 제거될 예정입니다.
프롬프트에서 다음 중 하나를 나타내는 형식의 IP 주소 범위를 지정하세요.X.X.X.X‑X.X.X.Y
개인 IP 주소의 실제 범위(예: 192.168.100.100-192.168.100.110아래에 사용된 값)
단일 개인 IP 주소(예: 192.168.100.100-192.168.100.100)
$ microk8s enable dns storage metallbEnabling DNS
Applying manifest
...
Restarting kubelet
DNS is enabled
Enabling default storage class
...
Storage will be available soon
Enabling MetalLB
Enter each IP address range delimited by comma (e.g. '10.64.140.43-10.64.140.49,192.168.0.105-192.168.0.111'): 192.168.100.100-192.168.100.110
Applying Metallb manifest
...
MetalLB is enabled
MicroK8s가 실행 중인지 확인하세요:
$ microk8s statusmicrok8s is running
high-availability: no
datastore master nodes: 127.0.0.1:19001
datastore standby nodes: none
addons:
enabled:
dns # CoreDNS
ha-cluster # Configure high availability on the current node
metallb # Loadbalancer for your Kubernetes cluster
storage # Storage class; allocates storage from host directory
...
대부분의 유틸리티가 찾을 것으로 예상하는 파일( ~/.kube/config )에 MicroK8s 구성을 로드하고 디렉토리 및 파일에 권장되는 권한을 설정합니다.
복제된 MARA 리포의 루트 디렉토리에서 작업합니다(이전 단계에서 해당 디렉토리를 변경했습니다). MicroK8s 클러스터에 대한 Python 가상 환경을 설정합니다.
$ ./bin/setup_venv.sh
이 명령은 긴 추적을 생성합니다. 오류가 있는 경우 MARA GitHub repo의 알려진 문제/주의 사항 섹션에서 제안 사항을 확인하세요.
Python 가상 환경을 활성화합니다. 이 명령은 PATH가상 환경을 사용하도록 사용자 및 기타 환경 변수를 설정합니다.
$ source ./pulumi/python/venv/bin/activate
MicroK8s 클러스터가 MARA 배포에 맞게 올바르게 구성되었는지 확인하세요.
$ ./bin/testcap.sh
This script will perform testing on the current kubernetes installation using the currently active kubernetes configuration and context.
Any failures should be investigated, as they will indicate that the installation does not meet the minimum set of capabilities required to run MARA.
...
==============================================================
| All tests passed! This system meets the basic requirements |
| to deploy MARA. |
==============================================================
MARA 배치
이 섹션에서 MARA를 배포하는 데 사용되는 스크립트 start.sh는 배포가 성공하기 위해 추가 작업이 필요한 옵션을 수용합니다. 단순성을 위해 여기서는 다음과 같은 기본 배포를 가정합니다.
다른 지원되는 배포 옵션 중 하나가 아닌 kubeconfig 파일을 사용합니다. 다른 옵션에 대한 자세한 내용은 GitHub repo의 시작 가이드를 참조하세요.
우리가 MARA를 테스트한 NGINX 오픈 소스의 최신 버전을 사용합니다(반드시 최신 버전일 필요는 없습니다).
NGINX Open Source 기반의 NGINX Ingress Controller를 사용합니다. NGINX Plus 기반의 NGINX Ingress Controller를 사용하려면 Kubernetes 클러스터의 F5 Docker 레지스트리에서 NGINX Plus 기반 이미지를 사용해야 합니다. 자세한 내용은 아래 3단계NOTICE! 의 첫 번째를 참조하세요.
단일 표준 Kubernetes 컨텍스트를 사용합니다. NOTICE!3단계의 두 번째를 참조하세요.
MicroK8s 클러스터에 MARA 배포:
스크립트를 실행합니다 start.sh.
아직 Pulumi를 사용하도록 워크스테이션을 구성하지 않은 경우 Pulumi에 로그인하라는 메시지가 표시되고(필요한 경우 계정 생성) Pulumi 계정과 연결된 API 토큰을 입력하라는 메시지가 표시됩니다.
$ ./bin/start.shAdding to [/home/ubuntu/kic-reference-architectures/bin/venv/bin] to PATH
Manage your Pulumi stacks by logging in.
Run `pulumi login --help` for alternative login options.
Enter your access token from https://app.pulumi.com/account/tokens
or hit <ENTER> to log in using your browser : <token>
Please read the documentation for more details.
배포 유형을 선택하고 k프롬프트에 입력하여 kubeconfig 파일로 배포를 빌드합니다. makeDocker가 설치되지 않았다는 경고는 무시합니다. 대신 배포는 레지스트리의 NGINX Ingress Controller 이미지를 사용합니다.
Type a for AWS, k for kubeconfig? k
Calling kubeconfig startup script
make is not installed - it must be installed if you intend to build NGINX Kubernetes Ingress Controller from source.
docker is not installed - it must be installed if you intend to build NGINX Kubernetes Ingress Controller from source.
프롬프트에서 생성할 Pulumi 스택의 이름을 지정합니다(여기서는 mara). Pulumi 계정 내에서 고유해야 합니다.
Enter the name of the Pulumi stack to use in all projects: maraSubmodule source found
Configuring all Pulumi projects to use the stack: mara
Created stack 'mara'
NOTICE! Currently the deployment via kubeconfig only supports pulling images from the registry! A JWT is required in order to access the NGINX Plus repository. This should be placed in a file in the extras directory in the root, in a file named jwt.token
See https://docs.nginx.com/nginx-ingress-controller/installation/using-the-jwt-token-docker-secret/ for more details and examples.
No JWT found; writing placeholder manifest
NOTICE! When using a kubeconfig file you need to ensure that your environment is configured to connect to Kubernetes properly. If you have multiple kubernetes contexts (or custom contexts) you may need to remove them and replace them with a simple ~/.kube/config file. This will be addressed in a future release.
프롬프트에서 kubeconfig 파일의 전체 경로와 클러스터 이름을 지정합니다. 여기에 있습니다 ./home/<username>/.kube/configmicrok8s-cluster
Provide an absolute path to your kubeconfig filevalue: /home/<username>/.kube/config
Provide your clustername
value: microk8s-cluster
Attempting to connect to kubernetes cluster
다음 프롬프트에서 클러스터의 정규화된 도메인 이름(FQDN)을 지정합니다. 스크립트는 FQDN을 두 가지 목적으로 사용합니다. NGINX Ingress Controller를 구성하고 자체 서명된 인증서를 만드는 것입니다(두 번째 용도는 값이 IP 주소가 될 수 없음을 의미합니다). 다른 FQDN을 대체하는 경우 mara.example.com다음 단계에서도 사용해야 합니다.
Create a fqdn for your deploymentvalue: mara.example.com
Grafana 관리자 비밀번호를 지정하세요:
Create a password for the grafana admin user; this password will be used to access the Grafana dashboardThis should be an alphanumeric string without any shell special characters; it is presented in plain text due to current limitations with Pulumi secrets. You will need this password to access the Grafana dashboard.
value: <password>
설치 과정의 흔적이 나타나며 각 단계에 대한 다음 정보가 표시됩니다.
단계에서 수행되는 주요 작업을 설명하는 배너(예: LogstoreElasticsearch 배포 시작을 알림)
Pulumi가 수행할 작업 목록
각 Pulumi 작업에 대한 실시간 상태 표시기
예를 들어 Pulumi 및 MARA에서 생성된 진단은 정의된 호스트 이름 및 IP 주소입니다.
영향을 받는 자원의 수
경과 시간
마지막 단계(Bank of Sirius의 경우)가 완료되면 추적에서는 MetalLB가 NGINX Ingress Controller에 할당한 IP 주소(여기 192.168.100.100)와 배포를 위해 선택한 FQDN(여기 mara.example.com)을 배포에 대한 기타 정보와 함께 보고합니다.
The startup process has finished successfully
Next Steps:
1. Map the IP address (192.168.100.100) of your Ingress Controller with your FQDN (mara.example.com).
2. Use the ./bin/test-forward.sh program to establish tunnels you can use to connect to the management tools.
3. Use kubectl, k9s, or the Kubernetes dashboard to explore your deployment.
To review your configuration options, including the passwords defined, you can access the pulumi secrets via the following commands:
Main Configuration: pulumi config -C /jenkins/workspace/jaytest/bin/../pulumi/python/config
Bank of Sirius (Example Application) Configuration: pulumi config -C /jenkins/workspace/jaytest/bin/../pulumi/python/kubernetes/applications/sirius
K8 Loadbalancer IP: kubectl get services --namespace nginx-ingress
Please see the documentation in the github repository for more information
이전 단계에서 보고된 FQDN과 IP 주소 간의 매핑을 FQDN을 확인하는 데 사용하는 도구(로컬 /etc/hosts 파일 또는 DNS 서버 등)에서 만듭니다 .
MARA 배포에 대한 요청이 성공했는지 확인합니다. 자체 서명된 인증서를 수락하도록 -k옵션을 포함합니다 curl. 인증서에 대한 자세한 정보를 표시하려면 옵션 을 추가합니다 -v.
브라우저에서 https://mara.example.com 으로 이동하여 Bank of Sirius 웹사이트를 표시합니다. 이 글을 쓰는 시점에서 많은 브라우저(Firefox 및 Safari 포함)에서는 자체 서명 인증서를 사용하여 사이트에 대한 경고를 안전하게 클릭할 수 있습니다. Chrome을 사용하지 않는 것이 좋습니다. 최근 보안 변경으로 인해 사이트에 액세스하는 것이 금지될 가능성이 높습니다.
스크립트를 실행하여 test-forward.shKubernetes 포트 포워딩을 설정하여 MARA 관리 제품군( Elasticsearch , Grafana , Kibana , Locust , Prometheus )의 도구에 액세스할 수 있습니다 . 스크립트는 적절한 서비스 이름을 결정하고 kubectl명령을 실행하여 로컬 포트로 전달합니다.
참고: 포트 포워딩이 제대로 작동하려면 브라우저가 이 명령을 실행하는 명령 셸과 동일한 시스템에서 실행 중이어야 합니다. 그렇지 않은 경우(예: 가상화 환경을 사용하는 경우) 명령은 성공한 것처럼 보이지만 포트 포워딩은 실제로 작동하지 않습니다. 자세한 내용은 GitHub 리포지토리에서 MARA의 관리 도구 액세스를 참조하세요.
그게 다입니다! 이 지침을 따르면 약 20분 이내에 사용자 환경에서 작동하는 MARA 배포가 실행됩니다. 이 시점에서 다른 Kubernetes 애플리케이션과 마찬가지로 Bank of Sirius 애플리케이션과 상호 작용할 수 있습니다. 시작하기에 좋은 방법은 내장된 관찰 도구를 사용하여 Locust로 다양한 양의 부하를 생성할 때 환경이 어떻게 작동하는지 테스트하는 것입니다.
우리의 목표는 가능한 한 많은 Kubernetes 사용자에게 MARA를 최대한 유용하게 만드는 것입니다. 일부 구성 요소에 대한 선택 사항이 마음에 들지 않으신가요? 구성 요소를 대체하고 공유하고 싶으시다면 풀 리퀘스트를 여는 것을 권장합니다. 또한, 우리의 repo의 Issues and Discussions 페이지 에서 생각을 공유하고 질문을 해주세요. 의심스러운 가정에 대한 질문도 포함됩니다.
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
NGINX에서는 지난 몇 년 동안 애플리케이션을 진정으로 현대적이고 적응적으로 만들어야 할 필요성에 대해 논의해 왔습니다 . 즉, 이식성, 클라우드 네이티브, 복원성, 확장성 및 업데이트 용이성을 갖춰야 합니다. 최근에는 현대적 앱의 생성과 제공을 용이하게 하는 두 가지 개념이 대두되었습니다. 첫 번째는 Platform Ops 로, 기업 수준의 플랫폼 팀이 개발 및 DevOps 팀이 업무를 수행하는 데 필요한 모든 도구를 큐레이션, 유지 관리, 연결 및 보안합니다. 두 번째는 Shifting Left로 , 개발 라이프사이클의 초기 단계에서 프로덕션 등급 보안, 네트워킹 및 모니터링을 애플리케이션에 통합하는 것을 의미합니다. 개발자는 이전에 ITOps에 속했던 기능에 대한 책임이 더 커지지만 동시에 해당 기능을 구현하는 방법에 대한 선택권과 독립성이 더 커집니다.
좋은 말처럼 들리지만, 실제로 Platform Ops를 구현하고 인프라와 운영 툴링을 "좌측으로 이동"하는 것은 어렵습니다. 우선, 점점 더 많은 앱이 컨테이너화된 환경에서 고도로 분산된 방식으로 배포되고 있으며, 증가하는 수의 Kubernetes 오케스트레이션 엔진 중 하나를 사용하고 있습니다. 또한 기업은 클라우드 간 및 클라우드와 온프레미스 환경 간의 차이에 얽매이지 않고 여러 환경에 앱을 배포하고자 합니다.
현대 앱을 위한 "황금 이미지"
당연히 그렇듯이, 우리의 고객과 커뮤니티는 직면한 과제에 대한 도움을 계속 요청합니다. 그들은 모든 좋은 것을 원하지만, 보안, 네트워킹, 관찰 가능성 및 성능 모니터링, 확장 등 모든 부분을 하나로 모으려면 실제 작업이 필요합니다. 프로덕션 환경에 충분히 견고한 결과 플랫폼을 만들려면 더 많은 작업이 필요합니다. 그들은 "단일 리포에서 실행할 수 있는 최신 앱에 대한 '골든 이미지'가 없는 이유는 무엇일까?"라고 궁금해합니다.
좋은 질문이고, 우리는 좋은 답을 내는 것을 우리만의 과제로 삼았습니다. 첫째, 우리는 질문을 더 구체적으로 재구성했습니다. 우리는 고객과 커뮤니티가 다음과 같은 질문을 하고 있다고 생각합니다. "다양한 소프트웨어 제품을 더욱 응집력 있는 전체로 통합하고, 스택을 조정하여 올바른 구성과 설정을 확정하고, 작업과 수고를 덜어줄 수 있나요? 그리고 기본 서비스와 기능의 차이로 인해 주요 구성을 변경하지 않고도 다양한 클라우드에서 애플리케이션을 실행하기 쉽게 만들어줄 수 있나요?"
우리는 이러한 질문을 전체 커뮤니티에 유익한 것으로 진정으로 해결하는 솔루션을 봅니다. 수백 개의 기업과 모든 주요 클라우드 공급업체의 파트너뿐만 아니라 진정으로 제로섬이 아닌 승리입니다. 이상적으로는 솔루션이 "장난감"이 아니라 견고하고 테스트되었으며 Kubernetes 환경에서 실행되는 라이브 프로덕션 애플리케이션에 배포할 준비가 된 코드입니다. 그리고 솔직히 말해서, 우리는 누구나 GitHub에서 바로 우리의 작업을 훔칠 수 있기를 바랍니다.
요점은, 오늘 NGINX Sprint 2.0 에서 우리는 솔루션 출시를 발표합니다. 모던 앱 레퍼런스 아키텍처 (MARA)의 첫 번째 반복, 모던 앱을 위한 오픈 소스 아키텍처 및 배포 모델입니다. 여러분이 좋아하고, 사용하고, 훔치고, 더 나은 방법으로 개선하거나 사용자 지정하기 위해 수정하거나 포크하기를 바랍니다. 이 게시물은 우리가 무엇을 만들고 어떻게 작동하는지 살펴봅니다.
현대적 적응형 애플리케이션 정의
먼저, 이상적인 현대적이고 적응적인 애플리케이션을 정의해 보겠습니다. 마이크로서비스로 구성되고, 컨테이너화되고, 클라우드 네이티브 디자인 원칙(느슨하게 결합되고, 확장하기 쉽고, 인프라에 묶이지 않음)을 준수할 수 있지만 반드시 그럴 필요는 없습니다. 현대 애플리케이션의 정신의 일부는 인프라 추상화를 활용하도록 특별히 설계하는 것입니다. 이 정의는 간단하지만 모든 참조 아키텍처에 대한 기본 템플릿을 확립하기 때문에 중요합니다.
최신 애플리케이션 아키텍처의 핵심 요소로는 이식성, 확장성, 복원성, 민첩성이 있습니다.
이동성 – 다양한 유형의 기기와 인프라, 퍼블릭 클라우드와 온프레미스에 애플리케이션을 쉽게 배포할 수 있습니다.
확장성 – 앱은 전 세계 어디에서나 수요의 급증이나 감소에 맞춰 신속하고 원활하게 확장하거나 축소할 수 있습니다.
복원성 – 앱은 다양한 가용성 지역, 클라우드 또는 데이터 센터에 있는 새로 구동된 클러스터나 가상 환경으로 우아하게 장애 조치(failover)할 수 있습니다.
민첩성 – 앱은 자동화된 CI/CD 파이프라인을 통해 빠르게 업데이트될 수 있습니다. 최신 앱의 경우 이는 더 빠른 코드 속도와 더 빈번한 코드 푸시를 의미합니다.
참조 아키텍처 설계
우리는 최신 앱 정의와 배포 패턴의 기본 요구 사항을 충족하는 플랫폼을 만들고 싶었습니다. 기술적 목표 외에도 최신 앱 디자인 원칙을 설명하고 커뮤니티가 Kubernetes에서 배포하도록 장려하고 싶었습니다. 그리고 물론, 개발자, DevOps 및 Platform Ops 팀이 놀고, 수정하고, 개선할 수 있는 "훔칠 수 있는" 코드를 제공하고 싶었습니다. 간단히 말해서, 우리는 다음을 제공하고 싶었습니다.
장난감이 아닌 쉽게 배포 가능하고 프로덕션에 적합한 Kubernetes 아키텍처
Kubernetes에서 파트너 제품이 작동하는 방식을 강조하는 플랫폼
Kubernetes Ingress 컨트롤러를 쉽게 빌드하고 배포할 수 있는 푸시 버튼
향후 제품 및 제휴 통합을 위한 테스트 환경
플러그형 배포 프레임워크
발견 및 채택을 단순화하는 오픈 소스 코드의 단일 리포
플랫폼의 첫 번째 버전을 위해 내린 디자인과 파트너십 선택 사항은 다음과 같습니다(다음 버전에 대한 계획은 버전 2의 Many More Integrations and More Flexibility 참조 ). 우리는 레퍼런스 앱을 파트너에게 포괄적으로 만드는 것이 파트너와 커뮤니티 참여를 촉진하는 데 중요하다고 굳게 믿습니다.
오픈 소스 개발 – https://github.com/nginxinc/kic-reference-architectures/ ; NGINX/F5 커뮤니티와 협력하여 리포를 구축했습니다.
배포 대상 – Amazon Elastic Kubernetes Service (EKS)
Infrastructure-as-Code 자동화 – Python 및 Pulumi 는 거의 모든 인기 있는 코딩 언어에서 Terraform 레시피 및 자동화 스크립트를 허용합니다.
Ingress Controller 이미지 – 구독자를 위해 사전 빌드된 NGINX Plus , DockerHub에서 사전 빌드된 NGINX Open Source , 소스에서 빌드된 두 버전
로그 관리(저장 및 분석) – Elastic , 사용자들에게 매우 인기가 많기 때문에
성능 모니터링 및 대시보드 – Prometheus 및 Grafana
지속적인 개발(CD) – Spinnaker
TLS – 인증서 관리자
데모 애플리케이션 – Google Bank of Anthos
코드가 배포되는 방법
샘플 애플리케이션을 설치하고 배포하려면 시작 스크립트를 호출하는 단일 명령을 실행하고 다음 Pulumi 프로젝트가 표시된 순서대로 실행됩니다. 각 프로젝트 이름은 리포지토리의 루트 디렉토리를 기준으로 디렉토리 이름에 매핑됩니다 . 자세한 내용은 README를 참조하세요 .
vpc - Defines and installs VPC and subnets to use with EKS └─eks - Deploys EKS
└─ecr - Configures ECR for use in EKS cluster
└─kic-image-build - Builds new NGINX Ingress Controller image
└─kic-image-push - Pushes image built in previous step to ECR
└─kic-helm-chart - Deploys NGINX Ingress Controller to EKS
cluster
└─logstore - Deploys Elastic log store to EKS cluster
└─logagent - Deploys Elastic (filebeat) logging agent to
EKS cluster
└─certmgr - Deploys cert-manager.io Helm chart to EKS
cluster
└─anthos - Deploys Bank of Anthos application to EKS
cluster
버전 2에서는 더 많은 통합과 더 큰 유연성이 제공됩니다.
저희는 초기 노력이 Kubernetes 환경에 필요한 모든 통합을 제공하지 못할 수 있다는 점을 알고 있습니다. Platform Ops는 스마트하지만 무제한적인 선택에 관한 것입니다. Platform Ops, DevOps 및 개발자 팀이 새로운 참조 플랫폼을 시도하고 잠재적으로 채택하기 쉽도록 단기적으로 다음을 포함한 많은 개선 사항을 계획하고 있습니다.
Digital Ocean, OpenShift, Rancher, vSphere 및 기타 Kubernetes 환경을 구축하세요.
NGINX Controller와 통합하여 NGINX Plus Ingress Controller를 관리하고 모니터링합니다.
[ 편집기 – NGINX Controller는 이제 F5 NGINX Management Suite 입니다 .]
NGINX App Protect 에 대한 기본 구성 제공
BIG‑IP , 클라우드 서비스 , Volterra 와 같은 F5 제품 및 서비스와 통합
NGINX Service Mesh 및 Istio 기반 Aspen Mesh 와 통합
Terraform 및 기타 자동화 도구 와 기본적으로 통합
다른 CI/CD 옵션 지원
인프라 및 애플리케이션 서비스에 대해 별도 또는 여러 클러스터를 배포합니다.
저희는 저희의 작업이 다른 참조 플랫폼의 프레임워크가 되고 모든 유형의 차별화된 현대적 애플리케이션을 구축하기 위한 "도용 가능한" 시작점이 되기를 바랍니다. Kubernetes는 현대적 애플리케이션을 구축하고 Platforms Ops와 Shift‑left 문화를 강화하는 데 매우 강력한 메커니즘이기 때문에 참조 아키텍처가 더 광범위하고 플러그인이 가능할수록 더 좋습니다. 저희는 여러분, 커뮤니티가 저희 작업에 대해 어떻게 생각하는지, 그리고 더 중요한 것은 여러분이 그것으로 무엇을 구축하는지 보고 싶습니다.
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
지금, 수백만 명의 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 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
전문가에게 상담받기
애플리케이션 개발의 궁극적인 목표는 물론 앱을 인터넷에 노출하는 것입니다. 개발자에게 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 레코드가 정리됩니다.
이 솔루션은 다음 기술을 활용합니다(아래에 설치 및 구성 지침 제공):
솔루션을 구성하기 전에 다음이 필요합니다.
또한 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 저장소를 복제합니다.
$ 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.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 배포
Helm을 사용하여 NGINX Ingress Controller를 배포합니다. 세 가지 비표준 구성 옵션을 추가하고 있다는 점에 유의하세요 .
$ 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.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 3h8mcert-manager 배포
솔루션에서 cert-manager는 TLS 인증서를 얻을 때 DNS-01 챌린지 유형을 사용하는데 , 이를 위해서는 ClusterIssuer 리소스를 생성하는 동안 Cloudflare API 토큰을 제공해야 합니다 . 솔루션에서 API 토큰은 Kubernetes Secret 으로 제공됩니다 .
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!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 createdClusterIssuer 객체를 생성하고 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 createdClusterIssuer가 배포되고 준비되었는지 확인합니다(필드의 값 READY은 True).
$ kubectl get clusterissuerNAME READY AGE example-issuer True 3h9mExternalDNS 배포
cert-manager와 마찬가지로 ExternalDNS 프로젝트는 DNS를 관리하기 위해 Cloudflare API 토큰이 필요합니다. 두 프로젝트 모두에 동일한 토큰을 사용할 수 있지만 필수는 아닙니다.
프로젝트 간 통합을 활성화하기 위해 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외부 DNS 서비스( external-dns)를 만듭니다. 매니페스트가 꽤 길기 때문에 여기서는 두 부분으로 나눕니다. 첫 번째 부분은 계정, 역할 및 권한을 구성합니다.
$ 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 배포를 생성합니다.
$ 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 샘플 애플리케이션을 사용합니다 .
카페 애플리케이션을 배포합니다.
$ 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 createdCafe 애플리케이션에 NGINX Ingress Controller를 배포합니다. 다음 설정에 유의하세요.
이 단계를 완료하는 데 걸리는 시간은 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솔루션 검증
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인증서가 유효한지 확인하세요(필드의 값 READY이 True).
$ kubectl get certificatesNAME READY SECRET AGE cafe-secret True cafe-secret 8m51s신청서에 접속할 수 있는지 확인하세요.
$ 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를 배포할 때 어떤 일이 일어나는지 보여줍니다. 일부 운영 세부 사항은 생략됩니다.
문제 해결
Kubernetes의 복잡성과 우리가 사용하는 구성 요소를 감안할 때 포괄적인 문제 해결 가이드를 제공하기는 어렵습니다. 그럼에도 불구하고 문제를 파악하는 데 도움이 되는 몇 가지 기본 제안이 있습니다.
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
전문가에게 상담받기
사용자가 찾을 수 없다면 애플리케이션은 목적을 달성할 수 없습니다. 도메인 이름 시스템(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와 NGINX Ingress Controller 통합
ExternalDNS와 NGINX Ingress Controller를 통합하려면 다음 섹션의 단계를 수행하세요.
필수 조건
매니페스트 또는 Helm 차트를 사용하여 NGINX Ingress Controller를 배포합니다 . 배포 사양에 다음 명령줄 인수 와 동일한 인수를 추가합니다 .
필요한 경우 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 배포
샘플 배포를 위해 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.yamlExternalDNS 배포 사양에서 다음 인수를 업데이트합니다( 샘플 배포의 경우 external-dns-gcloud.yaml 의 59~62행 ):
참고: ExternalDNS 배포 사양에 포함해야 하는 인수는 선택한 DNS 공급자에 따라 다를 수 있습니다. 다른 DNS 공급자가 있는 클러스터에 ExternalDNS를 배포하는 방법에 대한 자습서 목록은 ExternalDNS 설명서를 참조하세요 .
클러스터에 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 1mNGINX Ingress 컨트롤러 구성
다음으로, 외부 연결을 Kubernetes 애플리케이션으로 라우팅하는 Ingress 부하 분산 규칙으로 VirtualServer 리소스를 구성합니다.
app-virtual-server.yaml 에서 필드를 설정합니다 host(라인 6):
6 host: ingress.external-dns.<my-domain>이 값과 external-dns-gcloud.yamldomain-filter 의 59번째 줄에 있는 값 (이전 섹션의 2단계 에서 설정 ) 간의 매핑은 DNS 레코드의 자동 업데이트를 가능하게 합니다.
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.YDNS 유형 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.YVirtualServer 호스트 이름을 로컬 머신에서 확인할 수 있는지 확인하려면 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이제 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 의 지침을 반복합니다 .
CI/CD 파이프라인에서 Infrastructure-as-Code 도구를 사용하여 ExternalDNS 및 NGINX Ingress Controller를 사용하여 외부 트래픽에 새 클러스터를 생성하고 노출할 수도 있습니다. 또한 여러 DNS 영역 또는 검색이 활성화된 방식에 따라 여러 DNS 공급자를 관리할 수도 있습니다.
결론
생산성과 침해를 완화하는 보안 조치의 균형을 맞추는 것은 어려울 수 있습니다. DevOps 팀에 제한을 가하면 종종 DevOps 팀과 NetOps/SecOps 팀 간에 마찰이 발생합니다. 이상적인 균형은 각 조직마다 다르며, NGINX는 우선순위와 요구 사항을 준수하는 균형을 확립할 수 있는 유연성을 제공합니다.
과거에 앱 소유자는 NetOps 팀에 의존하여 애플리케이션을 외부 시스템에 연결했습니다. NGINX와 ExternalDNS 통합을 사용하면 개발자와 DevOps 팀이 스스로 발견 가능한 애플리케이션을 배포할 수 있어 혁신을 위한 출시 시간을 단축하는 데 도움이 됩니다.
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
전문가에게 상담받기
유효한 SSL/TLS 인증서는 현대 애플리케이션 환경의 핵심 요구 사항입니다. 안타깝게도 애플리케이션을 배포할 때 인증서(또는 인증서) 갱신을 관리하는 것은 종종 뒷전으로 밀려납니다. 인증서는 수명이 제한되어 있으며 DigiCert 인증서의 경우 약 13개월 에서 Let's Encrypt 인증서의 경우 90일 까지 다양합니다 . 안전한 액세스를 유지하려면 이러한 인증서는 만료되기 전에 갱신/재발급해야 합니다. 대부분 운영팀의 업무량이 많기 때문에 인증서 갱신이 간과되는 경우가 종종 있으며, 인증서가 만료 날짜에 가까워지거나 더 나쁜 경우 만료되면 혼란이 발생합니다.
이렇게 될 필요는 없습니다. 약간의 계획과 준비로 인증서 관리를 자동화하고 간소화할 수 있습니다. 여기서는 세 가지 기술을 사용하는 Kubernetes 솔루션을 살펴보겠습니다.
이 블로그에서는 엔드포인트에 고유하고 자동으로 갱신되고 업데이트된 인증서를 제공하여 인증서 관리를 간소화하는 방법을 알아봅니다.
Kubernetes 환경의 인증서
기술적인 세부 사항을 살펴보기 전에 용어를 정의해야 합니다. "TLS 인증서"라는 용어는 Ingress 컨트롤러에서 HTTPS 연결을 활성화하는 데 필요한 두 가지 구성 요소를 말합니다.
인증서와 개인 키는 모두 Let's Encrypt 에서 발급합니다 . TLS 인증서가 작동하는 방식에 대한 전체 설명은 DigiCert의 게시물 How TLS/SSL Certificates Work를 참조하세요 .
쿠버네티스에서 이 두 구성 요소는 Secrets 로 저장됩니다. NGINX Ingress Controller 및 cert-manager 와 같은 쿠버네티스 워크로드는 이러한 Secrets를 쓰고 읽을 수 있으며, 쿠버네티스 설치에 액세스할 수 있는 사용자도 이를 관리할 수 있습니다.
cert-manager 소개
cert -manager 프로젝트는 Kubernetes 및 OpenShift와 함께 작동하는 인증서 컨트롤러입니다. Kubernetes에 배포하면 cert-manager는 Ingress 컨트롤러에 필요한 인증서를 자동으로 발급하고 유효하고 최신 상태인지 확인합니다. 또한 인증서의 만료 날짜를 추적하고 구성된 시간 간격으로 갱신을 시도합니다. 수많은 공개 및 비공개 발급자와 함께 작동하지만 Let's Encrypt와의 통합을 보여드리겠습니다.
두 가지 도전 유형
Let's Encrypt를 사용하면 모든 인증서 관리가 자동으로 처리됩니다. 이는 많은 편의성을 제공하지만, 다음과 같은 문제도 제기합니다. 이 서비스는 사용자가 문제의 정규화된 도메인 이름(FQDN)을 소유하고 있는지 어떻게 보장합니까?
이 문제는 챌린지를 사용하여 해결되는데 , 챌린지는 특정 도메인의 DNS 레코드에 액세스할 수 있는 사람만 제공할 수 있는 확인 요청에 답해야 합니다. 챌린지는 다음 두 가지 형태 중 하나를 취합니다.
HTTP-01은 DNS 공급자에 직접 액세스할 필요가 없으므로 인증서를 생성하는 가장 간단한 방법입니다. 이 유형의 챌린지는 항상 포트 80(HTTP)을 통해 수행됩니다. HTTP-01 챌린지를 사용할 때 cert-manager는 Ingress 컨트롤러를 활용하여 챌린지 토큰을 제공합니다.
인그레스 컨트롤러
Ingress 컨트롤러는 클러스터 외부에서 트래픽을 가져오고, 내부 Pod (하나 이상의 컨테이너 그룹)로 로드 밸런싱하고, 이탈 트래픽을 관리하는 Kubernetes용 전문 서비스입니다. 또한 Ingress 컨트롤러는 Kubernetes API를 통해 제어되며 Pod가 추가, 제거 또는 실패할 때 로드 밸런싱 구성을 모니터링하고 업데이트합니다.
Ingress 컨트롤러에 대해 자세히 알아보려면 다음 블로그를 읽어보세요.
아래 예에서는 F5 NGINX가 개발하고 유지 관리하는 NGINX Ingress Controller를 사용하겠습니다.
인증서 관리 예제
이러한 예에서는 테스트할 수 있는 작동하는 Kubernetes 설치가 있고 설치가 외부 IP 주소(Kubernetes LoadBalancer 개체)를 할당할 수 있다고 가정합니다. 또한 포트 80과 포트 443(HTTP-01 챌린지 사용 시) 또는 포트 443(DNS-01 챌린지 사용 시)에서 트래픽을 수신할 수 있다고 가정합니다. 이러한 예는 Mac OS X를 사용하여 설명하지만 Linux 또는 WSL에서도 사용할 수 있습니다.
또한 A 레코드를 조정할 수 있는 DNS 공급자와 FQDN이 필요합니다. HTTP-01 챌린지를 사용하는 경우 A 레코드를 추가하는 기능만 있으면 됩니다(또는 사용자를 위해 추가되도록 하면 됩니다). DNS-01 챌린지를 사용하는 경우 지원되는 DNS 공급자 또는 지원되는 웹훅 공급자 에 대한 API 액세스가 필요합니다 .
NGINX Ingress Controller 배포
가장 쉬운 방법은 Helm을 통해 배포하는 것입니다 . 이 배포를 통해 Kubernetes Ingress와 NGINX Virtual Server CRD를 모두 사용할 수 있습니다.
$ helm repo add nginx-stable https://helm.nginx.com/stable "nginx-stable" has been added to your repositories$ helm repo update Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "nginx-stable" chart repository Update Complete. ⎈Happy Helming!⎈$ helm install nginx-kic nginx-stable/nginx-ingress \ --namespace nginx-ingress --set controller.enableCustomResources=true \ --create-namespace --set controller.enableCertManager=true NAME: nginx-kic LAST DEPLOYED: Thu Sep 1 15:58:15 2022 NAMESPACE: nginx-ingress STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: The NGINX Ingress Controller has been installed.$ kubectl get deployments --namespace nginx-ingress NAME READY UP-TO-DATE AVAILABLE AGE nginx-kic-nginx-ingress 1/1 1 1 23s $ kubectl get services --namespace nginx-ingress NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-kic-nginx-ingress LoadBalancer 10.128.60.190 www.xxx.yyy.zzz 80:31526/TCP,443:32058/TCP 30sDNS A 레코드 추가
여기서의 프로세스는 귀하의 DNS 공급자에 따라 달라집니다. 이 DNS 이름은 Let's Encrypt 서버에서 확인할 수 있어야 하며, 레코드가 전파될 때까지 기다려야 작동할 수 있습니다. 이에 대한 자세한 내용은 SiteGround 문서 DNS 전파란 무엇이며 왜 그렇게 오래 걸리는가? 를 참조하세요.
선택한 FQDN을 확인할 수 있으면 다음 단계로 넘어갈 준비가 된 것입니다.
$ host cert.example.com cert.example.com has address www.xxx.yyy.zzzcert-manager 배포
다음 단계는 cert-manager의 최신 버전을 배포하는 것입니다. 다시 말하지만, 우리는 배포에 Helm을 사용할 것입니다.
$ helm repo add jetstack https://charts.jetstack.io "jetstack" has been added to your repositories$ helm repo update Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "nginx-stable" chart repository ...Successfully got an update from the "jetstack" chart repository Update Complete. ⎈Happy Helming!⎈$ helm install cert-manager jetstack/cert-manager \ --namespace cert-manager --create-namespace \ --version v1.9.1 --set installCRDs=true NAME: cert-manager LAST DEPLOYED: Thu Sep 1 16:01:52 2022 NAMESPACE: cert-manager STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: cert-manager v1.9.1 has been deployed successfully!In order to begin issuing certificates, you will need to set up a ClusterIssuer or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).
More information on the different types of issuers and how to configure them can be found in our documentation:
https://cert-manager.io/docs/configuration/
For information on how to configure cert-manager to automatically provision Certificates for Ingress resources, take a look at the `ingress-shim` documentation:
https://cert-manager.io/docs/usage/ingress/
$ kubectl get deployments --namespace cert-manager NAME READY UP-TO-DATE AVAILABLE AGE cert-manager 1/1 1 1 4m30s cert-manager-cainjector 1/1 1 1 4m30s cert-manager-webhook 1/1 1 1 4m30sNGINX Cafe 예제 배포
우리는 NGINX Cafe 예제를 사용하여 백엔드 배포 및 서비스를 제공할 것입니다. 이것은 NGINX에서 제공하는 설명서 내에서 사용되는 일반적인 예제입니다. 우리는 이것의 일부로 Ingress를 배포하지 않을 것입니다.
$ git clone https://github.com/nginxinc/kubernetes-ingress.git Cloning into 'kubernetes-ingress'... remote: Enumerating objects: 44979, done. remote: Counting objects: 100% (172/172), done. remote: Compressing objects: 100% (108/108), done. remote: Total 44979 (delta 87), reused 120 (delta 63), pack-reused 44807 Receiving objects: 100% (44979/44979), 60.27 MiB | 27.33 MiB/s, done. Resolving deltas: 100% (26508/26508), done.$ cd ./kubernetes-ingress/examples/ingress-resources/complete-example$ kubectl apply -f ./cafe.yaml deployment.apps/coffee created service/coffee-svc created deployment.apps/tea created service/tea-svc created$ kubectl get deployments,services --namespace default NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/coffee 2/2 2 2 69s deployment.apps/tea 3/3 3 3 68s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/coffee-svc ClusterIP 10.128.154.225 <none> 80/TCP 68s service/kubernetes ClusterIP 10.128.0.1 <none> 443/TCP 29m service/tea-svc ClusterIP 10.128.96.145 <none> 80/TCP 68sClusterIssuer 배포
cert-manager 내에서 ClusterIssuer를 사용하여 인증서를 발급할 수 있습니다. 이는 모든 네임스페이스에서 참조할 수 있고 정의된 인증서 발급 기관이 있는 모든 인증서 요청에서 사용할 수 있는 클러스터 범위 개체입니다. 이 예에서 Let's Encrypt 인증서에 대한 모든 인증서 요청은 이 ClusterIssuer에서 처리할 수 있습니다.
선택한 챌린지 유형에 대한 ClusterIssuer를 배포합니다. 이 게시물의 범위를 벗어나지만 ClusterIssuer에서 여러 개의 리졸버(선택자 필드에 따라 선택)를 지정할 수 있는 고급 구성 옵션 이 있습니다.
ACME 챌린지 기본 사항
ACME(Automated Certificate Management Environment) 프로토콜은 도메인 이름을 소유하고 있으므로 Let's Encrypt 인증서를 발급받을 수 있는지 확인하는 데 사용됩니다. 이 챌린지의 경우 전달해야 하는 매개변수는 다음과 같습니다.
HTTP-01 사용
이 예제에서는 HTTP-01 챌린지를 사용하여 도메인 소유권을 증명하고 인증서를 수신하기 위해 ClusterIssuer를 설정하는 방법을 보여줍니다.
$ cat << EOF | kubectl apply -f apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: prod-issuer spec: acme: email: example@example.com server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: prod-issuer-account-key solvers: - http01: ingress: class: nginx EOF clusterissuer.cert-manager.io/prod-issuer created$ kubectl get clusterissuer NAME READY AGE prod-issuer True 34sDNS-01 사용
이 예제에서는 DNS-01 챌린지를 사용하여 도메인 소유권을 인증하는 ClusterIssuer를 설정하는 방법을 보여줍니다. DNS 공급자에 따라 토큰을 저장하기 위해 Kubernetes Secret을 사용해야 할 가능성이 높습니다. 이 예제에서는 Cloudflare를 사용합니다 . namespace 사용에 유의하세요. cert-manager 네임스페이스에 배포된 cert-manager 애플리케이션은 Secret에 액세스할 수 있어야 합니다.
이 예시에서는 계정에서 만들 수 있는 Cloudflare API 토큰이 필요합니다 . 이는 아래의 <API Token> 줄에 입력해야 합니다. Cloudflare를 사용하지 않는 경우 공급자의 설명서를 따라야 합니다 .
$ cat << EOF | kubectl apply -f apiVersion: v1 kind: Secret metadata: name: cloudflare-api-token-secret namespace: cert-manager type: Opaque stringData: api-token: <API Token> EOF$ cat << EOF | kubectl apply -f apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: prod-issuer spec: acme: email: example@example.com server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: prod-issuer-account-key solvers: - dns01: cloudflare: apiTokenSecretRef: name: cloudflare-api-token-secret key: api-token EOF$ kubectl get clusterissuer NAME READY AGE prod-issuer True 31mIngress 배포
이것이 우리가 구축해 온 지점입니다. 즉, 애플리케이션에 Ingress 리소스를 배포하는 것입니다. 이렇게 하면 트래픽이 이전에 배포한 NGINX Cafe 애플리케이션으로 라우팅됩니다.
Kubernetes Ingress 사용
표준 Kubernetes Ingress 리소스를 사용하는 경우 다음 배포 YAML을 사용하여 Ingress를 구성하고 인증서를 요청합니다.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: cafe-ingress annotations: cert-manager.io/cluster-issuer: prod-issuer acme.cert-manager.io/http01-edit-in-place: "true" spec: ingressClassName: nginx tls: - hosts: - cert.example.com secretName: cafe-secret rules: - host: cert.example.com http: paths: - path: /tea pathType: Prefix backend: service: name: tea-svc port: number: 80 - path: /coffee pathType: Prefix backend: service: name: coffee-svc port: number: 80매니페스트의 몇 가지 주요 부분을 검토해 보는 것이 좋습니다.
$ kubectl apply -f ./cafe-virtual-server.yaml virtualserver.k8s.nginx.org/cafe created$ kubectl get certificates NAME READY SECRET AGE certificate.cert-manager.io/cafe-secret True cafe-secret 37mNGINX 가상 서버/가상 경로 사용
NGINX CRD를 사용하는 경우 다음 배포 YAML을 사용하여 Ingress를 구성해야 합니다.
apiVersion: k8s.nginx.org/v1 kind: VirtualServer metadata: name: cafe spec: host: cert.example.com tls: secret: cafe-secret cert-manager: cluster-issuer: prod-issuer 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다시 한번, 매니페스트의 몇 가지 핵심 부분을 검토해 보는 것이 좋습니다.
$ kubectl apply -f ./cafe-virtual-server.yaml virtualserver.k8s.nginx.org/cafe created$ kubectl get VirtualServers NAME STATE HOST IP PORTS AGE cafe Valid cert.example.com www.xxx.yyy.zzz [80,443] 51m인증서 보기
Kubernetes API를 통해 인증서를 볼 수 있습니다. 여기에는 인증서의 크기 및 연관된 개인 키를 포함한 인증서에 대한 세부 정보가 표시됩니다.
$ kubectl describe secret cafe-secret Name: cafe-secret Namespace: default Labels: <none> Annotations: cert-manager.io/alt-names: cert.example.com cert-manager.io/certificate-name: cafe-secret cert-manager.io/common-name: cert.example.com cert-manager.io/ip-sans: cert-manager.io/issuer-group: cert-manager.io/issuer-kind: ClusterIssuer cert-manager.io/issuer-name: prod-issuer cert-manager.io/uri-sans:Type: kubernetes.io/tlsData ==== tls.crt: 5607 bytes tls.key: 1675 bytes실제 인증서와 키를 보고 싶다면 다음 명령을 실행하면 됩니다. (참고: 이는 Kubernetes Secrets의 약점을 보여줍니다. 즉, 필요한 액세스 권한이 있는 사람은 누구나 읽을 수 있습니다.)
$ kubectl get secret cafe-secret -o yamlIngress 테스트
인증서를 테스트합니다. 여기서는 원하는 방법을 사용할 수 있습니다. 아래 예에서는 cURL을 사용합니다 . 성공은 서버 이름, 서버의 내부 주소, 날짜, 선택한 URI(경로)(커피 또는 차) 및 요청 ID를 포함하는 이전에 표시된 것과 유사한 블록으로 표시됩니다. 실패는 HTTP 오류 코드의 형태를 띠며, 대부분 400 또는 301입니다.
$ curl https://cert.example.com/tea Server address: 10.2.0.6:8080 Server name: tea-5c457db9-l4pvq Date: 02/Sep/2022:15:21:06 +0000 URI: /tea Request ID: d736db9f696423c6212ffc70cd7ebecf $ curl https://cert.example.com/coffee Server address: 10.2.2.6:8080 Server name: coffee-7c86d7d67c-kjddk Date: 02/Sep/2022:15:21:10 +0000 URI: /coffee Request ID: 4ea3aa1c87d2f1d80a706dde91f31d54인증서 갱신
처음에 우리는 이 접근 방식이 인증서 갱신을 관리할 필요성을 없앨 것이라고 약속했습니다. 하지만 아직 그 방법을 설명하지 못했습니다. 왜 그럴까요? 이는 cert-manager의 핵심 내장 부분이기 때문입니다. 이 자동 프로세스에서 cert-manager가 인증서가 없거나 만료되었거나 만료까지 15일 이내이거나 사용자가 CLI를 통해 새 인증서를 요청하는 경우 새 인증서가 자동으로 요청됩니다 . 이보다 더 쉬운 일은 없습니다.
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
전문가에게 상담받기
사이버 보안 공격의 정교함과 수는 기하급수적으로 증가하고 있으며, 온프레미스, 하이브리드 및 멀티 클라우드 Kubernetes 환경에 배포된 앱에 대한 상당한 노출 위험을 발생시키고 있습니다. 기존 보안 모델은 경계 기반이며, 환경의 보안 경계 내에 위치하는 경우 사용자가 신뢰할 수 있고(그리고 사용자 간의 통신이 안전하다고) 가정합니다. 오늘날의 분산 환경에서 경계 내부의 안전 지대라는 개념은 더 이상 존재하지 않습니다. 환경 "내부"에서 발생하는 통신은 외부 위협만큼 위험할 수 있습니다.
이 블로그에서는 Kubernetes 인프라를 보호하기 위해 Zero Trust 모델을 도입하는 이점과 NGINX가 보안 태세를 개선하는 데 어떻게 도움이 될 수 있는지 알아봅니다.
제로 트러스트란 무엇인가요?
Zero Trust 는 위치가 아닌 신원에 기반한 보안 모델입니다. 이는 요청자가 사내, 원격 또는 클라우드에 있는 것처럼 보이는지 여부에 관계없이 애플리케이션, 데이터 및 장치에 대한 액세스 요청이 공격일 수 있다고 가정합니다.
Zero Trust의 세 가지 핵심 원칙(절대 신뢰하지 말고, 항상 확인하고, 지속적으로 모니터링)을 구현하기 위해 모든 사용자, 서비스, 애플리케이션 및 기기는 지속적으로 인증 및 권한 부여 증명을 제시해야 합니다. 시간 제한 권한은 동적 액세스 정책과 최소 권한 기준에 따라 부여됩니다.
모든 통신은 암호화되고 모든 당사자를 인증하고 동적 액세스 정책에 따라 권한을 부여하는 정책 결정/시행 지점(PDP/PEP)을 통해 라우팅됩니다. 또한 감사, 모니터링, 보고 및 자동화 기능이 보안 위험을 분석, 평가 및 완화하기 위해 마련되어 있습니다.
Zero Trust가 보안 태세를 개선하는 방법
Zero Trust는 여러 가지 방법으로 보안 태세를 개선합니다.
Zero Trust는 Kubernetes 환경에서 실행되는 최신 클라우드 네이티브 앱에 특히 중요합니다. 느슨하게 결합되고 이식 가능한 분산 앱과 서비스는 컨테이너화되어 위치 기반 보안이 옵션이 아닌 하이브리드, 멀티 클라우드 환경에서 실행됩니다. 보안은 필연적으로 ID 및 권한의 지속적인 검증, 종단 간 암호화 및 모니터링에 달려 있습니다.
제로 트러스트 보안을 달성하는 방법
Zero Trust 원칙을 충족하려면 Kubernetes 환경에서 사용자, 애플리케이션, 서비스에 대한 인증, 권한 부여, 액세스 제어, 정책, 암호화, 모니터링, 감사와 같은 중요한 보안 기능을 제공해야 합니다.
이를 달성할 수 있는 한 가지 가능한 방법은 앱 자체에 보안을 구축하는 것입니다. 그러나 이는 개발자가 신뢰 설정 및 확인, 사용자 ID 및 인증서 관리, 모든 통신 암호화 및 복호화 등을 위한 여러 보안 절차를 구현해야 함을 의미합니다. 또한 TLS 및 Single Sign‑on(SSO)과 같은 타사 기술을 이해하고 통합해야 합니다. 이 모든 것이 이미 복잡한 Kubernetes 배포에 복잡성을 더할 뿐만 아니라 개발자가 집중해야 하는(그리고 원하는!) 것, 즉 앱의 비즈니스 기능을 최적화하는 데 방해가 됩니다.
당황하지 마세요. 더 나은 방법이 있습니다. 보안 및 기타 비기능적 요구 사항을 Kubernetes 인프라로 오프로드하세요! Ingress 컨트롤러 및 서비스 메시와 같은 Kubernetes 클러스터용 연결 도구는 사용자 또는 다른 앱이나 서비스에서 시작된 모든 앱 및 서비스 간 통신을 위한 PDP 및 PEP를 제공할 수 있습니다. 즉, 핵심 비즈니스 전문 지식과 기능에 집중하면서 앱을 더 빠르고 쉽게 제공할 수 있습니다.
F5 NGINX가 어떻게 도움이 될 수 있는지
다음 다이어그램에서 알 수 있듯이, 안전한 Kubernetes 연결을 위한 NGINX 솔루션에는 온프레미스, 하이브리드, 멀티 클라우드 등 모든 환경에서 사용자, 분산 애플리케이션, 마이크로서비스, API를 규모에 맞게, 종단 간 성공적으로 보호하는 데 필요한 모든 인프라 독립적 인 구성 요소와 도구가 포함되어 있습니다. 세계에서 가장 인기 있는 데이터 플레인으로 구동되는 이 솔루션은 다음을 결합합니다.
NGINX 솔루션을 사용하면 다음이 가능합니다.
NGINX로 포괄적인 Zero Trust 보안 구현
조직이 확장됨에 따라 앱의 기능에 국한되지 않은 요구 사항(예: Zero Trust 보안 기능)을 애플리케이션 계층에서 오프로드하는 것이 중요해집니다. 위에서 설명한 대로 이를 통해 개발자는 앱 전체에서 보안 로직을 빌드, 유지 관리 및 복제하는 부담에서 벗어날 수 있습니다. 대신 플랫폼 수준에서 보안 기술을 쉽게 활용할 수 있습니다. NGINX는 NGINX Ingress Controller를 사용하여 클러스터 가장자리에서 Kubernetes에 대한 중앙 집중식 보안 정책 시행을 제공하고 NGINX Service Mesh를 사용하여 클러스터 내에서 Kubernetes에 대한 중앙 집중식 보안 정책 시행을 제공합니다. 앱 보안 요구 사항에 따라 가장자리 또는 클러스터 내에 배포된 NGINX App Protect WAF 및 DoS를 사용하여 정교한 사이버 공격으로부터 고급 애플리케이션 보호 기능을 추가할 수 있습니다.
Kubernetes 배포에 포괄적인 Zero Trust 보안을 구현하는 데 필요한 기능이 NGINX 솔루션에 어떻게 포함되어 있는지 자세히 살펴보겠습니다.
인증 및 권한 부여
이 원칙을 해결하기 위해 NGINX 솔루션은 HTTP 기본 인증 , JSON 웹 토큰(JWT) , Okta 및 Azure Active Directory(AD)와 같은 ID 공급자와의 통합을 통한 OpenID Connect를 포함하여 인증 및 권한 부여를 구현하기 위한 여러 옵션을 제공합니다. NGINX 솔루션은 또한 서비스에 보안 ID를 발급합니다(애플리케이션 사용자에게 인증서 형태의 ID가 발급되는 것과 매우 유사). 이를 통해 Kubernetes 클러스터에서 작업을 수행하도록 인증 및 권한 부여를 받을 수 있습니다. 워크로드 ID를 처리하는 것 외에도 NGINX 솔루션은 PKI(공개 키 인프라) 및 인증 기관과의 기본 제공 통합을 통해 인증서 관리를 자동화합니다.
NGINX Ingress Controller는 이미 클러스터에 들어오는 모든 요청을 면밀히 조사하여 적절한 서비스로 라우팅하기 때문에 중앙에서 사용자를 인증하고 권한을 부여하는 데 가장 효율적인 위치이며, 일부 시나리오에서는 서비스를 인증하는 데도 가장 효율적인 위치입니다.
자세한 내용은 블로그에서 Okta와 NGINX Ingress Controller를 사용하여 Kubernetes에 대한 OpenID Connect 인증 구현을 읽어보세요.
데이터 암호화 및 무결성
앱 아키텍처가 Kubernetes 클러스터 내에서 서비스 간 통신을 포함하지 않는 경우 NGINX Ingress Controller가 데이터 무결성 요구 사항을 충족하기에 충분할 수 있습니다. 두 가지 기본 옵션이 있습니다.
아키텍처에 클러스터 내에서 서비스 간 통신이 포함되는 경우 데이터 무결성을 위해 NGINX Ingress Controller와 NGINX Service Mesh가 모두 필요합니다. NGINX Service Mesh는 특정 서비스만 서로 통신할 수 있도록 보장하고 mTLS를 사용하여 이를 인증하고 통신을 암호화합니다. NGINX Service Mesh를 사용하여 mTLS를 "제로 터치" 방식으로 구현할 수 있으므로 개발자는 인증서를 사용하여 애플리케이션을 개조하거나 상호 인증이 수행되고 있다는 것을 알 필요가 없습니다.
Kubernetes 클러스터에서 통신을 보호하는 방법에 대한 자세한 내용은 블로그의 NGINX 서비스 메시의 mTLS 아키텍처를 참조하세요.
접근 제어 및 접근 정책
NGINX Kubernetes 연결 솔루션은 조직의 보안 정책과 쉽게 일치할 수 있도록 RBAC를 지원합니다. RBAC를 사용하면 사용자는 IT 티켓을 제출하고 처리될 때까지 기다리지 않고도 업무를 수행하는 데 필요한 기능에 대한 게이트형 액세스를 얻을 수 있습니다. RBAC가 없으면 사용자는 필요하지 않거나 권한이 없는 권한을 얻을 수 있으며, 권한이 오용되면 취약성이 발생할 수 있습니다.
NGINX Ingress Controller로 RBAC를 구성하면 조직의 애플리케이션 개발 및 제공 환경에서 다양한 역할에 맞게 권한을 조정하여 여러 사람과 팀의 액세스를 제어할 수 있습니다. 세분화된 액세스 관리 도구를 통해 여러 팀에서 셀프 서비스와 거버넌스를 수행할 수 있습니다.
NGINX Ingress Controller로 RBAC를 활용하는 방법을 알아보려면 DevNetwork, NGINX Ingress Controller를 사용한 고급 Kubernetes 배포에 대한 웨비나를 시청하세요 . 13:50부터 전문가가 보안, 셀프서비스 및 멀티테넌시를 위해 RBAC와 리소스 할당을 활용하는 방법을 설명합니다.
관찰 가능성
아마도 Kubernetes 배포에서 모니터링 도구를 이미 사용하고 있을 것이고, 또 다른 도구가 필요하지 않을 것입니다. 클러스터 내부에서 무슨 일이 일어나고 있는지 전체적으로 파악할 수 있도록, JSON을 허용하고 OpenTelemetry , Grafana 및 Prometheus 와 같은 인기 있는 도구와 미리 빌드된 통합을 제공하는 모든 타사 도구에 메트릭을 쉽게 내보낼 수 있도록 NGINX Plus API 를 계측했습니다. 심층 추적을 통해 앱 연결에 대한 타겟팅된 통찰력을 얻을 수 있으므로 요청이 종단 간에 처리되는 방식을 이해할 수 있습니다 . NGINX Ingress Controller는 클러스터와 외부 클라이언트 간의 연결에 대한 통찰력을 제공하는 반면, NGINX Service Mesh는 클러스터 내의 컨테이너화된 마이크로서비스 기반 앱과 서비스 간의 연결을 다룹니다.
WAF 및 DoS 보호
NGINX App Protect의 모듈식 설계는 필요에 따라 동일하거나 다른 인스턴스에 WAF와 DoS 보호 중 하나 또는 둘 다를 배포할 수 있음을 의미합니다. 예를 들어, 클러스터 가장자리에 NGINX Ingress Controller를 사용하여 배포하기로 결정할 수 있으며, 이는 전체 단일 클러스터에서 일관된 세분화된 보호를 제공하는 데 이상적입니다. 대신 클러스터의 여러 앱에 대한 앱별 정책이 필요한 경우 서비스 또는 포드 수준에서 WAF 및/또는 DoS 보호를 배포할 수 있습니다.
WAF와 DoS 보호 기능을 구축하는 방법에 대한 자세한 내용은 블로그에서 보다 안전한 앱을 위해 보안 도구를 좌측으로 전환을 읽어보세요.
Kubernetes를 위한 NGINX Zero Trust 보안 솔루션 시작하기
Kubernetes 여정의 시작에 있는 사용자이든 오랫동안 Kubernetes를 운영 환경에서 사용해 온 고급 사용자이든, NGINX는 사용자의 요구 사항을 충족하고 보안 태세를 개선하는 데 필요한 포괄적인 도구와 빌딩 블록 세트를 제공합니다
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
전문가에게 상담받기
조직이 확장됨에 따라 Kubernetes의 개발 및 운영 워크플로는 더욱 복잡해집니다. 각 팀이 자체 클러스터를 갖는 것보다 팀이 Kubernetes 클러스터와 리소스를 공유하는 것이 일반적으로 더 비용 효율적이며 더 안전할 수 있습니다. 그러나 팀이 안전하고 보안적인 방식으로 리소스를 공유하지 않거나 해커가 구성을 악용하는 경우 배포에 심각한 손상이 발생할 수 있습니다.
네트워크 및 리소스 수준에서의 멀티 테넌시 관행과 네임스페이스 격리는 팀이 Kubernetes 리소스를 안전하게 공유하는 데 도움이 됩니다. 또한 테넌트별로 애플리케이션을 격리하여 침해 규모를 크게 줄일 수도 있습니다. 이 방법은 특정 팀이 소유한 애플리케이션의 하위 섹션만 손상될 수 있고 다른 기능을 제공하는 시스템은 그대로 유지되므로 복원력을 높이는 데 도움이 됩니다.
NGINX Ingress Controller는 여러 멀티 테넌시 모델을 지원하지만, 우리는 두 가지 주요 패턴을 봅니다. 인프라 서비스 공급자 패턴은 일반적으로 물리적 격리가 있는 여러 NGINX Ingress Controller 배포를 포함하는 반면, 엔터프라이즈 패턴은 일반적으로 네임스페이스 격리가 있는 공유 NGINX Ingress Controller 배포를 사용합니다. 이 섹션에서는 엔터프라이즈 패턴을 심층적으로 살펴봅니다. 여러 NGINX Ingress Controller를 실행하는 방법에 대한 자세한 내용은 설명서를 참조 하세요 .
NGINX Ingress Controller를 사용한 위임
NGINX Ingress Controller는 표준 Kubernetes Ingress 리소스와 사용자 지정 NGINX Ingress 리소스를 모두 지원하여 보다 정교한 트래픽 관리와 여러 팀에 대한 구성 제어 위임을 모두 가능하게 합니다. 사용자 지정 리소스는 VirtualServer, VirtualServerRoute , GlobalConfiguration , TransportServer 및 Policy 입니다 .
NGINX Ingress Controller를 사용하면 클러스터 관리자는 VirtualServer 리소스를 사용하여 외부 트래픽을 백엔드 애플리케이션으로 라우팅하는 Ingress 도메인(호스트 이름) 규칙을 프로비저닝하고 VirtualServerRoute 리소스를 사용하여 특정 URL의 관리를 애플리케이션 소유자와 DevOps 팀에 위임할 수 있습니다.
Kubernetes 클러스터에서 다중 테넌시를 구현할 때 선택할 수 있는 두 가지 모델이 있습니다. 전체 셀프 서비스 및 제한된 셀프 서비스입니다 .
전체 셀프 서비스 구현
전체 셀프 서비스 모델에서 관리자는 NGINX Ingress Controller 구성의 일상적인 변경에 관여하지 않습니다. 관리자는 NGINX Ingress Controller와 배포를 외부에 노출하는 Kubernetes Service를 배포하는 것에만 책임이 있습니다 . 그런 다음 개발자는 관리자를 포함하지 않고 할당된 네임스페이스 내에서 애플리케이션을 배포합니다. 개발자는 TLS 비밀을 관리하고, 도메인 이름에 대한 부하 분산 구성을 정의하고, VirtualServer 또는 표준 Ingress 리소스를 생성하여 애플리케이션을 노출할 책임이 있습니다.
이 모델을 설명하기 위해 다음 다이어그램에 나와 있는 것처럼 두 개의 하위 도메인 과 를 사용하여 샘플 bookinfo 애플리케이션(원래 Istio에서 생성)을 복제합니다. 관리자가 네임스페이스(녹색으로 강조 표시됨)에 NGINX Ingress Controller를 설치하고 배포하면 DevA(분홍색) 팀과 DevB(보라색) 팀이 자체 VirtualServer 리소스를 만들고 네임스페이스( 각각 및 ) 내에서 격리된 애플리케이션을 배포합니다 .a.bookinfo.comb.bookinfo.comnginx-ingressAB
DevA 팀과 DevB 팀은 도메인에 대한 Ingress 규칙을 설정하여 외부 연결을 해당 애플리케이션으로 라우팅합니다.
a.bookinfo.comTeam DevA는 네임스페이스 의 도메인 에 대한 애플리케이션을 노출하기 위해 다음 VirtualServer 리소스 개체를 적용합니다 A.
b.bookinfo.com마찬가지로, DevB 팀은 네임스페이스 의 도메인 에 대한 애플리케이션을 노출하기 위해 다음 VirtualServer 리소스를 적용합니다 B.
제한된 셀프 서비스 구현
제한된 셀프 서비스 모델에서 관리자는 클러스터에 들어오는 트래픽을 적절한 네임스페이스로 라우팅하도록 VirtualServer 리소스를 구성하지만, 네임스페이스의 애플리케이션 구성을 담당 개발 팀에 위임합니다. 이러한 각 팀은 VirtualServer 리소스에서 인스턴스화된 애플리케이션 하위 경로에 대해서만 책임을 지고 VirtualServerRoute 리소스를 사용하여 트래픽 규칙을 정의하고 네임스페이스 내에서 애플리케이션 하위 경로를 노출합니다.
다이어그램에 표시된 것처럼 클러스터 관리자는 nginx-ingress네임스페이스(녹색으로 강조 표시됨)에 NGINX Ingress Controller를 설치 및 배포하고 VirtualServerRoute 리소스 정의를 참조하는 경로 기반 규칙을 설정하는 VirtualServer 리소스를 정의합니다.
/productpage-A이 VirtualServer 리소스 정의는 두 개의 하위 경로에 대한 VirtualServerRoute 리소스 정의를 참조하는 두 개의 경로 기반 규칙을 설정합니다 /productpage-B.
네임스페이스AB 의 앱을 담당하는 개발자 팀은 VirtualServerRoute 리소스를 정의하여 네임스페이스 내의 애플리케이션 하위 경로를 노출합니다. 팀은 네임스페이스별로 격리 되고 관리자가 프로비저닝한 VirtualServer 리소스에서 설정한 애플리케이션 하위 경로를 배포하는 것으로 제한됩니다.
Team DevA(다이어그램의 분홍색)는 관리자가 설정한 애플리케이션 하위 경로 규칙을 노출하기 위해 다음 VirtualServerRoute 리소스를 적용합니다 /productpage-A.
Team DevB(보라색)는 관리자가 설정한 애플리케이션 하위 경로 규칙을 노출하기 위해 다음 VirtualServerRoute 리소스를 적용합니다 /productpage-B.
VirtualServer 및 VirtualServerRoute 리소스에서 구성할 수 있는 기능에 대한 자세한 내용은 NGINX Ingress Controller 설명서를 참조하세요 .
참고: 병합 가능한 Ingress 유형을 사용하여 크로스 네임스페이스 라우팅을 구성할 수 있지만 제한된 셀프 서비스 위임 모델에서는 이 접근 방식에 VirtualServer 및 VirtualServerRoute 리소스와 비교할 때 세 가지 단점이 있습니다.
제한된 셀프 서비스 모델에서 Kubernetes RBAC 활용
Kubernetes 역할 기반 액세스 제어(RBAC)를 사용하면 사용자에게 할당된 역할에 따라 네임스페이스 및 NGINX Ingress 리소스에 대한 사용자 액세스를 규제할 수 있습니다.
예를 들어, 제한된 셀프 서비스 모델에서 특별한 권한이 있는 관리자만 VirtualServer 리소스에 안전하게 액세스할 수 있습니다. 해당 리소스는 Kubernetes 클러스터의 진입점을 정의하기 때문에 오용하면 시스템 전체가 중단될 수 있습니다.
개발자는 VirtualServerRoute 리소스를 사용하여 자신이 소유한 애플리케이션 경로에 대한 Ingress 규칙을 구성하므로 관리자는 개발자가 해당 리소스만 만들 수 있도록 하는 RBAC 정책을 설정합니다. 개발자 액세스를 더욱 규제해야 하는 경우 해당 권한을 특정 네임스페이스로 제한할 수도 있습니다.
완전한 셀프 서비스 모델에서 개발자는 VirtualServer 리소스에 안전하게 액세스할 수 있지만, 관리자가 해당 권한을 특정 네임스페이스로 제한할 수도 있습니다.
RBAC 권한 부여에 대한 자세한 내용은 Kubernetes 설명서를 참조하세요 .
정책 추가
NGINX 정책 리소스는 분산 팀이 멀티 테넌시 배포에서 Kubernetes를 구성할 수 있도록 하는 또 다른 도구입니다. 정책 리소스는 OAuth 및 OpenID Connect (OIDC)를 사용한 인증, 속도 제한 및 웹 애플리케이션 방화벽(WAF)과 같은 기능을 활성화합니다. 정책 리소스는 VirtualServer 및 VirtualServerRoute 리소스에서 참조되어 Ingress 구성에서 적용됩니다.
예를 들어, 클러스터에서 ID 관리를 담당하는 팀은 Okta를 OIDC ID 공급자(IdP)로 사용하여 다음과 같이 JSON 웹 토큰 (JWT) 또는 OIDC 정책을 정의할 수 있습니다.
NetOps 및 DevOps 팀은 이 예와 같이 VirtualServer 또는 VirtualServerRoute 리소스를 사용하여 해당 정책을 참조할 수 있습니다.
NGINX Policy, VirtualServer 및 VirtualServerRoute 리소스를 함께 사용하면 관리자가 구성을 다른 팀에 쉽게 위임할 수 있는 분산 구성 아키텍처가 가능합니다. 팀은 네임스페이스 전반에 걸쳐 모듈을 조립하고 안전하고 확장 가능하며 관리하기 쉬운 방식으로 정교한 사용 사례로 NGINX Ingress Controller를 구성할 수 있습니다.
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
전문가에게 상담받기
NGINX Ingress Controller는 HTTP 트래픽과 함께 TCP 및 UDP 트래픽의 부하를 분산하므로 다음을 포함하여 해당 프로토콜을 기반으로 하는 다양한 앱과 유틸리티의 트래픽을 관리하는 데 사용할 수 있습니다.
NGINX Ingress Controller를 사용한 TCP 및 UDP 로드 밸런싱은 다음과 같은 상황에서 Kubernetes 애플리케이션에 네트워크 트래픽을 분산하는 데도 효과적인 솔루션입니다.
NGINX Ingress Controller에는 TCP/UDP 부하 분산을 지원하는 두 개의 NGINX Ingress 리소스가 함께 제공됩니다.
다음 다이어그램은 GlobalConfiguration 및 TransportServer 리소스에 대한 샘플 사용 사례를 보여줍니다. gc.yaml 에서 클러스터 관리자는 GlobalConfiguration 리소스에서 TCP 및 UDP 리스너를 정의합니다. ts.yaml 에서 DevOps 엔지니어는 MySQL 배포로 트래픽을 라우팅하는 TransportServer 리소스에서 TCP 리스너를 참조합니다.
gc.yaml 의 GlobalConfiguration 리소스는 두 개의 리스너를 정의합니다. syslog 서비스에 연결하기 위한 포트 514의 UDP 리스너와 MySQL 서비스에 연결하기 위한 포트 5353의 TCP 리스너입니다.
ts.yaml 의 TransportServer 리소스의 6~8행은 gc.yaml 에 이름( mysql-tcp) 으로 정의된 TCP 리스너를 참조하고 , 9~14행은 TCP 트래픽을 업스트림으로 보내는 라우팅 규칙을 정의합니다 mysql-db.
rawdata_content_schema이 예에서 DevOps 엔지니어는 MySQL 클라이언트를 사용하여 구성이 제대로 작동하는지 확인합니다. 이는 MySQL 배포 내 데이터베이스 의 테이블 목록이 포함된 출력을 통해 확인됩니다 .
$ echo “SHOW TABLES” | mysql –h <external_IP_address> -P <port> -u <user> –p rawdata_content_schema Enter Password: <password> Tables_in_rawdata_content_schema authors postsUDP 트래픽을 위한 TransportServer 리소스는 비슷하게 구성됩니다. 전체 예제는 GitHub의 NGINX Ingress Controller repo에서 Basic TCP/UDP Load Balancing을 참조하세요. 고급 NGINX 사용자는 repo의 Support for TCP/UDP Load Balancingstream-snippets 예제 에서 볼 수 있듯이 ConfigMap 키를 사용하여 기본 NGINX 구성으로 TransportServer 리소스를 확장할 수 있습니다 .
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
전문가에게 상담받기
2021년 8월 Sprint 2.0에서 NGINX Modern Applications Reference Architecture (MARA)를 공개했을 때 우리는 디자인 목표를 솔직하게 밝혔습니다. 우리는 Kubernetes에서 실행되고 보안, 확장성, 안정성, 모니터링 및 내성을 지원하도록 설계된 최신 애플리케이션 아키텍처의 예를 만들고 싶었습니다. 이 프로젝트는 시간 소모적인 통합 노력 없이 기능적 구성 요소를 결합하는 "플러그 앤 플레이" 방식으로 다양한 인프라에 배포할 수 있어야 했습니다.
Sprint 이후 몇 달 동안 우리는 로드맵을 추진해 왔습니다. 다른 프로젝트와 마찬가지로 우리는 성공과 실패를 겪었고, MARA에 성공 사례를 녹여냈으며, 배운 교훈 목록도 계속 늘렸습니다. 이러한 문제를 문서화하고 이러한 교훈을 염두에 두고 설계함으로써 다른 사람들이 같은 문제에 부딪히지 않도록 할 수 있기를 바랍니다.
우리는 최근 MARA 버전 1.0.0 으로 이정표에 도달했습니다 . 이 버전은 프로젝트 디렉토리를 재구성하고 환경을 인스턴스화하고 파괴하는 프로세스를 변경합니다. 중복된 코드를 제거하고, 향후 추가 사항을 쉽게 수용할 수 있는 디렉토리 구조를 만들고, 관리 스크립트를 표준화했습니다. 이 버전은 MARA의 역사에서 중요한 지점을 나타내므로, 우리는 잠시 멈추어 커뮤니티에 진행 상황을 보고하고, 더 중요한 교훈 중 일부라고 생각되는 것을 기록하고, 앞으로의 로드맵에 대한 정보를 제공하고자 했습니다.
원격 측정 – 메트릭, 로깅 및 추적
MARA의 핵심 기여자들은 대규모로 소프트웨어를 실행한 경험이 있으며 운영, 엔지니어링 및 관리 관점에서 서비스를 제공하는 데 필요한 사항을 이해합니다. 그들은 애플리케이션이 제대로 작동하지 않고 문제가 무엇인지 정확히 파악할 수 있는 쉬운 방법이 없을 때 느끼는 침울함을 알고 있습니다. DevOps 세계에 떠도는 인용문은 이 문제를 간결하게 요약합니다. "마이크로서비스 디버깅은 일련의 살인 미스터리를 푸는 것과 같습니다."
이를 염두에 두고, 우리는 단기 로드맵에서 관찰 가능성 추가를 최우선 순위로 삼았습니다. 이 맥락에서 관찰 가능성에는 로그 관리, 메트릭 및 추적 데이터가 포함됩니다. 그러나 데이터 수집만으로는 충분하지 않습니다. 데이터를 파헤치고 환경에서 무슨 일이 일어나고 있는지에 대한 의미 있는 결정을 내릴 수 있어야 합니다.
추적 옵션에 대한 우리의 탐색은 원격 측정 데이터, 로그, 메트릭 및 추적의 전체 범위를 지원하기 때문에 OpenTelemetry (OTEL)로 이어졌습니다. 우리는 OTEL 에이전트가 모든 추적 데이터를 수집, 처리 및 중복 제거한 다음 OTEL 수집기에 전달하여 집계하고 내보내는 구현을 구상했으며, 워크플로 끝에 시각화 시스템을 사용하여 데이터를 사용 가능하게 만들었습니다. 이 접근 방식은 사용자에게 데이터를 표시하고 분석하기 위한 가장 광범위한 선택권을 제공하는 동시에 OTEL 표준을 활용하여 초기 단계(수집, 집계 등)를 간소화합니다.
우리는 두 단계로 구현을 구축했습니다.
환경에서 OTEL 수집기를 관리하기 위해 Kubernetes용 OpenTelemetry Operator를 배포합니다 .
Bank of Sirius 애플리케이션을 도구화하여 추적 및 메트릭을 방출합니다.
MARA의 원래 버전은 로깅을 위해 Filebeat 와 함께 Elasticsearch를 사용했고, Grafana Loki 로 대체하는 것을 고려했지만 , 당장은 원래의 선택을 유지하기로 했습니다. 지표 측면에서, 우리는 처음에 사용했던 맞춤형 Prometheus 구성을 커뮤니티에서 유지 관리하는 kube-prometheus-stack Helm 차트로 대체하여 Prometheus 와 Grafana 에 기반한 원래 배포를 수정해야 한다는 것을 깨달았습니다. 이 차트는 Grafana, 노드 내보내기 , Kubernetes 환경을 관리하는 데 적합한 일련의 미리 구성된 대시보드 및 스크래핑 대상을 포함한 완전한 Prometheus 환경을 구성합니다. 여기에 F5 NGINX Ingress Controller 와 Bank of Sirius 애플리케이션 에 대한 몇 가지 추가 대시보드를 추가했습니다 .
이는 OTEL을 구현하는 데 필요한 엄청난 양의 작업에 대한 간략한 요약일 뿐입니다. 다른 사람들이 같은 가파른 학습 곡선을 오르는 수고를 덜어주기 위해, 저희는 블로그의 Integrating OpenTelemetry into the Modern Apps Reference Architecture – A Progress Report 에서 전체 프로세스를 문서화했습니다 .
배포 옵션 – Kubeconfig
MARA의 초기 버전에서 우리는 배포 환경으로 Amazon Elastic Kubernetes Service (EKS)를 선택했습니다. 그 이후로 많은 사용자가 비용상의 이유로 랩이나 워크스테이션과 같이 리소스가 덜 필요한 "로컬" 환경에서 MARA를 실행하고 싶다고 말했습니다. 이식성은 원래 프로젝트의 핵심 목표였고(지금도 그렇습니다) 이것이 우리가 그것을 달성할 수 있다는 것을 증명할 기회였습니다. 작업을 더 쉽게 하기 위해 우리는 최소 요구 사항을 충족하는 모든 Kubernetes 클러스터에서 실행할 수 있는 배포 절차를 설계하기로 결정했습니다.
첫 번째 단계로, 우리는 Kubernetes 클러스터와 통신하기 위해 kubeconfig 파일을 읽는 새로운 Pulumi 프로젝트를 MARA에 추가했습니다. 이 프로젝트는 Pulumi Kubernetes 프로젝트와 인프라 프로젝트(후자의 예로는 AWS와 Digital Ocean 프로젝트) 사이에 있습니다. 실제적으로 kubeconfig 프로젝트를 만들면 새로운 인프라 프로젝트를 통합하는 데 대한 장벽이 낮아집니다. 인프라 프로젝트가 kubeconfig 파일, 클러스터 이름, 클러스터 컨텍스트를 kubeconfig 프로젝트에 전달할 수 있다면 MARA 배포 절차의 나머지 부분은 원활하게 작동합니다.
테스트를 위해 K3s , Canonical MicroK8s , minikube를 포함하여 CPU와 메모리 요구 사항이 작은 설치하기 쉬운 Kubernetes 배포판을 여러 개 사용했습니다. 배포판은 모두 2개의 CPU 와 16GB RAM이 있는 Ubuntu 21.10을 실행하는 가상 머신(VM)에 배포되었습니다 . 또한 모든 배포판은 영구 볼륨과 Kubernetes LoadBalancer 지원을 제공하도록 구성되었습니다.
이 프로세스에서 가장 어려운 부분은 프로젝트의 일부인 맞춤형 NGINX Ingress Controller에 사용되는 개인 레지스트리로 작업하는 것이었습니다. (Mara를 배포할 때는 NGINX Open Source 또는 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 Open Source 또는 NGINX Plus 기반)를 사용해야 합니다.
클라우드 기반 배포에 필요한 리소스를 제공하지 않는 로컬 배포를 수용하기 위해 MARA 구성 파일에 여러 튜닝 매개변수를 추가했습니다. 대부분의 매개변수는 Elastic Stack 의 다양한 구성 요소에 대해 요청된 복제본 수와 관련이 있습니다 . 테스트가 진행됨에 따라 배포 환경의 리소스 제약 조건에 따라 MARA를 미세 조정하기 위한 추가 매개변수가 있을 것입니다.
이러한 변경 사항을 적용하면 K3s, MicroK8s 및 Minikube에 성공적으로 배포할 수 있으며 Azure Kubernetes Service (AKS), Digital Ocean , Google Kubernetes Engine , Linode 및 Rancher's Harvester 에서 로직을 성공적으로 테스트했습니다 . 자세한 내용은 MARA Provider Status 페이지 와 블로그의 MARA: Now Running on a Workstation Near You를 참조하세요.
파트너와의 협력
저희 파트너들은 MARA와의 협력에 대해 매우 수용적이고 지지적이었습니다. 그들 중 많은 사람들이 이 프로젝트에 대해 자세히 알아보고, 자사 제품에 이를 어떻게 활용할 수 있는지, 심지어 기능을 어떻게 추가할 수 있는지 문의해왔습니다.
우리는 MARA의 핵심 부분으로 Pulumi를 선택했는데 , 사용하기 쉽고 Python을 지원하기 때문입니다. Python은 매우 인기 있는 언어이기 때문에 MARA 코드를 대규모 커뮤니티에서 쉽게 이해할 수 있습니다. 또한 Pulumi의 활기찬 커뮤니티와 프로젝트 참여는 MARA를 통해 이루고자 하는 커뮤니티 참여의 모델이었습니다.
2021년 후반에 우리는 Sumo Logic 과 협력하여 MARA를 NGINX Ingress Controller를 사용한 클라우드 모니터링 솔루션 의 일부로 만들었습니다 . 이것은 MARA가 플러그 가능하다는 우리의 주장을 시험할 기회였습니다. 과제는 MARA에서 Sumo Logic 솔루션을 Grafana, Prometheus, Elastic으로 대체하는 것이었습니다. 우리는 다른 배포에 사용하는 것과 동일한 로직을 사용하여 솔루션을 성공적으로 구축하고 Sumo Logic SaaS에 연결할 뿐만 아니라 환경에서 메트릭을 가져오도록 구성하게 되어 기뻤습니다.
OpenTelemetry와의 작업의 일환으로 Lightstep 과 협업하여 OTEL 수집기를 쉽게 재구성하여 추적 및 메트릭을 Lightstep의 SaaS 오퍼링으로 내보낼 수 있었습니다. 이는 OTEL이 관찰 가능성의 미래라고 굳게 믿기 때문에 더 조사하고 싶은 분야입니다.
지금까지 얻은 교훈
지금까지 우리가 얻은 가장 큰 교훈은 모듈식 접근 방식의 지혜입니다. Sumo Logic과의 작업은 MARA 구성 요소를 성공적으로 혼합하고 일치시킬 수 있음을 보여줍니다. OTEL을 환경에 더욱 완벽하게 통합함에 따라 추가 확인을 기대합니다. 이전에 Elasticsearch를 Grafana Loki로 로그 관리 환경으로 대체하는 것을 고려하고 있다고 언급했는데, 이는 스택의 리소스 사용량을 줄이기 때문입니다. 그럼에도 불구하고 모든 것을 마이크로서비스로 만들어 극단적인 방향으로 가는 것보다는 "실용적인 모듈성"을 옹호합니다. 예를 들어, 많은 애플리케이션의 로그를 처리할 수 있는 전문화된 서비스를 갖는 것이 합리적이지만 로그 수집, 저장 및 시각화를 위해 별도의 마이크로서비스가 필요하다는 것은 덜 분명합니다.
또한 관련 매개변수를 생략하는 것보다 구성에 명시적으로 포함시켜 기본값을 설정하는 것이 도움이 된다는 것을 알게 되었습니다. 이는 관리자에게 두 가지 면에서 편리합니다. 기본값을 기억할 필요가 없고 구성의 올바른 위치에 올바른 구문으로 이미 나타나는 매개변수를 수정하기만 하면 쉽게 변경할 수 있습니다.
우리가 얻은 또 다른 고통스러운 교훈은 일부 솔루션이 최고이기 때문이 아니라 설치하기 가장 쉽거나 튜토리얼이 가장 좋기 때문에 인기가 있다는 것입니다. 이것이 설계 과정에서 가정에 의문을 제기하고 동료와 상의하는 것이 매우 중요한 이유입니다. 개방적인 의사소통 문화는 문제를 일찍 식별하고 해결하는 데 큰 도움이 됩니다.
그럼에도 불구하고, 우리는 여러 차례에 걸쳐 작동했지만 우리를 궁지에 몰거나 다른 문제를 일으킨 로직을 구현했습니다. 예를 들어, Pulumi를 통해 애플리케이션을 배포하기 시작했을 때, 우리는 ConfigMaps 에 YAML 매니페스트를 사용하여 Pulumi 변환을 통해 변수를 업데이트했습니다. 이는 효과가 있었지만, 여러 가지 이유로 이상적이지 않았습니다. 그 중 가장 중요한 이유는 유지 관리성이었습니다. 다음 반복에서 우리는 kube2pulumi를 사용하여 매니페스트를 Pulumi 코드로 변환하여 ConfigMaps를 빌드하는 데 사용할 수 있도록 함으로써 코드의 가독성과 유지 관리성을 개선했습니다 .
또 다른 교훈은 병합이 배포 YAML에 잘못된 설정을 삽입했을 때 시작되었습니다. 우리는 YAML의 큰 부분을 다시 작성하고 신중하게 검토하여 코드가 구문적으로 올바르고 원하는 대로 작동하는지 확인해야 했는데, 이는 좌절스럽고 시간이 많이 걸리는 과정이었습니다. 향후 문제를 피하기 위해 이제 GitHub 푸시 프로세스 중에 일반 YAML과 Kubernetes 특정 린팅 및 검증을 모두 자동화 했습니다 .
마지막으로, 처음부터 우리의 목표는 메인라인 브랜치가 항상 실행 가능하도록 하는 것이었습니다. 새로운 프로젝트를 체크아웃하고 메인라인에서 관리자가 도입한 문제를 해결해야 할 때는 좌절스럽습니다. 안타깝게도, 우리는 이 부분에서 몇 번 실패했는데, 여기에는 Bank of Sirius 하위 모듈의 예도 포함됩니다.
다음은 무엇인가
저희는 향후 몇 달 동안 NGINX Ingress Controller 빌드 리팩토링, 레지스트리 푸시, Ingress 호스트 이름/IP 주소 로직을 포함한 대규모 개발을 계획하고 있습니다.
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의 잠재력에 대해 기대하고 있으며, 곧 더 포괄적인 구현을 구현할 수 있기를 바랍니다. 전체 구현이 없더라도, 우리의 목표는 테스트를 실행하고, 영향을 측정하고, 데이터가 알려주는 내용에 대한 운영 결정을 내리는 것입니다.
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
전문가에게 상담받기
NGINX Modern Apps Reference Architecture (MARA) 프로젝트를 시작했을 때 , 우리는 이미 플랫폼에 익숙했고 부서 예산으로 비용을 지불할 수 있었기 때문에 AWS를 IaaS 공급자로 선택했습니다. 물론 모든 사람이 같은 경험이나 예산을 가지고 있는 것은 아니며, 여러분 중 많은 분들이 K3s , Canonical MicroK8s , minikube 와 같은 Kubernetes 배포판을 사용하여 로컬에서(랩 기반 환경 또는 워크스테이션에서) MARA를 실행할 수 있는 옵션을 제공해 달라고 요청했습니다 .
여러분의 의견을 듣고, 오늘 MicroK8s에서 MARA를 테스트 했으며, 여러분이 직접 배포할 수 있도록 지침을 제공하게 되어 기쁩니다!
왜 우리는 테스트를 위해 MicroK8s를 선택했을까요? 그것은 MARA에 필요한 DNS, 스토리지, 이탈 기능을 낮은 메모리 Foot-Print로 배포하기 쉬운 모델로 제공하기 때문입니다. MicroK8s를 사용하면 테스트 시나리오를 쉽고 반복적으로 반복하여 합리적인 수준의 성능을 제공하는 배포에 대한 최소 요구 사항을 결정할 수 있습니다.
이 작업이 다른 Kubernetes 배포판의 테스트를 용이하게 할 것으로 기대합니다. 다양한 배포판의 현재 상태에 대한 정보는 GitHub repo를 참조하세요 . 목록에 포함시키고 싶은 선호하는 배포판이 있으면 포크하고 테스트하고 풀 리퀘스트를 생성하세요!
리소스 제약 처리
MARA를 로컬로 실행하는 데 가장 큰 제약은 메모리와 CPU입니다. 예비 테스트 중에 메모리 고갈과 관련된 문제의 대부분이 Elasticsearch와 관련이 있다는 것을 발견했습니다. Kibana는 매우 적은 양의 메모리( 16GB 미만 )가 있는 구성에서는 거의 사용할 수 없습니다. 이 문제를 해결하기 위해 MARA 구성 파일에 전체 Elasticsearch 배포에 일반적으로 있는 중복 보호 기능을 제거하는 설정을 제공했습니다. 이로 인해 실패 모드 수가 늘어나지만 리소스가 제한된 환경에서는 필요한 트레이드오프 입니다.
CPU에 대한 제약은 샘플 Bank of Sirius 애플리케이션 에 부과되는 부하량과 직접 연결됩니다 . MARA 배포에는 Bank of Sirius에 부하를 생성하는 Locust가 포함되어 있으며 , 사용자 수와 새 사용자의 생성 속도에 대한 사용자 제어 설정이 있습니다.
Bank of Sirius의 부하를 늘리면 나머지 시스템에도 영향을 미칩니다. 사용자 Response 속도가 너무 높으면 MARA 성능이 저하되어 구성 요소가 충돌하거나 멈출 가능성이 높습니다. 이러한 동작을 일으키는 값은 사용 가능한 CPU에 따라 다르지만 요구 사항 에 지정된 용량 이상을 사용하여 최대 64명의 사용자와 한 번에 16명의 사용자로 생성된 부하를 처리할 수 있는 배포를 기대할 수 있습니다.
MicroK8s에 MARA 배포
이제 배경 지식을 갖추었으니, MicroK8s에서 MARA를 선보일 준비가 되었습니다!
요구 사항
root최소한 Ubuntu 20.04(Focal) 이상 을 실행하는 시스템(베어메탈 Linux 서버, 가상화 또는 클라우드)에 액세스 :
MARA에 필요한 모든 라이브러리와 바이너리가 있는 로컬 시스템의 Python 3 가상 환경. Python 3이 아직 설치되지 않았다면 다음 명령을 실행합니다.
$ sudo apt update$ sudo apt install -y python3-venvMicroK8s의 통합 MetalLB 로드 밸런서가 NGINX Ingress Controller egress에 할당할 최소 하나의 무료 IPv4 주소 . 로컬호스트를 통해 Bank of Sirius 애플리케이션에 액세스하는 경우 사용 가능한 개인 ( RFC 1918 호환) 주소가 허용됩니다. 예를 들어 네트워크가 192.168.100.0/24인 경우 10.10.10.10과 같은 주소를 사용할 수 있습니다.
Pulumi 계정과 액세스 토큰. 아직 없다면 Deploy MARA 의 1단계 에서 만들게 됩니다 .
Pulumi에서는 상태 파일을 S3 호환 객체 저장소나 로컬 파일 시스템에 저장할 수 있지만 MARA에서는 작성 시점에 이를 지원하지 않습니다. 이 제한은 MARA 또는 Pulumi의 향후 릴리스에서 제거될 예정입니다.
MicroK8s 설치 및 구성
MicroK8s 설치:
$ sudo snap install microk8s --classicmicrok8s (1.23/stable) v1.23.3 from Canonical✓ installed명령을 실행하는 데 필요한 권한을 설정합니다 microk8s. 의 경우 시스템에 대한 권한이 <username>있는 계정을 대체합니다 .root
$ sudo usermod -a -G microk8s <username>$ sudo chown -f -R <username> ~/.kube $ newgrp microk8s새로운 권한이 적용되도록 루트 권한이 있는 계정에서 로그아웃했다가 다시 로그인하세요.
DNS , 스토리지 , MetalLB 에 대한 MicroK8s 애드온을 활성화합니다 .
프롬프트에서 다음 중 하나를 나타내는 형식의 IP 주소 범위를 지정하세요.X.X.X.X‑X.X.X.Y
$ microk8s enable dns storage metallbEnabling DNS Applying manifest ... Restarting kubelet DNS is enabled Enabling default storage class ... Storage will be available soon Enabling MetalLB Enter each IP address range delimited by comma (e.g. '10.64.140.43-10.64.140.49,192.168.0.105-192.168.0.111'): 192.168.100.100-192.168.100.110 Applying Metallb manifest ... MetalLB is enabledMicroK8s가 실행 중인지 확인하세요:
$ microk8s statusmicrok8s is running high-availability: no datastore master nodes: 127.0.0.1:19001 datastore standby nodes: none addons: enabled: dns # CoreDNS ha-cluster # Configure high availability on the current node metallb # Loadbalancer for your Kubernetes cluster storage # Storage class; allocates storage from host directory ...대부분의 유틸리티가 찾을 것으로 예상하는 파일( ~/.kube/config )에 MicroK8s 구성을 로드하고 디렉토리 및 파일에 권장되는 권한을 설정합니다.
$ microk8s config > ~/.kube/config$ sudo chmod 0644 ~/.kube/configMARA Repo 복제 및 MicroK8s 클러스터 설정
MARA 저장소를 복제하고 Bank of Sirius 하위 모듈을 초기화합니다.
$ git clone https://github.com/nginxinc/kic-reference-architectures.git$ cd kic-reference-architectures/ $ git submodule update --init --recursive --remote복제된 MARA 리포의 루트 디렉토리에서 작업합니다(이전 단계에서 해당 디렉토리를 변경했습니다). MicroK8s 클러스터에 대한 Python 가상 환경을 설정합니다.
$ ./bin/setup_venv.sh이 명령은 긴 추적을 생성합니다. 오류가 있는 경우 MARA GitHub repo의 알려진 문제/주의 사항 섹션에서 제안 사항을 확인하세요.
Python 가상 환경을 활성화합니다. 이 명령은 PATH가상 환경을 사용하도록 사용자 및 기타 환경 변수를 설정합니다.
$ source ./pulumi/python/venv/bin/activateMicroK8s 클러스터가 MARA 배포에 맞게 올바르게 구성되었는지 확인하세요.
$ ./bin/testcap.sh This script will perform testing on the current kubernetes installation using the currently active kubernetes configuration and context. Any failures should be investigated, as they will indicate that the installation does not meet the minimum set of capabilities required to run MARA. ... ============================================================== | All tests passed! This system meets the basic requirements | | to deploy MARA. | ==============================================================MARA 배치
이 섹션에서 MARA를 배포하는 데 사용되는 스크립트 start.sh는 배포가 성공하기 위해 추가 작업이 필요한 옵션을 수용합니다. 단순성을 위해 여기서는 다음과 같은 기본 배포를 가정합니다.
MicroK8s 클러스터에 MARA 배포:
스크립트를 실행합니다 start.sh.
아직 Pulumi를 사용하도록 워크스테이션을 구성하지 않은 경우 Pulumi에 로그인하라는 메시지가 표시되고(필요한 경우 계정 생성) Pulumi 계정과 연결된 API 토큰을 입력하라는 메시지가 표시됩니다.
$ ./bin/start.shAdding to [/home/ubuntu/kic-reference-architectures/bin/venv/bin] to PATH Manage your Pulumi stacks by logging in. Run `pulumi login --help` for alternative login options. Enter your access token from https://app.pulumi.com/account/tokens or hit <ENTER> to log in using your browser : <token> Please read the documentation for more details.배포 유형을 선택하고 k프롬프트에 입력하여 kubeconfig 파일로 배포를 빌드합니다. makeDocker가 설치되지 않았다는 경고는 무시합니다. 대신 배포는 레지스트리의 NGINX Ingress Controller 이미지를 사용합니다.
Type a for AWS, k for kubeconfig? k Calling kubeconfig startup script make is not installed - it must be installed if you intend to build NGINX Kubernetes Ingress Controller from source. docker is not installed - it must be installed if you intend to build NGINX Kubernetes Ingress Controller from source.프롬프트에서 생성할 Pulumi 스택의 이름을 지정합니다(여기서는 mara). Pulumi 계정 내에서 고유해야 합니다.
Enter the name of the Pulumi stack to use in all projects: maraSubmodule source found Configuring all Pulumi projects to use the stack: mara Created stack 'mara' NOTICE! Currently the deployment via kubeconfig only supports pulling images from the registry! A JWT is required in order to access the NGINX Plus repository. This should be placed in a file in the extras directory in the root, in a file named jwt.token See https://docs.nginx.com/nginx-ingress-controller/installation/using-the-jwt-token-docker-secret/ for more details and examples. No JWT found; writing placeholder manifest NOTICE! When using a kubeconfig file you need to ensure that your environment is configured to connect to Kubernetes properly. If you have multiple kubernetes contexts (or custom contexts) you may need to remove them and replace them with a simple ~/.kube/config file. This will be addressed in a future release.프롬프트에서 kubeconfig 파일의 전체 경로와 클러스터 이름을 지정합니다. 여기에 있습니다 ./home/<username>/.kube/configmicrok8s-cluster
Provide an absolute path to your kubeconfig filevalue: /home/<username>/.kube/config Provide your clustername value: microk8s-cluster Attempting to connect to kubernetes cluster다음 프롬프트에서 클러스터의 정규화된 도메인 이름(FQDN)을 지정합니다. 스크립트는 FQDN을 두 가지 목적으로 사용합니다. NGINX Ingress Controller를 구성하고 자체 서명된 인증서를 만드는 것입니다(두 번째 용도는 값이 IP 주소가 될 수 없음을 의미합니다). 다른 FQDN을 대체하는 경우 mara.example.com다음 단계에서도 사용해야 합니다.
Create a fqdn for your deploymentvalue: mara.example.comGrafana 관리자 비밀번호를 지정하세요:
Create a password for the grafana admin user; this password will be used to access the Grafana dashboardThis should be an alphanumeric string without any shell special characters; it is presented in plain text due to current limitations with Pulumi secrets. You will need this password to access the Grafana dashboard. value: <password>설치 과정의 흔적이 나타나며 각 단계에 대한 다음 정보가 표시됩니다.
마지막 단계(Bank of Sirius의 경우)가 완료되면 추적에서는 MetalLB가 NGINX Ingress Controller에 할당한 IP 주소(여기 192.168.100.100)와 배포를 위해 선택한 FQDN(여기 mara.example.com)을 배포에 대한 기타 정보와 함께 보고합니다.
The startup process has finished successfully Next Steps: 1. Map the IP address (192.168.100.100) of your Ingress Controller with your FQDN (mara.example.com). 2. Use the ./bin/test-forward.sh program to establish tunnels you can use to connect to the management tools. 3. Use kubectl, k9s, or the Kubernetes dashboard to explore your deployment. To review your configuration options, including the passwords defined, you can access the pulumi secrets via the following commands: Main Configuration: pulumi config -C /jenkins/workspace/jaytest/bin/../pulumi/python/config Bank of Sirius (Example Application) Configuration: pulumi config -C /jenkins/workspace/jaytest/bin/../pulumi/python/kubernetes/applications/sirius K8 Loadbalancer IP: kubectl get services --namespace nginx-ingress Please see the documentation in the github repository for more information이전 단계에서 보고된 FQDN과 IP 주소 간의 매핑을 FQDN을 확인하는 데 사용하는 도구(로컬 /etc/hosts 파일 또는 DNS 서버 등)에서 만듭니다 .
MARA 배포에 대한 요청이 성공했는지 확인합니다. 자체 서명된 인증서를 수락하도록 -k옵션을 포함합니다 curl. 인증서에 대한 자세한 정보를 표시하려면 옵션 을 추가합니다 -v.
$ curl -k -I https://mara.example.comHTTP/1.1 200 OK Server: nginx/1.21.5 Date: Day, DD Mon YYYY hh:mm:ss TZ Content-Type: text/html; charset=utf-8 Content-Length: 7016 Connection: keep-alive브라우저에서 https://mara.example.com 으로 이동하여 Bank of Sirius 웹사이트를 표시합니다. 이 글을 쓰는 시점에서 많은 브라우저(Firefox 및 Safari 포함)에서는 자체 서명 인증서를 사용하여 사이트에 대한 경고를 안전하게 클릭할 수 있습니다. Chrome을 사용하지 않는 것이 좋습니다. 최근 보안 변경으로 인해 사이트에 액세스하는 것이 금지될 가능성이 높습니다.
스크립트를 실행하여 test-forward.shKubernetes 포트 포워딩을 설정하여 MARA 관리 제품군( Elasticsearch , Grafana , Kibana , Locust , Prometheus )의 도구에 액세스할 수 있습니다 . 스크립트는 적절한 서비스 이름을 결정하고 kubectl명령을 실행하여 로컬 포트로 전달합니다.
참고: 포트 포워딩이 제대로 작동하려면 브라우저가 이 명령을 실행하는 명령 셸과 동일한 시스템에서 실행 중이어야 합니다. 그렇지 않은 경우(예: 가상화 환경을 사용하는 경우) 명령은 성공한 것처럼 보이지만 포트 포워딩은 실제로 작동하지 않습니다. 자세한 내용은 GitHub 리포지토리에서 MARA의 관리 도구 액세스를 참조하세요.
$ ./bin/test-forward.shConnections Details ==================================== Kibana: http://localhost:5601 Grafana: http://localhost:3000 Locust: http://localhost:8089 Prometheus: http://localhost:9090 Elasticsearch: http://localhost:9200 ==================================== Issue Ctrl-C to Exit요약
그게 다입니다! 이 지침을 따르면 약 20분 이내에 사용자 환경에서 작동하는 MARA 배포가 실행됩니다. 이 시점에서 다른 Kubernetes 애플리케이션과 마찬가지로 Bank of Sirius 애플리케이션과 상호 작용할 수 있습니다. 시작하기에 좋은 방법은 내장된 관찰 도구를 사용하여 Locust로 다양한 양의 부하를 생성할 때 환경이 어떻게 작동하는지 테스트하는 것입니다.
우리의 목표는 가능한 한 많은 Kubernetes 사용자에게 MARA를 최대한 유용하게 만드는 것입니다. 일부 구성 요소에 대한 선택 사항이 마음에 들지 않으신가요? 구성 요소를 대체하고 공유하고 싶으시다면 풀 리퀘스트를 여는 것을 권장합니다. 또한, 우리의 repo의 Issues and Discussions 페이지 에서 생각을 공유하고 질문을 해주세요. 의심스러운 가정에 대한 질문도 포함됩니다.
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
전문가에게 상담받기
NGINX에서는 지난 몇 년 동안 애플리케이션을 진정으로 현대적이고 적응적으로 만들어야 할 필요성에 대해 논의해 왔습니다 . 즉, 이식성, 클라우드 네이티브, 복원성, 확장성 및 업데이트 용이성을 갖춰야 합니다. 최근에는 현대적 앱의 생성과 제공을 용이하게 하는 두 가지 개념이 대두되었습니다. 첫 번째는 Platform Ops 로, 기업 수준의 플랫폼 팀이 개발 및 DevOps 팀이 업무를 수행하는 데 필요한 모든 도구를 큐레이션, 유지 관리, 연결 및 보안합니다. 두 번째는 Shifting Left로 , 개발 라이프사이클의 초기 단계에서 프로덕션 등급 보안, 네트워킹 및 모니터링을 애플리케이션에 통합하는 것을 의미합니다. 개발자는 이전에 ITOps에 속했던 기능에 대한 책임이 더 커지지만 동시에 해당 기능을 구현하는 방법에 대한 선택권과 독립성이 더 커집니다.
좋은 말처럼 들리지만, 실제로 Platform Ops를 구현하고 인프라와 운영 툴링을 "좌측으로 이동"하는 것은 어렵습니다. 우선, 점점 더 많은 앱이 컨테이너화된 환경에서 고도로 분산된 방식으로 배포되고 있으며, 증가하는 수의 Kubernetes 오케스트레이션 엔진 중 하나를 사용하고 있습니다. 또한 기업은 클라우드 간 및 클라우드와 온프레미스 환경 간의 차이에 얽매이지 않고 여러 환경에 앱을 배포하고자 합니다.
현대 앱을 위한 "황금 이미지"
당연히 그렇듯이, 우리의 고객과 커뮤니티는 직면한 과제에 대한 도움을 계속 요청합니다. 그들은 모든 좋은 것을 원하지만, 보안, 네트워킹, 관찰 가능성 및 성능 모니터링, 확장 등 모든 부분을 하나로 모으려면 실제 작업이 필요합니다. 프로덕션 환경에 충분히 견고한 결과 플랫폼을 만들려면 더 많은 작업이 필요합니다. 그들은 "단일 리포에서 실행할 수 있는 최신 앱에 대한 '골든 이미지'가 없는 이유는 무엇일까?"라고 궁금해합니다.
좋은 질문이고, 우리는 좋은 답을 내는 것을 우리만의 과제로 삼았습니다. 첫째, 우리는 질문을 더 구체적으로 재구성했습니다. 우리는 고객과 커뮤니티가 다음과 같은 질문을 하고 있다고 생각합니다. "다양한 소프트웨어 제품을 더욱 응집력 있는 전체로 통합하고, 스택을 조정하여 올바른 구성과 설정을 확정하고, 작업과 수고를 덜어줄 수 있나요? 그리고 기본 서비스와 기능의 차이로 인해 주요 구성을 변경하지 않고도 다양한 클라우드에서 애플리케이션을 실행하기 쉽게 만들어줄 수 있나요?"
우리는 이러한 질문을 전체 커뮤니티에 유익한 것으로 진정으로 해결하는 솔루션을 봅니다. 수백 개의 기업과 모든 주요 클라우드 공급업체의 파트너뿐만 아니라 진정으로 제로섬이 아닌 승리입니다. 이상적으로는 솔루션이 "장난감"이 아니라 견고하고 테스트되었으며 Kubernetes 환경에서 실행되는 라이브 프로덕션 애플리케이션에 배포할 준비가 된 코드입니다. 그리고 솔직히 말해서, 우리는 누구나 GitHub에서 바로 우리의 작업을 훔칠 수 있기를 바랍니다.
요점은, 오늘 NGINX Sprint 2.0 에서 우리는 솔루션 출시를 발표합니다. 모던 앱 레퍼런스 아키텍처 (MARA)의 첫 번째 반복, 모던 앱을 위한 오픈 소스 아키텍처 및 배포 모델입니다. 여러분이 좋아하고, 사용하고, 훔치고, 더 나은 방법으로 개선하거나 사용자 지정하기 위해 수정하거나 포크하기를 바랍니다. 이 게시물은 우리가 무엇을 만들고 어떻게 작동하는지 살펴봅니다.
현대적 적응형 애플리케이션 정의
먼저, 이상적인 현대적이고 적응적인 애플리케이션을 정의해 보겠습니다. 마이크로서비스로 구성되고, 컨테이너화되고, 클라우드 네이티브 디자인 원칙(느슨하게 결합되고, 확장하기 쉽고, 인프라에 묶이지 않음)을 준수할 수 있지만 반드시 그럴 필요는 없습니다. 현대 애플리케이션의 정신의 일부는 인프라 추상화를 활용하도록 특별히 설계하는 것입니다. 이 정의는 간단하지만 모든 참조 아키텍처에 대한 기본 템플릿을 확립하기 때문에 중요합니다.
최신 애플리케이션 아키텍처의 핵심 요소로는 이식성, 확장성, 복원성, 민첩성이 있습니다.
참조 아키텍처 설계
우리는 최신 앱 정의와 배포 패턴의 기본 요구 사항을 충족하는 플랫폼을 만들고 싶었습니다. 기술적 목표 외에도 최신 앱 디자인 원칙을 설명하고 커뮤니티가 Kubernetes에서 배포하도록 장려하고 싶었습니다. 그리고 물론, 개발자, DevOps 및 Platform Ops 팀이 놀고, 수정하고, 개선할 수 있는 "훔칠 수 있는" 코드를 제공하고 싶었습니다. 간단히 말해서, 우리는 다음을 제공하고 싶었습니다.
플랫폼의 첫 번째 버전을 위해 내린 디자인과 파트너십 선택 사항은 다음과 같습니다(다음 버전에 대한 계획은 버전 2의 Many More Integrations and More Flexibility 참조 ). 우리는 레퍼런스 앱을 파트너에게 포괄적으로 만드는 것이 파트너와 커뮤니티 참여를 촉진하는 데 중요하다고 굳게 믿습니다.
코드가 배포되는 방법
샘플 애플리케이션을 설치하고 배포하려면 시작 스크립트를 호출하는 단일 명령을 실행하고 다음 Pulumi 프로젝트가 표시된 순서대로 실행됩니다. 각 프로젝트 이름은 리포지토리의 루트 디렉토리를 기준으로 디렉토리 이름에 매핑됩니다 . 자세한 내용은 README를 참조하세요 .
vpc - Defines and installs VPC and subnets to use with EKS └─eks - Deploys EKS └─ecr - Configures ECR for use in EKS cluster └─kic-image-build - Builds new NGINX Ingress Controller image └─kic-image-push - Pushes image built in previous step to ECR └─kic-helm-chart - Deploys NGINX Ingress Controller to EKS cluster └─logstore - Deploys Elastic log store to EKS cluster └─logagent - Deploys Elastic (filebeat) logging agent to EKS cluster └─certmgr - Deploys cert-manager.io Helm chart to EKS cluster └─anthos - Deploys Bank of Anthos application to EKS cluster버전 2에서는 더 많은 통합과 더 큰 유연성이 제공됩니다.
저희는 초기 노력이 Kubernetes 환경에 필요한 모든 통합을 제공하지 못할 수 있다는 점을 알고 있습니다. Platform Ops는 스마트하지만 무제한적인 선택에 관한 것입니다. Platform Ops, DevOps 및 개발자 팀이 새로운 참조 플랫폼을 시도하고 잠재적으로 채택하기 쉽도록 단기적으로 다음을 포함한 많은 개선 사항을 계획하고 있습니다.
NGINX Controller와 통합하여 NGINX Plus Ingress Controller를 관리하고 모니터링합니다.
[ 편집기 – NGINX Controller는 이제 F5 NGINX Management Suite 입니다 .]
저희는 저희의 작업이 다른 참조 플랫폼의 프레임워크가 되고 모든 유형의 차별화된 현대적 애플리케이션을 구축하기 위한 "도용 가능한" 시작점이 되기를 바랍니다. Kubernetes는 현대적 애플리케이션을 구축하고 Platforms Ops와 Shift‑left 문화를 강화하는 데 매우 강력한 메커니즘이기 때문에 참조 아키텍처가 더 광범위하고 플러그인이 가능할수록 더 좋습니다. 저희는 여러분, 커뮤니티가 저희 작업에 대해 어떻게 생각하는지, 그리고 더 중요한 것은 여러분이 그것으로 무엇을 구축하는지 보고 싶습니다.
위 내용과 같이 NGINX Ingress Controller 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
전문가에게 상담받기