鯨魚也是會翻船的,先把重要的東西存起來~
圖片來源:Docker (@Docker) / Twitter
來介紹一下 Kubernetes 的各種 volume~
Pod 裡的 container 可能隨時重啟或重建,為了避免重要檔案跟著被刪除,就必須要使用 volume 讓裡面的檔案能被保留
Kubernetes 的 volume 類型分為 Ephemeral Volume, Projected Volume, Persistent Volume
簡單列出幾個 volume:
emptyDir
: 建立空目錄儲存暫時性資料hostPath
: 掛 node 的目錄到 pod 內local
: 掛 node 的 local storage device 到 pod 內nfs
: 掛外部 NFS (Network File System) shareawsElasticBlockStore
, azureDisk
, azureFile
, gcePersistentDisk
: 雲端提供的儲存區cinder
, cephfs
, iscsi
: network storageconfigMap
, secret
, downwardAPI
: 特殊 volume 用來存 Kubernetes resource 相關資訊如果 container 掛了 volume,原本 container 的檔案會被清空,僅留存掛上去 volume 的檔案
生命週期短暫相依於 pod,用來儲存暫時性資料
支援的類型: emptyDir
, configMap
, downwardAPI
, secret
, CSI ephemeral volumes
, generic ephemeral volumes
emptyDir
,configMap
,downwardAPI
,secret
資料是由各 node 的 kubelet 管理的
emptyDir 會建立一個空目錄,可讓 container 儲存龐大的暫時性資料
分享一下目前遇過的案例~
在架 gitlab 會需要配置 shm,這裡改成使用 emptyDir 設定 Memory
apiVersion: v1
kind: Pod
...
spec:
containers:
- image: gitlab/gitlab-ee:15.0.1-ee.0
name: gitlab
volumeMounts:
- mountPath: /dev/shm
name: cache-volume
...
volumes:
- name: cache-volume
emptyDir:
medium: Memory
sizeLimit: 512Mi
用來存設定相關的值(key-value)或直接存成檔案
例如前面設定 Traefik 就有偷偷用到~
apiVersion: v1
kind: ConfigMap
metadata:
name: traefik-config
labels:
name: traefik-config
namespace: traefik
data:
dyn.yaml: |
tls:
options:
default:
minVersion: VersionTLS12
stores:
default:
defaultCertificate:
certFile: '/certs/tls.pem'
keyFile: '/certs/tls.key'
用來存較為隱密的資料,所有存在裡面的資料會使用 base64 encode,注意並非加密!
例如用在設定 tls 憑證
kubectl create secret generic tls-secret -n traefik \
--from-file=ca.pem \
--from-file=tls.pem=fullchain.pem \
--from-file=tls.key=example.domain.com.key
產生出來會像下面這樣...
apiVersion: v1
kind: Secret
metadata:
creationTimestamp: "2022-10-02T20:04:31Z"
name: tls-secret
namespace: traefik
resourceVersion: "682517"
uid: bc1c5822-715e-4082-8c55-363ca350a8bd
type: Opaque
data:
ca.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...
tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVk...
tls.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...
可以用來直接取得 cluster 相關資訊
這個我目前還沒實際用過...
先拿官網的範例~ 取用 Pod 本身的 label
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
spec:
containers:
- name: client-container
image: registry.k8s.io/busybox
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/podinfo/labels ]]; then
echo -en '\n\n'; cat /etc/podinfo/labels; fi;
sleep 5;
done;
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
透過 StorageClass 動態配置一個 volume 給 Pod,只有 Pod 在運行時才會掛載,通常用於快照或是需要動態調整容量的 volume
以下是官網的使用範例
kind: Pod
apiVersion: v1
metadata:
name: my-app
spec:
...
volumes:
- name: scratch-volume
ephemeral:
volumeClaimTemplate:
metadata:
labels:
type: my-frontend-volume
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "scratch-storage-class"
resources:
requests:
storage: 1Gi
感覺比較像 StatefulSet 需要的 volume 配置
以下是從 harbor redis 看到 StatefulSet 的例子
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: harbor-redis
namespace: harbor
...
spec:
...
volumeClaimTemplates:
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
app: harbor
chart: harbor
heritage: Helm
release: harbor
name: data
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: nfs-client
PV 獨立於 Namespace 外,由 admin 配置一塊儲存區 (PersistentVolume, PV),user 能夠請求使用 (PersistentVolumeClaim, PVC)
範例格式...
apiVersion: v1
kind: PersistentVolume
metadata:
name: <pv_name>
spec:
capacity:
storage: 1Gi # define pv size
accessModes:
- ReadWriteOnce
- ReadOnlyMany
persistentVolumeReclaimPolicy: Retain
gcePersistentDisk: # pv type
pdName: mongodb
fsType: ext4
volume 存取權限
RWO
, ReadWriteOnce
: 限同一 node 以 read-write 方式 mount volume。ROX
, ReadOnlyMany
: 多個不同 node 能以 read-only 方式 mount volume。RWX
, ReadWriteMany
: 多個不同 node 能以 read-write 方式 mount volume。RWOP
, ReadWriteOncePod
: 限定一個 pod 以 read-write 方式 mount volume。僅支援 CSI
和 Kubernetes v1.22^要注意不同的 volume plugin 支援度不同!
圖片來源:Persistent Volumes | Kubernetes
當 PVC 被移除時要怎麼回收釋出空間
Retain
: 不會更動 PV,若要移除資料需要手動處理Recycle
: 自動回收 rm -rf /thevolume/*
,支援 NFS
、hostPath
Delete
: 將 PersistentVolume 移除也會移除關聯的存儲區,用於 AWS EBS, GCE PD, Azure Disk, OpenStack Cinder, ...接著就來看看幾種 PV 吧~
mount Node 的目錄到 Pod 內,要注意 Pod 部署在哪個 Node,hostPath 無法跨 Node 共用
圖片來源:Book Kubernetes in Action (ISBN 9781617293726)
mount node 的 local storage device,例如 disk, partition
mount 外部 NFS (Network File System) share
範例:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs
spec:
accessModes:
- ReadWriteMany
storageClassName: "nfs-client"
resources:
requests:
storage: 1Gi
volumeName: nfs
mountOptions:
- nfsvers=4
nfs:
path: /cluster
server: 169.254.0.1
雲端平台提供的儲存區 awsElasticBlockStore
, azureDisk
, azureFile
, gcePersistentDisk
其他 network storage cinder
, cephfs
, iscsi
有試用過 iscsi...
iscsi 可以選擇以 block 或 filesystem 掛載,但 block 實用性不高...
apiVersion: v1
kind: PersistentVolume
metadata:
name: iscsi1-target1-lun1
labels:
volume: iscsi
host: iscsi1
target: target1
lun: "1"
spec:
storageClassName: iscsi-storage
capacity:
storage: 1Ti
accessModes:
- ReadWriteOnce
- ReadOnlyMany
# volumeMode: Block # change Filesystem to Block?
persistentVolumeReclaimPolicy: Retain
iscsi:
iqn: iqn.2004-04.com.qnap:ts-h1283xu-rp:iscsi.target1.tbw9d
lun: 1
targetPortal: 169.254.0.2:3260
initiatorName: iqn.1993-08.org.debian:01:754b4f5fdd
chapAuthDiscovery: true
chapAuthSession: true
secretRef: # 有設定 chap 的話要額外建立 secret
name: chap-secret
namespace: iscsi
---
apiVersion: v1
kind: Secret
metadata:
name: chap-secret
namespace: iscsi
type: "kubernetes.io/iscsi-chap"
data:
node.session.auth.username: ...
node.session.auth.password: ...
將已存在的 volume 一次映射到同一個目錄上
(所有 resource 必須在同一個 namespace 才可使用)
支援的類型: secret
, downwardAPI
, configMap
, serviceAccountToken
直接看官網的 all-in-one 例子~
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: busybox:1.28
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "cpu_limit"
resourceFieldRef:
containerName: container-test
resource: limits.cpu
- configMap:
name: myconfigmap
items:
- key: config
path: my-group/my-config
明天接續介紹 StoargeClass 之後會以 NFS 為使用範例~