Prometheus을 이용한 컨테이너 모니터링

choko's avatar
Jun 29, 2024
Prometheus을 이용한 컨테이너 모니터링
 

Prometheus

  • 오픈소스 기반의 모니터링 시스템, 시스템 리소스 등의 모니터링 지표를 수집하여 저장하고 검색할 수 있는 시스템
  • 구조가 간단해 운영이 쉽고, 자체 쿼리 언어를 가지고 있으며 Grafana를 통한 시각화 지원
  • go 로 만들어졌으며, 쿠버네티스의 메인 모니터링 시스템으로 많이 사용된다.
 
notion image

Prometheus 특징

  1. Metric 수집
      • node-exporter 를 사용하여 시스템에서 리소스를 수집한다. node-exporter 는 kubernetes daemonset으로 구성한다.
        Daemonset
      • node-exporter 는 HTTP GET으로 메트릭을 text 형태로 프로메테우스에 보내준다.
  1. pulling 방식
      • 모니터링 데이터 수집 방식에는 pulling(pull) 방식과 pushing(push) 방식이 있다.
        • pull : 데이터를 타겟에게서 가져옴
          • Auto-scaling이 빈번한 경우 불리(서버 추가마다 Host 관리 필요)
          • 데이터 구조에 따른 유연성이 좋음(일단 보내면 됨)
        • push : 데이터를 타겟으로 보내줌
          • Auto-scaling이 빈번한 경우 유리(서버 추가시 전송 데이터를 보내주기만 하면 됨)
          • 데이터 구조에 따른 유연성 나쁨(새로운 metric 구조가 나타날때마다 중앙서버에서 수정필요)
          → 프로메테우스에서는 Pulling 방식을 사용한다
  1. Service discovery
      • DNS, 쿠버네티스 등을 통해 모니터링 해야할 타겟 서비스 목록을 가져올 수 있음
  1. 데이터 저장
      • 수집된 데이터는 프로메테우스 내의 메모리, 로컬 디스크에 저장된다.
      • 구조상 스케일링이 불가능하다. 디스크 용량을 늘리는 방법밖에 없음
        • 따라서 HA(고가용성, High Availability - 장애가 발생해도 오랜 기간 연속적으로 이용 가능한 능력) 해결 방법을 위해 Thanos라는 오픈 소스를 사용하기도 한다.
  1. 쿼리
      • 이렇게 수집한 메트릭은 PromQL 쿼리를 통해 조회할 수 있다.
 
 
 

