콘텐츠로 이동

Nginx Ingress 관측 가능성 모범 사례


개요

Kubernetes는 Pod에 배포된 애플리케이션에 접근하기 위한 4계층 프록시를 제공합니다. 이러한 4계층 프록시를 가진 Service에 대해 Kubernetes는 4가지 접근 방식을 제공합니다:

  1. ClusterIP: 클러스터 내 다른 애플리케이션이 접근 가능하며, 외부에서는 접근할 수 없습니다.
  2. NodePort: 모든 노드에서 지정된 포트를 열어 외부에서 IP+포트를 통해 서비스에 접근할 수 있습니다. NodePort 포트를 지정하지 않으면 기본적으로 30000–32767 사이의 포트가 무작위로 할당됩니다.
  3. LoadBalancer: NodePort를 기반으로 클라우드 서비스 제공업체의 로드 밸런서를 사용하여 트래픽을 서비스로 전달합니다.
  4. ExternalName: CNAME과 그 값을 반환하여 서비스를 externalName 필드의 내용에 매핑할 수 있습니다.

위의 4가지 방식 모두 도메인 이름을 통해 클러스터 내 애플리케이션에 접근하는 요구를 충족할 수 없습니다. 도메인 이름을 통해 Kubernetes에 배포된 애플리케이션에 접근하는 가장 간단한 방법은 클러스터에 7계층 프록시 Nginx를 배포하고 도메인 이름을 통해 해당 Service로 전달하는 것입니다. 새로운 배포가 있을 때마다 Nginx 구성을 업데이트해야 합니다. 구성 업데이트 시 다른 애플리케이션에 영향을 주지 않도록 하기 위해 Ingress가 등장했습니다.

image

Ingress는 http 및 https 요청을 Kubernetes 클러스터 내부의 서비스로 전달하여 최종적으로 Service 백엔드의 Pod에 접근할 수 있게 합니다. Ingress는 Service에 외부에서 접근 가능한 URL을 제공하고, 트래픽을 로드 밸런싱하며, 도메인 기반 가상 호스트를 제공하도록 구성할 수 있습니다.

image

Ingress는 Ingress Controller와 Ingress 두 가지 주요 구성 요소로 이루어져 있습니다. 일반적으로 사용되는 Ingress로는 traefik Ingress와 Nginx Ingress가 있으며, 본 문서에서는 Nginx Ingress를 예로 듭니다. Ingress Controller는 Kubernetes API와 상호 작용하여 Kubernetes 클러스터 내 Ingress 서비스 규칙의 변경 사항을 동적으로 감지하고, 이러한 규칙을 읽어 Ingress 규칙에 따라 Kubernetes 클러스터 내 해당 Service로 전달합니다. Ingress는 이러한 규칙을 구성하는 것으로, 어떤 도메인이 Kubernetes 클러스터 내 어떤 Service에 해당하는지 명시합니다. 그런 다음 Ingress Controller의 Nginx 구성 템플릿을 기반으로 해당 Nginx 구성을 생성하고, Ingress Controller는 이러한 구성을 동적으로 로드하여 Ingress Controller Pod 내에서 실행되는 Nginx 서비스에 기록한 후 reload하여 구성을 적용합니다.

Ingress가 배포된 Kubernetes 클러스터의 경우 Ingress Controller의 CPU 사용률, 메모리 점유, 구성 파일 로드, 전달 성공률 등 리소스에 대한 관측이 매우 중요합니다.

Ingress 작동 원리:

  1. 클라이언트가 http://myNginx.com 요청을 보냅니다.
  2. 클라이언트의 DNS 서버가 Ingress Controller의 IP를 반환합니다.
  3. 클라이언트가 Ingress Controller에 http 요청을 보내고 Host 헤더에 myNginx.com을 지정합니다.
  4. Controller는 요청을 수신하고 헤더에서 클라이언트가 액세스하려는 서비스를 확인한 후, 해당 서비스와 연결된 endpoint 객체를 통해 Pod의 IP를 확인합니다.
  5. 클라이언트의 요청이 특정 Pod로 전달되어 실행됩니다.

image

전제 조건

Ingress 배포

프로덕션 환경에서는 DaemonSet 방식으로 Ingress를 배포하고 hostNetworktrue로 설정하여 Nginx가 호스트 네트워크를 직접 사용하도록 한 후, 클라우드 제공업체의 로드 밸런서를 통해 Ingress에 접근하는 것을 권장합니다.

1 deploy.yaml 다운로드

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/baremetal/deploy.yaml

2 deploy.yaml 편집

2.1 이미지 교체

다음 이미지를 사용하여 deploy.yaml 파일에서 사용된 이미지를 교체합니다.

registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.1.1
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
2.2 Deployment 리소스 파일 수정

kind: Deployment 부분을 찾아 다음과 같이 수정합니다.

kind: DaemonSet #수정

---
hostNetwork: true #추가
dnsPolicy: ClusterFirstWithHostNet #수정
kubectl apply -f deploy.yaml

메트릭 수집

Input 활성화

Guance에서 Ingress 메트릭 데이터를 수집하려면 datakit에서 prom 플러그인을 활성화해야 합니다. prom 플러그인 구성에서 exporter의 url을 지정합니다. Kubernetes 클러스터에서 Ingress Controller 메트릭을 수집하려면 annotations에 주석을 추가하는 방식을 권장합니다. Ingress가 배포된 deploy.yaml 파일을 열고, 이전 단계에서 수정한 DaemonSet 부분을 찾아 annotations을 추가합니다.

annotations:
  datakit/prom.instances: |
    [[inputs.prom]]
      url = "http://$IP:10254/metrics"
      source = "prom-ingress"
      metric_types = ["counter", "gauge", "histogram"]
      # metric_name_filter = ["cpu"]
      # measurement_prefix = ""
      measurement_name = "prom_ingress"
      interval = "60s"
      tags_ignore = ["build","le","path","method","release","repository"]
      metric_name_filter = ["nginx_process_cpu_seconds_total","nginx_process_resident_memory_bytes","request_size","response_size","requests","success","config_last_reload_successful"]
      [[inputs.prom.measurements]]
        prefix = "nginx_ingress_controller_"
        name = "prom_ingress"
      [inputs.prom.tags]
      namespace = "$NAMESPACE"

image

파라미터 설명

  • url: Exporter URL, 여러 url은 쉼표로 구분, 예시 "[http://127.0.0.1:9100/metrics",](http://127.0.0.1:9100/metrics",) "[http://127.0.0.1:9200/metrics"]
  • source: 수집기 별칭.
  • metric_types: 메트릭 유형, 선택 가능 값은 counter, gauge, histogram, summary.
  • measurement_name: 메저먼트 이름.
  • interval: 수집 주기.
  • inputs.prom.measurements: prefix가 일치하는 메트릭을 name의 메저먼트로 그룹화합니다.
  • tags_ignore: 무시할 태그.
  • metric_name_filter: 메트릭 필터, 필요한 메트릭 항목만 수집합니다.

annotations에서는 다음 와일드카드를 지원합니다:

  • $NAMESPACE: Pod 네임스페이스

Ingress Controller 재시작

kubectl delete -f deploy.yaml
kubectl apply -f deploy.yaml

데모 예제

Nginx 배포 파일 nginx-deployment.yaml 작성

nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: backend
  replicas: 1
  template:
    metadata:
      labels:
        app: backend
    spec:
      # nodeName: df-k8s-node2
      containers:
        - name: nginx
          image: nginx:latest
          resources:
            limits:
              memory: "128Mi"
              cpu: "128m"
          ports:
            - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: backend
  ports:
    - port: 80
      targetPort: 80

해당 nginx-ingress.yaml을 작성합니다. 이 규칙에 따라 도메인이 mynginx.com이면 Nginx-Service로 전달됩니다.

nginx-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nodeport-ingress
  namespace: default
spec:
  rules:
    - host: mynginx.com
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: nginx-service
                port:
                  number: 80

예제 배포

kubectl apply -f  nginx-deployment.yaml
kubectl apply -f  nginx-ingress.yaml

테스트 요청, 여기서

  • 8.136.204.98은 Kubernetes 클러스터에서 Ingress가 배포된 노드 IP입니다.
  • mynginx.comnginx-ingress.yaml에서 해당하는 host입니다.
curl -v http://8.136.204.98 -H 'host: mynginx.com'

메트릭 데이터 확인

Guance에 로그인한 후 「메트릭」에서 prom_ingress 메트릭을 찾습니다. prom_ingress는 annotations에서 measurement_name 파라미터의 값입니다.

image

Ingress 관측

Ingress 모니터링 대시보드

Guance에 로그인한 후 「시나리오」 - 「새 대시보드 생성」에서 템플릿 라이브러리에서 「Ingress Nginx 모니터링 대시보드」를 검색하고 「확인」을 클릭합니다.

Ingress 성능 지표를 표시하며, Ingress Controller의 평균 CPU 사용률, 평균 메모리 사용량, 네트워크 요청/응답 합계, Ingress Config 로드 횟수, Ingress Config 마지막 로드 결과, Ingress 전달 성공률 등을 포함합니다.

image

문서 평가

이 페이지가 도움이 되었나요?