{"msg":"操作成功","code":200,"data":{"createBy":"admin","createTime":"2021-09-11 17:52:09","updateBy":"admin","updateTime":"2021-09-11 17:52:09","remark":null,"id":71,"articleTitle":"Kubernetes（九）存储映射","articleUrl":"k8s_storage","articleThumbnail":"https://www.asumimoe.com/imgfiles/20220906/f93daad129a04b8db74eed70cd45263b.png","articleFlag":"0","draftStatus":"1","reprintStatement":"1","articleSummary":"容器磁盘上的文件的生命周期是短暂的，这就使得在容器中运行重要应用时会出现一些问题。首先，当容器崩溃时，kubelet会重启它，但是容器中的文件将丢失——容器以干净点状态（镜像最初点状态）重新启动。其次，在pod中同时运行多个容器时，这些容器之间通常需要共享文件。Kubernetes中的volume就能很好的解决了这些问题。","articleContent":"## Volume\n\n容器磁盘上的文件的生命周期是短暂的，这就使得在容器中运行重要应用时会出现一些问题。首先，当容器崩溃时，kubelet会重启它，但是容器中的文件将丢失——容器以干净点状态（镜像最初点状态）重新启动。其次，在pod中同时运行多个容器时，这些容器之间通常需要共享文件。Kubernetes中的volume就能很好的解决了这些问题。\n\nDocker中也有一个volume的概念，尽管它稍微宽松一些，管理也很少。在Docker中，卷就像是磁盘或是另一个容器中的一个目录。它的生命周期不受管理，直到最近才有了local-disk-backed卷。Docker现在提供来卷驱动程序，但是功能还非常有限（例如Docker1.7只允许每个容器使用一个卷驱动，并且无法给卷传递参数）。\n\n另一方面，Kubernetes中的卷有明确的寿命——与封装他的Pod相同。所以，卷的生命比Pod中点所有容器都长，当这个容器重启时数据仍然得以保存。当然，当pod不再存在时，卷也将不复存在。也许更重要点的是，Kubernetes支持多种类型的卷，Pod可以同时使用任意数量的卷。\n\n卷的核心是目录，可能还包含了一些数据，可以通过pod中的容器来访问。该目录是如何形成的、支持该目录的介质以及内容取决于所使用的特定卷类型。\n\n要使用卷，需要为pod指定为卷（spec.volumes 字段）以及将它挂载到容器的位置（spec.containers.volumeMounts 字段）。\n\n容器中的进程看到的是其由Docker镜像和卷组成点文件系统视图。Docker镜像位于文件系统层次结构的根目录，任何卷都被挂载在镜像的指定路径中。卷无法挂载到其他卷上或与其他卷有硬链接。Pod中的每个容器都必须独立指定每个卷的挂载位置。\n\nKubernetes的数据卷实现方式一共四种：\n\n- emptyDir\n- hostPath\n- NFS、Ceph等共享存储\n- PV与PVC\n\n## emptyDir（临时存储卷）\n\n### 介绍\n\nemptyDir 是最基础的 Volume 类型。正如其名字所示，一个 emptyDir Volume 是 Host 上的一个空目录。\n\nemptyDir Volume 对于容器来说是持久的，对于 Pod 则不是。当出于任何原因从节点中删除 Pod 时， emptyDir 中的数据将被永久删除。值得注意的是容器的崩溃并不会导致emptyDir的删除。也就是说：emptyDir Volume 的生命周期与 Pod 一致。Pod 中的所有容器都可以共享 Volume，它们可以指定各自的 mount 路径。\n\n### 实现\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: nginx\nspec:\n  containers:\n  - name: nginx\n    image: nginx\n    imagePullPolicy: IfNotPresent\n    volumeMounts:\n    - name: ken\n      mountPath: /usr/share/nginx/html\n  volumes:\n  - name: ken\n    emptyDir: {}\n```\n\n### 验证\n\n```shell\n\tdocker inspect 937208cf64ee \n\t...\n\t\"Mounts\": [\n\t            {\n\t                \"Type\": \"bind\",\n\t                \"Source\": \"/var/lib/kubelet/pods/704e6443-9b31-45b5-b41d-39e8e84bacb2/volumes/kubernetes.io~empty-dir/ken\",\n\t                \"Destination\": \"/usr/share/nginx/html\",\n\t                \"Mode\": \"\",\n\t                \"RW\": true,\n\t                \"Propagation\": \"rprivate\"\n\t            },\n\t...\n```\n\n## hostPath（节点存储卷）\n\n### 介绍\n\nhostPath类型的存储卷是指将工作节点上某个文件系统的目录或文件挂载于Pod中的一种存储卷，它独立于Pod资源的生命周期，因而具有持久性。但它是工作节点本地的存储空间，仅适用于特定情况下的存储卷使用要求，例如，将工作节点上的文件系统关联为Pod的存储卷，从而使得容器访问节点文件系统上的数据。这一点在运行有管理任务的系统级Pod资源需要访问节点上的文件时尤为有用。\n\nhostPath的用途如如下：\n\n- 运行需要访问Docker内部的容器；使用/var/lib/docker的hostPath\n- 在容器中运行cAdvisor；使用/dev/cgroups的hostPath\n- 运行pod指定给定的hostPath是否应该在pod运行之前存在，是否应该创建，以及它应该以什么形式存在\n\n配置hostPath存储卷点嵌套字段共有两个：一个是用于指定工作节点上点目录路径的必须字段path；另一个是指定存储卷类型的type，它支持使用的卷类型包含以下几种：\n\n- DirectoryCreate：如果在给定的路径上没有任何东⻄存在，那么将根据需要在那⾥创建⼀个空⽬录，权限设置为 0755，与 Kubelet 具有相同的组和所有权；\n- Directory：给定的路径下必须存在⽬录；\n- FileOrCreate：如果在给定的路径上没有任何东⻄存在，那么会根据需要创建⼀个空⽂件，权限设置为0644，与 Kubelet 具有相同的组和所有权；\n- File：给定的路径下必须存在⽂件；\n- Socket：给定的路径下必须存在 UNIX 套接字；\n- CharDevice：给定的路径下必须存在字符设备；\n- BlockDevice：给定的路径下必须存在块设备；\n- “”：空字符串，默认配置，在关联hostPath存储卷之前不进行任何检查\n\n### 实现\n\n```yaml\n[root@k8s-master storage]# cat volumes-hostpath-demo.yaml \napiVersion: v1\nkind: Pod\nmetadata:\n  name: volumes-hostpath-demo\nspec:\n  containers:\n   - name: filebeat\n     image: ikubernetes/filebeat:5.6.7-alpine\n     env:\n     - name: REDIS_HOST\n       value: redis.ilinux.io:6379\n     - name: LOG_LEVEL\n       value: info\n     volumeMounts:\n     - name: varlog\n       mountPath: /var/log\n     - name: socket\n       mountPath: /var/run/docker.sock\n     - name: varlibdockercontainers\n       mountPath: /var/lib/docker/containers\n       readOnly : true\n  volumes:\n  - name: varlog\n    hostPath :\n      path: /var/log   #宿主机上路径\n  - name: varlibdockercontainers\n    hostPath:\n      path: /var/lib/docker/containers #宿主机上路径\n      type: Directory  #目录必须存在\n  - name: socket\n    hostPath:\n      path: /var/run/docker.sock\n```\n\n### 验证\n\n```shell\n[root@k8s-master storage]# kubectl describe pod volumes-hostpath-demo\n...\n    Mounts:  #挂载点\n      /var/lib/docker/containers from varlibdockercontainers (ro)\n      /var/log from varlog (rw)\n      /var/run/docker.sock from socket (rw)\n      /var/run/secrets/kubernetes.io/serviceaccount from default-token-fsshk (ro)\nConditions:\n  Type              Status\n  Initialized       True \n  Ready             True \n  ContainersReady   True \n  PodScheduled      True \nVolumes:\n  varlog:\n    Type:          HostPath (bare host directory volume) #bare host directory volume表示没有做检查\n    Path:          /var/log\n    HostPathType:  \n  varlibdockercontainers:\n    Type:          HostPath (bare host directory volume)\n    Path:          /var/lib/docker/containers\n    HostPathType:  \n  socket:\n    Type:          HostPath (bare host directory volume)\n    Path:          /var/run/docker.sock\n    HostPathType:  \n  default-token-fsshk:\n    Type:        Secret (a volume populated by a Secret)\n```\n\n## NFS\n\nNFS网络文件系统，为众多网络存储中的一种。nfs卷能将NFS挂载到你的pod中。不像emptyDir，当删除Pod时，nfs卷的内容被保留，卷仅仅是被卸载。另外，NFS是文件系统级共享服务，它支持同时存在的多路挂载请求。\n\n注意：要使用nfs,必须先拥有自己的NFS服务器，然后才能使用。\n\n### 实现\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: nginx\nspec:\n  containers:\n  - name: nginx\n\timage: nginx\n\tvolumeMounts:\n\t- name: web-vol\n\t  mountPath: /usr/share/nginx/html\n  volumes:\n  - name: web-vol\n\tnfs:\n\t  path: /nfsshare\n\t  server: 192.168.52.211\n```","categoryId":10,"viewCount":1444,"categoryName":"Kubernetes","author":"球接子","authorAvatar":null,"tagIds":[16],"tagNames":["Kubernetes"]}}