# Prometheus 스크레이프 잡이 메트릭스에 접근하지 못함

**URL:** https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902
**Category:** Self-hosting
**Tags:** prometheus
**Created:** [5월 13, 2023, 5:23오후 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902 "2023-05-13T17:23:40Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![Crius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/crius/32/317214_2.png) [@Crius](https://meta.discourse.org/u/Crius)
#### Post date: [5월 13, 2023, 5:23오후 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/1 "2023-05-13T17:23:41Z")

</div>

현재 실행 중인 Discourse 설치 환경이 있습니다(실제로는 두 개, 하나는 스테이징, 다른 하나는 프로덕션이며 각각 다른 VM에 설치되어 있습니다). 스테이징 환경에서 테스트를 진행하고 있습니다. [공식 가이드](https://github.com/discourse/discourse/blob/main/docs/INSTALL-cloud.md)를 따라 설치했습니다.

현재 동일한 VM에 이미 배포된 Discourse 설치 환경과 함께 `docker compose`를 통해 Grafana/Prometheus/Node Exporter 스택이 배포되어 있습니다.

다음은 docker-compose.yaml 파일입니다.

```plaintext
version: "3"

services:
    cadvisor:
        image: gcr.io/cadvisor/cadvisor:latest
        container_name: cadvisor
        restart: unless-stopped
        volumes:
            - /:/rootfs:ro
            - /var/run:/var/run:ro
            - /sys:/sys:ro
            - /var/lib/docker/:/var/lib/docker:ro
            - /dev/disk/:/dev/disk:ro
        networks:
            - prometheus-cadvisor

    node_exporter:
        image: quay.io/prometheus/node-exporter:latest
        container_name: node_exporter
        command:
            - '--path.rootfs=/host'
        pid: host
        restart: unless-stopped
        volumes:
            - '/:/host:ro,rslave'
        networks:
            - prometheus-node_exporter

    prometheus:
        image: prom/prometheus:latest
        restart: unless-stopped
        container_name: prometheus
        ports:
            - "9090:9090"
        volumes:
            - ./prometheus:/app.cfg
        networks:
            - world
            - prometheus-cadvisor
            - prometheus-node_exporter
            - discourse
            - grafana-prometheus
        command: >-
            --config.file=/app.cfg/prometheus.yaml
            --storage.tsdb.path=/prometheus
            --web.console.libraries=/usr/share/prometheus/console_libraries
            --web.console.templates=/usr/share/prometheus/consoles

    grafana:
        image: grafana/grafana:latest
        container_name: grafana
        restart: unless-stopped
        ports:
            - "3000:3000"
        environment:
            GF_SECURITY_ADMIN_USER: [OMITTED]
            GF_SECURITY_ADMIN_PASSWORD: [OMITTED]
            GF_PATHS_PROVISIONING: '/app.cfg/provisioning'
        volumes:
            - ./grafana:/app.cfg
            - ./grafana/provisioning:/etc/grafana/provisioning
        networks:
            - world
            - grafana-prometheus

networks:
    world:
    grafana-prometheus:
        internal: true
    prometheus-cadvisor:
        internal: true
    prometheus-node_exporter:
        internal: true
    discourse:
        external: true

```

`bridge` 네트워크가 아닌 특정 네트워크를 지정하여 Discourse를 다시 빌드하고, Prometheus를 동일한 네트워크에 연결했습니다.

```plaintext
docker network create -d bridge discourse
/var/discourse/launcher rebuild app --docker-args '--network discourse'

```

Prometheus 컨테이너에 진입하여 내부 네트워크 별칭을 사용하여 Discourse 컨테이너로 ping을 보내어 테스트했는데, 정상적으로 도달할 수 있었습니다.

 ![image](https://global.discourse-cdn.com/meta/original/4X/7/9/1/7917411c592e67e070685f89df7b1875b7e90476.png)

이제 Prometheus 작업을 구성하여 메트릭을 스크레이프하도록 내부 IP를 사용했을 때, `server returned HTTP status 404 Not Found`만 확인할 수 있습니다.

다음은 Prometheus 구성입니다:

```plaintext
global:
  scrape_interval: 30s
  scrape_timeout: 10s

rule_files:

scrape_configs:
  - job_name: prometheus
    metrics_path: /metrics
    static_configs:
      - targets:
        - 'prometheus:9090'
  - job_name: node_exporter
    static_configs:
      - targets:
        - 'node_exporter:9100'
  - job_name: discourse_exporter
    static_configs:
      - targets:
        - 'vmuniqueID-app:80'

```

`vmuniqueID`는 실제 VM 이름의 대체 값입니다.

[여기](https://meta.discourse.org/t/discourse-prometheus/72666?u=crius)의 문서에 따르면 내부 IP를 통한 접근이 허용되어야 합니다:

> 기본적으로 `metrics` 라우트에 대한 관리자와 사설 IP의 접근을 허용합니다.

무엇이 부족한지 확인하는 데 도움을 주십시오 😛

---

<div class="post-metadata">

### Author: ![Crius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/crius/32/317214_2.png) [@Crius](https://meta.discourse.org/u/Crius)
#### Post date: [5월 13, 2023, 5:47오후 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/2 "2023-05-13T17:47:49Z")

</div>

더 자세히 알아보기 위해 Discourse에서 API 키를 생성하고 내부 호스트네임으로 요청을 시도해 보았습니다. 응답은 301이 아니었는데, 모든 요청이 https로 리다이렉트되어야 하므로 이는 정상적인 동작입니다.

 ![image](https://global.discourse-cdn.com/meta/original/4X/f/b/3/fb34b8ac7b46df772bfe0f2ee7d89db9cafb4ca7.png)

제 생각에 문제는 내부 IP에서 들어오는 요청조차도 권한이 없는 것으로 처리되어, 이로 인해 404 오류가 발생한다는 점입니다.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [5월 14, 2023, 2:14오전 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/3 "2023-05-14T02:14:36Z")

</div>

프로메테우스 플러그인이 설치되고 활성화되어 있나요? 이 플러그인은 사설 IP 주소로부터의 요청을 허용해야 하지만, 현재 요청을 보내고 있는 IP에 대한 액세스를 허용하도록 환경 변수를 설정해 보실 수 있습니다.

---

<div class="post-metadata">

### Author: ![Crius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/crius/32/317214_2.png) [@Crius](https://meta.discourse.org/u/Crius)
#### Post date: [5월 14, 2023, 10:04오후 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/4 "2023-05-14T22:04:23Z")

</div>

네, Prometheus는 같은 VM에 있고 docker 컨테이너로 배포되어 있습니다. 모든 것이 정상적으로 작동합니다(다른 익스포터들도 배포되어 있음) 그런데 왜인지 Discourse Prometheus 플러그인은 명확하게 실행 중임에도 요청을 받아들이지 않습니다.

ENV 변수라고 하셨을 때, Discourse의 app.yaml 파일에 있는 환경을 말씀하시는 거죠?

즉, 이런 형태인가요:

```plaintext
env:
  DISCOURSE_PROMETHEUS_TRUSTED_IP_ALLOWLIST_REGEX: 172.20.0.3

```

`172.20.0.3`은 Discourse도 연결되어 있는 docker 가상 네트워크에서 Prometheus가 가질 현재 내부 IP입니다.

이미 컨테이너들이 공유하는 외부 IP(VM의 정적 IP)를 사용해보았지만, 같은 네트워크에 있으므로 한 컨테이너가 다른 컨테이너에 접근할 때는 내부 IP를 통해 이루어집니다.

`./launcher restart app`을 실행하면 환경 변수가 반영되는 데 충분할까요?

그 경우 다음 오류가 발생합니다:

```plaintext
Get "http://vmi1187507-app:80/metrics": dial tcp: lookup vmi1187507-app on 127.0.0.11:53: server misbehaving

```

 ![image](https://global.discourse-cdn.com/meta/original/4X/1/1/5/1157d21ea38aedb09b4269623f4dbb40b80304ca.png)

`vmi1187507-app`은 해당 네트워크에서의 컨테이너 네트워크 이름입니다. 이름은 정확하며, 실행 중인 Prometheus 컨테이너에서 ping을 보낼 수 있습니다.  
솔직히 `127.0.0.11:53`이 어디서 오는지 모르겠습니다 🤔

환경 변수를 주석 처리해도 메시지는 동일합니다.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [5월 14, 2023, 10:18오후 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/5 "2023-05-14T22:18:44Z")

</div>

> [@Crius](#):
>
> `./launcher restart app`를 실행하면 환경변수가 제대로 로드될 거죠?

그렇게 **생각** 은 하지만, 확신은 하지 못하겠습니다. 컨테이너 내부에서 테스트를 해보고, 거기서 `curl` 명령으로 요청을 보낼 수 있는지 확인해 보세요.

---

<div class="post-metadata">

### Author: ![Crius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/crius/32/317214_2.png) [@Crius](https://meta.discourse.org/u/Crius)
#### Post date: [5월 14, 2023, 10:33오후 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/6 "2023-05-14T22:33:06Z")

</div>

prometheus 컨테이너에서 wget을 실행하면 다음과 같은 결과가 반환됩니다:

```plaintext
/prometheus # wget http://vmi1229594-app:80/metrics
Connecting to vmi1229594-app:80 (172.20.0.2:80)
Connecting to [public URL] (172.67.69.84:443)
wget: note: TLS certificate validation not implemented
wget: server returned error: HTTP/1.1 404 Not Found

```

여기서 Discourse의 nginx 컨테이너가 자동 리다이렉트를 수행하고 있는 것 같습니다.  
발생하는 상황은 내부 Cloudflare IP인 공개 도메인의 https로 포워딩을 시도하고, 당연히 모든 요청을 거부하는 것입니다.

이것은 본질적인 문제가 아닙니다. 내부 IP에서 `http://yourwebsite.com/metrics` 경로로 요청이 들어올 경우 이 리다이렉트는 일어나지 않아야 하며, 플러그인이 nginx conf에 이 규칙을 추가하여 이를 처리해 줄 것으로 기대했습니다. 그런데 이것이 일어나지 않는 것 같습니다.

Discourse 개발진 중 누가 이 문제에 대해 의견을 남겨주실 수 있을까요? 무작위로 사람들을 언급하고 싶지 않고, 이전에 아무도 이 문제를 보고하지 않은 것 같아 이상합니다.

수정: 컨테이너에 랜덤한 호스트네임이 할당되는 것을 확인했기 때문에 네트워크 설정에 정적 호스트네임도 지정하여 다시 빌드했습니다.  
그 후에도 prometheus 잡을 metrics의 https 버전으로 접근하도록 설정해 보았지만, 문제는 첫 번째 단계로 돌아가게 됩니다:

```plaintext
global:
  scrape_interval: 30s
  scrape_timeout: 10s

rule_files:

scrape_configs:
# other jobs
# [...]
  - job_name: discourse_exporter
    scheme: https
    tls_config:
      insecure_skip_verify: true
    static_configs:
      - targets:
        - 'discourse_app'

```

```plaintext
/prometheus # wget https://discourse_app/metrics
Connecting to discourse_app (172.20.0.2:443)
wget: note: TLS certificate validation not implemented
Connecting to [public URL] (104.26.4.193:443)
wget: server returned error: HTTP/1.1 404 Not Found

```

 ![image](https://global.discourse-cdn.com/meta/original/4X/0/4/3/043c9f48b0a2de87c87316b021d3d60f204f6753.png)

이 시점에서 이것은 플러그인 자체의 문제인 것으로 보입니다.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [5월 15, 2023, 12:40오전 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/7 "2023-05-15T00:40:09Z")

</div>

> [@Crius](#):
>
> 여기서 추측컨대, Discourse nginx 컨테이너의 자동 리다이렉트 때문이겠죠?

맞는 것 같습니다. 컨테이너 이름이 아니라 호스트 이름을 사용해 액세스해야 합니다.

---

<div class="post-metadata">

### Author: ![Crius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/crius/32/317214_2.png) [@Crius](https://meta.discourse.org/u/Crius)
#### Post date: [5월 15, 2023, 7:42오전 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/8 "2023-05-15T07:42:00Z")

</div>

저는 호스트네임을 사용하고 있습니다. 많이 그리고 늦게 작성해서 혼란스러웠을 수 있지만, 분명히 내부 네트워크 호스트네임을 사용하고 있습니다.

---

<div class="post-metadata">

### Author: ![JammyDodger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jammydodger/32/254611_2.png) [@JammyDodger](https://meta.discourse.org/u/JammyDodger)
#### Post date: [5월 15, 2023, 9:39오전 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/9 "2023-05-15T09:39:16Z")

</div>

이 분야가 제 전문 분야는 아니지만, 토픽 타이머에 의해 삭제된 게시물들을 뒤져서 관련이 있을 만한 것이 있는지 확인해 보았고, 이 정도는 찾은 것 같습니다. (완전히 틀린 것이라면 죄송합니다 🙂 🙏 )

[Getting Discourse to see the Prometheus server IP - #5 by ishan](https://meta.discourse.org/t/getting-discourse-to-see-the-prometheus-server-ip/265015/5?u=jammydodger)  
[Using Prometheous with Cloudflare](https://meta.discourse.org/t/using-prometheous-with-cloudflare/265022)

---

<div class="post-metadata">

### Author: ![Crius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/crius/32/317214_2.png) [@Crius](https://meta.discourse.org/u/Crius)
#### Post date: [5월 15, 2023, 10:21오전 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/10 "2023-05-15T10:21:45Z")

</div>

@JammyDodger 감사합니다. 하지만 불행히도 해당 리소스는 도움이 되지 않았습니다.

유사한 문제를 다루고 있지만, 이 경우와 약간 다르기 때문에 적용이 되지 않습니다.  
확실히 하기 위해, 해당 토픽 중 하나에서 제안한 방법(그리고 @pfaffman님의 조언도 포함하여)을 시도해 보았고, `DISCOURSE_PROMETHEUS_TRUSTED_IP_ALLOWLIST_REGEX` 환경 변수를 가지고 여러 가지로 테스트해 보았습니다.

다음과 같이 테스트해 보았습니다:

- 주석 처리
- 내부 IP 값으로 추가
- 외부 IP 값으로 추가

또한 Prometheus 스크레이프 잡을 변경하여 Discourse 설치 환경을 다음과 같이 지정해 보았습니다:

- 직접 내부 IP
- Docker 내부 호스트명
- 직접 외부 IP
- 공개 도메인 이름

모든 경우에서 `http`와 `https`를 모두 시도해 보았습니다.

모든 경우에서 404 오류가 발생합니다.  
요청이 내부 IP에서 오고 있으므로, 실제 페이지 응답이 반환되기를 기대했습니다.

---

<div class="post-metadata">

### Author: ![leonardo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/leonardo/32/228634_2.png) [@leonardo](https://meta.discourse.org/u/leonardo)
#### Post date: [5월 15, 2023, 4:41오후 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/11 "2023-05-15T16:41:24Z")

</div>

> [@pfaffman](#):
>
> 컨테이너 이름이 아닌 호스트 이름으로 액세스해야 합니다.

Jay가 여기서 말하고자 한 것은, 우연히 올바른 IP로 해석되는 임의의 호스트 이름이 아니라, 컨테이너 .yml 정의에 설정된 호스트 이름(`DISCOURSE_HOSTNAME`)을 사용해야 한다는 것입니다.

이것은 의도적으로 설정된 것입니다. 이렇게 함으로써 어디서든 공개 인스턴스를 역프록시(reverse proxy)하는 것이 간단히 불가능해지고, 설정된 호스트 이름만 허용되도록 합니다:

```bash
$ curl -I https://try.discourse.org/about.json
HTTP/2 200
server: nginx
date: Mon, 15 May 2023 16:25:05 GMT
content-type: application/json; charset=utf-8
[...]

# 아래는 try.somebogusreverseproxy.com에 try.discourse.org와 동일한 IP 주소를 가리키는 DNS 레코드를 생성한 것과
# 동일하며, https://try.somebogusreverseproxy.com/about.json을 요청하는 것과 같습니다.
$ curl -H 'Host: try.somebogusreverseproxy.com' -I https://try.discourse.org/about.json
HTTP/2 404
cache-control: no-cache
content-length: 1427
content-type: text/html
cdck-proxy-id: app-router-tiehunter02.sea1
cdck-proxy-id: app-balancer-tieinterceptor1b.sea1

```

반대로, 이렇게 시도해 보면:

```bash
curl -H 'Host: YOUR_CONFIGURED_HOSTNAME' -I https://discourse_app/metrics

```

동작은 하지만, 이는 해킹(hack)에 가깝습니다. Discourse가 설정된 호스트 이름으로 투명하게 접근할 수 있도록 필요한 DNS를 설정할 것으로 기대합니다:

```bash
curl -I https://YOUR_CONFIGURED_HOSTNAME/metrics

```

이를 수행하는 방법은 요구 사항에 따라 크게 다르지만, 가장 간단한 옵션은 HTTP 요청이 발생하는 위치에서 `/etc/hosts`에 별칭(alias)을 설정하는 것입니다.

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [5월 15, 2023, 5:43오후 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/12 "2023-05-15T17:43:04Z")

</div>

> [@Crius](#):
>
> `http://vmi1187507-app:80/metrics`

Prometheus 익스포터는 포트 80에서 실행되지 않습니다. 자체 포트에서 리스닝하며, 기본적으로 [포트 9405](https://github.com/discourse/discourse-prometheus/blob/main/plugin.rb#L37)를 사용합니다.

---

<div class="post-metadata">

### Author: ![Crius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/crius/32/317214_2.png) [@Crius](https://meta.discourse.org/u/Crius)
#### Post date: [5월 16, 2023, 10:28오전 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/13 "2023-05-16T10:28:33Z")

</div>

좋은 발견이지만, 해당 특정 포트를 대상으로 하면 “connection refused” 메시지가 나옵니다.

`Get "http://discourse_app:9405/metrics": dial tcp 172.20.0.2:9405: connect: connection refused`

확실히 하기 위해 prometheus 컨테이너 내부에서 `wget`으로 테스트도 해보았습니다.

```plaintext
/prometheus # ping discourse_app
PING discourse_app (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.223 ms
64 bytes from 172.20.0.2: seq=1 ttl=64 time=0.270 ms
^C
--- discourse_app ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.223/0.246/0.270 ms
/prometheus # wget discourse_app:9405/metrics
Connecting to discourse_app:9405 (172.20.0.2:9405)
wget: can't connect to remote host (172.20.0.2): Connection refused

```

> [@leonardo](#):
>
> 반대로, 이렇게 시도해 보세요:
> 
> ```plaintext
> curl -H 'Host: YOUR_CONFIGURED_HOSTNAME' -I https://discourse_app/metrics
> 
> ```

네, (prometheus 컨테이너는 barebone busybox라서) 대신 wget으로 테스트했지만, 어쨌든 metrics에 접근할 수 있었습니다.

즉, 말씀하시는 것은 prometheus가 실행 중인 컨테이너의 /etc/hosts에 해당 주소를 해석하도록 하는 항목을 추가하는 방법을 찾아야 한다는 뜻이죠… 거기에선 이해를 못 했네요 🙂

제가 한 일은 단순히 nginx만 실행하는 또 다른 docker 컨테이너를 추가하고, 수신하는 요청에 `Host` 헤더를 추가하는 포워드 프록시 구성을 제공하는 것이었습니다. 이 컨테이너는 어떤 포트도 노출하지 않으므로, 어쨌든 내부 가상 네트워크에서만 접근할 수 있습니다.

그럼 무엇이 어떻게 바뀌었을까요?

Prometheus Job:

```plaintext
  - job_name: discourse_exporter_proxy
    scheme: http
    static_configs:
      - targets:
        - 'discourse_forward_proxy:8080'

```

docker-compose.yaml (프록시 관련 부분만)

```plaintext
version: "3"

services:
# [...]
    discourse_forward_proxy:
        image: nginx:latest
        container_name: discourse_forward_proxy
        restart: unless-stopped
        volumes:
            - ./discourse_forward_proxy/:/etc/nginx/conf.d
        networks:
            - prometheus-discourse_forward_proxy
            - discourse
# [...]

networks:
    prometheus-discourse_forward_proxy:
        internal: true
    discourse:
        external: true

```

`docker-compose.yaml`이 있는 디렉터리에서 `./discourse_forward_proxy/discourse_forward_proxy.conf` 파일을 만들어야 합니다.

```plaintext
server {
    listen 8080;

    location /metrics {
      proxy_set_header Host "YOUR_DOMAIN_HERE.COM";
      proxy_pass https://discourse_app/metrics;
    }
}

```

이렇게 하면 됩니다:

 ![image](https://global.discourse-cdn.com/meta/original/4X/0/8/c/08cf8bbf77d08c9ca3775c98d011eb9059e5fba5.png)

---

<div class="post-metadata">

### Author: ![Crius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/crius/32/317214_2.png) [@Crius](https://meta.discourse.org/u/Crius)
#### Post date: [5월 16, 2023, 12:17오후 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/14 "2023-05-16T12:17:08Z")

</div>

기록을 위해 말씀드리자면, 필요한 모든 것을 설정해 둔 저장소를 하나 보유하고 있습니다.  
포워딩 프록시 설정 파일에 포함된 우리 웹사이트의 FQDN과 같은 일부 하드코딩된 값이 포함되어 있어, 다른 사람이 사용하려면 변경이 필요하지만, 다른 분들께 유용할 수 있을 것입니다.

Docker Compose부터 Nginx 설정, 그리고 리소스와 대시보드에 대한 Grafana 프로비저닝까지 모든 것이 포함되어 있습니다.

> **[GitHub - netgamers-forum/ngi-monitor-stack](https://github.com/netgamers-forum/ngi-monitor-stack)**
>
> Contribute to netgamers-forum/ngi-monitor-stack development by creating an account on GitHub.

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [5월 16, 2023, 2:56오후 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/16 "2023-05-16T14:56:43Z")

</div>

> [@Crius](#):
>
> Get “http://discourse\_app:9405/metrics”: dial tcp 172.20.0.2:9405: connect: connection refused

이는 다음 줄 때문입니다:

```plaintext
GlobalSetting.add_default :prometheus_collector_port, 9405
GlobalSetting.add_default :prometheus_webserver_bind, "localhost"
GlobalSetting.add_default :prometheus_trusted_ip_allowlist_regex, ""

```

`localhost`에 바인딩한다는 것은 localhost IP로만 연결할 수 있음을 의미하므로, `172.20.0.2`로 연결하는 것이 실패하는 것입니다. 이는 의도된 것보다 훨씬 더 넓은 대상에게 노출되지 않도록 하는 보안 조치입니다.

컨테이너 정의 파일에 다음을 설정하면:

```plaintext
  DISCOURSE_PROMETHEUS_WEBSERVER_BIND: '*'

```

모든 IP 주소에서 리스닝하게 되어 다른 컨테이너에서 연결할 수 있게 됩니다.

이것이 작동하게 된 이유는 다음과 같습니다:

```plaintext
server {
    listen 8080;

    location /metrics {
      proxy_set_header Host "YOUR_DOMAIN_HERE.COM";
      proxy_pass https://discourse_app/metrics;
    }
}

```

이 nginx 컨테이너가 이제 `localhost` IP를 통해 prometheus와 통신하고 있기 때문입니다.

서비스가 리스닝 중인 IP나 포트가 확실하지 않다면, `ss -ltp` 또는 `netstat -ltp`를 사용할 수 있습니다(_컨테이너 내부에서!_ 필요한 패키지는 각각 `net-tools`와 `iproute2`입니다). 예를 들어, 저는 방금 prometheus 플러그인이 포함된 컨테이너를 다시 빌드한 후 다음과 같은 것을 확인했습니다:

```plaintext
root@discourse-docker-app:/# ss -ltp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process                             
LISTEN 0 128 127.0.0.1:3000 0.0.0.0:*                                            
LISTEN 0 128 0.0.0.0:postgresql 0.0.0.0:*                                            
LISTEN 0 128 0.0.0.0:https 0.0.0.0:* users:(("nginx",pid=555,fd=7))     
LISTEN 0 128 127.0.0.1:9405 0.0.0.0:*                                            
LISTEN 0 128 0.0.0.0:redis 0.0.0.0:*                                            
LISTEN 0 128 0.0.0.0:http 0.0.0.0:* users:(("nginx",pid=555,fd=6))     
LISTEN 0 128 [::]:postgresql [::]:*                                            
LISTEN 0 128 [::]:https [::]:* users:(("nginx",pid=555,fd=8))     
LISTEN 0 128 [::]:redis [::]:*

root@discourse-docker-app:/# curl http://172.17.0.2:9405/metrics
curl: (7) Failed to connect to 172.17.0.2 port 9405: Connection refused

root@discourse-docker-app:/# curl http://localhost:9405/metrics
# HELP discourse_collector_working Is the master process collector able to collect metrics
# TYPE discourse_collector_working gauge
discourse_collector_working 1

# HELP discourse_collector_rss total memory used by collector process
# TYPE discourse_collector_rss gauge
discourse_collector_rss 38178816
…

```

> [@Crius](#):
>
> 솔직히 그 `127.0.0.11:53`이 어디에서 오는지 모르겠습니다 🤔

`vmi1187507-app`에 대한 IP 조회 요청을 거부하는 네임서버입니다. 포트 53은 DNS입니다.

---

<div class="post-metadata">

### Author: ![Crius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/crius/32/317214_2.png) [@Crius](https://meta.discourse.org/u/Crius)
#### Post date: [5월 16, 2023, 11:18오후 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/19 "2023-05-16T23:18:08Z")

</div>

Michael, 정말 좋은 내용입니다. 시간을 내어 작성해 주셔서 감사합니다.

이번 주 업무 시간 동안 이미 너무 많은 시간을 썼기 때문에, 주말에 테스트해 보겠습니다 😛

시도해 본 과정에서, prometheus가 포함된 컨테이너가 메트릭을 요청하는 것으로 보이는 내부 IP를 `DISCOURSE_PROMETHEUS_TRUSTED_IP_ALLOWLIST_REGEX`에 추가해 보았지만 작동하지 않았습니다.

`DISCOURSE_PROMETHEUS_WEBSERVER_BIND`를 제안하셨는데, 이 값을 어디서 찾으신 건지 여쭤봐도 될까요? `app.yml` 파일에 추가해야 하는 또 다른 환경 변수라고 이해하고 있는데, 맞나요?

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [5월 17, 2023, 12:07오전 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/20 "2023-05-17T00:07:23Z")

</div>

> [@Crius](#):
>
> 하지만 작동하지 않았습니다

_어떤 식으로_ 작동하지 않았나요?

연결에 실패했다면, allowlist 설정은 중요하지 않습니다. 왜냐하면 allowlist은 L4 연결 _이후_에 작동하기 때문입니다.

> [@Crius](#):
>
> 그 정보를 어디서 얻었는지 여쭤봐도 될까요?

Discourse 코드베이스에는 _마법_ 🪄 같은 부분이 있습니다. ENV에 `DISCOURSE_SITE_OR_GLOBAL_SETTING_NAME`을 설정하면 해당 값이 오버라이드됩니다.

따라서 해당 값을 설정하면 아래 설정이 오버라이드됩니다:

```plaintext
GlobalSetting.add_default :prometheus_webserver_bind, "localhost"

```

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [6월 16, 2023, 12:08오전 UTC](https://meta.discourse.org/t/prometheus-scrape-job-cannot-reach-the-metrics/264902/21 "2023-06-16T00:08:23Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
