본문 바로가기

Infrastructure/Kubernetes

[CKA] Networking (Ingress)

Networking (Ingress)

  • 이번 장에서는 Certified Kubernetes Administrator (CKA) 을 준비하며 "Ingress"에 대해서 자세하게 알아보도록 한다.

Ingress

초기 배포 시나리오

  • 온라인 스토어 애플리케이션: my-onlinestore.com에서 접근 가능한 온라인 스토어 애플리케이션을 쿠버네티스 클러스터에 배포한다.
  • 배포 및 서비스: 애플리케이션은 파드로 배포되고 MySQL 데이터베이스는 mysql-service(ClusterIP) 서비스를 통해 애플리케이션에 연결된다.
  • 외부 접근: 애플리케이션을 외부에서 접근할 수 있도록 NodePort 서비스(예: 38080 포트)를 생성한다.

  • DNS 설정: DNS 서버를 설정하여 노드 IP 주소에 my-onlinestore.com 도메인을 연결한다.

  • 포트 번호 제거: 사용자가 포트 번호를 입력하지 않도록 프록시 서버를 사용하여 80 포트 요청을 38080 포트로 전달한다.

클라우드 환경에서의 배포

  • LoadBalancer 서비스: Google Cloud Platform(GCP)과 같은 클라우드 환경에서는 NodePort 대신 LoadBalancer 서비스를 사용할 수 있다.
  • 클라우드 로드 밸런서 프로비저닝: 쿠버네티스는 GCP에 네트워크 로드 밸런서 프로비저닝 요청을 보내고 GCP는 트래픽을 서비스 포트로 라우팅하는 로드 밸런서에 자동으로 배포한다.
  • 외부 IP 주소: 로드 밸런서는 외부 IP 주소를 가지며 DNS를 통해 my-onlinestore.com 도메인에 연결된다.

다중 서비스 배포 및 문제점

  • 비디오 스트리밍 서비스 추가: my-onlinestore.com/watch에서 접근 가능한 비디오 스트리밍 서비스를 추가한다.
  • 별도 배포 및 서비스: 비디오 스트리밍 서비스는 별도의 배포 및 LoadBalancer 서비스(video-service)로 배포된다.
  • 별도 로드 밸런서 및 IP 주소: 각 LoadBalancer 서비스는 별도의 로드 밸런서 및 IP 주소를 가지므로 클라우드 비용이 증가한다.

  • URL 기반 라우팅: 사용자가 입력한 URL에 따라 트래픽을 다른 서비스로 라우팅해야 한다.
  • 로드 밸런서 재구성: 새로운 서비스가 추가될 때마다 로드 밸런서를 재구성해야 한다.
  • SSL/TLS 설정: HTTPS를 사용하여 보안을 강화해야 하며, SSL/TLS 설정은 애플리케이션, 로드 밸랜서, 프록시 서버 등 다양한 수준에서 수행할 수 있다.
  • 개발자 부담 증가: 개발자가 애플리케이션 수준에서 SSL/TLS를 구현하는 것은 부담이 된다.

기존 방식의 문제점

  • 복잡한 구성 관리: 다중 서비스, URL 기반 라우팅, SSL/TLS 설정 등을 관리하는 것은 복잡하고 어렵다.
  • 팀 간 협업 필요: 방화벽 규칙 설정 등 다양한 팀의 협업이 필요하다.
  • 비용 증가: 각 서비스마다 클라우드 로드 밸런서를 프로비저닝하는 것은 비용이 많이 든다.

Ingress의 역할

  • 단일 외부 접근 URL: Ingress는 사용자가 애플리케이션에 접근할 수 있도록 단일 외부 접근 URL을 제공한다.
  • URL 기반 라우팅: URL 경로에 따라 클러스터 내의 다른 서비스로 트래픽을 라우팅하도록 구성할 수 있다.
  • SSL/TLS 보안: SSL/TLS 보안을 구성하여 HTTPS를 통한 안전한 통신을 제공한다.
  • Layer 7 로드 밸런서: Ingress는 쿠버네티스 클러스터에 내장된 Layer 7 로드 밸런서 역할을 한다.
  • 쿠버네티스 기본 요소: 다른 쿠버네티스 객체와 마찬가지로 쿠버네티스 기본 요소를 사용하여 구성할 수 있다.

Ingress 접근 방식

  • 외부 노출: Ingress는 클러스터 외부에서 접근할 수 있도록 노출되어야 한다.
    • NodePort 서비스를 사용하거나 클라우드 네이티브 LoadBalancer를 사용한다.
    • 이는 일회성 구성이며, 이후 모든 로드 밸런싱, SSL/TLS, URL 기반 라우팅 설정은 Ingress 컨트롤러에서 수행된다.

