关于segmentfault:从入门到上手什么是K8S持久卷

133次阅读

共计 6565 个字符,预计需要花费 17 分钟才能阅读完成。


本文是介绍 Kubernetes 的基本概念的系列文章之一,在第一篇文章中,咱们简略介绍了长久卷(Persistent Volumes)。在本文中,咱们将学习如何设置数据持久性,并将编写 Kubernetes 脚本以将咱们的 Pod 连贯到长久卷。在此示例中,将应用 Azure 文件存储 (Azure File Storage) 来存储来自咱们 MongoDB 数据库的数据,但您能够应用任何类型的卷来实现雷同的后果(例如 Azure Disk,GCE 长久磁盘,AWS 弹性块存储等)。

如果你想全面理解 K8S 其余概念的话,能够先查看此前公布的文章。

请留神:本文提供的脚本不限定于某个平台,因而您能够应用其余类型的云提供商或应用具备 K3S 的本地集群实际本教程。本文倡议应用 K3S,因为它十分轻,所有的依赖项被打包在单个二进制中包装大小小于 100MB。它也是一种高可用的认证的 Kubernetes 发行版,用于在资源受限环境中的生产工作负载。想理解更多信息,请查看官网文档:

https://docs.rancher.cn/k3s/

后期筹备

在开始本教程之前,请确保已装置 Docker。同时装置 Kubectl(如果没有,请拜访以下链接装置:

https://kubernetes.io/docs/tasks/tools/#install-kubectl-on-windows

在 kubectl Cheat Sheet. 中能够找到整个本教程中应用的 kubectl 命令:

https://kubernetes.io/docs/reference/kubectl/cheatsheet/

本教程中,咱们将应用 Visual Studio Code,您也能够应用其余的编辑器。

Kubernetes 长久卷能够解决什么问题?

请记住,咱们有一个节点(硬件设施或虚拟机)和在节点外部,咱们有一个 Pod(或多个 Pod),在 Pod 中,咱们有容器。Pod 的状态是临时的,所以他们诡秘莫测(时常会被删除或从新调度等)。在这种状况下,如果你想在 Pod 被删除之后曾经保留其中的数据,你须要数据挪动到 Pod 内部。这样它就能够独立于任何 Pod 存在。此外部地位称为卷,它是存储系统的形象。应用卷,您能够在多个 Pod 放弃长久化状态。

什么时候应用长久卷

当容器开始被广泛应用时,它们旨在反对无状态工作负载,其持久性数据存储在其余中央。从那时起,人们做了很多致力以反对容器生态系统中的有状态利用。

每个我的项目都须要某种数据持久性,因而,您通常须要一个数据库来存储数据。但在简洁的设计中,你不想依赖具体的实现;您想写一个尽可能能够重复使用和独立于平台的应用程序。

始终以来,始终须要向应用程序暗藏存储实现的详细信息。但当初,在云原生利用的时代,云提供商创立了的环境中,想要拜访数据的应用程序或用户须要与特定存储系统集成。例如,许多应用程序间接应用特定存储系统,诸如 Amazon S3、AzureFile 或块存储等,这造成了不衰弱的依赖。Kubernetes 正在尝试通过创立一个名为长久卷的形象来扭转这一状况,它容许云原生应用程序连贯到各种云存储系统,而无需与这些零碎建设明确的依赖关系。这能够使云存储的耗费更加无缝和打消集成老本。它还能够更容易地迁徙云并采纳多云策略。

即便有时候,因为金钱,工夫或人力等客观条件的限度,你须要做出一些斗争,将你的应用程序与特定的平台或提供商间接耦合,您应该尽量避免尽可能多的间接依赖项。从理论数据库实现中解耦应用程序的一种办法(还有其余解决方案,但这些解决方案更加简单)是应用容器(和长久卷来避免数据失落)。这样,您的应用程序将依赖于形象而不是特定实现。

当初真正的问题是,咱们是否应该总是应用带有持久性卷的容器化数据库,或者哪些存储系统类型不应该在容器中应用?

何时应用长久卷并没有通用的黄金法令,但作为终点,您应该思考可扩展性和集群中节点失落的解决。

依据可扩展性,咱们能够有两种类型的存储系统:

  • 垂直伸缩——包含传统的 RDMS 解决方案,例如 MySQL、PostgreSQL 以及 SQL Server
  • 程度伸缩——包含“NoSQL”解决方案,例如 ElasticSearch 或基于 Hadoop 的解决方案

像 MySQL、Postgres、Microsoft SQL 等垂直伸缩的解决方案不应进入容器。这些数据库平台须要高 I / O、共享磁盘、块存储等,并且不能优雅地解决集群中的节点失落,这通常产生在基于容器的生态系统中。

对于程度伸缩的应用程序(Elastic、Cassandra、Kafka 等),您应该应用容器,因为它们能够接受数据库集群中的节点失落,并且数据库应用程序能够独立地再均衡。

通常,您能够并且应该分布式数据库容器化,这些数据库应用冗余存储技术,能够接受数据库集群中的节点失落(Elasticsearch 是一个十分好的例子)。

Kubernetes 长久卷的类型

咱们能够依据其生命周期和配置形式对 Kubernetes 卷进行分类。

思考到卷的生命周期,咱们能够分为:

  • 长期卷,即与节点的生命周期严密耦合(例如 ExpertDir 或 HostPath),如果节点开张,则删除它们的截阵数量。
  • 长久卷,即长期存储,并且与 Ppd 或节点生命周期无关。这些能够是云卷(如 gcePersistentDisk、awselasticBlockStore、AzureFile 或 AzureDisk),NFS(网络文件系统)或 Persistent
    Volume Claim(一系列形象来连贯到底层云提供存储卷)。

依据卷的配置形式,咱们能够分为:

  1. 间接拜访
  2. 动态配置
  1. 动静配置

间接拜访长久卷

在这种状况下,Pod 将间接与 Volume 耦合,因而它将晓得存储系统(例如,Pod 将与 Azure 存储帐户耦合)。该解决方案与云无关,它取决于具体实施而不是形象。因而,如果可能的话尽量避免这样的解决方案。它惟一的长处是速度快,在 Pod 中创立 Secret,并指定应应用的 Secret 和确切的存储类型。

创立 Secret 脚本如下:

apiVersion: v1  
kind: Secret  
metadata:  
  name: static-persistence-secret  
type: Opaque  
data:  
  azurestorageaccountname: "base64StorageAccountName"  
  azurestorageaccountkey: "base64StorageAccountKey"

在任何 Kubernetes 脚本中,在第 2 行咱们指定了资源的类型。在这种状况下,咱们称之为 Secret。在第 4 行,咱们给它一个名字(咱们称之为动态,因为它是由管理员手动创立的,而不是主动生成的)。从 Kubernetes 的角度来看,Opaque 类型意味着该 Secret 的内容(数据)是非结构化的(它能够蕴含任意键值对)。要理解无关 Kubernetes Secrets 的更多信息,能够参阅 Secrets Design Document 和 ConfigureKubernetes Secrets。

https://github.com/kubernetes/community/blob/master/contributors/design-proposals/auth/secrets.md

https://kubernetes.io/docs/concepts/configuration/secret/

在数据局部中,咱们必须指定帐户名称(在 Azure 中,它是存储帐户的名称)和 Access 键(在 Azure 中,抉择存储帐户下的“Settings”,Access key)。别忘了两者应该应用 Base64 进行编码。

下一步是批改咱们的 Deployment 脚本以应用卷(在这种状况下,卷是 Azure File Storage)。

apiVersion: apps/v1  
kind: Deployment  
metadata:  
  name: user-db-deployment  
spec:  
  selector:  
    matchLabels:  
      app: user-db-app  
  replicas: 1  
  template:  
    metadata:  
      labels:  
        app: user-db-app  
    spec:  
      containers:  
        - name: mongo  
          image: mongo:3.6.4  
          command:  
            - mongod  
            - "--bind_ip_all"  
            - "--directoryperdb"  
          ports:  
            - containerPort: 27017  
          volumeMounts:  
            - name: data  
              mountPath: /data/db  
          resources:  
            limits:  
              memory: "256Mi"  
              cpu: "500m"  
      volumes:  
        - name: data  
          azureFile:  
            secretName: static-persistence-secret  
            shareName: user-mongo-db  
            readOnly: false

咱们能够发现,惟一的区别是,从第 32 行咱们指定了应用的卷,给它一个名称并指定底层存储系统的确切详细信息。secretName 必须是先前创立的 Secret 的名称。

Kubernetes 存储类

要理解动态或动静配置,首先咱们必须理解 Kubernetes 存储类。

通过 StorageClass,管理员能够提供对于可用存储的配置文件或“类”。不同的类可能映射到不同服务质量级别,或备份策略或由集群管理员确定的任意策略。

例如,你能够有一个在 HDD 上存储数据的配置文件,命名为慢速存储,或一个在 SSD 上存储数据的配置文件,命名为疾速存储。这些存储的类型由供应者确定。对于 Azure,有两种提供者:AzureFile 和 AzureDisk(区别在于 AzureFile 能够与 Read Wriite Many 拜访模式一起应用,而 AzureDisk 只反对 Read Write Once 拜访,当您心愿同时应用多个 Pod 时,这可能是不利因素)。您能够在此处理解无关不同类型的 Storage Classes:

https://kubernetes.io/docs/concepts/storage/storage-classes/

以下是 Storage Class 的脚本:

kind: StorageClass  
apiVersion: storage.k8s.io/v1  
metadata:  
  name: azurefilestorage  
provisioner: kubernetes.io/azure-file  
parameters:  
  storageAccount: storageaccountname  
reclaimPolicy: Retain  
allowVolumeExpansion: true

Kubernetes 预约义提供者属性的值(请参阅 Kubernetes 存储类)。保留回收策略意味着在咱们删除 PVC 和 PV 之后,未革除理论存储介质。咱们能够将其设置为删除和应用此设置,一旦删除 PVC,它也会触发相应的 PV 以及理论存储介质(此处理论存储是 Azure 文件存储)的删除。

长久卷及 Persistent Volume Claim

Kubernetes 对每一个传统的存储操作流动(供给 / 配置 / 附加)都有一个匹配的原语。长久卷是供给,存储类正在配置,并且长久卷 Claim 是附加的。

来自初始文档:

*Persistent Volume(PV)是集群中的存储,它已由管理员配置或应用存储类动静配置。
Persistent Volume Claim(PVC)是用户存储的申请。它相似于 Pod。Pod 耗费节点资源与 PVC 耗费 PV 资源是相似的。Pod 能够申请特定的资源级别(CPU 和内存)。Claim 能够申请特定的大小和拜访模式(例如,它们能够装置一次读 / 写或屡次只读)。
这意味着管理员将创立长久卷以指定 Pod 能够应用的存储大小、拜访模式和存储类型。开发人员将创立 Persistent Volume Claim,要求提供一个卷、拜访权限和存储类型。这样一来,在“开发侧”和“运维侧”之间就有了显著的辨别。开发人员负责要求必要的卷(PVC),运维人员负责筹备和配置要求的卷(PV)。
动态和动静配置之间的差别是,如果没有长久卷和管理员手动创立的 Secret,Kubernetes 将尝试主动创立这些资源。*

动静配置

在这种状况下,没有手动创立的长久卷和 Secret,因而 Kubernetes 将尝试生成它们。Storage Class 是必要的,咱们将应用在前文中创立的 Storage Class。

PersistentVolumeClaim 的脚本如下所示:

apiVersion: v1  
kind:Persistent Volume Claim  
metadata:  
  name: persistent-volume-claim-mongo  
spec:  
  accessModes:  
    - ReadWriteMany  
  resources:  
    requests:  
      storage: 1Gi  
  storageClassName: azurefilestorage

以及咱们更新的 Deployment 脚本:

apiVersion: apps/v1  
kind: Deployment  
metadata:  
  name: user-db-deployment  
spec:  
  selector:  
    matchLabels:  
      app: user-db-app  
  replicas: 1  
  template:  
    metadata:  
      labels:  
        app: user-db-app  
    spec:  
      containers:  
        - name: mongo  
          image: mongo:3.6.4  
          command:  
            - mongod  
            - "--bind_ip_all"  
            - "--directoryperdb"  
          ports:  
            - containerPort: 27017  
          volumeMounts:  
            - name: data  
              mountPath: /data/db  
          resources:  
            limits:  
              memory: "256Mi"  
              cpu: "500m"  
      volumes:  
        - name: data  
          Persistent Volume Claim:  
            claimName: persistent-volume-claim-mongo

如你所见,在第 34 行中,咱们通过名称援用了先前创立的 PVC。在这种状况下,咱们没有手动为它创立长久卷或 Secret,因而它将主动创立。

这种办法的最重要的劣势是您不用手动创立 PV 和 Secret,而且 Deployment 是与云无关的。存储的底层细节不存在于 Pod 的 spec 中。然而也有一些毛病:您无奈配置存储帐户或文件共享,因为它们是主动生成的,并且您无奈重复使用 PV 或 Secret ——它们将为每个新 Claim 从新生成。

动态配置

动态和动静配置之间的惟一区别是咱们手动创立动态配置中的长久卷和 Secret。这样,咱们就能够齐全管制在集群中创立的资源。

长久卷脚本如下:

apiVersion: v1  
kind: PersistentVolume  
metadata:  
  name: static-persistent-volume-mongo  
  labels:  
    storage: azurefile  
spec:  
  capacity:  
    storage: 1Gi  
  accessModes:  
    - ReadWriteMany  
  storageClassName: azurefilestorage  
  azureFile:  
    secretName: static-persistence-secret  
    shareName: user-mongo-db  
    readOnly: false

重要的是,在第 12 行咱们按名称援用 Storage Class。此外,在第 14 行咱们援用了 Secret,用于拜访底层存储系统。

本文更举荐这个解决方案,即便它须要更多的工作,但它是与云无关的(cloud-agnostic)。它还容许您利用无关角色(集群管理员与开发人员)的关注点拆散,并让您管制命名和创立资源。

总结

在本文中,咱们理解了如何应用 Volume 长久化数据和状态,并提出了三种不同的办法来设置零碎,即为间接拜访、动静配置和动态配置,并探讨了每个零碎的优缺点。

作者简介

Czako Zoltan,一位经验丰富的全栈开发人员,在包含前端,后端,DevOps,物联网和人工智能等多个畛域都领有丰盛的教训。

正文完
 0