블로그 | NGINX

Kubernetes Ingress 및 Egress 트래픽 관리를 단순화하는 방법

NGINX-F5-수평-검정-유형-RGB의 일부
케이트 오스본 썸네일
케이트 오스본
2021년 6월 28일 게시

서비스 메시가 Kubernetes 환경 관리를 실제로 더 복잡하게 만들 수 있는 한 가지 이유는 서비스 메시를 Ingress 컨트롤러 와 별도로 구성해야 하는 경우입니다. 별도의 구성은 시간 많이 걸리는 것이 아닙니다. 이러한 구성 오류는 적절한 트래픽 라우팅을 방해하고 심지어 보안 취약성(악의적인 행위자가 제한된 앱에 액세스하는 경우)과 열악한 환경(고객이 권한이 있는 앱에 액세스할 수 없는 경우)으로 이어질 수 있는 구성 오류의 가능성을 높입니다. 별도로 구성을 수행하는 데 걸리는 시간 외에도 오류 문제 해결에 더 많은 시간을 소모하게 됩니다.

NGINX Plus 기반 NGINX Ingress Controller를 NGINX Service Mesh 와 통합하여 수신 및 송신 mTLS 트래픽을 모두 제어하면 이러한 문제를 피하고 시간을 절약할 수 있습니다. 이 비디오 데모에서는 전체 단계를 다룹니다.

지원 문서는 다음 섹션에서 참조됩니다.

필수 조건 (0:18)

실제 데모를 시작하기 전에 다음과 같은 전제 조건을 수행했습니다.

  1. Kubernetes 클러스터에 NGINX Server Mesh 제어 평면을 설치하고 서비스 메시에 대한 mTLS와 엄격한 정책을 설정했습니다 .

  2. Kubernetes 클러스터에 NGINX Plus 기반 NGINX Ingress Controller를 DaemonSet이 아닌 배포로 설치하고 egress를 활성화 하고 LoadBalancer 유형의 서비스로 노출했습니다 .

    메모: 이 데모는 NGINX 오픈 소스 기반 NGINX Ingress Controller와 함께 작동하지 않습니다. 읽기 편하도록 이 블로그의 나머지 부분에서는 NGINX Plus 기반 NGINX Ingress Controller를 간단히 "NGINX Ingress Controller"라고 합니다.

  3. 당사의 지침 에 따라 샘플 bookinfo 앱을 다운로드하고, NGINX 서비스 메시 사이드카를 주입하고, 앱을 배포했습니다.

1단계에서 만들어진 엄격한 정책으로 인해 메시 외부의 클라이언트에서 bookinfo 앱으로 보내는 요청은 사이드카에서 거부됩니다. 데모에서 다음 명령을 먼저 실행하여 포트 포워딩을 설정하여 이를 보여드리겠습니다.

> kubectl port-forward svc/product-page 9080 127.0.0.1:9080 -> 9080에서 전달 [::1]:9080 -> 9080에서 전달 9080에 대한 연결 처리

앱에 접속하려고 하면 상태 코드가 나타납니다.503 왜냐하면 우리 로컬 머신이 서비스 메시의 일부가 아니기 때문입니다.

> 컬 로컬호스트:9080503

NGINX 서비스 메시를 사용하여 NGINX Ingress Controller 배포(1:50)

앱을 노출하는 과정의 첫 번째 단계는 NGINX Ingress Controller 인스턴스를 배포하는 것입니다. 해당 지침은 'Kubernetes를 위한 NGINX Plus Ingress Controller로 배포 ' 튜토리얼에서 제공됩니다.

NGINX는 이러한 목적을 위해 Deployment와 DaemonSet 매니페스트를 모두 제공합니다. 데모에서는 배포 매니페스트인 nginx-plus-ingress.yaml을 사용합니다. 여기에는 동일한 NGINX Ingress Controller 인스턴스를 통해 수신 및 송신 트래픽을 모두 라우팅하기 위한 주석이 포함되어 있습니다.

매니페스트를 사용하면 NGINX Ingress Controller와 NGINX Service Mesh의 인증 기관(CA)인 Spire를 직접 통합할 수 있으므로 NGINX Service Mesh 사이드카를 NGINX Ingress Controller에 주입할 필요가 없습니다. 대신, NGINX Ingress Controller는 Spire CA에서 직접 인증서와 키를 가져와 메시의 포드에서 mTLS에 사용합니다. 매니페스트에는 Spire 에이전트 주소가 지정되어 있습니다.

그리고 Spire 에이전트 UNIX 소켓을 NGINX Ingress Controller Pod에 마운트합니다.

