Kubernetes
  • 序言
  • 基礎入門
    • Kubernetes 簡介
    • Kubernetes 基本概念
    • Kubernetes 101
    • Kubernetes 201
    • Kubernetes 集群
  • 核心原理
    • 核心原理
    • 架構原理
    • 設計理念
    • 核心組件
      • etcd
      • kube-apiserver
      • kube-scheduler
      • kube-controller-manager
      • kubelet
      • kube-proxy
      • kube-dns
      • Federation
      • kubeadm
      • hyperkube
      • kubectl
    • 資源對象
      • Autoscaling
      • ConfigMap
      • CronJob
      • CustomResourceDefinition
      • DaemonSet
      • Deployment
      • Ingress
      • Job
      • LocalVolume
      • Namespace
      • NetworkPolicy
      • Node
      • PersistentVolume
      • Pod
      • PodPreset
      • ReplicaSet
      • Resource Quota
      • Secret
      • SecurityContext
      • Service
      • ServiceAccount
      • StatefulSet
      • Volume
  • 部署配置
    • 部署指南
    • kubectl 安裝
    • 單機部署
    • 特性開關
    • 最佳配置
    • 版本支持
    • 集群部署
      • kubeadm
      • kops
      • Kubespray
      • Azure
      • Windows
      • LinuxKit
      • kubeasz
    • 附加組件
      • Addon-manager
      • DNS
      • Dashboard
      • 監控
      • 日誌
      • Metrics
      • GPU
      • Cluster Autoscaler
      • ip-masq-agent
    • Kubernetes-The-Hard-Way
      • 準備部署環境
      • 安裝必要工具
      • 創建計算資源
      • 配置創建證書
      • 配置生成配置
      • 配置生成密鑰
      • 部署 Etcd 群集
      • 部署控制節點
      • 部署計算節點
      • 配置 Kubectl
      • 配置網絡路由
      • 部署 DNS 擴展
      • 煙霧測試
      • 刪除集群
  • 插件擴展
    • API 擴展
      • Aggregation
      • CustomResourceDefinition
    • 訪問控制
      • 認證
      • RBAC 授權
      • 准入控制
    • Scheduler 擴展
    • 網絡插件
      • CNI
      • Flannel
      • Calico
      • Weave
      • Cilium
      • OVN
      • Contiv
      • SR-IOV
      • Romana
      • OpenContrail
      • Kuryr
    • 運行時插件 CRI
      • CRI-tools
      • Frakti
    • 存儲插件
      • 容器存儲接口 CSI
      • FlexVolume
      • glusterfs
    • 網絡策略
    • Ingress Controller
      • Ingress + Letsencrypt
      • minikube Ingress
      • Traefik Ingress
      • Keepalived-VIP
    • Cloud Provider 擴展
    • Device 插件
  • 服務治理
    • 服務治理
      • 一般準則
      • 滾動升級
      • Helm
      • Operator
      • Service Mesh
      • Linkerd
      • Linkerd2
    • Istio
      • 安裝
      • 流量管理
      • 安全管理
      • 策略管理
      • 度量管理
      • 排錯
      • 社區
    • Devops
      • Draft
      • Jenkins X
      • Spinnaker
      • Kompose
      • Skaffold
      • Argo
      • Flux GitOps
  • 實踐案例
    • 實踐概覽
    • 資源控制
    • 集群高可用
    • 應用高可用
    • 調試
    • 端口映射
    • 端口轉發
    • 用戶管理
    • GPU
    • HugePage
    • 安全
    • 審計
    • 備份恢復
    • 證書輪換
    • 大規模集群
    • 大數據與機器學習
      • Spark
      • Tensorflow
    • Serverless
  • 排錯指南
    • 排錯概覽
    • 集群排錯
    • Pod 排錯
    • 網絡排錯
    • PV 排錯
      • AzureDisk
      • AzureFile
    • Windows 排錯
    • 雲平臺排錯
      • Azure
    • 排錯工具
  • 社區貢獻
    • 開發指南
    • 單元測試和集成測試
    • 社區貢獻
  • 附錄
    • 生態圈
    • 學習資源
    • 國內鏡像
    • 如何貢獻
    • 參考文檔
Powered by GitBook
On this page
  • Volume 類型
  • API 版本對照表
  • emptyDir
  • hostPath
  • NFS
  • gcePersistentDisk
  • awsElasticBlockStore
  • gitRepo
  • 使用 subPath
  • FlexVolume
  • Projected Volume
  • 本地存儲限額
  • Mount 傳遞
  • Volume 快照
  • Windows Volume
  • 掛載傳播
  • 其他的 Volume 參考示例
  1. 核心原理
  2. 資源對象

Volume

我們知道默認情況下容器的數據都是非持久化的,在容器消亡以後數據也跟着丟失,所以 Docker 提供了 Volume 機制以便將數據持久化存儲。類似的,Kubernetes 提供了更強大的 Volume 機制和豐富的插件,解決了容器數據持久化和容器間共享數據的問題。

