# CSI - Container Storage Interface(容器存儲接口)
CSI 代表[容器存儲接口](https://github.com/container-storage-interface/spec/blob/master/spec.md),CSI 試圖建立一個行業標準接口的規范,借助 CSI 容器編排系統(CO)可以將任意存儲系統暴露給自己的容器工作負載。有關詳細信息,請查看[設計方案](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/container-storage-interface.md)。
`csi` 卷類型是一種 out-tree(即跟其它存儲插件在同一個代碼路徑下,隨 Kubernetes 的代碼同時編譯的) 的 CSI 卷插件,用于 Pod 與在同一節點上運行的外部 CSI 卷驅動程序交互。部署 CSI 兼容卷驅動后,用戶可以使用 `csi` 作為卷類型來掛載驅動提供的存儲。
CSI 持久化卷支持是在 Kubernetes v1.9 中引入的,作為一個 alpha 特性,必須由集群管理員明確啟用。換句話說,集群管理員需要在 apiserver、controller-manager 和 kubelet 組件的 “`--feature-gates =`” 標志中加上 “`CSIPersistentVolume = true`”。
CSI 持久化卷具有以下字段可供用戶指定:
- `driver`:一個字符串值,指定要使用的卷驅動程序的名稱。必須少于 63 個字符,并以一個字符開頭。驅動程序名稱可以包含 “。”、“ - ”、“_” 或數字。
- `volumeHandle`:一個字符串值,唯一標識從 CSI 卷插件的 `CreateVolume` 調用返回的卷名。隨后在卷驅動程序的所有后續調用中使用卷句柄來引用該卷。
- `readOnly`:一個可選的布爾值,指示卷是否被發布為只讀。默認是 false。
## 使用說明
下面將介紹如何使用 CSI。
### 動態配置
可以通過為 CSI 創建插件 `StorageClass` 來支持動態配置的 CSI Storage 插件啟用自動創建/刪除 。
例如,以下 `StorageClass` 允許通過名為 `com.example.team/csi-driver` 的 CSI Volume Plugin 動態創建 “fast-storage” Volume。
```yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: fast-storage
provisioner: com.example.team/csi-driver
parameters:
type: pd-ssd
```
要觸發動態配置,請創建一個 `PersistentVolumeClaim` 對象。例如,下面的 PersistentVolumeClaim 可以使用上面的 StorageClass 觸發動態配置。
```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-request-for-storage
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: fast-storage
```
當動態創建 Volume 時,通過 CreateVolume 調用,將參數 `type:pd-ssd` 傳遞給 CSI 插件 `com.example.team/csi-driver` 。作為響應,外部 Volume 插件會創建一個新 Volume,然后自動創建一個 `PersistentVolume` 對象來對應前面的 PVC 。然后,Kubernetes 會將新的 `PersistentVolume` 對象綁定到 `PersistentVolumeClaim`,使其可以使用。
如果 `fast-storage` StorageClass 被標記為默認值,則不需要在 `PersistentVolumeClaim` 中包含 StorageClassName,它將被默認使用。
### 預配置 Volume
您可以通過手動創建一個 `PersistentVolume` 對象來展示現有 Volumes,從而在 Kubernetes 中暴露預先存在的 Volume。例如,暴露屬于 `com.example.team/csi-driver` 這個 CSI 插件的 `existingVolumeName Volume`:
```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-manually-created-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
csi:
driver: com.example.team/csi-driver
volumeHandle: existingVolumeName
readOnly: false
```
### 附著和掛載
您可以在任何的 pod 或者 pod 的 template 中引用綁定到 CSI volume 上的 `PersistentVolumeClaim`。
```yaml
kind: Pod
apiVersion: v1
metadata:
name: my-pod
spec:
containers:
- name: my-frontend
image: dockerfile/nginx
volumeMounts:
- mountPath: "/var/www/html"
name: my-csi-volume
volumes:
- name: my-csi-volume
persistentVolumeClaim:
claimName: my-request-for-storage
```
當一個引用了 CSI Volume 的 pod 被調度時, Kubernetes 將針對外部 CSI 插件進行相應的操作,以確保特定的 Volume 被 attached、mounted, 并且能被 pod 中的容器使用。
關于 CSI 實現的詳細信息請參考[設計文檔](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/container-storage-interface.md)。
## 創建 CSI 驅動
Kubernetes 盡可能少地指定 CSI Volume 驅動程序的打包和部署規范。[這里](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/container-storage-interface.md#third-party-csi-volume-drivers)記錄了在 Kubernetes 上部署 CSI Volume 驅動程序的最低要求。
最低要求文件還包含[概述部分](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/container-storage-interface.md#recommended-mechanism-for-deploying-csi-drivers-on-kubernetes),提供了在 Kubernetes 上部署任意容器化 CSI 驅動程序的建議機制。存儲提供商可以運用這個機制來簡化 Kubernetes 上容器式 CSI 兼容 Volume 驅動程序的部署。
作為推薦部署的一部分,Kubernetes 團隊提供以下 sidecar(輔助)容器:
- [External-attacher](https://github.com/kubernetes-csi/external-attacher)
可監聽 Kubernetes VolumeAttachment 對象并觸發 ControllerPublish 和 ControllerUnPublish 操作的 sidecar 容器,通過 CSI endpoint 觸發 ;
- [External-provisioner](https://github.com/kubernetes-csi/external-provisioner)
監聽 Kubernetes PersistentVolumeClaim 對象的 sidecar 容器,并觸發對 CSI 端點的 CreateVolume 和DeleteVolume 操作;
- [Driver-registrar](https://github.com/kubernetes-csi/driver-registrar)(DEPRECATED)
使用 Kubelet(將來)注冊 CSI 驅動程序的 sidecar 容器,并將 `NodeId` (通過 `GetNodeID` 調用檢索到 CSI endpoint)添加到 Kubernetes Node API 對象的 annotation 里面。
- [Cluster Driver Registrar](https://github.com/kubernetes-csi/cluster-driver-registrar)
創建 CSIDriver 這個集群范圍的 CRD 對象。
- [Node Driver Registrar](https://github.com/kubernetes-csi/node-driver-registrar)
替代 Driver-registrar。
存儲供應商完全可以使用這些組件來為其插件構建 Kubernetes Deployment,同時讓它們的 CSI 驅動程序完全意識不到 Kubernetes 的存在。
另外 CSI 驅動完全是由第三方存儲供應商自己維護的,在 kubernetes 1.9 版本中 CSI 還處于 alpha 版本。
## 參考
- [Container Storage Interface (CSI)](https://github.com/container-storage-interface/spec/blob/master/spec.md)
- 序言
- 云原生
- 云原生(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快速入門指南
- 邊緣計算
- 人工智能