매니페스트에 대해 주목해야 할 마지막 사항은 -enable-internal-routes CLI 인수로, 이를 통해 송신 서비스로 라우팅할 수 있습니다.

데모를 시작하기 전에 kubectl apply -f nginx-plus-ingress.yaml 명령을 실행하여 NGINX Ingress Controller를 설치했고 , 이때 nginx-ingress 네임스페이스에서 배포를 검사합니다. 다음 출력의 READY 열에서 볼 수 있듯이 NGINX Service Mesh 사이드카를 주입하지 않았기 때문에 NGINX Ingress Controller Pod에 대한 컨테이너가 하나뿐입니다.

또한 클러스터 외부의 NGINX Ingress Controller의 외부 IP 주소(여기서는 35.233.133.188)를 노출하기 위해 LoadBalancer 유형의 서비스를 배포했습니다. 해당 IP 주소에서 샘플 bookinfo 애플리케이션에 접속하겠습니다.

> kubectl get pods --namespace=nginx-ingress 이름 준비 상태 재시작 연령 pod/nginx-ingress-867f954b8f0fzdrm 1/1 실행 중 0 3d3h 이름 유형 클러스터-IP 외부-IP ... service-nginx-ingress LoadBalancer 10.31.245.207 35.233.133.188 ... ... 항구 연령 ... 80:31469/TCP, 443:32481/TCP 4d2h ...

표준 Kubernetes Ingress 리소스를 사용하여 앱 노출(3:55)

이제 bookinfo-ingress.yaml 에 정의된 표준 Kubernetes Ingress 리소스를 사용하여 메시에 bookinfo 앱을 노출합니다. 해당 지침은 'NGINX Plus Ingress Controller를 사용하여 애플리케이션 노출 ' 튜토리얼에서 제공됩니다.

리소스는 10번째 줄에서 bookinfo 앱에 대한 Kubernetes Secret을 참조하고 bookinfo.example.com 에 대한 요청이 productpage 서비스로 전송되도록 지정하는 라우팅 규칙을 포함합니다( 11~18번째 줄 ). 비밀은 bookinfo-secret.yaml 에 정의되어 있습니다:

데모에서는 자체 서명된 키와 인증서를 로드하려면 다음 명령을 실행합니다.

> kubectl apply -f bookinfo-secret.yaml secret/bookinfo-secret 변경되지 않음

Ingress 리소스를 활성화합니다.

> kubectl apply -f bookinfo-ingress.yaml ingress.networking.k8s.io/bookinfo-ingress 삭제됨

그리고 출력 끝의 이벤트에서 확인된 대로 Ingress Controller가 리소스에 정의된 경로를 추가했는지 확인합니다.

> kubectl describe ingress bookinfo-ingress ...
이벤트:
  유형 이유 나이 발신자 메시지 ---- ------ ---- ---- ------- 정상 AddedOrUpdated 5s nginx-ingress-controller 구성 ... ...default/bookinfo-ingress가 추가되거나 업데이트되었습니다.

데모에서는 이제 브라우저를 사용하여 https://bookinfo.example.com/ 에서 bookinfo 앱에 액세스합니다. (이전에 로컬 /etc/hosts 파일에 Ingress Controller 서비스의 IP 주소(위에서 언급한 데모의 35.233.133.188)와 bookinfo.example.com 간의 매핑을 추가했습니다. 자세한 내용은 설명서를 참조하세요.) 이 페이지의 Book Reviews 섹션에 있는 정보는 bookinfo.yaml 에 정의된 리뷰 서비스의 세 가지 버전을 거치며 요청이 순환함에 따라 주기적으로 변경됩니다( 다운로드 ).

다음으로 클러스터로의 유입 트래픽을 검사합니다 . NGINX Ingress Controller의 공개 IP 주소를 통해 productpage 서비스에 요청을 하기 위해 generate-traffic.sh 스크립트를 실행한 다음, nginx-meshctl top 명령을 실행하여 트래픽을 모니터링합니다.

> nginxmesh-ctl top deploy/productpage-v1 배포 방향 리소스 성공률 P99 P90 P50 ... productpage-v1 To details-v1 100.00% 3ms 3ms 2ms To reviews-v2 100.00% 99ms 90ms 20ms To reviews-v3 100.00% 99ms 85ms 18ms To reviews-v1 100.00% 20ms 17ms 9ms From nginx-ingress 100.00% 192ms 120ms 38ms ... 요청 수 ... 14 ... 5 ... 5 ... 12

NGINX VirtualServer 리소스를 사용하여 앱 노출(6:45)

