Kubernetes技术分析之存储

来源:互联网 发布:小学生绘画软件下载 编辑:程序博客网 时间:2024/05/01 04:59

概述

Docker的流行激活了一直不温不火的PaaS,随着而来的是各类Micro-PaaS的出现,Kubernetes是其中最具代表性的一员,它是Google多年大规模容器管理技术的开源版本。本系列文章将逐一分析Kubernetes,本文详细介绍如何使用Kubernetes支持的几种Volume。

Kubernetes存储

众所周知,使用Docker的时候,容器中的数据是临时,即当容器销毁时,其中的数据时丢失。如果需要持久化数据,需要使用Docker Volume挂载宿主机上的文件目录到容器中。Kubernetes中的Volume则是基于Docker进行扩展,支持更加丰富的功能,Kubernetes支持以下类型的Volume:

emptyDir

如果Pod配置了emptyDir类型Volume, Pod 被分配到Node上时候,会创建emptyDir,只要Pod运行在Node上,emptyDir都会存在(容器挂掉不会导致emptyDir丢失数据),但是如果Pod从Node上被删除(Pod被删除,或者Pod发生迁移),emptyDir也会被删除,并且永久丢失。
现在创建一个Pod使用emptyDir, busybox-pod.yaml:

apiVersion: v1kind: Podmetadata:  name: busybox  labels:    name: busyboxspec:  containers:    - image: busybox      command:        - sleep        - "3600"      imagePullPolicy: IfNotPresent      name: busybox      volumeMounts:        - mountPath: /busybox-data          name: data  volumes:    - name: data      emptyDir: {}

Pod运行后,docker inspect它的容器:

    "Volumes": {        "/busybox-data": "/var/lib/kubelet/pods/da47d6b1-374c-11e5-ad0f-005056817c3e/volumes/kubernetes.io~empty-dir/data",        "/dev/termination-log": "/var/lib/kubelet/pods/da47d6b1-374c-11e5-ad0f-005056817c3e/containers/busybox/4f4c540ea667e78fca68886d5b5700abb652523dc39d3ca36bb2573ea016be21"    },    "VolumesRW": {        "/busybox-data": true,        "/dev/termination-log": true    },    "VolumesRelabel": {        "/busybox-data": "",        "/dev/termination-log": ""    }

可以看到容器挂载配置的emptyDir:

/var/lib/kubelet/pods/<id>/volumes/kubernetes.io~empty-dir/data =》 /busybox-data

hostPath

hostPath允许挂载Node上的文件系统到Pod里面去。如果Pod有需要使用Node上的东西,可以使用hostPath,不过不过建议使用,因为理论上Pod不应该感知Node的。
busybox-pod.yaml:

apiVersion: v1kind: Podmetadata:  name: busybox  labels:    name: busyboxspec:  containers:    - image: busybox      command:        - sleep        - "3600"      imagePullPolicy: IfNotPresent      name: busybox      volumeMounts:        - mountPath: /busybox-data          name: data  volumes:  - hostPath:      path: /tmp/data    name: data

docker inspect:

   "Volumes": {        "/busybox-data": "/tmp/data",        "/dev/termination-log": "/var/lib/kubelet/pods/522b7dd3-374f-11e5-ad0f-005056817c3e/containers/busybox/d6b5adcaf869ad290a3c4602313fc813451eabcc47d4583ee6dd4f6ba9fd8009"    },    "VolumesRW": {        "/busybox-data": true,        "/dev/termination-log": true    },    "VolumesRelabel": {        "/busybox-data": "",        "/dev/termination-log": ""    }

emptyDir和hostPat很多场景是无法满足持久化需求,因为在Pod发生迁移的时候,数据都无法进行转移的,这就需要分布式文件系统的支持。

nfs

NFS 是Network File System的缩写,即网络文件系统。Kubernetes中通过简单地配置就可以挂载NFS到Pod中,而NFS中的数据是可以永久保存的,同时NFS支持同时写操作。
下面的例子将在Kubernetes上部署一个NFS服务端,然后部署一个Pod使用该NFS服务端
nfs-server-pod.yaml:

apiVersion: v1kind: Podmetadata:  name: nfs-server  labels:    role: nfs-serverspec:  containers:    - name: nfs-server      image: jsafrane/nfs-data      ports:        - name: nfs          containerPort: 2049      securityContext:        privileged: true

注意:运行nfs-server-pod需要kubelet开启privileged

nfs-service.yaml:

kind: ServiceapiVersion: v1metadata:  name: nfs-serverspec:  clusterIP: 10.254.234.223  ports:    - port: 2049  selector:    role: nfs-server

创建完可以查看下NFS的配置:

$ kubectl exec nfs-server cat /etc/exports  /mnt/data *(rw,sync,no_root_squash,insecure,fsid=0)$ kubectl exec nfs-server cat /mnt/data/index.htmlHello world!