Ingress 작동 방식

  • 리버스 프록시/로드밸런싱 솔루션: Ingress는 Nginx, HAProxy, Traefik과 같은 리버스 프록시 또는 로드 밸런싱 솔루션을 기반으로 구현된다.
  • Ingress 컨트롤러: 지원되는 솔루션을 쿠버네티스 클러스터에 배포하여 Ingress 컨트롤러를 구성한다.
  • Ingress 리소스: URL 라우팅, SSL/TLS 인증서 등 Ingress 구성을 정의하는 규칙 집합이다.
    • 파드, Deployment, Service와 마찬가지로 정의 파일을 사용하여 생성된다.

Ingress 컨트롤러

  • 쿠버네티스 클러스터는 기본적으로 Ingress 컨트롤러를 제공하지 않는다.
  • Ingress 리소스를 사용하려면 Ingress 컨트롤러를 수동으로 배포해야 한다.
  • Ingress 컨트롤러가 배포되지 않은 상태에서 Ingress 리소스를 생성해도 작동하지 않는다.

  • 쿠버네티스 프로젝트 지원: GCE 및 Nginx는 쿠버네티스 프로젝트에서 지원 및 유지 관리된다.
  • 컨트롤러의 역할: Ingress 컨트롤러는 단순한 로드 밸런서나 Nginx 서버가 아닌 쿠버네티스 클러스터를 모니터링하고 Ingress 리소스 변경 사항을 감지하여 Nginx 서버를 동적으로 구성하는 기능을 포함한다.

  • ConfigMap: Nginx 설정 옵션을 분리하기 위해 ConfigMap을 사용한다. (초기에는 빈 객체도 사용이 가능하다.)
  • 환경 변수: 파드 이름 및 네임스페이스를 환경 변수로 전달하여 Nginx가 파드 내부에서 설정 데이터를 읽을 수 있도록 한다.
  • 포트: Ingress 컨트롤러는 80 및 443 포트를 사용한다.

  • 서비스: NodePort 유형의 서비스를 생성하여 Ingress 컨트롤러를 외부로 노출한다.
  • 서비스 계정: Ingress 컨트롤러가 쿠버네티스 클러스터를 모니터링하고 리소스를 구성할 수 있도록 적절한 권한을 가진 서비스 계정을 생성한다.

Ingress 리소스 구성

  • Ingress 리소스: Ingress 컨트롤러에 적용되는 규칙 및 구성 집합니다.

  • 단일 애플리케이션 라우팅: 모든 트래픽을 단일 애플리케이션으로 전달하는 규칙을 구성할 수 있다.
  • URL 기반 라우팅: URL 경로에 따라 다른 애플리케이션으로 트래픽을 라우팅하는 규칙을 구성할 수 있다.
    • 예: my-online-store.com/wear -> wear 앱, my-online-store.com/watch -> video 앱
  • 도메인 기반 라우팅: 도메인 이름에 따라 다른 애플리케이션으로 트래픽을 라우팅하는 규칙을 구성할 수 있다.
    • 예: wear.my-online-store.com -> wear 앱, watch.my-online-store.com -> video 앱

  • Ingress 정의 파일: Ingress 리소스는 쿠버네티스 정의 파일(Ingress-wear.yaml)을 사용하여 생성된다.
    • apiVersion: extensions/v1beta1 (쿠버네티스 버전에 따라 변경 가능)
    • kind: Ingress
    • metadata: 이름 및 기타 메타데이터
    • spec: 규칙 및 구성
  • 단일 백엔드: spec.backend 섹션에 서비스 이름 및 포트를 지정하여 모든 트래픽을 단일 서비스로 라우팅한다.

  • 규칙 기반 라우팅: spec.rules 섹션에 규칙을 정의하여 다양한 조건에 따라 트래픽을 라우팅한다.
    • 호스트 기반 규칙: host 필드를 사용하여 도메인 이름별로 규칙을 정의한다.
    • 경로 기반 규칙: 각 규칙 내에 paths 필드를 사용하여 URL 경로별로 트래픽을 라우팅한다.

  • 기본 백엔드: kubectl describe ingress 명령어를 사용하여 Ingress 리소스의 세부 정보를 확인하면 기본 백엔드 서비스(default-http-backend)가 표시된다.
    • 정의된 규칙과 일치하지 않는 URL에 대한 요청은 기본 백엔드 서비스로 전달된다.
    • 404 오류 페이지를 표시하는 기본 백엔드 서비스를 배포해야 한다.