다음으로 NGINX VirtualServer 리소스를 사용하여 앱을 노출하는 대체 방법을 보여드리겠습니다. 이는 트래픽 분할 및 콘텐츠 기반 라우팅과 같은 보다 복잡한 트래픽 처리를 지원하는 맞춤형 NGINX Ingress Controller 리소스입니다.

먼저 표준 Ingress 리소스를 삭제합니다.

> kubectl delete -f bookinfo-ingress.yaml ingress.networking.k8s.io "bookinfo-ingress" 삭제됨

bookinfo-vs.yaml 파일은 bookinfo-ingress.yaml 과 동일한 비밀로 mTLS를 구성합니다( 7~8행 ). 9~12행은 productpage 서비스를 업스트림으로 정의하고, 13~24행은 bookinfo.example.com 에서 이루어지는 모든 GET 요청을 해당 업스트림으로 전송하는 경로를 정의합니다. GET 이외의 HTTP 메서드의 경우 상태 코드를 반환합니다.405 .

우리는 리소스를 적용합니다:

> kubectl apply -f bookinfo-vs.yaml virtualserver.kubernetes.nginx.org/bookinfo-vs 생성됨

그런 다음 Ingress 리소스에서와 동일한 단계를 수행합니다. 즉, kubectl describe 명령을 실행하여 올바른 배포를 확인하고 브라우저에서 앱에 액세스합니다. 앱이 올바르게 작동하고 있다는 또 다른 확인은 POST 메서드를 거부한다는 것입니다.

> curl -k -X POST https://bookinfo.example.com/ 메서드가 허용되지 않습니다.

NGINX Ingress Controller를 사용하여 보안 Egress 경로 구성(8:44)

이제 NGINX Ingress Controller를 통해 송신 트래픽을 라우팅하는 방법을 보여드리겠습니다. NGINX Plus Ingress Controller를 사용하여 보안된 송신 경로 구성 튜토리얼에서는 다양한 샘플 앱을 사용하여 이 프로세스를 다룹니다.

우리는 이미 bash.yaml 에 간단한 bash pod를 정의하고 요청을 보내는 기본 네임스페이스에 배포했습니다. 이 출력의 READY 열에 표시된 대로 NGINX 서비스 메시 사이드카를 통해 주입되었습니다.

> kubectl get all 이름 준비 상태 재시작 연령 pod/bash-6ccb678958-zsgm7 2/2 실행 중 0 77초 이름 유형 클러스터 IP 외부 IP 포트 연령 service/kubernetes 클러스터 IP 10.31.240.1 <없음> 443/TCP 4d2h ...

NGINX 서비스 메시에 속하지 않은 엔터티인 송신 서비스 로의 요청을 포드 내부에서 활성화하려는 경우가 여러 가지 있습니다. 배포된 서비스의 예는 다음과 같습니다.

  • 클러스터 외부
  • 다른 클러스터에서
  • 동일한 클러스터에 있지만 NGINX 서비스 메시 사이드카로 주입되지 않음

데모에서는 최종 사용 사례를 고려하고 있습니다. NGINX 서비스 메시에서 제어되지 않고 NGINX 서비스 메시 사이드카의 자동 주입이 비활성화된 레거시 네임스페이스에 배포된 애플리케이션이 있습니다. 앱에서 실행되는 Pod가 하나뿐입니다.

> kubectl get all --namespaces=legacy 이름 준비 상태 재시작 연령 pod/target-5f7bcb96c6-km9lz 1/1 실행 중 0 27m 이름 유형 클러스터 IP 외부 IP 포트 연령 service/target-svc 클러스터 IP 10.31.245.213 <없음> 80/TCP,443/TCP 27m ...

NGINX 서비스 메시에 대해 엄격한 mTLS 정책을 구성했다는 점을 기억하세요. 따라서 두 서비스가 서로를 인증할 수 없기 때문에 bash 포드에서 대상 서비스로 직접 요청을 전송할 수 없습니다. 우리가 시도하면 상태 코드가 나타납니다.503 여기에 그림으로 나타낸 바와 같습니다.

> kubectl exec -it bash-6ccb678958-zsgm7 -c bash -- curl 대상-svc.legacy curl: (56) 수신 실패: 피어 503 명령에 의해 연결이 재설정되었으며 종료 코드 56으로 종료되었습니다.

해결 방법은 bash pod가 NGINX Ingress Controller를 통해 송신 트래픽을 보낼 수 있도록 하는 것입니다. bash.yaml14-15번째 줄 에 있는 주석의 주석 처리를 제거합니다.

