1. 程式人生 > >2018年3月29日 11:02:33 關於docker分享之分布式存儲 glusterfs

2018年3月29日 11:02:33 關於docker分享之分布式存儲 glusterfs

glusterfs k8s docker

2018年3月29日 11:02:33 關於docker分享之分布式存儲 glusterfs
經典語錄:

實際實驗搭建:
前提 是要保證 一個 /data目錄不和根分區在同一個磁盤!
1、centos7安裝glusterfs
參考鏈接:https://wiki.centos.org/SpecialInterestGroup/Storage/gluster-Quickstart
#To Use the RPMs from Storage SIG, you need to install the centos-release-gluster RPM as it will provide the required YUM repository files. This RPM is available from CentOS Extras.

yum install centos-release-gluster -y
yum --enablerepo=centos-gluster*-test install glusterfs-server -y
systemctl enable glusterd
systemctl start glusterd
systemctl status glusterd

2、組建集群(配置信任存儲池):
#從glusterfs官網跳轉過來的
技術分享圖片

[root@docker1 ~]# ping docker2       #確保hostname可以通訊
PING dubbo2 (192.168.0.78) 56(84) bytes of data.
64 bytes from dubbo2 (192.168.0.78): icmp_seq=1 ttl=64 time=0.200 ms
64 bytes from dubbo2 (192.168.0.78): icmp_seq=2 ttl=64 time=0.167 ms
64 bytes from dubbo2 (192.168.0.78): icmp_seq=3 ttl=64 time=0.191 ms
^C
--- dubbo2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.167/0.186/0.200/0.013 ms
[root@docker1 ~]# gluster peer probe docker2
peer probe: success.                           #建立集群成功!
#驗證檢查  docker2和docker1建立集群成功!
[root@docker1 ~]# gluster peer status
Number of Peers: 1
Hostname: docker2
Uuid: e675b971-b503-4342-82ff-182858656282
State: Peer in Cluster (Connected)

[root@docker2 ~]# gluster peer status
Number of Peers: 1
Hostname: docker1
Uuid: 283ff245-7adf-4359-98c7-873cfcaa4a13
State: Peer in Cluster (Connected)

3、建立 GlusterFS volume

On both docker1 and docker2:

[root@docker1 ~]# mkdir -p /data/brick1/gv0

[root@docker2 ~]# mkdir -p /data/brick1/gv0

From any single server:

[root@docker1 ~]# gluster volume create gv0 replica 2 docker1:/data/brick1/gv0
Replica 2 volumes are prone to split-brain. Use Arbiter or Replica 3 to avoid this. See: http://docs.gluster.org/en/latest/Administrator%20Guide/Split%20brain%20and%20ways%20to%20deal%20with%20it/.
Do you still want to continue?           #上述提示是2臺集群有腦裂的風險,建議3臺建群,有自動選舉決策能力
(y/n) y
volume create: gv0: success: please start the volume to access data
[root@docker1 ~]# gluster volume start gv0
volume start: gv0: success

#查看一下
[root@docker1 ~]# gluster volume info
Volume Name: gv0
Type: Replicate
Volume ID: 47a40786-eb5e-4845-b324-6feb4557d428
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: docker1:/data/brick1/gv0
Brick2: docker2:/data/brick1/gv0
Options Reconfigured:
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off

4、客戶端使用

yum install centos-release-gluster -y
yum -y install glusterfs-fuse  #glusterfs-client和glusterfs-fuse等價,其實都是安裝的glusterfs-fuse!

#如果客戶端不安裝gluster-fuse,其實還可以以nfs協議傳輸,也就是把glusterfs當作nfs來用!(這裏埋個伏筆,馬上後面有講到)

原理等:
拓展研究的網址:
http://gluster.readthedocs.io/en/latest/Quick-Start-Guide/Architecture/ #英文講解,最正宗!(其實網頁翻譯後一樣 0.0)
https://www.ibm.com/developerworks/cn/opensource/os-cn-glusterfs-docker-volume/index.html #中文版可能好看些

