HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
📖
공부한 책
/쿠버네티스 교과서/
15장. 인그레스를 이용한 인입 트래픽 관리

15장. 인그레스를 이용한 인입 트래픽 관리

인그레스의 라우팅 과정실제 인그레스 사용 예시(aws)인그레스 클래스인그레스 컨트롤러구성인그레스의 유형1. 이름 기반의 가상 호스팅2. 로드 밸런싱3. 팬아웃인그레스 규칙을 이용한 HTTP 트래픽 라우팅두 애플리케이션을 하나의 도메인에서 사용할 수 있도록인그레스를 통해 외부 접근 차단인그레스 컨트롤러 비교하기응답캐시 기능을 적용한 인그레스 컨트롤러스티키 세션 적용인그레스 클래스로, 여러 인그레스 컨트롤러 중 어떤걸 사용할지 결정인그레스를 사용하여 HTTPS 적용하기인그레스 및 인그레스 컨트롤러의 이해

인그레스의 라우팅 과정

  • 인그레스는 리버스 프록시(Nginx, Traefik .. )를 인그레스 컨트롤러 로 사용하며 리버스 프록시에 좀 더 주도적인 역할을 맡긴다.
  • 로드밸런서 → 리버스 프록시 → 클러스터 IP 서비스
notion image
  • 위 다이어그램의 핵심은 인그레스 컨트롤러(Nginx 파드). 이 컨트롤러는 쉽게 교체할 수 있는 리버스 프록시임
    • Nginx, HAProxy, 컨투어, 트래픽 등 다양한 선택지가 있음
    • 인그래스 객체에는 라우팅 규칙이 일반적인 형태로 기술되어 있고 컨트롤러가 이 규칙을 프록시에 적용함
      • 사실상 인그레스 리소스는 라우팅 규칙 명세만 수행하며, 실제 규칙 구현과 트래픽 처리는 인그레스 컨트롤러가 담당
    • 프록시마다 기능에 차이가 있으므로 인그레스 정의에는 공통적인 내용만 담기며, 애너테이션으로 특정 프록시만 지원하는 기능을 추가
  • 인그레스 컨트롤러는 기존의 컨트롤러와 다른 점이, 파드에서 실행되며 인그레스 객체를 감시함. 그러다 어떤 변경을 감지하면 프록시에 변경된 규칙을 적용
    • apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: hello-kiamol labels: kiamol: ch15 spec: rules: - http: paths: - path: / pathType: Prefix backend: service: name: hello-kiamol port: number: 80
    • 인그레스 객체를 새로 배치하면 객체에 담긴 라우팅 규칙이 Nginx 설정에 추가됨
    • Nginx 관점에서 보면 hello-kiamol 서비스를 업스트림(콘텐츠를 받아올 곳)으로 삼는 프록시 서버가 설정되는 것과 같은 결과
    • 인그레스의 명세 내용
      • rules: Ingress에서 트래픽 라우팅 규칙을 정의하는 상위 구조
      • host: 특정 도메인 이름 기반으로 트래픽을 구분하는 필드
      • path: 도메인 내에서 URL 경로에 따라 트래픽을 라우팅하는 규칙
      • backend: 트래픽을 전달할 대상 서비스와 포트를 정의
 
인그레스 컨트롤러의 리버스 프록시로서의 기능
  • 네트워크 트래픽 처리
  • SSL Termination: HTTPS 요청 처리 및 복호화
  • 로드 밸런싱 : 파드간 트래픽 분배
 
고민해야할 내용
  • 적합한 인그레스 컨트롤러 선택: 예) NGINX, Traefik, AWS ALB 등
  • 인그레스 컨트롤러의 배치와 제공하는 추가 기능 파악
 
인그레스 라우팅 규칙은 유일하지 않아도 된다 (예: 동일한 도메인 내에서 경로 기반으로 분리 가능)

실제 인그레스 사용 예시(aws)

