2. Kubernetes的基本概念和术语(3)

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 2. Kubernetes的基本概念和术语(3)

12. Volume

Volume(存储卷)是Pod中能够被多个容器访问的共享目录。Kubernetes的Volume概念、用途和目的与Docker的Volume比较类似,但两者不能等价。首先,Kubernetes中的Volume被定义在Pod上,然后被一个Pod里的多个容器挂载到具体的文件目录下;其次,Kubernetes中的Volume与Pod的生命周期相同,但与容器的生命周期不相关,当容器终止或者重启时,Volume中的数据也不会丢失。最后Kubernetes支持多种类型的Volume,例如GlusterFS、Ceph等先进的分布式文件系统。

Volume的使用也比较简单,在大多数情况下,我们先在Pod上声明一个Volume,然后在容器里引用该Volume并挂载(Mount)到容器里的某个目录上。举例来说,我们要给之前的Tomcat Pod增加一个名为datavol的Volume,并且挂载到容器的/mydata-data目录上,则只要对Pod的定义文件做如下修正即可(注意代码中的粗体部分):

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

除了可以让一个Pod里的多个容器共享文件、让容器的数据写到宿主机的磁盘上或者写文件到网络存储中,Kubernetes的Volume还扩展出了一种非常有实用价值的功能,即容器配置文件集中化定义与管理,这是通过ConfigMap这种新的资源对象来实现的,后面会详细说明。Kubernetes提供了非常丰富的Volume类型,下面逐一进行说明:

12.1 emptyDir

一个emptyDir Volume是在Pod分配到Node时创建的。从它的名称就可以看出,它的初始内容为空,并且无须指定宿主机上对应的目录文件,因为这是Kubernetes自动分配的一个目录,当Pod从Node上移除时,emptyDir中的数据也会被永久删除,emptyDir的一些用途如下。


◎ 临时空间,例如用于某些应用程序运行时所需的临时目录,且无须永久保留。

◎ 长时间任务的中间过程CheckPoint的临时保存目录。

◎ 一个容器需要从另一个容器中获取数据的目录(多容器共享目录)。

目前,用户无法控制emptyDir使用的介质种类。如果kubelet的配置是使用硬盘,那么所有emptyDir都将被创建在该硬盘上。Pod在将来可以设置emptyDir是位于硬盘、固态硬盘上还是基于内存的tmpfs上,上面的例子便采用了emptyDir类的Volume。

12.2 hostPath

hostPath为在Pod上挂载宿主机上的文件或目录,它通常可以用于以下几方面。


◎ 容器应用程序生成的日志文件需要永久保存时,可以使用宿主机的高速文件系统进行存储。

需要访问宿主机上Docker引擎内部数据结构的容器应用时,可以通过定义hostPath为宿主机/var/lib/docker目录,使容器内部应用可以直接访问Docker的文件系统。

在使用这种类型的Volume时,需要注意以下几点。


◎ 在不同的Node上具有相同配置的Pod,可能会因为宿主机上的目录和文件不同而导致对Volume上目录和文件的访问结果不一致。

◎ 如果使用了资源配额管理,则Kubernetes无法将hostPath在宿主机上使用的资源纳入管理。

在下面的例子中使用宿主机的/data目录定义了一个hostPath类型的

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data
      # this field is optional
      type: Directory

12.3 NFS

使用NFS网络文件系统提供的共享目录存储数据时,我们需要在系

统中部署一个NFS Server。定义NFS类型的Volume的示例如下:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs
spec:
  capacity:
    storage: 1Mi
  accessModes:
    - ReadWriteMany
  nfs:
    server: nfs-server.default.svc.cluster.local
    path: "/"

nfs挂载实例

12.4 其他类型的Volume

◎ iscsi:使用iSCSI存储设备上的目录挂载到Pod中。

◎ flocker:使用Flocker管理存储卷。

◎ glusterfs:使用开源GlusterFS网络文件系统的目录挂载到Pod中。

◎ rbd:使用Ceph块设备共享存储(Rados Block Device)挂载Pod中。

◎ gitRepo:通过挂载一个空目录,并从Git库clone一个gitrepository以供Pod使用。

◎ secret:一个Secret Volume用于为Pod提供加密的信息,你可以将定义在Kubernetes中的Secret直接挂载为文件让Pod访问。SecretVolume是通过TMFS(内存文件系统)实现的,这种类型的Volume总是不会被持久化的。

secret实例:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret


阅读延申:

kubernetes secret使用

13. Persistent Volume