前面是基礎部分了,相信群裏大家都會安裝的了,很簡單的分布式存儲,其實比起nfs來說可能還要更加的簡單!
為了填充下篇幅,特盜取上述網址的圖片來講講glusterfs的原理和我的理解(其實還參考了老男孩架構班glusterfs的講解):

企業級的容器應用常常需要將重要的數據持久化,方便在不同容器間共享。為了能夠持久化數據以及共享容器間的數據,Docker 提出了 Volume 的概念。單機環境的數據卷難以滿足 Docker 集群化的要求,因此需要引入分布式文件系統。目前開源的分布式文件系統有許多,例如 GFS,Ceph,HDFS,FastDFS,GlusterFS 等。GlusterFS 因其部署簡單、擴展性強、高可用等特點,在分布式存儲領域被廣泛使用。本文主要介紹了如何利用 GlusterFS 為 Docker 集群提供可靠的分布式文件存儲。

GlusterFS 概述
GlusterFS (Gluster File System) 是一個開源的分布式文件系統。
GlusterFS 總體架構與組成部分如圖1所示,它主要由存儲服務器(Brick Server)、客戶端以及 NFS/Samba 存儲網關組成。
技術分享圖片
不難發現,GlusterFS 架構中沒有元數據服務器組件(這個是對比fastdfs來說的,其實我對那個也了解不深,姑且認為會一個就得了把,其實可以理解這段是廢話,你就認為它性能好就行了!),這是其最大的設計這點,對於提升整個系統的性能、可靠性和穩定性都有著決定性的意義。

  • GlusterFS 支持 TCP/IP 和 InfiniBand RDMA 高速網絡互聯。
  • 客戶端可通過原生 GlusterFS 協議訪問數據,其他沒有運行 GlusterFS 客戶端的終端可通過 NFS/CIFS 標準協議通過存儲網關訪問數據(存儲網關提供彈性卷管理和訪問代理功能)。
  • 存儲服務器主要提供基本的數據存儲功能,客戶端彌補了沒有元數據服務器的問題,承擔了更多的功能,包括數據卷管理、I/O 調度、文件定位、數據緩存等功能,利用 FUSE(File system in User Space)模塊(所以客戶端使用需要安裝glusterfs-fuse)將 GlusterFS 掛載到本地文件系統之上,實現 POSIX 兼容的方式來訪問系統數據。


重點來了,
GlusterFS卷類型

為了滿足不同應用對高性能、高可用的需求,GlusterFS 支持 7 種卷,即 distribute 卷、stripe 卷、replica 卷、distribute stripe 卷、distribute replica 卷、stripe Replica 卷、distribute stripe replica 卷。其實不難看出,GlusterFS 卷類型實際上可以分為 3 種基本卷和 4 種復合卷,每種類型的卷都有其自身的特點和適用場景。(怎麽說呢,我的理解就是raid磁盤系列,每種都有自己的優缺點,你根據需求是性能還是擴容,隨便選用即可! 只要關註前面的三種基本卷就行了,後面的反正也是前面的組合混搭,至少我覺得後面幾種卷用的應該不太多把。。。)
技術分享圖片

###For example to create a distributed volume with four storage servers using TCP.
gluster volume create test-volume server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4 Creation of test-volume has been successful Please start the volume to access data

別人的小結:基於 Hash 算法將文件分布到所有 brick server,只是擴大了磁盤空間,不具備容錯能力。由於distribute volume 使用本地文件系統,因此存取效率並沒有提高,相反會因為網絡通信的原因使用效率有所降低,另外本地存儲設備的容量有限制,因此支持超大型文件會有一定難度。
技術分享圖片

###For example, to create a replicated volume with two storage servers:
gluster volume create test-volume replica 2 transport tcp server1:/exp1 server2:/exp2
Creation of test-volume has been successful
Please start the volume to access data

別人的小結:文件同步復制到多個 brick 上,文件級 RAID1,具有容錯能力,寫性能下降,讀性能提升。Replicated 模式,也稱作 AFR(Auto File Replication),相當於 RAID1,即同一文件在多個鏡像存儲節點上保存多份,每個 replicated 子節點有著相同的目錄結構和文件,replica volume 也是在容器存儲中較為推崇的一種。