# internal-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:059075917335:certificate/b68b9bd9-b951-4c2a-9ce7-6019c2e2a9ec alb.ingress.kubernetes.io/healthcheck-interval-seconds: "30" alb.ingress.kubernetes.io/healthcheck-path: /api/system/livez alb.ingress.kubernetes.io/healthcheck-port: traffic-port alb.ingress.kubernetes.io/healthcheck-protocol: HTTP alb.ingress.kubernetes.io/healthcheck-timeout-seconds: "5" alb.ingress.kubernetes.io/healthy-threshold-count: "2" alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]' alb.ingress.kubernetes.io/load-balancer-attributes: deletion_protection.enabled=true,access_logs.s3.enabled=true,access_logs.s3.bucket=s3-dev-logistics-laas-alb-accesslog,access_logs.s3.prefix=eks-svc-int-ingress,idle_timeout.timeout_seconds=600 alb.ingress.kubernetes.io/scheme: internal alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS13-1-2-2021-06 alb.ingress.kubernetes.io/ssl-redirect: "443" alb.ingress.kubernetes.io/success-codes: 200-302 alb.ingress.kubernetes.io/target-type: ip alb.ingress.kubernetes.io/unhealthy-threshold-count: "2" kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{"alb.ingress.kubernetes.io/certificate-arn":"arn:aws:acm:ap-northeast-2:059075917335:certificate/b68b9bd9-b951-4c2a-9ce7-6019c2e2a9ec","alb.ingress.kubernetes.io/healthcheck-interval-seconds":"30","alb.ingress.kubernetes.io/healthcheck-path":"/api/system/livez","alb.ingress.kubernetes.io/healthcheck-port":"traffic-port","alb.ingress.kubernetes.io/healthcheck-protocol":"HTTP","alb.ingress.kubernetes.io/healthcheck-timeout-seconds":"5","alb.ingress.kubernetes.io/healthy-threshold-count":"2","alb.ingress.kubernetes.io/listen-ports":"[{\"HTTP\": 80}, {\"HTTPS\":443}]","alb.ingress.kubernetes.io/load-balancer-attributes":"deletion_protection.enabled=true,access_logs.s3.enabled=true,access_logs.s3.bucket=s3-dev-logistics-laas-alb-accesslog,access_logs.s3.prefix=eks-svc-int-ingress,idle_timeout.timeout_seconds=600","alb.ingress.kubernetes.io/scheme":"internal","alb.ingress.kubernetes.io/ssl-policy":"ELBSecurityPolicy-TLS13-1-2-2021-06","alb.ingress.kubernetes.io/ssl-redirect":"443","alb.ingress.kubernetes.io/success-codes":"200-302","alb.ingress.kubernetes.io/target-type":"ip","alb.ingress.kubernetes.io/unhealthy-threshold-count":"2","kubernetes.io/ingress.class":"alb"},"name":"dev-logistics-laas-internal-ingress","namespace":"dev-logistics-laas"},"spec":{"rules":[{"host":"dev.itgo.ai","http":{"paths":[{"backend":{"service":{"name":"dev-itgo-homepage-service","port":{"number":8080}}},"path":"/","pathType":"Prefix"}]}},{"host":"mobile.dev.itgo.ai","http":{"paths":[{"backend":{"service":{"name":"dev-mobile-web-service","port":{"number":8080}}},"path":"/","pathType":"Prefix"}]}},{"host":"admintest.dev.itgo.ai","http":{"paths":[{"backend":{"service":{"name":"dev-admin-web-service","port":{"number":8080}}},"path":"/","pathType":"Prefix"}]}},{"host":"solution.dev.itgo.ai","http":{"paths":[{"backend":{"service":{"name":"dev-brokerage-web-service","port":{"number":8080}}},"path":"/","pathType":"Prefix"}]}},{"host":"tms.dev.itgo.ai","http":{"paths":[{"backend":{"service":{"name":"dev-tms-backend-1-service","port":{"number":16006}}},"path":"/","pathType":"Prefix"}]}},{"host":"tms-admintest.dev.itgo.ai","http":{"paths":[{"backend":{"service":{"name":"dev-tms-admin-backend-service","port":{"number":16006}}},"path":"/","pathType":"Prefix"}]}},{"host":"api.dev.itgo.ai","http":{"paths":[{"backend":{"service":{"name":"dev-laas-backend-apis-service","port":{"number":8080}}},"path":"/","pathType":"Prefix"}]}},{"host":"logistics.dev.itgo.ai","http":{"paths":[{"backend":{"service":{"name":"dev-laas-frontend-web-service","port":{"number":3000}}},"path":"/","pathType":"Prefix"}]}},{"host":"roouty-api.dev.itgo.ai","http":{"paths":[{"backend":{"service":{"name":"dev-laas-roouty-service","port":{"number":5000}}},"path":"/","pathType":"Prefix"}]}},{"host":"aidx.dev.itgo.ai","http":{"paths":[{"backend":{"service":{"name":"dev-laas-optimal-fare-service","port":{"number":10055}}},"path":"/","pathType":"Prefix"}]}},{"host":"selectadmin.dev.itgo.ai","http":{"paths":[{"backend":{"service":{"name":"dev-laas-admin-cli-service","port":{"number":9300}}},"path":"/","pathType":"Prefix"}]}}]}} kubernetes.io/ingress.class: alb finalizers: - ingress.k8s.aws/resources generation: 1 name: dev-logistics-laas-internal-ingress namespace: dev-logistics-laas spec: rules: - host: dev.itgo.ai http: paths: - backend: service: name: dev-itgo-homepage-service port: number: 8080 path: / pathType: Prefix - host: mobile.dev.itgo.ai http: paths: - backend: service: name: dev-mobile-web-service port: number: 8080 path: / pathType: Prefix - host: admintest.dev.itgo.ai http: paths: - backend: service: name: dev-admin-web-service port: number: 8080 path: / pathType: Prefix - host: solution.dev.itgo.ai http: paths: - backend: service: name: dev-brokerage-web-service port: number: 8080 path: / pathType: Prefix - host: tms.dev.itgo.ai http: paths: - backend: service: name: dev-tms-backend-1-service port: number: 16006 path: / pathType: Prefix - host: tms-admintest.dev.itgo.ai http: paths: - backend: service: name: dev-tms-admin-backend-service port: number: 16006 path: / pathType: Prefix - host: api.dev.itgo.ai http: paths: - backend: service: name: dev-laas-backend-apis-service port: number: 8080 path: / pathType: Prefix - host: logistics.dev.itgo.ai http: paths: - backend: service: name: dev-laas-frontend-web-service port: number: 3000 path: / pathType: Prefix - host: roouty-api.dev.itgo.ai http: paths: - backend: service: name: dev-laas-roouty-service port: number: 5000 path: / pathType: Prefix - host: aidx.dev.itgo.ai http: paths: - backend: service: name: dev-laas-optimal-fare-service port: number: 10055 path: / pathType: Prefix - host: selectadmin.dev.itgo.ai http: paths: - backend: service: name: dev-laas-admin-cli-service port: number: 9300 path: / pathType: Prefix status: loadBalancer: ingress: - hostname: internal-k8s-devlogis-devlogis-83ad23facd-651227745.ap-northeast-2.elb.amazonaws.com
Laas backend 의 Ingress 정의
  • 주요 역할:
    • URL, 도메인, 및 경로 기반 트래픽 라우팅
    • 각 도메인에 대해 적절한 서비스와 연결
  • 구성 요소:
    • Annotations: AWS ALB 관련 설정 정의
      • alb.ingress.kubernetes.io/certificate-arn: HTTPS를 위한 ACM 인증서 ARN.
      • alb.ingress.kubernetes.io/healthcheck-*: ALB의 Health Check 설정.
      • alb.ingress.kubernetes.io/listen-ports: ALB가 수신할 포트 정의 (HTTP: 80, HTTPS: 443)
      • alb.ingress.kubernetes.io/scheme: ALB의 스키마 (internal 설정으로 내부 전용)
      • alb.ingress.kubernetes.io/target-type: ip로 설정하여 Pod IP에 직접 연결
      • 기타 세부 옵션으로 ALB 설정 세부 조정.
    • Spec:
      • 여러 host 정의로 각 도메인 이름과 해당 서비스 연결
      • 각 도메인 별로 서비스 이름과 포트 지정
      • 예: dev.itgo.ai -> dev-itgo-homepage-service:8080