之前提到的Volume是被定义在Pod上的,属于计算资源的一部分,而实际上,网络存储是相对独立于计算资源而存在的一种实体资源。比如在使用虚拟机的情况下,我们通常会先定义一个网络存储,然后从中划出一个“网盘”并挂接到虚拟机上。Persistent Volume(PV)和与之相关联的Persistent Volume Claim(PVC)也起到了类似的作用。PV可以被理解成Kubernetes集群中的某个网络存储对应的一块存

储,它与Volume类似,但有以下区别。


◎ PV只能是网络存储,不属于任何Node,但可以在每个Node上访问。


◎ PV并不是被定义在Pod上的,而是独立于Pod之外定义的。


◎ PV目前支持的类型包括:gcePersistentDisk、

AWSElasticBlockStore、AzureFile、AzureDisk、FC(Fibre Channel)Flocker、NFS、iSCSI、RBD(Rados Block Device)、CephFS、Cinder、GlusterFS、VsphereVolume、Quobyte Volumes、VMware Photon、Portworx Volumes、ScaleIO Volumes和HostPath(仅供单机测 试)。


下面给出了NFS类型的PV的一个YAML定义文件,声明了需要10Gi

的存储空间:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"

比较重要的是PV的accessModes属性,目前有以下类型。

  • ReadWriteOnce:读写权限,并且只能被单个Node挂载。
  • ReadOnlyMany:只读权限,允许被多个Node挂载。
  • ReadWriteMany:读写权限,允许被多个Node挂载。
$ kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml
$ kubectl get pv task-pv-volume
NAME             CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS      CLAIM     STORAGECLASS   REASON    AGE
task-pv-volume   10Gi       RWO           Retain          Available             manual                   4s     

说说PV的状态。PV是有状态的对象,它的状态有以下几种。


◎ Available:空闲状态。

◎ Bound:已经绑定到某个PVC上。

◎ Released:对应的PVC已经被删除,但资源还没有被集群收回。

◎ Failed:PV自动回收失败。

共享存储的原理解析和实践指南详见第8章的说明。


如果某个Pod想申请某种类型的PV,则首先需要定义一个

PersistentVolumeClaim对象

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi
$ kubectl apply -f https://k8s.io/examples/pods/storage/pv-claim.yaml
$ kubectl get pv task-pv-volume
NAME             CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS    CLAIM                   STORAGECLASS   REASON    AGE
task-pv-volume   10Gi       RWO           Retain          Bound     default/task-pv-claim   manual                   2m
$ kubectl get pvc task-pv-claim
NAME            STATUS    VOLUME           CAPACITY   ACCESSMODES   STORAGECLASS   AGE
task-pv-claim   Bound     task-pv-volume   10Gi       RWO           manual         30s

pod使用pv与pvc

apiVersion: v1
kind: Pod
metadata:
  name: task-pv-pod
spec:
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: task-pv-claim
  containers:
    - name: task-pv-container
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage

阅读延申:

https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/

14. namespace

Namespace(命名空间)是Kubernetes系统中的另一个非常重要的概念,Namespace在很多情况下用于实现多租户的资源隔离。Namespace通过将集群内部的资源对象“分配”到不同的Namespace中,形成逻辑上分组的不同项目、小组或用户组,便于不同的分组在共享使用整个集群的资源的同时还能被分别管理。Kubernetes集群在启动后会创建一个名为default的Namespace,通过kubectl可以查看:

$ kubectl get namespace
NAME              STATUS   AGE
default           Active   1d
kube-node-lease   Active   1d
kube-public       Active   1d
kube-system       Active   1d
kubectl run nginx --image=nginx --namespace=<insert-namespace-name-here>
kubectl get pods --namespace=<insert-namespace-name-here>

15. Annotation

Annotation(注解)与Label类似,也使用key/value键值对的形式进行定义。不同的是Label具有严格的命名规则,它定义的是Kubernetes对象的元数据(Metadata),并且用于Label Selector。Annotation则是用户任意定义的附加信息,以便于外部工具查找。在很多时候,Kubernetes的模块自身会通过Annotation标记资源对象的一些特殊信息。


通常来说,用Annotation来记录的信息如下。


◎ build信息、release信息、Docker镜像信息等,例如时间戳、release id号、PR号、镜像Hash值、Docker

Registry地址等。

◎ 日志库、监控库、分析库等资源库的地址信息。

◎ 程序调试工具信息,例如工具名称、版本号等。

◎ 团队的联系信息,例如电话号码、负责人名称、网址等。

16. ConfigMap