與 Docker 不同,Kubernetes Volume 的生命週期與 Pod 綁定

  • 容器掛掉後 Kubelet 再次重啓容器時,Volume 的數據依然還在

  • 而 Pod 刪除時,Volume 纔會清理。數據是否丟失取決於具體的 Volume 類型,比如 emptyDir 的數據會丟失,而 PV 的數據則不會丟

Volume 類型

目前,Kubernetes 支持以下 Volume 類型:

  • emptyDir

  • hostPath

  • gcePersistentDisk

  • awsElasticBlockStore

  • nfs

  • iscsi

  • flocker

  • glusterfs

  • rbd

  • cephfs

  • gitRepo

  • secret

  • persistentVolumeClaim

  • downwardAPI

  • azureFileVolume

  • azureDisk

  • vsphereVolume

  • Quobyte

  • PortworxVolume

  • ScaleIO

  • FlexVolume

  • StorageOS

  • local

注意,這些 volume 並非全部都是持久化的,比如 emptyDir、secret、gitRepo 等,這些 volume 會隨着 Pod 的消亡而消失。

API 版本對照表

Kubernetes 版本
Core API 版本

v1.5+

core/v1

emptyDir

如果 Pod 設置了 emptyDir 類型 Volume, Pod 被分配到 Node 上時候,會創建 emptyDir,只要 Pod 運行在 Node 上,emptyDir 都會存在(容器掛掉不會導致 emptyDir 丟失數據),但是如果 Pod 從 Node 上被刪除(Pod 被刪除,或者 Pod 發生遷移),emptyDir 也會被刪除,並且永久丟失。

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}

hostPath

hostPath 允許掛載 Node 上的文件系統到 Pod 裏面去。如果 Pod 需要使用 Node 上的文件,可以使用 hostPath。

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /data

NFS

NFS 是 Network File System 的縮寫,即網絡文件系統。Kubernetes 中通過簡單地配置就可以掛載 NFS 到 Pod 中,而 NFS 中的數據是可以永久保存的,同時 NFS 支持同時寫操作。

volumes:
- name: nfs
  nfs:
    # FIXME: use the right hostname
    server: 10.254.234.223
    path: "/"

gcePersistentDisk

gcePersistentDisk 可以掛載 GCE 上的永久磁盤到容器,需要 Kubernetes 運行在 GCE 的 VM 中。

volumes:
  - name: test-volume
    # This GCE PD must already exist.
    gcePersistentDisk:
      pdName: my-data-disk
      fsType: ext4

awsElasticBlockStore

awsElasticBlockStore 可以掛載 AWS 上的 EBS 盤到容器,需要 Kubernetes 運行在 AWS 的 EC2 上。

volumes:
  - name: test-volume
    # This AWS EBS volume must already exist.
    awsElasticBlockStore:
      volumeID: <volume-id>
      fsType: ext4

gitRepo

gitRepo volume 將 git 代碼下拉到指定的容器路徑中

  volumes:
  - name: git-volume
    gitRepo:
      repository: "git@somewhere:me/my-git-repository.git"
      revision: "22f1d8406d464b0c0874075539c1f2e96c253775"

使用 subPath

Pod 的多個容器使用同一個 Volume 時,subPath 非常有用

apiVersion: v1
kind: Pod
metadata:
  name: my-lamp-site
spec:
    containers:
    - name: mysql
      image: mysql
      volumeMounts:
      - mountPath: /var/lib/mysql
        name: site-data
        subPath: mysql
    - name: php
      image: php
      volumeMounts:
      - mountPath: /var/www/html
        name: site-data
        subPath: html
    volumes:
    - name: site-data
      persistentVolumeClaim:
        claimName: my-lamp-site-data

FlexVolume

  - name: test
    flexVolume:
      driver: "kubernetes.io/lvm"
      fsType: "ext4"
      options:
        volumeID: "vol1"
        size: "1000m"
        volumegroup: "kube_vg"

Projected Volume

Projected volume 將多個 Volume 源映射到同一個目錄中,支持 secret、downwardAPI 和 configMap。

apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
  - name: container-test
    image: busybox
    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

本地存儲限額

v1.7 + 支持對基於本地存儲(如 hostPath, emptyDir, gitRepo 等)的容量進行調度限額,可以通過 --feature-gates=LocalStorageCapacityIsolation=true 來開啓這個特性。

爲了支持這個特性,Kubernetes 將本地存儲分爲兩類

  • storage.kubernetes.io/overlay,即 /var/lib/docker 的大小

  • storage.kubernetes.io/scratch,即 /var/lib/kubelet 的大小

Kubernetes 根據 storage.kubernetes.io/scratch 的大小來調度本地存儲空間,而根據 storage.kubernetes.io/overlay 來調度容器的存儲。比如

