跳至主要内容

Volume - EmptyDir

EmptyDir 是 Kubernetes 中的一種臨時性 Volume,主要用於 Pod 內部的數據存儲。 它在 Pod 啟動時創建,並在 Pod 終止後被刪除。EmptyDir 是簡單且高效的數據存儲解決方案,適合用於短期存儲需求,例如緩存、臨時文件或數據交換。


工作原理

  • 當 Pod 啟動時,Kubernetes 會自動在節點上創建一個空的目錄,並將其掛載到容器中指定的位置。
  • 如果 Pod 重啟,EmptyDir 的內容仍然保留。
  • 當 Pod 被刪除時,EmptyDir 的數據也會一併清除。
  • 如果 Pod 被重新調度到其他節點,EmptyDir 內容不會隨之遷移。

可設定的參數

EmptyDir 可以通過以下方式進行配置,滿足不同的使用需求:

1. medium

  • 用於指定 EmptyDir 的存儲介質。
  • 選項
    • 默認值為空字符串(""),表示存儲在節點的磁碟上。
    • 設定為 Memory 時,EmptyDir 將使用節點內存作為存儲介質(通過 tmpfs 實現)。
  • 示例
    volumes:
    - name: temp-storage
    emptyDir:
    medium: Memory

2. sizeLimit

  • 用於設置 EmptyDir 的大小限制。
  • 特點
    • 僅在 medium: Memory 時有效,限制內存的最大使用量。
    • 如果未設置,則使用節點可用內存的默認分配。
  • 示例
    volumes:
    - name: temp-storage
    emptyDir:
    medium: Memory
    sizeLimit: '256Mi'

適用場景

  • 緩存數據:例如臨時數據存儲和處理。
  • 共享數據:在同一 Pod 的多個容器之間共享文件。
  • 臨時數據:只在 Pod 的生命週期內需要的數據。

注意事項

  1. EmptyDir 的內容不會持久化,Pod 終止後所有數據將丟失。
  2. 使用 medium: Memory 時,請注意不要超過節點內存限制,以免影響節點穩定性。
  3. 不適合用於需要長期存儲的數據場景。

實作一個 EmptyDir

  1. 首先我們建立一個 pod,裡面有多個 container,其中我們定義 volume 是 html,並且是 EmptyDir,分別掛載到 nginx 和 alpine 這兩個容器中, alpine 是每 10 秒會寫入日期到 index.html,nginx 則負責將這個 index.html 顯示給用戶。
emptydir-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: emptydir-pod
spec:
volumes:
- name: html # 定義一個名為 html 的 Volume,類型為 EmptyDir(未指定 medium,默認使用磁碟)
emptyDir: {}
containers:
- name: nginx
image: nginx:latest
volumeMounts:
- name: html # 將名為 html 的 Volume 掛載到容器內
mountPath: /usr/share/nginx/html # 掛載路徑為 nginx 預設的靜態文件目錄
- name: alpine
image: alpine:latest
volumeMounts:
- name: html # 同樣將名為 html 的 Volume 掛載到容器內
mountPath: /html # 掛載路徑為 /html
command: ['/bin/sh', '-c']
args:
- while true; do
echo $(hostname) $(date) >> /html/index.html;
sleep 10;
done
  1. 建立這個 Pod,並且查看這個 Pod 的狀態。
kubectl.exe apply -f emptydir-pod.yaml
---

pod/emptydir-pod created
kubectl.exe describe pods/emptydir-pod
---

Name: emptydir-pod
...中間省略...
Containers:
nginx:
...中間省略...
Mounts:
/usr/share/nginx/html from html (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hwnlw (ro)
alpine:
...中間省略...
Mounts:
/html from html (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hwnlw (ro)
...中間省略...
Volumes:
html:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
...後面省略...
  1. 接著我們透過 port-forwart 來訪問這個 Pod。
kubectl.exe port-forward pods/emptydir-pod 8080:80
---

Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
  1. 透過訪問這個 Pod,我們可以看每隔 10 秒鐘就有一筆數據被記錄,並且 alpine 和 nginx 這兩個 container 共用一個 volume。
(Invoke-WebRequest -Uri http://localhost:8080 -UseBasicParsing).Content
---

emptydir-pod Thu Jan 23 08:40:51 UTC 2025
emptydir-pod Thu Jan 23 08:41:01 UTC 2025
emptydir-pod Thu Jan 23 08:41:11 UTC 2025
emptydir-pod Thu Jan 23 08:41:21 UTC 2025
emptydir-pod Thu Jan 23 08:41:31 UTC 2025
  1. 相同我們也可以透過 memory 的方式,在定義 medium 的地方設定為 Memory。
emptydir-memory-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: emptydir-memory-pod
spec:
volumes:
- name: html
emptyDir:
medium: Memory
sizeLimit: 256Mi
containers:
- name: nginx
image: nginx:latest
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
- name: alpine
image: alpine:latest
volumeMounts:
- name: html
mountPath: /html
command: ['/bin/sh', '-c']
args:
- while true; do
echo $(hostname) $(date) >> /html/index.html;
sleep 10;
done
  1. 依照上面的方式執行他,並且使用port-forward後,直接呼叫Pod,可以看到一樣每10秒輸出一次。
kubectl.exe apply -f emptydir-memory-pod.yaml
---

pod/emptydir-memory-pod created
kubectl.exe port-forward pods/emptydir-memory-pod 8080:80
---

Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
(Invoke-WebRequest -Uri http://localhost:8080 -UseBasicParsing).Content
---

emptydir-memory-pod Thu Jan 23 08:46:54 UTC 2025
emptydir-memory-pod Thu Jan 23 08:47:04 UTC 2025
emptydir-memory-pod Thu Jan 23 08:47:14 UTC 2025
emptydir-memory-pod Thu Jan 23 08:47:24 UTC 2025
emptydir-memory-pod Thu Jan 23 08:47:34 UTC 2025