iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
Kubernetes

探討k8s部署方式系列 第 17 篇

把 FastAPI 做成 Docker Image(續)[Day17]

  • 分享至 

  • xImage
  •  

二十六、systemd 跟 Docker 不是完全互斥

這也是很容易誤會的一點。

不是:

用了 Docker
就完全沒有 systemd

Docker Engine 本身在 Linux 上往往就是由 systemd 管理。

例如:

systemctl status docker

所以可能是:

systemd
   │
   ▼
Docker Daemon
   │
   ▼
Container
   │
   ▼
FastAPI

差別是:

以前:

systemd
→ 直接管理 FastAPI Process

現在:

systemd
→ 管理 Docker

Docker
→ 管理 FastAPI Container

二十七、Nginx 要怎麼接 Docker?

目前:

Container

映射:

Host :8000

所以原本 Nginx:

location / {
    proxy_pass http://127.0.0.1:8000;
}

完全可以不改。

架構:

Internet
   │
   ▼
Nginx
Host :80
   │
   ▼
Host :8000
   │
   ▼
Docker Port Mapping
   │
   ▼
Container :8000
   │
   ▼
FastAPI

因此這次從 systemd 改 Docker,對外部使用者甚至可以完全沒有感覺。


二十八、更安全一點的 Port Binding

如果只有 Host 上的 Nginx 需要存取 FastAPI,可以不把:

8000

開給所有 Network Interface。

不要:

-p 8000:8000

而可以:

-p 127.0.0.1:8000:8000

表示:

Host 127.0.0.1:8000

↓

Container 8000

這樣外部網路不能直接:

server-ip:8000

存取 FastAPI。

只能:

Nginx
→ localhost:8000

架構跟前面的 systemd 部署保持一致:

Internet
   │
   ▼
Nginx :80/:443
   │
   ▼
127.0.0.1:8000
   │
   ▼
Container

二十九、加入 Container Health Check

前面的 FastAPI 已經有:

/health

Dockerfile 也可以加入:

HEALTHCHECK \
    --interval=30s \
    --timeout=3s \
    --start-period=5s \
    --retries=3 \
    CMD python -c \
    "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health')"

完整 Dockerfile:

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install \
    --no-cache-dir \
    -r requirements.txt

COPY app ./app

HEALTHCHECK \
    --interval=30s \
    --timeout=3s \
    --start-period=5s \
    --retries=3 \
    CMD python -c \
    "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health')"

CMD [
    "uvicorn",
    "app.main:app",
    "--host",
    "0.0.0.0",
    "--port",
    "8000"
]

查看:

docker ps

一段時間後可能顯示:

Up ... (healthy)

因此:

/health

開始真正被 Infrastructure 使用。

之後到了 Kubernetes,這個概念就會演進成:

Liveness Probe

Readiness Probe

三十、Image 應該盡可能 Immutable

Docker 很重要的一個思維就是:

Immutable Image。

可以理解成:

Image Build 完之後,不要再去修改裡面的 Application。

例如:

backend:v1

應該永遠代表同一份內容。

如果程式修改:

重新 Build

產生:

backend:v2

而不是:

進 Container
vim main.py

修改 Production Code。

因為一旦這樣做:

Running Container

跟

Docker Image

就會不一致。

Container 重建後,修改又全部消失。



上一篇
把 FastAPI 做成 Docker Image(續)[Day16]
系列文
探討k8s部署方式 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言