nginx 컨테이너 네트워크 DNS가 잘못된 IP 주소로 확인됩니다.

nginx 컨테이너 네트워크 DNS가 잘못된 IP 주소로 확인됩니다.

patch-nginx 컨테이너는 nginx 프로세스 내에서 patch-backend의 IP 주소를 잘못 확인했지만 nginx 명령줄에서 수동으로 확인할 때는 확인되지 않았습니다.

Podman 컨테이너 내에서 nginx를 에이전트로 실행하고 있지만 인터넷 검색을 통해 이 문제가 Docker에도 존재하고 해결책이 없는 것으로 나타났습니다.

nginx 로그에 다음이 표시됩니다.

2023/07/12 19:33:52 [error] 24#24: *52 connect() failed (113: No route to host) while connecting to upstream, client: 10.89.0.119, server: patches.lan, request: "GET /api/auth HTTP/1.1", upstream: "https://10.89.0.117:9000/api/auth", host: "10.10.25.131", referrer: "https://10.10.25.131/"

        10.89.0.119 - - [12/Jul/2023:19:33:52 +0000]
        "GET /api/auth HTTP/1.1" 502 559
        "https://10.10.25.131/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
        Certificate: "-"
        Client Key: "-"

업스트림 호스트가 10.89.0.117임을 알 수 있습니다. nginx 구성을 확인하러갔습니다. -proxy_pass가 다음을 가리킵니다 patches-backend.

events {
    worker_connections 1024;
}

http {
    include    /etc/nginx/mime.types;
    access_log    /var/log/nginx/access.log;
    error_log    /var/log/nginx/error.log;

    log_format custom '
        $remote_addr - $remote_user [$time_local]
        "$request" $status $body_bytes_sent
        "$http_referer" "$http_user_agent"
        Certificate: "$ssl_client_cert"
        Client Key: "$ssl_client_raw_cert"
        ';

    server {
        listen 80;
        listen [::]:80;

        server_name patches.lan 10.10.25.131 ;

        return 301 https://$host$request_uri;
    }

    server {
        listen 443 ssl;
        listen [::]:443 ssl;

        server_name patches.lan 10.10.25.131 ;


        access_log /var/log/nginx/access.log custom;

        # Client-facing certificate and key
        ssl_certificate /patches/server_certs/patches.lan.crt;
        ssl_certificate_key /patches/server_certs/patches.lan.key;


        # Disable client certificate request
        ssl_verify_client optional_no_ca;




        location /api {
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $http_host;



            # Set X-SSL-CERT header with client certificate
            proxy_set_header X-SSL-CERT $ssl_client_escaped_cert;

            proxy_pass https://patches-backend:9000;
        }

        location / {
            proxy_set_header Host $http_host;



            # Set X-SSL-CERT header with client certificate
            proxy_set_header X-SSL-CERT $ssl_client_escaped_cert;

            proxy_pass http://patches-frontend:3000;
        }
    }

모든 것이 그래야만 합니다. nginx 컨테이너에서 백엔드까지 DNS 이름에 대해 컬을 확인했습니다.

root@87c91993cab5:/# curl patches-backend:9000
curl: (52) Empty reply from server

이것은 그래야만합니다. 하지만 확인해 보니 podman inspect patches-backend다음과 같습니다.

...SNIP...
"Networks": {
                    "host-bridge-net": {
                         "EndpointID": "",
                         "Gateway": "10.89.0.1",
                         "IPAddress": "10.89.0.120",
                         "IPPrefixLen": 24,
                         "IPv6Gateway": "",
                         "GlobalIPv6Address": "",
                         "GlobalIPv6PrefixLen": 0,
                         "MacAddress": "3e:c9:de:23:44:a6",
                         "NetworkID": "host-bridge-net",
                         "DriverOpts": null,
                         "IPAMConfig": null,
                         "Links": null,
                         "Aliases": [
                              "e9485d2c8cf7"
                         ]
                    }
               }
...SNIP...

patch-backend는 명백히 10.89.0.120이지만, nginx의 맥락에서 어떻게든 해당 호스트 이름을 10.89.0.117네트워크 어디에도 존재하지 않는 호스트 이름으로 확인합니다(로그에서 볼 수 있듯이).

나는 이것이 어떻게 일어 났는지 전혀 모른다. nginx 구성에는 IP 대신 호스트 이름이 있으므로 어딘가에 하드코딩된 IP가 아니며 위에 표시된 것처럼 patches-backend명령줄에서 확인할 때 nginx 컨테이너가 올바르게 확인됩니다. 그러나 nginx 프로세스는 존재하지 않는 IP 주소를 얻었습니다. 내 컨테이너에는 IP 117이 없습니다.

# Reverse search 10.89.0.117 (the wrong IP) across all containers
[grant@patches2 opt]$ podman inspect -f '{{.Name}}' $(podman ps -a -q --format='{{.ID}}') | xargs -I {} sh -c 'podman inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" {} | grep -w 10.89.0.117 && echo Container: {}'
# Reverse search 10.89.0.120 (the correct IP) across all containers
[grant@patches2 opt]$ podman inspect -f '{{.Name}}' $(podman ps -a -q --format='{{.ID}}') | xargs -I {} sh -c 'podman inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" {} | grep -w 10.89.0.120 && echo Container: {}'
10.89.0.120
Container: patches-backend

어떻게 이런 일이 일어나는지 상상할 수 없으며 간단한 예를 들어 재현할 수도 없습니다. nginx에는 추가 구성이 적용되지 않는다는 점은 주목할 가치가 있습니다. 이것이 유일한 구성입니다.

답변1

간단히 대답하자면 nginx대부분의 경우 구성이 로드되는 동안 DNS 확인이 캐시되고 재부팅하면 nginxDNS 캐시가 플러시되고 새 IP 주소를 얻거나 TTL이 만료될 때까지 기다릴 수 있다는 것입니다.

하나 있다https://serverfault.com은 좋은 답변을 제공합니다더 나은 설명과 팁을 통해 DNS 확인자 및 nginx변수를 사용하여 각 요청에 대해 새로운 조회를 수행할 수 있습니다.

관련 정보