如何在 docker 容器中获取真实的客户端 IP 以登录到数据库

问题描述 投票:0回答:0

我有以下 docker compose 文件:

version: "3.8"

services:
    postgres:
        image: postgres:11
        volumes:
            - myapp_postgres_volume:/var/lib/postgresql/data
            - type: tmpfs
              target: /dev/shm
              tmpfs:
                size: 536870912 # 512MB
        environment:
            POSTGRES_DB: elearning_academy
            POSTGRES_USER: myapp
            POSTGRES_PASSWORD: myapp123
        networks:
            - myapp_network

    pgadmin:
        image: dpage/pgadmin4:5.4
        volumes:
            - myapp_pgadmin_volume:/var/lib/pgadmin
        environment:
            PGADMIN_DEFAULT_EMAIL: [email protected]
            PGADMIN_DEFAULT_PASSWORD: myapp123
        ports:
            - 8080:80
        networks:
            - myapp_network
            
    redis:
        image: redis:6.2.4
        volumes:
            - myapp_redis_volume:/data
        networks:
            - myapp_network

    wsgi:
        image: wsgi:myapp3
        volumes:
            - /myapp/frontend/static/
            - ./wsgi/myapp:/myapp
            - /myapp/frontend/clientApp/node_modules
            - /etc/timezone:/etc/timezone:ro
            - /etc/localtime:/etc/localtime:ro
            - /var/run/docker.sock:/var/run/docker.sock:ro
        depends_on:
            - postgres
            - redis
        ports:
            - 9090
            - 3000:3000
            - 8000:8000
        environment:
            C_FORCE_ROOT: 'true'
            SERVICE_PORTS: 9090
        networks:
            - myapp_network
        deploy:
            replicas: 1
            update_config:
                parallelism: 1
                delay: 10s
            restart_policy:
                condition: on-failure
                max_attempts: 3
                window: 120s

    nodejs:
        image: nodejs:myapp3
        volumes:
            - ./nodejs/frontend:/frontend
            - /frontend/node_modules
        depends_on:
            - wsgi
        ports:
            - 9000:9000 # development
            - 9999:9999 # production
        environment:
            BACKEND_API_URL: http://0.0.0.0:3000
        networks:
            - myapp_network

    nginx:
        image: mydockeraccount/nginx-brotli:1.21.0
        volumes:
            - ./nginx:/etc/nginx/conf.d:ro
            - ./wsgi/myapp:/myapp:ro
            - myapp_nginx_volume:/var/log/nginx/
            - /etc/timezone:/etc/timezone:ro
            - /etc/localtime:/etc/localtime:ro
        networks:
            - myapp_network
            
    haproxy:
        image: haproxy:2.3.9
        volumes:
            - ./haproxy:/usr/local/etc/haproxy/:ro
            - /var/run/docker.sock:/var/run/docker.sock
            - /etc/timezone:/etc/timezone:ro
            - /etc/localtime:/etc/localtime:ro
        depends_on:
            - wsgi
            - nodejs
            - nginx
        ports:
            - 9763:80
        networks:
            - myapp_network
        deploy:
            placement:
                constraints: [node.role == manager]

volumes:
    myapp_postgres_volume:
    myapp_redis_volume:
    myapp_nginx_volume:
    myapp_pgadmin_volume:

networks:
    myapp_network:
        driver: overlay

如您所见,我有一个 nodejs 应用程序和一个 django (wsgi) 应用程序。我已经编写了 django 中间件来将传入的 IP 记录到数据库中。但是,它记录的 IP 与实际 IP 不同。在网上看了之后,我开始知道这可能是由于 docker 网络的配置方式所致(

overlay
可以在上面的 docker compose 文件的最后一行中看到)。我在网上看到需要在
host
模式下配置docker网络。所以我尝试将
network_mode: host
添加到每个服务并从上面的文件中删除
networks
部分。

version: "3.8"