可以看到export了/mnt/data最为/, 并且/mnt/data下有个index.html

NFS 服务端安装完成后,需要在Kubernetes的每个Node安装NF客户端:

$ yum install nfs-utils

现在创建一个Pod使用NFS:

apiVersion: v1kind: Podmetadata:  name: nfs-webspec:  containers:    - name: web      image: nginx       ports:        - name: web          containerPort: 80      volumeMounts:          # name must match the volume name below          - name: nfs            mountPath: "/usr/share/nginx/html"  volumes:    - name: nfs      nfs:        # FIXME: use the right hostname        server: 10.254.234.223        path: "/"

该Pod启动一个nginx,然后挂载NFS Server的/到/usr/share/nginx/html, 即使用其中的index.html。

查看Pod的容器,可以看到容器挂载
/var/lib/kubelet/pods/<id>/volumes/kubernetes.io~nfs/nfs=> /usr/share/nginx/html

而实际上/var/lib/kubelet/pods//volumes/kubernetes.io~nfs/nfs挂载到NFS Server,效果如以下命令:

mount -t nfs 10.254.234.223:/ /var/lib/kubelet/pods/<id>/volumes/kubernetes.io~nfs/nfs

glusterfs

GlusterFS是一个开源的分布式文件系统,具有强大的横向扩展能力,通过扩展能够支持数PB存储容量和处理数千客户端。同样地,Kubernetes支持Pod挂载到GlusterFS,这样数据将会永久保存。
首先需要一个GlusterFS环境,本文使用2台机器(CentOS7)安装GlusterFS服务端,在2台机器的 /etc/hosts配置以下信息:

192.168.3.150    gfs1192.168.3.151    gfs2

在2台机器上安装:

$ wget http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm$ rpm -ivh epel-release-7-5.noarch.rpm$ wget -P /etc/yum.repos.d http://download.gluster.org/pub/gluster/glusterfs/LATEST/EPEL.repo/glusterfs-epel.repo$ yum install glusterfs-server$ service glusterd start

注意: GlusterFS服务端需要关闭SELinux:修改/etc/sysconfig/selinux中SELINUX=disabled。然后清空iptables: iptables -F

安装后查询状态:

$ service glusterd status

添加集群:
在gfs1上操作:

$ gluster peer probe gfs2

在gfs2上操作:

$ gluster peer probe gfs1

创建volume :
在gfs1上操作:

$ mkdir /data/brick/gvol0$ gluster volume create gvol0 replica 2 gfs1:/data/brick/gvol0 gfs2:/data/brick/gvol0$ gluster volume start gvol0$ gluster volume info

安装成功的话可以挂载试验下:

$ mount -t glusterfs gfs1:/gvol0 /mnt
GlusterFS服务端安装成功后,需要在每个Node上安装GlusterFS客户端:
$ yum install glusterfs-client

接着创建GlusterFS Endpoint,gluasterfs-endpoints.json:

{  "kind": "Endpoints",  "apiVersion": "v1",  "metadata": {    "name": "glusterfs-cluster"  },  "subsets": [    {      "addresses": [        {          "IP": "192.168.3.150"        }      ],      "ports": [        {          "port": 1        }      ]    },    {      "addresses": [        {          "IP": "192.168.3.151"        }      ],      "ports": [        {          "port": 1        }      ]    }  ]}

最后创建一个Pod挂载GlusterFS Volume, busybox-pod.yaml:

apiVersion: v1kind: Podmetadata:  name: busybox  labels:    name: busyboxspec:  containers:    - image: busybox      command:        - sleep        - "3600"      imagePullPolicy: IfNotPresent      name: busybox      volumeMounts:        - mountPath: /busybox-data          name: data  volumes:  - glusterfs:      endpoints: glusterfs-cluster      path: gvol0    name: data

查看Pod的容器,可以看到容器挂载

/var/lib/kubelet/pods/<id>/volumes/kubernetes.io~glusterfs/data => /busybox-data

在kubernetes.io~glusterfs/data目录下执行查询:

$ mount | grep gvol0192.168.3.150:gvol0 on /var/lib/kubelet/pods/<id>/volumes/kubernetes.io~glusterfs/data type fuse.glusterfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072)

参考

  • http://kubernetes.io/v1.0/docs/user-guide/volumes.html
  • http://kubernetes.io/v1.0/examples/nfs/
  • http://kubernetes.io/v1.0/examples/glusterfs/
  • http://linoxide.com/file-system/install-configure-glusterfs-centos-7-aarch64/

作者简介

吴龙辉,现任网宿科技高级运营工程师,致力于云计算PaaS的研究和实践,活跃于CloudFoundry,Docker,Kubernetes等开源社区,贡献代码和撰写技术文档。
邮箱:wulh@chinanetcenter.com/wlh6666@qq.com

0 0