인그레스 클래스

apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: annotations: meta.helm.sh/release-name: aws-load-balancer-controller meta.helm.sh/release-namespace: kube-system generation: 1 labels: app.kubernetes.io/instance: aws-load-balancer-controller app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: aws-load-balancer-controller app.kubernetes.io/version: v2.7.1 helm.sh/chart: aws-load-balancer-controller-1.7.1 name: alb spec: controller: ingress.k8s.aws/alb
ALB
Ingress 리소스가 사용할 Ingress Controller를 정의
  • 주요 역할:
    • 클러스터 내 여러 Ingress Controller 중 특정 컨트롤러 지정
    • spec.controller에 ingress.k8s.aws/alb 설정으로 AWS ALB Controller 사용 지정
  • 구성 요소:
    • Annotations 및 Labels: AWS ALB Controller 설정 정보를 포함
    • name: alb로 명명되어 Ingress 리소스에서 참조

인그레스 컨트롤러

apiVersion: apps/v1 kind: Deployment metadata: annotations: deployment.kubernetes.io/revision: "1" meta.helm.sh/release-name: aws-load-balancer-controller meta.helm.sh/release-namespace: kube-system generation: 1 labels: app.kubernetes.io/instance: aws-load-balancer-controller app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: aws-load-balancer-controller app.kubernetes.io/version: v2.7.1 helm.sh/chart: aws-load-balancer-controller-1.7.1 name: aws-load-balancer-controller namespace: kube-system spec: progressDeadlineSeconds: 600 replicas: 2 revisionHistoryLimit: 10 selector: matchLabels: app.kubernetes.io/instance: aws-load-balancer-controller app.kubernetes.io/name: aws-load-balancer-controller strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: annotations: prometheus.io/port: "8080" prometheus.io/scrape: "true" creationTimestamp: null labels: app.kubernetes.io/instance: aws-load-balancer-controller app.kubernetes.io/name: aws-load-balancer-controller spec: affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - podAffinityTerm: labelSelector: matchExpressions: - key: app.kubernetes.io/name operator: In values: - aws-load-balancer-controller topologyKey: kubernetes.io/hostname weight: 100 containers: - args: - --cluster-name=eks-dev-logistics-laas - --ingress-class=alb image: public.ecr.aws/eks/aws-load-balancer-controller:v2.7.1 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 2 httpGet: path: /healthz port: 61779 scheme: HTTP initialDelaySeconds: 30 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 name: aws-load-balancer-controller ports: - containerPort: 9443 name: webhook-server protocol: TCP - containerPort: 8080 name: metrics-server protocol: TCP readinessProbe: failureThreshold: 2 httpGet: path: /readyz port: 61779 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 resources: {} securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true runAsNonRoot: true terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /tmp/k8s-webhook-server/serving-certs name: cert readOnly: true dnsPolicy: ClusterFirst priorityClassName: system-cluster-critical restartPolicy: Always schedulerName: default-scheduler securityContext: fsGroup: 65534 serviceAccount: aws-load-balancer-controller serviceAccountName: aws-load-balancer-controller terminationGracePeriodSeconds: 10 volumes: - name: cert secret: defaultMode: 420 secretName: aws-load-balancer-tls
AWS Load Balancer Controller는 Ingress 리소스를 기반으로 ALB를 생성하고 트래픽을 라우팅
  • AWS 로드 밸런서 컨트롤러를 통해 인터넷 트래픽 라우팅 - Amazon EKS
    • notion image
  • 주요 역할:
    • IngressClass에 따라 Ingress 리소스를 감지하고 처리
      • 라우팅 규칙의 추가나 변경 감지
    • AWS API를 호출하여 ALB 생성 및 구성
    • ALB 설정과 Kubernetes 서비스 연결
    • Ingress 에 정의된 라우팅 규칙에 따라 리버스 프록시에 적용
  • 구성 요소:
    • Pod:
      • 실행 중인 컨테이너: aws-load-balancer-controller:v2.7.1
      • 주요 포트:
        • webhook-server: 9443 (Kubernetes Webhook Server)
        • metrics-server: 8080
    • Args:
      • -cluster-name: EKS 클러스터 이름 지정
      • -ingress-class: alb 지정으로 ALB 처리 담당
    • Annotations:
      • Health 체크 및 Prometheus 메트릭 수집 지원
    • Affinity:
      • Pod 간 겹치지 않게 스케줄링 설정 (PodAntiAffinity)