services:
    postgres:
        image: postgres:11
        volumes:
            - myapp_postgres_volume:/var/lib/postgresql/data
            - type: tmpfs
              target: /dev/shm
              tmpfs:
                size: 536870912 # 512MB
        environment:
            POSTGRES_DB: elearning_academy
            POSTGRES_USER: myapp
            POSTGRES_PASSWORD: myapp123
        network_mode: host

    pgadmin:
        image: dpage/pgadmin4:5.4
        volumes:
            - myapp_pgadmin_volume:/var/lib/pgadmin
        environment:
            PGADMIN_DEFAULT_EMAIL: [email protected]
            PGADMIN_DEFAULT_PASSWORD: myapp123
        ports:
            - 8080:80
        network_mode: host

    redis:
        image: redis:6.2.4
        volumes:
            - myapp_redis_volume:/data
        network_mode: host

    wsgi:
        image: wsgi:myapp3
        volumes:
            - /myapp/frontend/static/
            - ./wsgi/myapp:/myapp
            - /myapp/frontend/clientApp/node_modules
            - /etc/timezone:/etc/timezone:ro
            - /etc/localtime:/etc/localtime:ro
            - /var/run/docker.sock:/var/run/docker.sock:ro
        depends_on:
            - postgres
            - redis
        ports:
            - 9090
            - 3000:3000
            - 8000:8000
        environment:
            C_FORCE_ROOT: 'true'
            SERVICE_PORTS: 9090
        network_mode: host
        deploy:
            replicas: 1
            update_config:
                parallelism: 1
                delay: 10s
            restart_policy:
                condition: on-failure
                max_attempts: 3
                window: 120s

    nodejs:
        image: nodejs:myapp3
        volumes:
            - ./nodejs/frontend:/frontend
            - /frontend/node_modules
        depends_on:
            - wsgi
        ports:
            - 9000:9000 # development
            - 9999:9999 # production
        environment:
            BACKEND_API_URL: http://0.0.0.0:3000
        network_mode: host

    nginx:
        image: mydockeraccount/nginx-brotli:1.21.0
        volumes:
            - ./nginx:/etc/nginx/conf.d:ro
            - ./wsgi/myapp:/myapp:ro
            - myapp_nginx_volume:/var/log/nginx/
            - /etc/timezone:/etc/timezone:ro
            - /etc/localtime:/etc/localtime:ro
        network_mode: host

    haproxy:
        image: haproxy:2.3.9
        volumes:
            - ./haproxy:/usr/local/etc/haproxy/:ro
            - /var/run/docker.sock:/var/run/docker.sock
            - /etc/timezone:/etc/timezone:ro
            - /etc/localtime:/etc/localtime:ro
        depends_on:
            - wsgi
            - nodejs
            - nginx
        ports:
            - 9763:80
        network_mode: host
        deploy:
            placement:
                constraints: [node.role == manager]

volumes:
    myapp_postgres_volume:
    myapp_redis_volume:
myapp_nginx_volume:
myapp_pgadmin_volume:

当我运行

docker stack deploy -c docker-compose.yml my_stack
时,它输出
Ignoring unsupported options: network_mode.
我试图检查网络是如何创建的:

$ docker network ls
NETWORK ID     NAME                       DRIVER    SCOPE
tp6olv2atq06   myapp_default              overlay   swarm

所以它最终只配置在覆盖模式下,而不是在主机模式下。

进一步阅读在线显示主机网络模式不适用于以

docker stack deploy
启动的群。 (可能相关的未决问题:github 链接)。

对于开发,我只是将 vscode 连接到 nodejs 和 wsgi 容器并在调试模式下运行应用程序。所以 nginx 在开发过程中不参与。但是,在部署中我们确实使用了 nginx,它也是作为 docker 容器部署的。

现在我有以下问题:

Q1. 是否正在配置 nginx 以设置

X-Real-IP
header with actual IP only solution?
Q2. 我不能做一些 docker 配置或更改 docker compose 文件以获得 docker 容器(在我的例子中是 django)内的真实 IP 地址,而不对 nginx 做任何更改吗?说以某种方式配置这些容器在
host
网络上?
Q3. 如果我以某种方式配置 nginx 以设置
X-Real-IP
标头,它是否会在开发时工作,因为在开发时不涉及 nginx?
Q4. this 答案的评论似乎表明,如果 nginx 本身作为 docker 容器运行,则配置它以添加
X-Real-IP
标头将不起作用。是这样吗

docker nginx docker-compose docker-swarm network-monitoring
© www.soinside.com 2019 - 2024. All rights reserved.