为了能够准确和深刻理解Kubernetes ConfigMap的功能和价值,我们需要从Docker说起。我们知道,Docker通过将程序、依赖库、数据及配置文件“打包固化”到一个不变的镜像文件中的做法,解决了应用的部署的难题,但这同时带来了棘手的问题,即配置文件中的参数在运行期如何修改的问题。我们不可能在启动Docker容器后再修改容器里的配置文件,然后用新的配置文件重启容器里的用户主进程。为了解决这个问

题,Docker提供了两种方式:


◎ 在运行时通过容器的环境变量来传递参数;

◎ 通过Docker Volume将容器外的配置文件映射到容器内。

这两种方式都有其优势和缺点,在大多数情况下,后一种方式更合适我们的系统,因为大多数应用通常从一个或多个配置文件中读取参数。但这种方式也有明显的缺陷:我们必须在目标主机上先创建好对应的配置文件,然后才能映射到容器里。上述缺陷在分布式情况下变得更为严重,因为无论采用哪种方式,写入(修改)多台服务器上的某个指定文件,并确保这些文件保持一致,都是一个很难完成的目标。此外,在大多数情况下,我们都希望能集中管理系统的配置参数,而不是管理一堆配置文件。针对上述问题,Kubernetes给出了一个很巧妙的设计实现,如下所述。

首先,把所有的配置项都当作key-value字符串,当然value可以来自某个文本文件,比如配置项password=123456、user=root、host=192.168.8.4用于表示连接FTP服务器的配置参数。这些配置项可以作为Map表中的一个项,整个Map的数据可以被持久化存储在Kubernetes的Etcd数据库中,然后提供API以方便Kubernetes相关组件或客户应用CRUD操作这些数据,上述专门用来保存配置参数的Map就是Kubernetes ConfigMap资源对象。接下来,Kubernetes提供了一种内建机制,将存储在etcd中的

ConfigMap通过Volume映射的方式变成目标Pod内的配置文件,不管目标Pod被调度到哪台服务器上,都会完成自动映射。进一步地,如果ConfigMap中的key-value数据被修改,则映射到Pod中的“配置文件”也会随之自动更新。于是,Kubernetes ConfigMap就成了分布式系统中最为简单(使用方法简单,但背后实现比较复杂)且对应用无侵入的配置中心。ConfigMap配置集中化的一种简单方案如图1.16所示:

1035234-20181020215539574-213176954.png

阅读延申:

k8s ConfigMap文件映射详解


17. 小结

上述这些组件是Kubernetes系统的核心组件,它们共同构成了Kubernetes系统的框架和计算模型。通过对它们进行灵活组合,用户就可以快速、方便地对容器集群进行配置、创建和管理。除了本章所介绍的核心组件,在Kubernetes系统中还有许多辅助配置的资源对象,例如LimitRange、ResourceQuota。另外,一些系统内部使用的对象Binding、Event等请参考Kubernetes的API文档


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
Kubernetes 调度 Perl
在K8S中,Pod亲和性概念是什么?
在K8S中,Pod亲和性概念是什么?
|
1月前
|
Kubernetes 负载均衡 安全
在k8S中,网络模型概念是什么?
在k8S中,网络模型概念是什么?
|
1月前
|
存储 Kubernetes Cloud Native
在k8S中,rook概念是什么?
在k8S中,rook概念是什么?
|
1月前
|
JSON Kubernetes Cloud Native
在k8S中,CNI模型概念是什么?
在k8S中,CNI模型概念是什么?
|
1月前
|
消息中间件 Kubernetes 数据库
在k8S中,初始化容器(init container)概念原理是什么?
在k8S中,初始化容器(init container)概念原理是什么?
|
1月前
|
存储 Kubernetes Docker
在K8S中,与K8S相关基础概念有哪些?
在K8S中,与K8S相关基础概念有哪些?
|
2月前
|
存储 Kubernetes 负载均衡
k8s原理概念基础入门
k8s原理概念基础入门
179 2
|
3月前
|
存储 Kubernetes 调度
K8S中的核心概念
【6月更文挑战第25天】k8s资源对象可以用yaml或者json格式声明。每个资源对象都有自己的特定结构定义,并统一保存在etcd这种非关系型数据库中。
|
4月前
|
存储 Kubernetes API
Kubernetes学习-核心概念篇(三) 核心概念和专业术语
Kubernetes学习-核心概念篇(三) 核心概念和专业术语
Kubernetes学习-核心概念篇(三) 核心概念和专业术语
|
4月前
|
存储 Kubernetes 负载均衡
k8s 数据流向 与 核心概念详细介绍
k8s 数据流向 与 核心概念详细介绍