구성

Ingress ("dev-logistics-laas-internal-ingress") └─ IngressClass ("alb") └─AWS Load Balancer Controller (Deployment: "aws-load-balancer-controllr") └── ALB ├── Certificate (ARN: ACM 인증서) ├── Health Check 설정 ├── Target Groups (서비스와 연결) └── Listener (HTTP: 80, HTTPS: 443)
  • Ingress: HTTP/HTTPS 트래픽 규칙 정의
    • ALB 설정을 위한 여러 AWS-specific Annotations 포함
  • IngressClass: AWS ALB Controller와 Ingress 연동 설정
    • Ingress의 ingressClassName을 통해 연결
  • AWS Load Balancer Controller:
    • Ingress 리소스를 감지하고 AWS ALB를 프로비저닝 및 설정
    • Pod와 연결된 서비스 트래픽을 외부로 노출
  • ALB:
    • AWS 상에서 관리되는 로드 밸런서로 클러스터 외부와 내부를 연결

인그레스의 유형

1. 이름 기반의 가상 호스팅

  • 설명:
    • Ingress에서 host 필드를 사용해 트래픽을 특정 도메인 이름 기반으로 라우팅
    • 예를 들어:
      • dev.itgo.ai → dev-itgo-homepage-service
      • mobile.dev.itgo.ai → dev-mobile-web-service
    • 하나의 로드 밸런서(ALB)가 여러 도메인/호스트 이름에 대해 트래픽을 처리
  • 적용 부분:
    • 각 host에 따라 다른 서비스로 트래픽을 전달하는 Ingress 규칙 정의
    • ALB는 이 규칙에 따라 도메인 기반으로 트래픽을 분리
