# 本地持久化存儲
本地持久化卷允許用戶通過標準 PVC 接口以簡單便攜的方式訪問本地存儲。PV 中包含系統用于將 Pod 安排到正確節點的節點親和性信息。
一旦配置了本地卷,外部靜態配置器(provisioner)可用于幫助簡化本地存儲管理。請注意,本地存儲配置器與大多數配置器不同,并且尚不支持動態配置。相反,它要求管理員預先配置每個節點上的本地卷,并且這些卷應該是:
1. Filesystem volumeMode(默認)PV—— 將它們掛載到發現目錄下。
2. Block volumeMode PV——在發現目錄下為節點上的塊設備創建一個符號鏈接。
配置器將通過為每個卷創建和清除 PersistentVolumes 來管理發現目錄下的卷。
## 配置要求
- 本地卷插件希望路徑穩定,包括在重新啟動時和添加或刪除磁盤時。
- 靜態配置器僅發現掛載點(對于文件系統模式卷)或符號鏈接(對于塊模式卷)。對于基于目錄的本地卷必須綁定到發現目錄中。
## 版本兼容性
推薦配置器版本與Kubernetes版本
| Provisioner version | K8s version | Reason |
| ------------------------------------------------------------ | ----------- | ----------------------- |
| [2.1.0](https://github.com/kubernetes-incubator/external-storage/tree/local-volume-provisioner-v2.1.0/local-volume) | 1.10 | Beta API default, block |
| [2.0.0](https://github.com/kubernetes-incubator/external-storage/tree/local-volume-provisioner-v2.0.0/local-volume) | 1.8, 1.9 | Mount propagation |
| [1.0.1](https://github.com/kubernetes-incubator/external-storage/tree/local-volume-provisioner-v1.0.1/local-volume) | 1.7 | |
## K8s功能狀態
另請參閱[已知問題](https://github.com/kubernetes-incubator/external-storage/blob/master/local-volume/KNOWN_ISSUES.md)和 [CHANGELOG](https://github.com/kubernetes-incubator/external-storage/blob/master/local-volume/CHANGELOG.md)。
### 1.10:Beta
- 添加了新的 `PV.NodeAffinity` 字段。
- **重要:** Alpha PV NodeAffinity annotation 已棄用。用戶必須手動更新其 PV 以使用新的 NodeAffinity字段或運行[一次性更新作業](https://github.com/kubernetes-incubator/external-storage/blob/master/local-volume/utils/update-pv-to-beta)。
- Alpha:添加了對 raw block 的支持。
### 1.9:Alpha
- 新的 StorageClass `volumeBindingMode` 參數將延遲PVC綁定,直到 pod 被調度。
### 1.7:Alpha
- 新的`local` PersistentVolume 源,允許指定具有 node affinity 的目錄或掛載點。
- 使用綁定到該 PV 的 PVC 的 Pod 將始終調度到該節點。
### 未來的功能
- 本地塊設備作為卷源,具有分區和 fs 格式化
- 共享本地持久化存儲的動態資源調配
- 當地 PV 健康監測、污點和容忍
- 內聯 PV(使用專用本地磁盤作為臨時存儲)
## 用戶指南
這些說明反映了最新版本的代碼庫。有關舊版本的說明,請參閱[版本兼容性](https://github.com/kubernetes-incubator/external-storage/tree/master/local-volume#version-compatibility)下的版本鏈接。
### 步驟1:使用本地磁盤啟動集群
#### 啟用alpha feature gate
##### 1.10+
如果需要原始的本地塊功能,
```bash
export KUBE_FEATURE_GATES ="BlockVolume = true"
```
注意:1.10 之前的 Kubernetes 版本需要[幾個附加 feature gate](https://github.com/kubernetes-incubator/external-storage/tree/local-volume-provisioner-v2.0.0/local-volume#enabling-the-alpha-feature-gates),因為持久的本地卷和其他功能處于 alpha 版本。
#### 選項1:裸金屬環境
1. 根據應用程序的要求對每個節點上的磁盤進行分區和格式化。
2. 根據 StorageClass 將所有文件系統掛載到同一個目錄下。目錄在 configmap 中指定,見下文。
3. 使用 `KUBE_FEATURE_GATES `配置 Kubernetes API server、controller manager、scheduler 和所有kubelet,[如上所述](https://github.com/kubernetes-incubator/external-storage/tree/master/local-volume#enabling-the-alpha-feature-gates)。
4. 如果不使用默認 Kubernetes 調度程序策略,則必須啟用以下謂詞:
- 1.9之前:`NoVolumeBindConflict`
- 1.9+:`VolumeBindingChecker`
#### 選項2:本地測試集群
1. 創建 `/mnt/disks `目錄并將多個卷掛載到其子目錄。下面的示例使用三個 ram 磁盤來模擬真實的本地卷:
```bash
mkdir/mnt/disks
vol for vol1 vol2 vol3;do
mkdir/mnt/disks/$vol
mount -t tmpfs $vol/mnt/disks/$vol
DONE
```
2. 運行本地集群。
```bash
$ALLOW_PRIVILEGED = true LOG_LEVEL = 5 FEATURE_GATES = $KUBE_FEATURE_GATES hack/local-up-cluster.sh
```
### 步驟2:創建StorageClass(1.9+)
要延遲卷綁定,直到 pod 被調度,并在單個 pod 中處理多個本地 PV,必須使用設置為 `WaitForFirstConsumer` 的 `volumeBindingMode` 創建 StorageClass。
```bash
$kubectl create -f provisioner/deployment/kubernetes/example/default_example_storageclass.yaml
```
### 步驟3:創建本地持久卷
#### 選項1:使用本地卷靜態配置器
1. 生成 Provisioner 的 ServiceAccount、Role、DaemonSet 和 ConfigMap 規范,并對其進行自定義。
這一步使用 helm 模板來生成規格。有關安裝說明,請參閱[helm readme](https://github.com/kubernetes-incubator/external-storage/blob/master/local-volume/helm)。要使用[默認值](https://github.com/kubernetes-incubator/external-storage/blob/master/local-volume/helm/provisioner/values.yaml)生成配置器的規格,請運行:
```bash
helm template ./helm/provisioner > ./provisioner/deployment/kubernetes/provisioner_generated.yaml
```
您也可以提供一個自定義值文件:
```bash
helm template ./helm/provisioner --values custom-values.yaml > ./provisioner/deployment/kubernetes/provisioner_generated.yaml
```
2. 部署配置程序
如果用戶對 Provisioner 的 yaml 文件的內容感到滿意,可以用 **kubectl** 創建 Provisioner 的 DaemonSet 和 ConfigMap。
```bash
$kubectl create -f ./provisioner/deployment/kubernetes/provisioner_generated.yaml
```
3. 檢查發現的本地卷
一旦啟動,外部靜態配置器將發現并創建本地 PV。
例如,如果目錄 `/mnt/disks/` 包含一個目錄 `/mnt/disks/vol1`,則靜態配置器會創建以下本地卷 PV:
```bash
$ kubectl get pv
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
local-pv-ce05be60 1024220Ki RWO Delete Available local-storage 26s
$ kubectl describe pv local-pv-ce05be60
Name: local-pv-ce05be60
Labels: <none>
Annotations: pv.kubernetes.io/provisioned-by=local-volume-provisioner-minikube-18f57fb2-a186-11e7-b543-080027d51893
StorageClass: local-fast
Status: Available
Claim:
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1024220Ki
NodeAffinity:
Required Terms:
Term 0: kubernetes.io/hostname in [my-node]
Message:
Source:
Type: LocalVolume (a persistent volume backed by local storage on a node)
Path: /mnt/disks/vol1
Events: <none>
```
上面描述的 PV 可以通過引用 `local-fast` storageClassName 聲明和綁定到 PVC。
#### 選項2:手動創建本地持久化卷
有關示例 PersistentVolume 規范,請參閱[Kubernetes文檔](https://kubernetes.io/docs/concepts/storage/volumes/#local)。
### 步驟4:創建本地持久卷聲明
```yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: example-local-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: local-storage
```
請替換以下元素以反映您的配置:
- 卷所需的存儲容量“5Gi”
- “local-storage”,與本地 PV 關聯的存儲類名稱應該用于滿足此 PVC
對于試圖聲明 “Block” PV 的 “Block” volumeMode PVC,可以使用以下示例:
```yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: example-local-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
volumeMode: Block
storageClassName: local-storage
```
請注意,此處唯一需要注意的字段是 volumeMode,它已被設置為“Block”。
## 最佳實踐
- 對于IO隔離,建議每個卷使用整個磁盤
- 對于容量隔離,建議使用單個分區
- 避免重新創建具有相同節點名稱的節點,而仍然存在指定了該節點親和性的舊 PV。否則,系統可能認為新節點包含舊的 PV。
- 對于帶有文件系統的卷,建議在 fstab 條目和該掛載點的目錄名稱中使用它們的 UUID(例如 `ls -l/dev/disk/by-uuid ` 的輸出)。這種做法可確保即使設備路徑發生變化(例如,如果 `/dev/sda1` 在添加新磁盤時變為 `/dev/sdb1`),也不會錯誤地掛在本地卷。此外,這種做法將確保如果創建具有相同名稱的另一個節點,則該節點上的任何卷都是唯一的,而不會誤認為是具有相同名稱的另一個節點上的卷。
- 對于沒有文件系統的 raw block 卷,使用唯一的 ID 作為符號鏈接名稱。根據您的環境,`/dev/disk/by-id/ `中的卷 ID 可能包含唯一的硬件序列號。否則,應該生成一個唯一的 ID。符號鏈接名稱的唯一性將確保如果創建具有相同名稱的另一個節點,則該節點上的任何卷都是唯一的,而不會誤認為是具有相同名稱的另一個節點上的卷。
### 刪除/清理底層卷
當您想要停用本地卷時,以下是可能的工作流程。
1. 停止使用卷的 pod
2. 從節點中刪除本地卷(即卸載、拔出磁盤等)
3. 刪除 PVC
4. 供應商將嘗試清理卷,但由于卷不再存在而會失敗
5. 手動刪除 PV 對象
## 參考
- [Local Persistent Storage User Guide](https://github.com/kubernetes-incubator/external-storage/tree/master/local-volume)
- 序言
- 云原生
- 云原生(Cloud Native)的定義
- CNCF - 云原生計算基金會簡介
- CNCF章程
- 云原生的設計哲學
- Play with Kubernetes
- 快速部署一個云原生本地實驗環境
- Kubernetes與云原生應用概覽
- 云原生應用之路——從Kubernetes到Cloud Native
- 云原生編程語言
- 云原生編程語言Ballerina
- 云原生編程語言Pulumi
- 云原生的未來
- Kubernetes架構
- 設計理念
- Etcd解析
- 開放接口
- CRI - Container Runtime Interface(容器運行時接口)
- CNI - Container Network Interface(容器網絡接口)
- CSI - Container Storage Interface(容器存儲接口)
- Kubernetes中的網絡
- Kubernetes中的網絡解析——以flannel為例
- Kubernetes中的網絡解析——以calico為例
- 具備API感知的網絡和安全性管理開源軟件Cilium
- Cilium架構設計與概念解析
- 資源對象與基本概念解析
- Pod狀態與生命周期管理
- Pod概覽
- Pod解析
- Init容器
- Pause容器
- Pod安全策略
- Pod的生命周期
- Pod Hook
- Pod Preset
- Pod中斷與PDB(Pod中斷預算)
- 集群資源管理
- Node
- Namespace
- Label
- Annotation
- Taint和Toleration(污點和容忍)
- 垃圾收集
- 控制器
- Deployment
- StatefulSet
- DaemonSet
- ReplicationController和ReplicaSet
- Job
- CronJob
- Horizontal Pod Autoscaling
- 自定義指標HPA
- 準入控制器(Admission Controller)
- 服務發現
- Service
- Ingress
- Traefik Ingress Controller
- 身份與權限控制
- ServiceAccount
- RBAC——基于角色的訪問控制
- NetworkPolicy
- 存儲
- Secret
- ConfigMap
- ConfigMap的熱更新
- Volume
- Persistent Volume(持久化卷)
- Storage Class
- 本地持久化存儲
- 集群擴展
- 使用自定義資源擴展API
- 使用CRD擴展Kubernetes API
- Aggregated API Server
- APIService
- Service Catalog
- 資源調度
- QoS(服務質量等級)
- 用戶指南
- 資源對象配置
- 配置Pod的liveness和readiness探針
- 配置Pod的Service Account
- Secret配置
- 管理namespace中的資源配額
- 命令使用
- Docker用戶過度到kubectl命令行指南
- kubectl命令概覽
- kubectl命令技巧大全
- 使用etcdctl訪問kubernetes數據
- 集群安全性管理
- 管理集群中的TLS
- kubelet的認證授權
- TLS bootstrap
- 創建用戶認證授權的kubeconfig文件
- IP偽裝代理
- 使用kubeconfig或token進行用戶身份認證
- Kubernetes中的用戶與身份認證授權
- Kubernetes集群安全性配置最佳實踐
- 訪問Kubernetes集群
- 訪問集群
- 使用kubeconfig文件配置跨集群認證
- 通過端口轉發訪問集群中的應用程序
- 使用service訪問群集中的應用程序
- 從外部訪問Kubernetes中的Pod
- Cabin - Kubernetes手機客戶端
- Kubernetic - Kubernetes桌面客戶端
- Kubernator - 更底層的Kubernetes UI
- 在Kubernetes中開發部署應用
- 適用于kubernetes的應用開發部署流程
- 遷移傳統應用到Kubernetes中——以Hadoop YARN為例
- 最佳實踐概覽
- 在CentOS上部署Kubernetes集群
- 創建TLS證書和秘鑰
- 創建kubeconfig文件
- 創建高可用etcd集群
- 安裝kubectl命令行工具
- 部署master節點
- 安裝flannel網絡插件
- 部署node節點
- 安裝kubedns插件
- 安裝dashboard插件
- 安裝heapster插件
- 安裝EFK插件
- 生產級的Kubernetes簡化管理工具kubeadm
- 使用kubeadm在Ubuntu Server 16.04上快速構建測試集群
- 服務發現與負載均衡
- 安裝Traefik ingress
- 分布式負載測試
- 網絡和集群性能測試
- 邊緣節點配置
- 安裝Nginx ingress
- 安裝配置DNS
- 安裝配置Kube-dns
- 安裝配置CoreDNS
- 運維管理
- Master節點高可用
- 服務滾動升級
- 應用日志收集
- 配置最佳實踐
- 集群及應用監控
- 數據持久化問題
- 管理容器的計算資源
- 集群聯邦
- 存儲管理
- GlusterFS
- 使用GlusterFS做持久化存儲
- 使用Heketi作為Kubernetes的持久存儲GlusterFS的external provisioner
- 在OpenShift中使用GlusterFS做持久化存儲
- GlusterD-2.0
- Ceph
- 用Helm托管安裝Ceph集群并提供后端存儲
- 使用Ceph做持久化存儲
- 使用rbd-provisioner提供rbd持久化存儲
- OpenEBS
- 使用OpenEBS做持久化存儲
- Rook
- NFS
- 利用NFS動態提供Kubernetes后端存儲卷
- 集群與應用監控
- Heapster
- 使用Heapster獲取集群和對象的metric數據
- Prometheus
- 使用Prometheus監控kubernetes集群
- Prometheus查詢語言PromQL使用說明
- 使用Vistio監控Istio服務網格中的流量
- 分布式跟蹤
- OpenTracing
- 服務編排管理
- 使用Helm管理Kubernetes應用
- 構建私有Chart倉庫
- 持續集成與發布
- 使用Jenkins進行持續集成與發布
- 使用Drone進行持續集成與發布
- 更新與升級
- 手動升級Kubernetes集群
- 升級dashboard
- 領域應用概覽
- 微服務架構
- 微服務中的服務發現
- 使用Java構建微服務并發布到Kubernetes平臺
- Spring Boot快速開始指南
- Service Mesh 服務網格
- 企業級服務網格架構
- Service Mesh基礎
- Service Mesh技術對比
- 采納和演進
- 定制和集成
- 總結
- Istio
- 安裝并試用Istio service mesh
- 配置請求的路由規則
- 安裝和拓展Istio service mesh
- 集成虛擬機
- Istio中sidecar的注入規范及示例
- 如何參與Istio社區及注意事項
- Istio教程
- Istio免費學習資源匯總
- 深入理解Istio Service Mesh中的Envoy Sidecar注入與流量劫持
- 深入理解Istio Service Mesh中的Envoy Sidecar代理的路由轉發
- Linkerd
- Linkerd 使用指南
- Conduit
- Condiut概覽
- 安裝Conduit
- Envoy
- Envoy的架構與基本術語
- Envoy作為前端代理
- Envoy mesh教程
- SOFAMesh
- SOFAMesh中的Dubbo on x-protocol
- SOFAMosn
- 使用 SOFAMosn 構建 SOFAMesh
- 大數據
- Spark standalone on Kubernetes
- 運行支持Kubernetes原生調度的Spark程序
- Serverless架構
- 理解Serverless
- FaaS-函數即服務
- OpenFaaS快速入門指南
- 邊緣計算
- 人工智能