這個用法需要註意的地方就是 中間指定卷類型如果為n個副本,則後面必須接對應n個 節點地址;
假如你前面指定4個副本,後面接的2個pv地址,那麽就是raid0+1了,即後面所謂的復合卷 distribute stripe volume.
假如你前面指定2個副本,後面接的4個節點地址,即下面所謂的基礎卷 Distributed Replicated Glusterfs Volume.
技術分享圖片

###For example, four node distributed (replicated) volume with a two-way mirror:
gluster volume create test-volume replica 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4 
Creation of test-volume has been successful Please start the volume to access data

別人的小結:Brick server 數量是條帶數的倍數,兼具 distribute 和 stripe 卷的特點。分布式的條帶卷,volume 中 brick 所包含的存儲服務器數必須是 stripe 的倍數(>=2倍),兼顧分布式和條帶式的功能。每個文件分布在四臺共享服務器上,通常用於大文件訪問處理,最少需要 4 臺服務器才能創建分布條帶卷。
技術分享圖片

###For example, to create a striped volume across two storage servers:
gluster volume create test-volume stripe 2 transport tcp server1:/exp1 server2:/exp2
Creation of test-volume has been successful
Please start the volume to access data

別人的小結:類似 RAID0,文件分成數據塊以 Round Robin 方式分布到 brick server 上,並發粒度是數據塊,支持超大文件,大文件的讀寫性能高。

GlusterFS 客戶端常用命令: (創建信任集群後,在任意一個節點執行下面命令,集群全部配置生效,這句話或許說的不夠準確呢!)

命令 功能
gluster peer probe 添加節點
gluster peer detach 移除節點
gluster volume create 創建卷
gluster volume start 啟動卷
gluster volume stop 停止卷
gluster volume delete 刪除卷


其實上面說了這麽多,也就是打個基礎和鋪墊,對於今天的標題來說,這才是重點!!!

基於docker的持久化,如果要使用到glusterfs必須安裝別人寫的第三方插件,(我覺得主要是docker懶,沒有出系統化的持久化方案,或許未來更新叠代應該也不會有了,因為有k8s了,哈哈哈!)
摘抄如下:接下來,我們再來看GlusterFS如何作為Docker的存儲。Docker Volume是一種可以將容器以及容器生產的數據分享開來的數據格式,我們可以使用宿主機的本地存儲作為Volume的提供方,也可以使用Volume Plugin接入許多第三方的存儲。 GitHub就有一個Docker GlusterFS Volume Plugin,方便我們將GlusterFS掛載到容器中。
原文:https://www.ibm.com/developerworks/cn/opensource/os-cn-glusterfs-docker-volume/index.html (也就是上面的中文拓展網址)

基於k8s編排工具的持久化,k8s是原生就支持glusterfs的存儲驅動的,當然k8s還支持別的很多種存儲驅動,今天就講講它算了。
安裝好k8s後,直接部署下面幾個文件即可!

[root@docker3 glusterfs]# cat glusterfs-pvc.yaml    #先創建pv,再創建pvc。比如創建個100G的大磁盤,裏面分個50G的分區出來!用的是分區名字。
apiVersion: v1
kind: PersistentVolume
metadata:
  name: gluster-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  glusterfs:
    endpoints: "glusterfs-cluster"
    path: "gv0"
    readOnly: false
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: glusterfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

[root@docker3 glusterfs]# cat glusterfs-endpoints.json  #ep的意思其實就是指定glusterfs集群的節點ip地址
{
  "kind": "Endpoints",
  "apiVersion": "v1",
  "metadata": {
    "name": "glusterfs-cluster"
  },
  "subsets": [
    {
      "addresses": [
        {
          "ip": "192.168.0.78"
        }
      ],
      "ports": [
        {
          "port": 1
        }
      ]
    },
    {
      "addresses": [
        {
          "ip": "192.168.0.101"
        }
      ],
      "ports": [
        {
          "port": 1
        }
      ]
    }
  ]
}

