> For the complete documentation index, see [llms.txt](https://philipzheng.gitbook.io/docker_practice/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://philipzheng.gitbook.io/docker_practice/security/control_group.md).

# 控制組

控制組 (Cgroups) 是 Linux 容器機制的另外一個關鍵元件。如果說命名空間 (Namespace) 決定了容器能 **看到** 什麼，那麼控制組就決定了容器能 **使用** 多少資源。

在安全領域中，資源的不可用性本身就是一種安全威脅。控制組負責實作資源的審計和限制，這對於抵禦資源耗盡型攻擊（如拒絕服務攻擊 DoS）至關重要。

## 為什麼資源限制關乎安全？

預設情況下，Docker 容器對系統資源的使用是沒有限制的：一個容器理論上可以使用宿主機所有的 CPU 計算能力、吃光所有的記憶體、耗盡所有的系統 PID。

想像一下以下場景：

* 一個惡意使用者向你暴露在公網的應用發起海量併發請求。
* 應用程式邏輯中存在記憶體洩漏漏洞。
* 駭客在入侵容器後，在裡面執行了挖礦木馬程式。

如果沒有 Cgroups 的限制，某個容器內的異常行為（或惡意攻擊）將會榨乾宿主機的資源，導致宿主機上其他健康的容器甚至 Docker 守護程式自身因為 OOM（Out Of Memory）崩潰或 CPU 飢餓而停止回應。

## 核心資源限制實戰

為了確保多租戶平台（如公有或私有的 PaaS 平台）的穩定性，或者在生產環境防止服務級聯故障，我們要養成在啟動容器時 **明確宣告資源上限** 的習慣。

### 1. 記憶體限制

限制記憶體可以防止應用程式因記憶體洩漏或惡意載荷導致宿主機 OOM。

**關鍵參數：**

* `-m, --memory=""`：硬限制，容器可使用的最大記憶體量。
* `--memory-swap=""`：限制容器可使用的記憶體與 Swap 總量。

**實戰示例：**

限制容器最多只能使用 512MB 記憶體，並且禁用 Swap（將 memory 和 memory-swap 設定成一樣的值即可）：

```bash
$ docker run -d \
  --name web_app \
  --memory="512m" \
  --memory-swap="512m" \
  nginx:alpine
```

如果該容器內的應用嘗試分配超過 512MB 的記憶體，該程式將會被核心的 OOM Killer 殺掉，但絕不會波及到宿主機的其他部分。

### 2. CPU 限制

限制 CPU 可以防止個別計算密集型的容器壟斷 CPU 時間片，保證系統的排程公平性。

**關鍵參數：**

* `--cpus=<value>`：指定容器可以使用的 CPU 核心數量（可以是小數）。
* `-c, --cpu-shares=0`：軟限制，設定容器使用 CPU 的相對權重（預設是 1024）。

**實戰示例：**

限制容器最多使用 1.5 個 CPU 核心的算力：

```bash
$ docker run -d \
  --name worker_app \
  --cpus="1.5" \
  busybox \
  md5sum /dev/urandom
```

即使上面的命令是一個死迴圈的雜湊計算程式，容器也永遠無法吃滿雙核 CPU 系統的全部算力。

### 3. 程式數限制

程式炸彈（Fork Bomb）是一種典型的拒絕服務攻擊方式，它透過不斷 `fork()` 新程式來耗盡系統的程式表條目，導致系統無法建立任何新任務。

**關鍵參數：**

* `--pids-limit=<number>`：限制容器內允許建立的最大程式數。

**實戰示例：**

一個常規的 Web 服務程式數通常在幾十到上百之間。我們可以設定一個合理的上限來防範 Fork 炸彈：

```bash
$ docker run -d \
  --name app_service \
  --pids-limit=100 \
  python:alpine python app.py
```

當容器內的程式總數達到 100 時，任何嘗試衍生新程式的操作都會失敗並回傳 `Resource temporarily unavailable`，從而挫敗相關的攻擊行為。

## 最佳實務建議

在生產環境中，不僅要在單機使用 Docker 命令時設定這些參數，更應當在集群編排工具中將資源配額制度化。

例如，在 Kubernetes 中，強烈建議為每個 Pod 設定 `requests` 和 `limits`：

```yaml
resources:
  requests:
    memory: "256Mi"
    cpu: "250m"
  limits:
    memory: "512Mi"
    cpu: "500m"
```

透過 Cgroups 的資源邊界控制，你可以從根本上切斷一條導致整個系統雪崩的脆弱鏈路。這也進一步使得 Docker 以及容器技術成為了現代高可用服務的基礎設施首選。
