# Kubernetes 中使用 Gluster FS

以 RC 形式运行在 Kubernetes 集群中的 Pod，会因为 Scale 等需要在不同的 Node 之间发生迁移，因此需要有独立于 Node 文件系统的共享存储服务，同时这一存储服务也应该符合集群的运行需要，简单的 NFS 不管是效率上还是可靠性上，都是不具备这一能力的。这里以 [Gluster FS](https://www.gluster.org/)  作为存储引擎，为容器集群提供云存储服务。

K8S 的存储卷使用稍有点古怪，Gluster FS 的使用，需要首先定义一个 [Endpoint + Service](http://kubernetes.io/docs/user-guide/services/) 形式的代理，来定义 Gluster FS 集群，然后就可以通过[持久卷](http://blog.fleeto.us/translation/persistent-volumes)或者用 Pod 直接加载了。

## 定义 Service

首先用一个 YML 文件来定义 Endpoint 和 Service：

~~~yaml
---
kind: List
apiVersion: v1
items:
- kind: Endpoints
  apiVersion: v1
  metadata:
    name: service_name
  subsets:
  - addresses:
    - ip: 12.34.56.78
    ports:
    - port: 111
- kind: Service
  apiVersion: v1
  metadata:
    name: service_name
  spec:
    ports:
      - port: 111
~~~

- Port 可随意填写
- Service Name 需要一致，这个值将会用到后面的引用中
- ip：Gluster FS 的 IP 地址

定义文件生成结束后，利用 `kubectl create -f xx.yaml` 的方式加载到集群之中。可以用 `kubectl get svc,endpoints` 来验证结果。

接下来有两种加载方式可以选择：持久卷和 Pod 直接加载。

## Pod 直接加载

可以在 Pod 中直接定义一个 Gluster FS 格式的卷来进行加载：

~~~yaml
spec:
containers:
- name: nginx-docker-images
  image: nginx:latest
  volumeMounts:
    - mountPath: /glusterfs
      name: test-volume
volumes:
  - name: test-volume
    glusterfs:
      endpoints: glusterfs-cluster
      path: gv0
      readOnly: false
~~~

- endpoints: 这里指定的就是上一届中定义的服务名称
- path: gluster fs 中的卷名称
- readOnly: 是否只读加载

## 持久卷加载

首先定义一个持久卷：

~~~yaml
kind: PersistentVolume
apiVersion: v1
metadata:
  name: gluster-volumen-gv01
spec:
  capacity:
    storage: 1Mi
  accessModes:
    - ReadWriteMany
  glusterfs:
    endpoints: glusterfs-svc
    path: gv0
~~~

内容同上面的 Pod 卷定义大同小异，具体参数可以参考持久卷的相关文档。

然后定义一个 PVC

~~~yaml
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaim2m
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 2Mi
~~~

最后，在 Pod 中利用 PVC 来进行卷加载

~~~yaml
volumes:
  - name: test-volume
    persistentVolumeClaim:
      # 上面定义的 PVC 名称
      claimName: myclaim1m
~~~