화물잇고 해당

2. 로드 밸런싱

  • 설명
    • Ingress 규칙에 따라 연결된 각 서비스로 트래픽을 분배
    • ALB는 Target Group에 따라 각 서비스로 트래픽을 라우팅
    • 각 서비스 뒤에서 실행 중인 여러 Pod 간 트래픽을 자동으로 로드 밸런싱
  • 적용 부분:
    • alb.ingress.kubernetes.io/target-type: ip 설정으로 각 Pod의 IP 주소를 직접 Target Group으로 연결
    • 각 서비스의 여러 인스턴스(Pod) 간 부하를 분산
화물잇고 해당

3. 팬아웃

  • 단일 URL 경로를 기반으로 여러 백엔드 서비스로 트래픽을 분배하는 방식
    • /api/auth → Service A
    • /api/data → Service B
화물잇고는 해당하지 않음

인그레스 규칙을 이용한 HTTP 트래픽 라우팅

  • 인그레스는 HTTP와 HTTPS 요청만 처리 (웹 트래픽 한정)
    • 다른 프로토콜(TCP, UDP 등)은 별도의 서비스 타입(예: LoadBalancer, NodePort)을 사용
왜 사용할까?
  1. 도메인 기반 라우팅으로 사용자 편의성 향상:
      • 포트번호를 달리하는 대신, 직관적인 도메인 네임을 사용하여 트래픽을 라우팅
      • 예: app1.dev.example.com → 앱 1, app2.dev.example.com → 앱 2
      • 이를 통해 비운영 환경에서도 애플리케이션 여러 개를 동시에 실행하고 테스트 가능
  1. 세부적인 외부 접근 제어:
      • 모든 서비스가 외부에 노출되지 않도록, 명시적으로 노출하려는 경로만 설정 가능
      • 클러스터 내부 서비스는 비공개 상태를 유지하여 보안을 강화
  1. 중앙 집중식 관리:
      • 여러 서비스의 트래픽 라우팅 규칙을 한곳에서 관리 가능(Ingress 리소스)
      • 트래픽 라우팅 정책 변경이 용이
  1. SSL/TLS를 통한 보안 강화:
      • Ingress Controller에서 SSL Termination 설정을 통해 클라이언트와의 통신을 안전하게 유지
      • HTTPS 트래픽을 쉽게 설정하고 관리 가능
  1. 로드 밸런싱:
      • Ingress Controller가 기본적으로 로드 밸런싱을 지원하여 트래픽 분산 처리
  1. 응답 캐싱:
      • 정적 콘텐츠 캐싱
      • 기본 기능은 아님
 
  • 인그레스는 HTTP와 HTTPS 요청, 즉 다시 말해 웹 트래픽만 다룬다.
  • 인그레스 목적이 HTTP 요청에 담긴 라우팅 정보를 적절한 백엔드 서비스에 매칭해 주는 것이기에
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: hello-kiamol labels: kiamol: ch15 spec: rules: - host: hello.kiamol.local http: paths: - path: / pathType: Prefix backend: service: name: hello-kiamol port: number: 80
  • hello.kiamol.local/ → hello-kiamol 서비스의 80 포트로 연결