Prometheus 구성

  • 보통 ClusterRole/ClusterRoleBinding, Service/ServiceAccount 등의 별도 구성 세팅 후 진행한다.
  • prometheus.yml(프로메테우스 설정 파일)을 담은 configmap도 할당해준다.
    • prometheus.yml configmap 예시
      • apiVersion: v1 kind: ConfigMap metadata: name: prometheus-properties namespace: .. labels: name: prometheus-properties data: prometheus.yml: |- global: scrape_interval: 5s scrape_configs: - job_name: prometheus scrape_interval: 10s static_configs: - targets: [localhost:9090] # -> prometheus port - job_name: 'event-router' static_configs: - targets: ['eventrouter.kube-system.svc.cluster.local:8080'] - job_name: 'kubernetes-nodes' scheme: https tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token kubernetes_sd_configs: - role: node relabel_configs: - action: labelmap regex: __meta_kubernetes_node_label_(.+) - target_label: __address__ replacement: kubernetes.default.svc:443 - source_labels: [__meta_kubernetes_node_name] regex: (.+) target_label: __metrics_path__ replacement: /api/v1/nodes/${1}/proxy/metrics ....
      • global
        • scrape_interval : 5s → 5초마다 메트릭 업데이트(전역)
      • scrape_configs: 모니터링 할 job들 명시
        • job_name : 모니터링 할 job
        • scrape_interval: 개별 scrape_interval 명시
        • static_configs : target ip(name):port
    • prometheus.yaml
      • apiVersion: apps/v1 kind: Deployment metadata: name: prometheus namespace: mdl spec: replicas: 1 selector: matchLabels: name: prometheus template: metadata: labels: name: prometheus spec: volumes: - name: prometheus-properties configMap: defaultMode: 420 name: prometheus-properties - name: prometheus-storage persistentVolumeClaim: claimName: storage-pvc containers: - name: prometheus image: prom/prometheus:latest imagePullPolicy: Always args: - "--config.file=/etc/prometheus/prometheus.yml" - "--storage.tsdb.path=/storage/prometheus/" ports: - containerPort: 9090 volumeMounts: - name: prometheus-properties mountPath: /etc/prometheus/ - name: prometheus-storage mountPath: /storage initContainers: - name: prometheus-data-permission-fix image: busybox:latest imagePullPolicy: Always command: ["/bin/sh", "-c", "mkdir -p /storage/prometheus && chmod -R 777 /storage/prometheus"] volumeMounts: - name: prometheus-storage mountPath: /storage
  • node-exporter 작성
    • daemonset으로 구성하여 호스트 시스템의 리소스 및 하드웨어 메트릭을 수집하고, Prometheus에 노출시킨다.
    • node-exporter 예시
      • nodeselector이 없으므로 모든 노드에 node-exporter daemonset 적용
      • apiVersion: apps/v1 kind: DaemonSet metadata: name: node-exporter labels: app: node-exporter spec: selector: matchLabels: app: node-exporter template: metadata: labels: app: node-exporter spec: containers: - image: prom/node-exporter imagePullPolicy: Always name: node-exporter args: - --path.procfs=/host/proc - --path.sysfs=/host/sys - --path.rootfs=/host/root - --collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/pods/.+)($|/) - --collector.filesystem.ignored-fs-types=^(tmpfs|autofs|binfmt_misc|cgroup|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|mqueue|proc|procfs|pstore|rpc_pipefs|securityfs|sysfs|tracefs)$ volumeMounts: - mountPath: /host/proc mountPropagation: HostToContainer name: proc readOnly: true - mountPath: /host/sys mountPropagation: HostToContainer name: sys readOnly: true - mountPath: /host/root mountPropagation: HostToContainer name: root readOnly: true ports: - containerPort: 9100 protocol: TCP name: http tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule volumes: - hostPath: path: /proc name: proc - hostPath: path: /sys name: sys - hostPath: path: / name: root --- apiVersion: v1 kind: Service metadata: annotations: prometheus.io/scrape: 'true' labels: app: node-exporter name: node-exporter spec: ports: - name: http port: 9100 targetPort: 9100 selector: app: node-exporter
  • 필요시 grafana까지 적용
    • grafana.yaml 예시
      • apiVersion: apps/v1 kind: Deployment metadata: name: grafana namespace: mdl spec: replicas: 1 selector: matchLabels: app: grafana template: metadata: name: grafana labels: app: grafana spec: containers: - name: grafana image: prom/grafana imagePullPolicy: Always ports: - name: grafana containerPort: 3000 env: - name: GF_SERVER_HTTP_PORT value: "3000" - name: GF_AUTH_BASIC_ENABLED value: "false" - name: GF_AUTH_ANONYMOUS_ENABLED value: "true" - name: GF_AUTH_ANONYMOUS_ORG_ROLE value: Admin - name: GF_SERVER_ROOT_URL value: / --- apiVersion: v1 kind: Service metadata: name: grafana namespace: mdl annotations: prometheus.io/scrape: 'true' prometheus.io/port: '3000' spec: selector: app: grafana type: NodePort ports: - port: 3000 targetPort: 3000 nodePort: 30004
 
 

모니터링 확인

 
 

Pod를 프로메테우스 타겟에 추가하기

// prometheus.yaml config에 job 부분 추가 - job_name: MDM_SRE_Fabric scrape_interval: 10s file_sd_configs: - files: - /prometheus/fabric_targets.json // 이후 pod 생성마다 addPrometheusTarget fabric_targets.json에 밑에와 같이 pod:port name을 추가 { // mdl-... ca:7054 }
 
 
 
 

ref
Share article

Tom의 TIL 정리방