[root@docker3 glusterfs]# cat glusterfs-service.json   #svc主要就是把容器和應用給發布出去,比如通過cluster(集群)的port(端口) 1就能訪問到了
{
  "kind": "Service",
  "apiVersion": "v1",
  "metadata": {
    "name": "glusterfs-cluster"
  },
  "spec": {
    "ports": [
      {"port": 1}
    ]
  }
}

[root@docker3 glusterfs]# cat nginx-deployment.yaml #dep主要的作用就是部署任務了。
apiVersion: extensions/v1beta1
kind: Deployment      #部署一個nginx到k8s集群
metadata:
  name: nginx-deployment
spec:
  replicas: 3                #副本為3
  template:
    metadata:
      labels:
        app: nginx          #標簽是app:nginx
    spec:
      containers:
      - name: nginx
        image: nginx       #鏡像是nginx:laster,拉取最新的nginx鏡像
        volumeMounts:
        - name: glusterfsvol
          mountPath: /usr/share/nginx/html   #掛載到容器的位置
        ports:
        - containerPort: 80
      volumes:
      - name: glusterfsvol
        glusterfs:
          endpoints: glusterfs-cluster  #這裏就和上面第三步創建的的ep的name必須對應,不然就報錯!
          path: gv0                               #這是glusterfs的pvc名稱,也就是第一步創建的那個
          readOnly: false                      #並不是只讀

---

apiVersion: v1
kind: Service             #發布服務svc,讓外界能訪問到容器
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx             #這個標簽就是匹配上面發布nginx的那個標簽!
  ports:
  - name: http
    port: 80                 #外界訪問cluster集群的 端口是80
    protocol: TCP        
    targetPort: 80       #外界訪問pod的端口是 80
  type: NodePort       #其實這裏還有個nodeport,也就是訪問node節點的端口,既然沒有指定端口的話,部署就應該是隨機指定一個,特點好像是5位數的端口。(後面驗證了一下,Kubernetes 會從 30000-32767 中分配一個可用的端口??? 我也不懂為啥我的實驗不一致呢?或者說前面這個說法是錯的。埋坑!!!)

填坑:
我自己自定義了端口範圍。。。
技術分享圖片
總的來說,port和nodePort都是service的端口,前者暴露給集群內客戶訪問服務,後者暴露給集群外客戶訪問服務。從這兩個端口到來的數據都需要經過反向代理kube-proxy流入後端pod的targetPod,從而到達pod上的容器內。

實驗結果:

[root@docker3 PV]# kubectl get all -o wide
NAME                      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINERS   IMAGES    SELECTOR
deploy/nginx-deployment   3         3         3            3           22m       nginx        nginx     app=nginx

NAME                             DESIRED   CURRENT   READY     AGE       CONTAINERS   IMAGES    SELECTOR
rs/nginx-deployment-5b87cb9b85   3         3         3         22m       nginx        nginx     app=nginx,pod-template-hash=1643765641

NAME                      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINERS   IMAGES    SELECTOR
deploy/nginx-deployment   3         3         3            3           22m       nginx        nginx     app=nginx

NAME                             DESIRED   CURRENT   READY     AGE       CONTAINERS   IMAGES    SELECTOR
rs/nginx-deployment-5b87cb9b85   3         3         3         22m       nginx        nginx     app=nginx,pod-template-hash=1643765641

NAME                                   READY     STATUS    RESTARTS   AGE       IP            NODE
po/nginx-deployment-5b87cb9b85-49lmx   1/1       Running   0          22m       172.17.23.7   192.168.0.101
po/nginx-deployment-5b87cb9b85-8php8   1/1       Running   0          22m       172.17.23.2   192.168.0.101
po/nginx-deployment-5b87cb9b85-phl87   1/1       Running   0          22m       172.17.35.3   192.168.0.78

NAME                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE       SELECTOR
svc/glusterfs-cluster   ClusterIP   10.10.10.246   <none>        1/TCP          8d        <none>
svc/kubernetes          ClusterIP   10.10.10.1     <none>        443/TCP        12d       <none>
svc/nginx-service       NodePort    10.10.10.149   <none>        80:36914/TCP   22m       app=nginx

That‘s ALL!
Thankyou!

2018年3月29日 11:02:33 關於docker分享之分布式存儲 glusterfs