두 애플리케이션을 하나의 도메인에서 사용할 수 있도록

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: vweb labels: kiamol: ch15 annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: vweb.kiamol.local http: paths: - path: / pathType: Prefix backend: service: name: vweb-v2 port: number: 80 - path: /v1 pathType: Prefix backend: service: name: vweb-v1 port: number: 80 - path: /v2 pathType: Prefix backend: service: name: vweb-v2 port: number: 80
  • path 정보 추가가 되면 Overwrite 된다.
  • annotation 인 nginx.ingress.kubernetes.io/rewrite-target: / 로 인해 http://vweb.kiamol.local/v1 의 요청을 vweb-v1/ 로 전달하게 됨
    • 해당 애너테이션으로 인해 요청에 포함된 경로는 무시하고 백엔드의 루트로만 리라이팅 됨

인그레스를 통해 외부 접근 차단

공개 경로만을 Ingress 객체에 열거하고 외부로 노출하지 않고자하는 경로는 인그레스 정의에 포함시키지 않는 방법으로 외부 접근 차단이 가능함
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: todo labels: kiamol: ch15 spec: rules: - host: todo.kiamol.local http: paths: - pathType: Exact path: / backend: serviceName: todo-web servicePort: 80 - pathType: Exact path: /list backend: serviceName: todo-web servicePort: 80 - pathType: Exact path: /new backend: serviceName: todo-web servicePort: 80 - pathType: Prefix path: /static backend: serviceName: todo-web servicePort: 80

인그레스 컨트롤러 비교하기

인그레스 컨트롤러는 크게 두 가지 유형
  • 리버스 프록시
  • 현대적 프록시
플랫폼마다 달리 동작하며 다른 서비스(클라우드에서 제공하는 컨트롤러는 외부 로드밸런서를 활용할 수 있음)와 통합이 쉬움
필요한 기능이 무엇인지, 어떤 기술을 선호하느냐에 따라 두 가지 중 한가지를 선택하면 됨

응답캐시 기능을 적용한 인그레스 컨트롤러

apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: pi labels: kiamol: ch15 annotations: nginx.ingress.kubernetes.io/proxy-buffering: "on" nginx.ingress.kubernetes.io/configuration-snippet: | proxy_cache static-cache; proxy_cache_valid 10m; spec: rules: - host: pi.kiamol.local http: paths: - path: / backend: serviceName: pi-web servicePort: 80
  • 애플리케이션의 변경이나 추가 컴포넌트 없이 인그레스 규칙만 변경해서 애플리케이션에 캐싱을 적용할 수 있음
  • 인그레스 컨트롤러(Nginx)가 애너테이션에서 설정을 읽어서 캐시 기능이 적용됨

스티키 세션 적용

apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: todo-new annotations: nginx.ingress.kubernetes.io/affinity: cookie spec: rules: - host: todo.kiamol.local http: paths: - pathType: Exact path: /new backend: serviceName: todo-web servicePort: 80 --- apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: todo-static annotations: nginx.ingress.kubernetes.io/proxy-buffering: "on" nginx.ingress.kubernetes.io/configuration-snippet: | proxy_cache static-cache; proxy_cache_valid 60m; add_header X-Cache $upstream_cache_status; spec: rules: - host: todo.kiamol.local http: paths: - pathType: Prefix path: /static backend: serviceName: todo-web servicePort: 80 --- apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: todo spec: rules: - host: todo.kiamol.local http: paths: - pathType: Exact path: / backend: serviceName: todo-web servicePort: 80 - pathType: Exact path: /list backend: serviceName: todo-web servicePort: 80
  • CSRF 문제가 발생하여, /new 경로에 대해 요청할때만 스티키 세션을 적용하도록 기능 추가
  • 해당 경로에 대해 요청할시 계속 같은 파드에 대해 요청되도록 작동함

인그레스 클래스로, 여러 인그레스 컨트롤러 중 어떤걸 사용할지 결정

서로 다른 프록시 기능을 사용하려고 두 개 이상의 인그레스 컨트롤러를 실행했다면 애플리케이션에서도 어떤 인그레스 컨트롤러를 사용할지 결정해야 함. 여기에 쓰는 것이 인그레스 클래스
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: todo2-new labels: kiamol: ch15 annotations: kubernetes.io/ingress.class: traefik traefik.ingress.kubernetes.io/router.pathmatcher: Path spec: rules: - host: todo2.kiamol.local http: paths: - path: /new pathType: Exact backend: service: name: todo-web-sticky port: number: 80
 
여러개의 인그레스 컨트롤러를 두는 것
  • Ingress Controller는 클러스터 내 트래픽 라우팅을 담당하며, 각각 별도의 IP 주소를 가짐
  • DNS 설정을 통해 도메인 이름을 Ingress Controller의 IP 주소와 연결하여 외부에서 접근 가능
  • Ingress Controller는 로드 밸런서의 형태로 외부에 노출됩니다

인그레스를 사용하여 HTTPS 적용하기

HTTPS 를 인그레스에 맡기는 것이 좋은데, 그 이유는 인증서 관리를 중앙화할 수 있기 때문임
인그레스 리소스는 쿠버네티스 비밀값 객체에 담긴 TLS 인증서를 사용할 수 있음
# 파드가 실행되면 인증서 생성 kubectl apply -f ./cert-generator.yaml # 서비스 계정에 임시로 cluster-admin 권한 부여 kubectl apply -f ./cert-temp-rolebinding.yaml # 파드에 접속 후 인증서 및 키 파일 이름을 쿠버네티스에서 사용하는 이름으로 변경 mv server-cert.pem tls.crt mv server-key.pem tls.key kubectl create secret tls kiamol-cert --key=tls.key --cert=tls.crt
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: todo2-new labels: kiamol: ch15 annotations: kubernetes.io/ingress.class: traefik traefik.ingress.kubernetes.io/router.pathmatcher: Path traefik.ingress.kubernetes.io/router.tls: "true" spec: rules: - host: todo2.kiamol.local http: paths: - path: /new backend: serviceName: todo-web-sticky servicePort: 80 tls: - secretName: kiamol-cert
tls 필드에 비밀값의 이름을 기재하면 만든 인증서로 HTTPS 가 적용됨

인그레스 및 인그레스 컨트롤러의 이해

  • 클러스터를 운영하다 보면 결국 인그레스 컨트롤러를 하나 정도는 배치할 수 밖에 없다. TLS 인증서 관리와 도메인 네임에 대한 라우팅 설정을 애플리케이션에서 할 필요가 없기 때문이다.
  • 쿠버네티스의 인그레스는 인그레스 구현체를 교체 가능한 설계와 공통 인그레스 정의 덕분에 매우 유연하다. 하지만 이를 사용하는 입장에서는 덜 직관적
    • 인그레스 정의에는 라우팅 규칙만 기재가능
    • 프록시 같은 고급 기능 사용시, 애너테이션에 상당한 양의 설정 기재 필요 — 호환성이 좋지 않음
      • Nginx 에서 Traefik 이나 HAProxy, 컨투어 로 이주할 일이 생긴다면 별도의 프로젝트로 진행해야 할 정도
      • 쿠버네티스 커뮤니티에서는 이런 인그레스 문제점을 파악하고 이를 장기적으로 서비스 API 로 교체해 나가는 작업에 착수