爲容器請求 64MB 的可寫層存儲空間

apiVersion: v1
kind: Pod
metadata:
  name: ls1
spec:
  restartPolicy: Never
  containers:
  - name: hello
    image: busybox
    command: ["df"]
    resources:
      requests:
        storage.kubernetes.io/overlay: 64Mi

爲 empty 請求 64MB 的存儲空間

apiVersion: v1
kind: Pod
metadata:
  name: ls1
spec:
  restartPolicy: Never
  containers:
  - name: hello
    image: busybox
    command: ["df"]
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    emptyDir:
      sizeLimit: 64Mi

Mount 傳遞

  • HostToContainer:這是開啓 MountPropagation=true 時的默認模式,等效於 rslave 模式,即容器可以看到 Host 上面在該 volume 內的任何新 Mount 操作

  • Bidirectional:等效於 rshared 模式,即 Host 和容器都可以看到對方在該 Volume 內的任何新 Mount 操作。該模式要求容器必須運行在特權模式(即 securityContext.privileged=true)

注意:

  • 使用 Mount 傳遞需要開啓 --feature-gates=MountPropagation=true

Volume 快照

TODO: 補充 Volume 快照的設計原理和示例。

Windows Volume

Windows 容器暫時只支持 local、emptyDir、hostPath、AzureDisk、AzureFile 以及 flexvolume。注意 Volume 的路徑格式需要爲 mountPath: "C:\\etc\\foo" 或者 mountPath: "C:/etc/foo"。

apiVersion: v1
kind: Pod
metadata:
  name: hostpath-pod
spec:
  containers:
  - name: hostpath-nano
    image: microsoft/nanoserver:1709
    stdin: true
    tty: true
    volumeMounts:
    - name: blah
      mountPath: "C:\\etc\\foo"
      readOnly: true
  nodeSelector:
    beta.kubernetes.io/os: windows
  volumes:
  - name: blah
    hostPath:
      path: "C:\\AzureData"
apiVersion: v1
kind: Pod
metadata:
  name: empty-dir-pod
spec:
  containers:
  - image: microsoft/nanoserver:1709
    name: empty-dir-nano
    stdin: true
    tty: true
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
    - mountPath: C:/scratch
      name: scratch-volume
  volumes:
  - name: cache-volume
    emptyDir: {}
  - name: scratch-volume
    emptyDir: {}
  nodeSelector:
    beta.kubernetes.io/os: windows

掛載傳播

支持三種選項:

  • None:即私有掛載(private)

  • HostToContainer:即 Host 內在該目錄中的新掛載都可以在容器中看到,等價於 Linux 內核的 rslave。

  • Bidirectional:即 Host 內在該目錄中的新掛載都可以在容器中看到,同樣容器內在該目錄中的任何新掛載也都可以在 Host 中看到,等價於 Linux 內核的 rshared。僅特權容器(privileged)可以使用 Bidirectional 類型。

注意:

  • 使用前需要開啓 MountPropagation 特性

  • 如未設置,則 v1.9 和 v1.10 中默認爲私有掛載(None),而 v1.11 中默認爲 HostToContainer

  • Docker 服務的 systemd 配置文件中需要設置 MountFlags=shared

其他的 Volume 參考示例

PreviousStatefulSetNext部署指南

Last updated 1 year ago

如果內置的這些 Volume 不滿足要求,則可以使用 FlexVolume 實現自己的 Volume 插件。注意要把 volume plugin 放到 /usr/libexec/kubernetes/kubelet-plugins/volume/exec/<vendor~driver>/<driver>,plugin 要實現 init/attach/detach/mount/umount 等命令(可參考 lvm 的 )。

在 Kubernetes 中,Volume Mount 默認是 ,但從 v1.8 開始,Kubernetes 支持配置 Mount 傳遞(mountPropagation)。它支持兩種選項

rslave 和 rshared 的說明可以參考

v1.8 新增了 pre-alpha 版本的 Volume 快照,但還只是一個雛形,並且其實現不在 Kubernetes 核心代碼中,而是存放在 中。

是 v1.9 引入的新功能,並在 v1.10 中升級爲 Beta 版本。掛載傳播用來解決同一個 Volume 在不同的容器甚至是 Pod 之間掛載的問題。通過設置 `Container.volumeMounts.mountPropagation),可以爲該存儲卷設置不同的傳播類型。

示例
私有的
內核文檔
kubernetes-incubator/external-storage
掛載傳播(MountPropagation)
https://github.com/kubernetes/examples/tree/master/staging/volumes/iscsi
iSCSI Volume 示例
cephfs Volume 示例
Flocker Volume 示例
GlusterFS Volume 示例
RBD Volume 示例
Secret Volume 示例
downwardAPI Volume 示例
AzureFile Volume 示例
AzureDisk Volume 示例
Quobyte Volume 示例
Portworx Volume 示例
ScaleIO Volume 示例
StorageOS Volume 示例