그런 다음 새로운 구성을 적용합니다.

> kubectl apply -f bash.yaml deployment.apps/bash 구성됨

새로운 bash pod가 시작되었는지 확인하세요.

> kubectl get pods 이름 준비 상태 재시작 나이 bash-678c8b4579-7sfml 2/2 실행 중 0 6s bash-6ccb678958-zsgm7 2/2 종료 중 0 3m28s

이제 이전과 동일한 kubectl exec 명령을 실행하여 bash pod에서 대상 서비스로 요청을 보내면 상태 코드가 표시됩니다.404 대신에503 . 이는 bash pod가 NGINX Ingress Controller에 요청을 성공적으로 전송했지만, 정의된 경로가 없기 때문에 컨트롤러가 요청을 어디로 전달해야 할지 모른다는 것을 나타냅니다.

legacy-route.yaml 에 다음 Ingress 리소스 정의를 사용하여 필요한 경로를 만듭니다. 7번째 줄의 내부 경로 주석은 대상 서비스가 인터넷에 노출되지 않고, NGINX 서비스 메시 내의 워크로드에만 노출된다는 것을 의미합니다.

새 리소스를 활성화하고 NGINX Ingress Controller가 리소스에 정의된 경로를 추가했는지 확인합니다.

> kubectl apply -f legacy-route.yaml ingress.networking.k8s.io/target-internal-route가 생성되었습니다. > kubectl describe ingress target-internal-route -n legacy ...
이벤트:
  유형 이유 나이 발신자 메시지 ---- ------ ---- ---- ------- 정상 AddedOrUpdated 6s nginx-ingress-controller 구성 ... ...legacy/target-internal-route가 추가되거나 업데이트되었습니다.

이제 kubectl exec 명령을 실행하면 대상 서비스에 도달합니다.

{"요구사항": {"방법": "GET" "url": "/",
"host": "target-svc.legacy",
"remoteAddr": "10.28.2.76:56086"}}

NGINX Ingress Controller를 통해 송신 트래픽을 라우팅하는 이점은 클러스터 내부에서 어떤 외부 서비스에 접근할 수 있는지 정확하게 제어할 수 있다는 것입니다. 즉, 경로를 정의한 서비스에만 해당됩니다.

데모에서 보여드릴 마지막 내용은 이탈 트래픽을 모니터링하는 방법입니다. kubectl exec 명령을 실행하여 여러 요청을 보낸 후 다음 명령을 실행합니다.

> nginxmesh-ctl top deploy/nginx-ingress -n nginx-ingress 배포 방향 리소스 성공률 P99 P90 P50 요청 수 nginx-ingress 대상으로 100.00% 1ms 1ms 1ms 9 bash에서 100.00% 0ms 0ms 0ms 9

지연에 "아니오"라고 말하세요 - NGINX Ingress Controller를 사용하여 NGINX 서비스 메시를 시도하세요

많은 서비스 메시가 유입 및 유출 게이트웨이 옵션을 제공하지만, NGINX 통합을 통해 지연 시간이 단축되는 추가 이점을 누릴 수 있을 것으로 생각합니다. 대부분의 메시는 Ingress 컨트롤러에 사이드카를 삽입해야 하며, 이를 위해 트래픽이 앱으로 가는 길에 추가 홉을 만들어야 합니다. 몇 초가 중요하며, 디지털 경험 속도를 늦추는 추가 이동으로 인해 고객이 다른 곳으로 눈을 돌릴 수도 있습니다. NGINX Service Mesh는 NGINX Ingress Controller에 사이드카를 주입하지 않기 때문에 불필요한 지연 시간을 발생시키지 않습니다. 대신, 메시의 CA인 Spire와 직접 통합하여 NGINX Ingress Controller가 NGINX Service Mesh의 일부가 됩니다. NGINX Ingress Controller는 Spire 에이전트로부터 인증서와 키를 간단히 가져와 메시형 Pod와 mTLS 인증서 교환에 참여하는 데 사용합니다.

Kubernetes용 NGINX Ingress Controller에는 두 가지 버전이 있습니다. NGINX 오픈 소스와 NGINX 플러스. 이 블로그에서 설명한 대로 NGINX Service Mesh와 함께 NGINX Ingress Controller를 배포하려면 무료 30일 평가판이 제공되는 NGINX Plus 버전을 사용해야 합니다.

NGINX Service Mesh는 완전히 무료이며 즉시 다운로드 할 수 있으며 10분 이내에 배포할 수 있습니다! 시작하려면 문서를 확인하고 GitHub을 통해 결과를 알려주세요.


"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."