URL 기반 라우팅 예시

  • my-online-store.com 도메인에 대한 단일 규칙을 정의한다.

  • paths 배열을 사용하여 /wear/watch 경로에 대한 백엔드 서비스를 지정한다.
  • kubectl create 명령어를 사용하여 Ingress 리소스를 생성하고 kubectl describe ingress 명령어를 사용하여 세부 정보를 확인한다.

도메인 기반 라우팅 예시

  • wear.my-online-store.comwatch.my-online-store.com 도메인에 대한 두 개의 규칙을 정의한다.
  • 각 규칙의 host 필드에 도메인 이름을 지정하고 백엔드 서비스를 지정한다.

URL 기반 vs 도메인 기반 라우팅

  • URL 기반 라우팅은 단일 도메인에 대한 여러 경로를 처리하는 데 사용된다.
  • 도메인 기반 라우팅은 여러 도메인에 대한 트래픽을 처리하는 데 사용된다.
  • 각 규칙 내에 여러 경로를 정의하여 다양한 URL 경로를 처리할 수 있다.

Ingress의 변화

  • apiVersion, serviceName, servicePort: 이전 버전과 현재 버전의 쿠버네티스에서 Ingress의 apiVersion, serviceName, servicePort 등과 같은 설정에 변경 사항이 있다.
  • 쿠버네티스 1.20+의 변경 사항: 쿠버네티스 1.20 버전 이상에서는 Ingress 리소스를 명령형 방식으로 생성할 수 있다.

명령형 Ingress 리소스 생성


rewrite-target

Ingress 컨트롤러별 옵션

  • 각 Ingress 컨트롤러는 작동 방식을 사용자 정의하기 위한 다양한 옵션을 제공한다.
  • NGINX Ingress 컨트롤러는 많은 옵션을 가지고 있으며, 자세한 내용은 공식 문서를 참조할 수 있다.
  • 이번에는 rewrite-target 옵션에 대해서 알아본다.

시나리오

  • watch 앱은 http://<watch-service>:<port>/에서 비디오 스트리밍 웹 페이지를 표시한다.
  • wear 앱은 http://<wear-service>:<port>/에서 의류 웹 페이지를 표시한다.
  • Ingress를 사용하여 다음과 같은 URL 라우팅을 구성해야 한다.
    • http://<ingress-service>:<ingress-port>/watch -> http://<watch-service>:<port>/
    • http://<ingress-service>:<ingress-port>/wear -> http://<wear-service>:<port>/
  • /watch/wear URL 경로는 Ingress 컨트롤러에서 구성되며, 백엔드 애플리케이션에는 구성되지 않는다.

rewrite-target 옵션의 필요성

  • rewrite-target 옵션이 없으면 다음과 같은 URL 라우팅이 발생한다.
    • http://<ingress-service>:<ingress-port>/watch -> http://<watch-service>:<port>/watch
    • http://<ingress-service>:<ingress-port>/wear -> http://<wear-service>:<port>/wear
  • 백엔드 애플리케이션은 /watch 또는 /wear 경로를 처리하더라도 구성되지 않았으므로 404 오류가 발생한다.
  • rewrite-target 옵션을 사용하여 요청이 watch 또는 wear 애플리케이션으로 전달될 때 URL을 재작성해야 한다.

rewrite-target 옵션 작동 방식

  • rewrite-target 옵션은 rules->http->paths->path 아래에 있는 URL 경로를 rewrite-target 값으로 바꾼다.
  • 검색 및 바꾸기 함수와 유사하게 작동한다.
  • 예시: replace(path, rewrite-target)
  • 실습 예시: replace("/watch","/") 또는 replace("/wear","/")
  • Ingress yaml파일의 annotation에 "nginx.ingress.kubernetes.io/rewrite-target: /"를 추가하여 경로를 재작성할 수 있다.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  namespace: critical-space
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /pay
        backend:
          serviceName: pay-service
          servicePort: 8282
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: rewrite
  namespace: default
spec:
  rules:
  - host: rewrite.bar.com
    http:
      paths:
      - backend:
          serviceName: http-svc
          servicePort: 80
        path: /something(/|$)(.*)

참고한 강의

'Infrastructure > Kubernetes' 카테고리의 다른 글

[CKA] 클러스터 설계  (0) 2025.03.15
[CKA] Networking (Gateway API)  (0) 2025.03.12
[CKA] Networking (ClusterDNS)  (0) 2025.03.12
[CKA] Networking (Service Networking)  (0) 2025.03.12
[CKA] Networking (CNI)  (0) 2025.03.12