【问题标题】:Open docker port running on host network to outside traffic打开在主机网络上运行的 docker 端口到外部流量
【发布时间】:2022-02-16 00:20:21
【问题描述】:

如何让我的 docker 容器运行 gunicorn / FastAPI 服务器以响应外部流量?

这就是我的容器的运行方式

docker run --detach --net host -v "/path/to/app/app":"/app" -it me/app:appfastapi_latest /start.sh
cat start.sh
#! /usr/bin/env sh
set -e

# Start Gunicorn
exec gunicorn -k "uvicorn.workers.UvicornWorker" -c /app/gunicorn_conf.py "main:app"
cat ./app/gunicorn_conf.py
...
host = "0.0.0.0"
port = "8000"
bind = f"{host}:{port}"
...
docker logs container_id

...
[2022-02-15 05:40:10 +0000] [1] [INFO] Listening at: http://127.0.0.1:8000 (1)

^^^ this was before a fix in the conf, now its
0.0.0.0:8000
...

来自主机的卷曲容器

curl localhost:8000/hw                                                                                                                 {"message":"Hello World"}

这是应该的。但是当我这样做时

curl domain:8000/hw
curl: (7) Failed to connect to domain port 8000: Connection refused

我不知道如何解决这个问题。在我的 FastAPI 主目录中

ORIGINS = [
    "http://127.0.0.1:8000",
    "http://localhost:8000",
    "http://domain:8000",
]


app = FastAPI(title="MY API", root_path=ROOT_PATH, docs_url="/")
app.add_middleware(
    CORSMiddleware,
    allow_origins=ORIGINS,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

我打开了防火墙(我相信)

sudo iptables -L                                                                                                                       
Chain INPUT (policy ACCEPT)                                                                                                                                           
target     prot opt source               destination                                                                                                                  
ACCEPT     tcp  --  172.17.0.2           anywhere             tcp dpt:mysql                                                                                           
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:8000                                                                                            
                                                                                                                                                                      
Chain FORWARD (policy DROP)                                                                                                                                           
target     prot opt source               destination                                                                                                                  
DOCKER-USER  all  --  anywhere             anywhere                                                                                                                   
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere                                                                                                      
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED                                                                             
DOCKER     all  --  anywhere             anywhere                                                                                                                     
ACCEPT     all  --  anywhere             anywhere                                                                                                                     
ACCEPT     all  --  anywhere             anywhere 

Chain OUTPUT (policy ACCEPT)                                                                                                                                          target     prot opt source               destination                                                                                                                                                                                                                                                                                        Chain DOCKER (1 references)                                                                                                                                           target     prot opt source               destination                                                                                                                                                                                                                                                                                        Chain DOCKER-ISOLATION-STAGE-1 (1 references)                                                                                                                         target     prot opt source               destination                                                                                                                  DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere                                                                                                      RETURN     all  --  anywhere             anywhere                                                                                                                                                                                                                                                                                           Chain DOCKER-ISOLATION-STAGE-2 (1 references)                                                                                                                         target     prot opt source               destination                                                                                                                  DROP       all  --  anywhere             anywhere                                                                                                                     RETURN     all  --  anywhere             anywhere  

我已经为 8000 端口打开了

sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT

我的系统是Debian9,

docker --version
Docker version 19.03.15, build 99e3ed8919

【问题讨论】:

  • 在您的docker run 命令中,您只需编写-p 8000:8000 即可将内部端口映射到主机端口。
  • ...并删除--network host,这会使任何-p 选项无效。 (但由于它完全禁用了 Docker 网络,并且您的应用程序直接连接到主机的网络堆栈,我认为这不是您的问题。)
  • 我不得不这样做 --net host 因为服务器需要连接到主机上的 MariaDB,这更容易。 docker网络是首选吗?我认为在主机网络上运行更直接......
  • 如果您有两个需要相互通信的 docker 容器,我建议为它们创建一个网络docker network create my-app,然后将两个容器分配到该网络。这样,它们可以通过使用容器名称作为主机名来相互访问(例如,如果 MAriaDB 容器的名称为 myapp-mariadb,您可以从 FastAPI 容器连接到它,只需使用 myapp-mariadb:3306 作为主机和端口数据库连接)
  • 谢谢,我知道,但它是一个实时系统,所以我必须逐步更换组件......

标签: docker gunicorn fastapi iptables


【解决方案1】:

Listening at: http://127.0.0.1:8000

表示gunicorn正在监听docker容器的localhost。无法从外部网络访问容器的本地主机。您应该将0.0.0.0:8000 设置为能够从外部访问。

是的,您尝试设置

host = "0.0.0.0"
port = "8000"

但是 gunicorn config file 没有 hostport 参数。你应该改用bind = '0.0.0.0:8000'

运行容器时不要忘记publish port-p 8000:8000

【讨论】:

  • 谢谢,检查绑定...
  • 是的,gunicorn.conf 似乎是一个不好的例子,或者我修改错了。我现在有bind=f'{host}:{port},它可以在主机上运行。 curl domain:8000/hw 在主机上工作,但在远程机器上它仍然得到curl: (7) Failed to connect to domain port 8000: Connection refused。现在必须是防火墙吗?
  • 会不会和docker隔离阶段有关?我需要谷歌这意味着什么。
  • @ElDude 我不知道你的网络架构,所以我无法检查主机外部发生了什么。然而,第二个问题至少在 docker 范围之外(可能)。
  • 我也在查看我的 ISP 设置,似乎他们有我忘记的防火墙设置。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-25
  • 2021-01-29
  • 2021-06-16
  • 1970-01-01
  • 2016-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多