# 在OpenShift中使用GlusterFS做持久化存儲
### 概述
本文由Daniel Messer(Technical Marketing Manager Storage @RedHat)和Keith Tenzer(Solutions Architect @RedHat)共同撰寫。
- [Storage for Containers Overview – Part I](https://keithtenzer.com/2017/03/07/storage-for-containers-overview-part-i/)
- [Storage for Containers using Gluster – Part II](https://keithtenzer.com/2017/03/24/storage-for-containers-using-gluster-part-ii/)
- [Storage for Containers using Container Native Storage – Part III](https://keithtenzer.com/2017/03/29/storage-for-containers-using-container-native-storage-part-iii/)
- [Storage for Containers using Ceph – Part IV](https://keithtenzer.com/2017/04/07/storage-for-containers-using-ceph-rbd-part-iv/)
- [Storage for Containers using NetApp ONTAP NAS – Part V](https://keithtenzer.com/2017/04/05/storage-for-containers-using-netapp-ontap-nas-part-v/)
- [Storage for Containers using NetApp SolidFire – Part VI](https://keithtenzer.com/2017/04/05/storage-for-containers-using-netapp-solidfire-part-vi/)
### Gluster作為Container-Ready Storage(CRS)
在本文中,我們將介紹容器存儲的首選以及如何部署它。 Kusternet和OpenShift支持GlusterFS已經有一段時間了。 GlusterFS的適用性很好,可用于所有的部署場景:裸機、虛擬機、內部部署和公共云。 在容器中運行GlusterFS的新特性將在本系列后面討論。
GlusterFS是一個分布式文件系統,內置了原生協議(GlusterFS)和各種其他協議(NFS,SMB,...)。 為了與OpenShift集成,節點將通過FUSE使用原生協議,將GlusterFS卷掛在到節點本身上,然后將它們綁定到目標容器中。 OpenShift / Kubernetes具有實現請求、釋放和掛載、卸載GlusterFS卷的原生程序。
### CRS概述
在存儲方面,根據OpenShift / Kubernetes的要求,還有一個額外的組件管理集群,稱為“heketi”。 這實際上是一個用于GlusterFS的REST API,它還提供CLI版本。 在以下步驟中,我們將在3個GlusterFS節點中部署heketi,使用它來部署GlusterFS存儲池,將其連接到OpenShift,并使用它來通過PersistentVolumeClaims為容器配置存儲。 我們將總共部署4臺虛擬機。 一個用于OpenShift(實驗室設置),另一個用于GlusterFS。
注意:您的系統應至少需要有四核CPU,16GB RAM和20 GB可用磁盤空間。
### 部署OpenShift
首先你需要先部署OpenShift。最有效率的方式是直接在虛擬機中部署一個All-in-One環境,部署指南見 [the “OpenShift Enterprise 3.4 all-in-one Lab Environment” article.](https://keithtenzer.com/2017/03/13/openshift-enterprise-3-4-all-in-one-lab-environment/)。
確保你的OpenShift虛擬機可以解析外部域名。編輯`/etc/dnsmasq.conf`文件,增加下面的Google DNS:
```ini
server=8.8.8.8
```
重啟:
```bash
# systemctl restart dnsmasq
# ping -c1 google.com
```
### 部署Gluster
GlusterFS至少需要有以下配置的3臺虛擬機:
- RHEL 7.3
- 2 CPUs
- 2 GB內存
- 30 GB磁盤存儲給操作系統
- 10 GB磁盤存儲給GlusterFS bricks
修改/etc/hosts文件,定義三臺虛擬機的主機名。
例如(主機名可以根據你自己的環境自由調整)
```bash
# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.16.99.144 ocp-master.lab ocp-master
172.16.128.7 crs-node1.lab crs-node1
172.16.128.8 crs-node2.lab crs-node2
172.16.128.9 crs-node3.lab crs-node3
```
**在3臺GlusterFS虛擬機上都執行以下步驟**:
```bash
# subscription-manager repos --disable="*"
# subscription-manager repos --enable=rhel-7-server-rpms
```
如果你已經訂閱了GlusterFS那么可以直接使用,開啟`rh-gluster-3-for-rhel-7-server-rpms`的yum源。
如果你沒有的話,那么可以通過EPEL使用非官方支持的GlusterFS的社區源。
```bash
# yum -y install http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
# rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7
```
在`/etc/yum.repos.d/`目錄下創建`glusterfs-3.10.repo`文件:
```ini
[glusterfs-3.10]
name=glusterfs-3.10
description="GlusterFS 3.10 Community Version"
baseurl=https://buildlogs.centos.org/centos/7/storage/x86_64/gluster-3.10/
gpgcheck=0
enabled=1
```
驗證源已經被激活。
```Bash
# yum repolist
```
現在可以開始安裝GlusterFS了。
```bash
# yum -y install glusterfs-server
```
需要為GlusterFS peers打開幾個基本TCP端口,以便與OpenShift進行通信并提供存儲:
```bash
# firewall-cmd --add-port=24007-24008/tcp --add-port=49152-49664/tcp --add-port=2222/tcp
# firewall-cmd --runtime-to-permanent
```
現在我們可以啟動GlusterFS的daemon進程了:
```bash
# systemctl enable glusterd
# systemctl start glusterd
```
完成。GlusterFS已經啟動并正在運行。其他配置將通過heketi完成。
**在GlusterFS的一臺虛擬機上安裝heketi**
```bash
[root@crs-node1 ~]# yum -y install heketi heketi-client
```
### 更新EPEL
如果你沒有Red Hat Gluster Storage訂閱的話,你可以從EPEL中獲取heketi。 在撰寫本文時,2016年10月那時候還是3.0.0-1.el7版本,它不適用于OpenShift 3.4。 你將需要更新到更新的版本:
```bash
[root@crs-node1 ~]# yum -y install wget
[root@crs-node1 ~]# wget https://github.com/heketi/heketi/releases/download/v4.0.0/heketi-v4.0.0.linux.amd64.tar.gz
[root@crs-node1 ~]# tar -xzf heketi-v4.0.0.linux.amd64.tar.gz
[root@crs-node1 ~]# systemctl stop heketi
[root@crs-node1 ~]# cp heketi/heketi* /usr/bin/
[root@crs-node1 ~]# chown heketi:heketi /usr/bin/heketi*
```
在`/etc/systemd/system/heketi.service`中創建v4版本的heketi二進制文件的更新語法文件:
```ini
[Unit]
Description=Heketi Server
[Service]
Type=simple
WorkingDirectory=/var/lib/heketi
EnvironmentFile=-/etc/heketi/heketi.json
User=heketi
ExecStart=/usr/bin/heketi --config=/etc/heketi/heketi.json
Restart=on-failure
StandardOutput=syslog
StandardError=syslog
[Install]
WantedBy=multi-user.target
```
```bash
[root@crs-node1 ~]# systemctl daemon-reload
[root@crs-node1 ~]# systemctl start heketi
```
Heketi使用SSH來配置GlusterFS的所有節點。創建SSH密鑰對,將公鑰拷貝到所有3個節點上(包括你登陸的第一個節點):
```bash
[root@crs-node1 ~]# ssh-keygen -f /etc/heketi/heketi_key -t rsa -N ''
[root@crs-node1 ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@crs-node1.lab
[root@crs-node1 ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@crs-node2.lab
[root@crs-node1 ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@crs-node3.lab
[root@crs-node1 ~]# chown heketi:heketi /etc/heketi/heketi_key*
```
剩下唯一要做的事情就是配置heketi來使用SSH。 編輯`/etc/heketi/heketi.json`文件使它看起來像下面這個樣子(改變的部分突出顯示下劃線):
```json
{
"_port_comment":"Heketi Server Port Number",
"port":"8080",
"_use_auth":"Enable JWT authorization. Please enable for deployment",
"use_auth":false,
"_jwt":"Private keys for access",
"jwt":{
"_admin":"Admin has access to all APIs",
"admin":{
"key":"My Secret"
},
"_user":"User only has access to /volumes endpoint",
"user":{
"key":"My Secret"
}
},
"_glusterfs_comment":"GlusterFS Configuration",
"glusterfs":{
"_executor_comment":[
"Execute plugin. Possible choices: mock, ssh",
"mock: This setting is used for testing and development.",
" It will not send commands to any node.",
"ssh: This setting will notify Heketi to ssh to the nodes.",
" It will need the values in sshexec to be configured.",
"kubernetes: Communicate with GlusterFS containers over",
" Kubernetes exec api."
],
"executor":"ssh",
"_sshexec_comment":"SSH username and private key file information",
"sshexec":{
"keyfile":"/etc/heketi/heketi_key",
"user":"root",
"port":"22",
"fstab":"/etc/fstab"
},
"_kubeexec_comment":"Kubernetes configuration",
"kubeexec":{
"host":"https://kubernetes.host:8443",
"cert":"/path/to/crt.file",
"insecure":false,
"user":"kubernetes username",
"password":"password for kubernetes user",
"namespace":"OpenShift project or Kubernetes namespace",
"fstab":"Optional: Specify fstab file on node. Default is /etc/fstab"
},
"_db_comment":"Database file name",
"db":"/var/lib/heketi/heketi.db",
"_loglevel_comment":[
"Set log level. Choices are:",
" none, critical, error, warning, info, debug",
"Default is warning"
],
"loglevel":"debug"
}
}
```
完成。heketi將監聽8080端口,我們來確認下防火墻規則允許它監聽該端口:
```bash
# firewall-cmd --add-port=8080/tcp
# firewall-cmd --runtime-to-permanent
```
重啟heketi:
```bash
# systemctl enable heketi
# systemctl restart heketi
```
測試它是否在運行:
```bash
# curl http://crs-node1.lab:8080/hello
Hello from Heketi
```
很好。heketi上場的時候到了。 我們將使用它來配置我們的GlusterFS存儲池。 該軟件已經在我們所有的虛擬機上運行,但并未被配置。 要將其改造為滿足我們需求的存儲系統,需要在拓撲文件中描述我們所需的GlusterFS存儲池,如下所示:
```bash
# vi topology.json
{
"clusters": [
{
"nodes": [
{
"node": {
"hostnames": {
"manage": [
"crs-node1.lab"
],
"storage": [
"172.16.128.7"
]
},
"zone": 1
},
"devices": [
"/dev/sdb"
]
},
{
"node": {
"hostnames": {
"manage": [
"crs-node2.lab"
],
"storage": [
"172.16.128.8"
]
},
"zone": 1
},
"devices": [
"/dev/sdb"
]
},
{
"node": {
"hostnames": {
"manage": [
"crs-node3.lab"
],
"storage": [
"172.16.128.9"
]
},
"zone": 1
},
"devices": [
"/dev/sdb"
]
}
]
}
]
}
```
該文件格式比較簡單,基本上是告訴heketi要創建一個3節點的集群,其中每個節點包含的配置有FQDN,IP地址以及至少一個將用作GlusterFS塊的備用塊設備。
現在將該文件發送給heketi:
```bash
# export HEKETI_CLI_SERVER=http://crs-node1.lab:8080
# heketi-cli topology load --json=topology.json
Creating cluster ... ID: 78cdb57aa362f5284bc95b2549bc7e7d
Creating node crs-node1.lab ... ID: ffd7671c0083d88aeda9fd1cb40b339b
Adding device /dev/sdb ... OK
Creating node crs-node2.lab ... ID: 8220975c0a4479792e684584153050a9
Adding device /dev/sdb ... OK
Creating node crs-node3.lab ... ID: b94f14c4dbd8850f6ac589ac3b39cc8e
Adding device /dev/sdb ... OK
```
現在heketi已經配置了3個節點的GlusterFS存儲池。很簡單!你現在可以看到3個虛擬機都已經成功構成了GlusterFS中的可信存儲池(Trusted Stroage Pool)。
```bash
[root@crs-node1 ~]# gluster peer status
Number of Peers: 2
Hostname: crs-node2.lab
Uuid: 93b34946-9571-46a8-983c-c9f128557c0e
State: Peer in Cluster (Connected)
Other names:
crs-node2.lab
Hostname: 172.16.128.9
Uuid: e3c1f9b0-be97-42e5-beda-f70fc05f47ea
State: Peer in Cluster (Connected)
```
現在回到OpenShift!
### 將Gluster與OpenShift集成
為了集成OpenShift,需要兩樣東西:一個動態的Kubernetes Storage Provisioner和一個StorageClass。 Provisioner在OpenShift中開箱即用。 實際上關鍵的是如何將存儲掛載到容器上。 StorageClass是OpenShift中的用戶可以用來實現的PersistentVolumeClaims的實體,它反過來能夠觸發一個Provisioner實現實際的配置,并將結果表示為Kubernetes PersistentVolume(PV)。
就像OpenShift中的其他組件一樣,StorageClass也簡單的用YAML文件定義:
```Bash
# cat crs-storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
metadata:
name: container-ready-storage
annotations:
storageclass.beta.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://crs-node1.lab:8080"
restauthenabled: "false"
```
我們的provisioner是kubernetes.io/glusterfs,將它指向我們的heketi實例。 我們將類命名為“container-ready-storage”,同時使其成為所有沒有顯示指定StorageClass的PersistentVolumeClaim的默認StorageClass。
為你的GlusterFS池創建StorageClass:
```bash
# oc create -f crs-storageclass.yaml
```
### 在OpenShift中使用Gluster
我們來看下如何在OpenShift中使用GlusterFS。首先在OpenShift虛擬機中創建一個測試項目。
```bash
# oc new-project crs-storage --display-name="Container-Ready Storage"
```
這會向Kubernetes/OpenShift發出storage請求,請求一個PersistentVolumeClaim(PVC)。 這是一個簡單的對象,它描述最少需要多少容量和應該提供哪種訪問模式(非共享,共享,只讀)。 它通常是應用程序模板的一部分,但我們只需創建一個獨立的PVC:
```bash
# cat crs-claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-crs-storage
namespace: crs-storage
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
```
發送該請求:
```bash
# oc create -f crs-claim.yaml
```
觀察在OpenShfit中,PVC正在以動態創建volume的方式實現:
```bash
# oc get pvc
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
my-crs-storage Bound pvc-41ad5adb-107c-11e7-afae-000c2949cce7 1Gi RWO 58s
```
太棒了! 你現在可以在OpenShift中使用存儲容量,而不需要直接與存儲系統進行任何交互。 我們來看看創建的volume:
```bash
# oc get pv/pvc-41ad5adb-107c-11e7-afae-000c2949cce7
Name: pvc-41ad5adb-107c-11e7-afae-000c2949cce7
Labels:
StorageClass: container-ready-storage
Status: Bound
Claim: crs-storage/my-crs-storage
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1Gi
Message:
Source:
Type: Glusterfs (a Glusterfs mount on the host that shares a pod's lifetime)
EndpointsName: gluster-dynamic-my-crs-storage
Path: vol_85e444ee3bc154de084976a9aef16025
ReadOnly: false
```
What happened in the background was that when the PVC reached the system, our default StorageClass reached out to the GlusterFS Provisioner with the volume specs from the PVC. The provisioner in turn communicates with our heketi instance which facilitates the creation of the GlusterFS volume, which we can trace in it’s log messages:
該volume是根據PVC中的定義特別創建的。 在PVC中,我們沒有明確指定要使用哪個StorageClass,因為heketi的GlusterFS StorageClass已經被定義為系統范圍的默認值。
在后臺發生的情況是,當PVC到達系統時,默認的StorageClass請求具有該PVC中volume聲明規格的GlusterFS Provisioner。 Provisioner又與我們的heketi實例通信,這有助于創建GlusterFS volume,我們可以在其日志消息中追蹤:
```bash
[root@crs-node1 ~]# journalctl -l -u heketi.service
...
Mar 24 11:25:52 crs-node1.lab heketi[2598]: [heketi] DEBUG 2017/03/24 11:25:52 /src/github.com/heketi/heketi/apps/glusterfs/volume_entry.go:298: Volume to be created on cluster e
Mar 24 11:25:52 crs-node1.lab heketi[2598]: [heketi] INFO 2017/03/24 11:25:52 Creating brick 9e791b1daa12af783c9195941fe63103
Mar 24 11:25:52 crs-node1.lab heketi[2598]: [heketi] INFO 2017/03/24 11:25:52 Creating brick 3e06af2f855bef521a95ada91680d14b
Mar 24 11:25:52 crs-node1.lab heketi[2598]: [heketi] INFO 2017/03/24 11:25:52 Creating brick e4daa240f1359071e3f7ea22618cfbab
...
Mar 24 11:25:52 crs-node1.lab heketi[2598]: [sshexec] INFO 2017/03/24 11:25:52 Creating volume vol_85e444ee3bc154de084976a9aef16025 replica 3
...
Mar 24 11:25:53 crs-node1.lab heketi[2598]: Result: volume create: vol_85e444ee3bc154de084976a9aef16025: success: please start the volume to access data
...
Mar 24 11:25:55 crs-node1.lab heketi[2598]: Result: volume start: vol_85e444ee3bc154de084976a9aef16025: success
...
Mar 24 11:25:55 crs-node1.lab heketi[2598]: [asynchttp] INFO 2017/03/24 11:25:55 Completed job c3d6c4f9fc74796f4a5262647dc790fe in 3.176522702s
...
```
成功! 大約用了3秒鐘,GlusterFS池就配置完成了,并配置了一個volume。 默認值是replica 3,這意味著數據將被復制到3個不同節點的3個塊上(用GlusterFS作為后端存儲)。 該過程是通過Heketi在OpenShift進行編排的。
你也可以從GlusterFS的角度看到有關volume的信息:
```bash
[root@crs-node1 ~]# gluster volume list
vol_85e444ee3bc154de084976a9aef16025
[root@crs-node1 ~]# gluster volume info vol_85e444ee3bc154de084976a9aef16025
Volume Name: vol_85e444ee3bc154de084976a9aef16025
Type: Replicate
Volume ID: a32168c8-858e-472a-b145-08c20192082b
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: 172.16.128.8:/var/lib/heketi/mounts/vg_147b43f6f6903be8b23209903b7172ae/brick_9e791b1daa12af783c9195941fe63103/brick
Brick2: 172.16.128.9:/var/lib/heketi/mounts/vg_72c0f520b0c57d807be21e9c90312f85/brick_3e06af2f855bef521a95ada91680d14b/brick
Brick3: 172.16.128.7:/var/lib/heketi/mounts/vg_67314f879686de975f9b8936ae43c5c5/brick_e4daa240f1359071e3f7ea22618cfbab/brick
Options Reconfigured:
transport.address-family: inet
nfs.disable: on
```
請注意,GlusterFS中的卷名稱如何對應于OpenShift中Kubernetes Persistent Volume的“路徑”。
或者,你也可以使用OpenShift UI來配置存儲,這樣可以很方便地在系統中的所有已知的StorageClasses中進行選擇:


讓我們做點更有趣的事情,在OpenShift中運行工作負載。
在仍運行著crs-storage項目的OpenShift虛擬機中執行:
```bash
# oc get templates -n openshift
```
你應該可以看到一個應用程序和數據庫模板列表,這個列表將方便你更輕松的使用OpenShift來部署你的應用程序項目。
我們將使用MySQL來演示如何在OpenShift上部署具有持久化和彈性存儲的有狀態應用程序。 Mysql-persistent模板包含一個用于MySQL數據庫目錄的1G空間的PVC。 為了演示目的,可以直接使用默認值。
```bash
# oc process mysql-persistent -n openshift | oc create -f -
```
等待部署完成。你可以通過UI或者命令行觀察部署進度:
```bash
# oc get pods
NAME READY STATUS RESTARTS AGE
mysql-1-h4afb 1/1 Running 0 2m
```
好了。我們已經使用這個模板創建了一個service,secrets、PVC和pod。我們來使用它(你的pod名字將跟我的不同):
```bash
# oc rsh mysql-1-h4afb
```
你已經成功的將它掛載到MySQL的pod上。我們連接一下數據庫試試:
```bash
sh-4.2$ mysql -u $MYSQL_USER -p$MYSQL_PASSWORD -h $HOSTNAME $MYSQL_DATABASE
```
這點很方便,所有重要的配置,如MySQL憑據,數據庫名稱等都是pod模板中的環境變量的一部分,因此可以在pod中作為shell的環境變量。 我們來創建一些數據:
```Bash
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| sampledb |
+--------------------+
2 rows in set (0.02 sec)
mysql> \u sampledb
Database changed
mysql> CREATE TABLE IF NOT EXISTS equipment (
-> equip_id int(5) NOT NULL AUTO_INCREMENT,
-> type varchar(50) DEFAULT NULL,
-> install_date DATE DEFAULT NULL,
-> color varchar(20) DEFAULT NULL,
-> working bool DEFAULT NULL,
-> location varchar(250) DEFAULT NULL,
-> PRIMARY KEY(equip_id)
-> );
Query OK, 0 rows affected (0.13 sec)
mysql> INSERT INTO equipment (type, install_date, color, working, location)
-> VALUES
-> ("Slide", Now(), "blue", 1, "Southwest Corner");
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> SELECT * FROM equipment;
+----------+-------+--------------+-------+---------+------------------+
| equip_id | type | install_date | color | working | location |
+----------+-------+--------------+-------+---------+------------------+
| 1 | Slide | 2017-03-24 | blue | 1 | Southwest Corner |
+----------+-------+--------------+-------+---------+------------------+
1 row in set (0.00 sec)
```
很好,數據庫運行正常。
你想看下數據存儲在哪里嗎?很簡單!查看剛使用模板創建的mysql volume:
```bash
# oc get pvc/mysql
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
mysql Bound pvc-a678b583-1082-11e7-afae-000c2949cce7 1Gi RWO 11m
# oc describe pv/pvc-a678b583-1082-11e7-afae-000c2949cce7
Name: pvc-a678b583-1082-11e7-afae-000c2949cce7
Labels:
StorageClass: container-ready-storage
Status: Bound
Claim: crs-storage/mysql
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1Gi
Message:
Source:
Type: Glusterfs (a Glusterfs mount on the host that shares a pod's lifetime)
EndpointsName: gluster-dynamic-mysql
Path: vol_6299fc74eee513119dafd43f8a438db1
ReadOnly: false
```
GlusterFS的volume名字是vol_6299fc74eee513119dafd43f8a438db1。回到你的GlusterFS虛擬機中,輸入:
```bash
# gluster volume info vol_6299fc74eee513119dafd43f8a438db
Volume Name: vol_6299fc74eee513119dafd43f8a438db1
Type: Replicate
Volume ID: 4115918f-28f7-4d4a-b3f5-4b9afe5b391f
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: 172.16.128.7:/var/lib/heketi/mounts/vg_67314f879686de975f9b8936ae43c5c5/brick_f264a47aa32be5d595f83477572becf8/brick
Brick2: 172.16.128.8:/var/lib/heketi/mounts/vg_147b43f6f6903be8b23209903b7172ae/brick_f5731fe7175cbe6e6567e013c2591343/brick
Brick3: 172.16.128.9:/var/lib/heketi/mounts/vg_72c0f520b0c57d807be21e9c90312f85/brick_ac6add804a6a467cd81cd1404841bbf1/brick
Options Reconfigured:
transport.address-family: inet
nfs.disable: on
```
你可以看到數據是如何被復制到3個GlusterFS塊的。我們從中挑一個(最好挑選你剛登陸的那臺虛擬機并查看目錄):
```bash
# ll /var/lib/heketi/mounts/vg_67314f879686de975f9b8936ae43c5c5/brick_f264a47aa32be5d595f83477572becf8/brick
total 180300
-rw-r-----. 2 1000070000 2001 56 Mar 24 12:11 auto.cnf
-rw-------. 2 1000070000 2001 1676 Mar 24 12:11 ca-key.pem
-rw-r--r--. 2 1000070000 2001 1075 Mar 24 12:11 ca.pem
-rw-r--r--. 2 1000070000 2001 1079 Mar 24 12:12 client-cert.pem
-rw-------. 2 1000070000 2001 1680 Mar 24 12:12 client-key.pem
-rw-r-----. 2 1000070000 2001 352 Mar 24 12:12 ib_buffer_pool
-rw-r-----. 2 1000070000 2001 12582912 Mar 24 12:20 ibdata1
-rw-r-----. 2 1000070000 2001 79691776 Mar 24 12:20 ib_logfile0
-rw-r-----. 2 1000070000 2001 79691776 Mar 24 12:11 ib_logfile1
-rw-r-----. 2 1000070000 2001 12582912 Mar 24 12:12 ibtmp1
drwxr-s---. 2 1000070000 2001 8192 Mar 24 12:12 mysql
-rw-r-----. 2 1000070000 2001 2 Mar 24 12:12 mysql-1-h4afb.pid
drwxr-s---. 2 1000070000 2001 8192 Mar 24 12:12 performance_schema
-rw-------. 2 1000070000 2001 1676 Mar 24 12:12 private_key.pem
-rw-r--r--. 2 1000070000 2001 452 Mar 24 12:12 public_key.pem
drwxr-s---. 2 1000070000 2001 62 Mar 24 12:20 sampledb
-rw-r--r--. 2 1000070000 2001 1079 Mar 24 12:11 server-cert.pem
-rw-------. 2 1000070000 2001 1676 Mar 24 12:11 server-key.pem
drwxr-s---. 2 1000070000 2001 8192 Mar 24 12:12 sys
```
你可以在這里看到MySQL數據庫目錄。 它使用GlusterFS作為后端存儲,并作為綁定掛載給MySQL容器使用。 如果你檢查OpenShift VM上的mount表,你將會看到GlusterFS的mount。
### 總結
在這里我們是在OpenShift之外創建了一個簡單但功能強大的GlusterFS存儲池。 該池可以獨立于應用程序擴展和收縮。 該池的整個生命周期由一個簡單的稱為heketi的前端管理,你只需要在部署增長時進行手動干預。 對于日常配置操作,使用它的API與OpenShifts動態配置器交互,無需開發人員直接與基礎架構團隊進行交互。
o這就是我們如何將存儲帶入DevOps世界 - 無痛苦,并在OpenShift PaaS系統的開發人員工具中直接提供。
GlusterFS和OpenShift可跨越所有環境:裸機,虛擬機,私有和公共云(Azure,Google Cloud,AWS ...),確保應用程序可移植性,并避免云供應商鎖定。
祝你愉快在容器中使用GlusterFS!
(c) 2017 Keith Tenzer
原文鏈接:https://keithtenzer.com/2017/03/24/storage-for-containers-using-gluster-part-ii/
- 序言
- 云原生
- 云原生(Cloud Native)的定義
- CNCF - 云原生計算基金會簡介
- CNCF章程
- 云原生的設計哲學
- Play with Kubernetes
- 快速部署一個云原生本地實驗環境
- Kubernetes與云原生應用概覽
- 云原生應用之路——從Kubernetes到Cloud Native
- 云原生編程語言
- 云原生編程語言Ballerina
- 云原生編程語言Pulumi
- 云原生的未來
- Kubernetes架構
- 設計理念
- Etcd解析
- 開放接口
- CRI - Container Runtime Interface(容器運行時接口)
- CNI - Container Network Interface(容器網絡接口)
- CSI - Container Storage Interface(容器存儲接口)
- Kubernetes中的網絡
- Kubernetes中的網絡解析——以flannel為例
- Kubernetes中的網絡解析——以calico為例
- 具備API感知的網絡和安全性管理開源軟件Cilium
- Cilium架構設計與概念解析
- 資源對象與基本概念解析
- Pod狀態與生命周期管理
- Pod概覽
- Pod解析
- Init容器
- Pause容器
- Pod安全策略
- Pod的生命周期
- Pod Hook
- Pod Preset
- Pod中斷與PDB(Pod中斷預算)
- 集群資源管理
- Node
- Namespace
- Label
- Annotation
- Taint和Toleration(污點和容忍)
- 垃圾收集
- 控制器
- Deployment
- StatefulSet
- DaemonSet
- ReplicationController和ReplicaSet
- Job
- CronJob
- Horizontal Pod Autoscaling
- 自定義指標HPA
- 準入控制器(Admission Controller)
- 服務發現
- Service
- Ingress
- Traefik Ingress Controller
- 身份與權限控制
- ServiceAccount
- RBAC——基于角色的訪問控制
- NetworkPolicy
- 存儲
- Secret
- ConfigMap
- ConfigMap的熱更新
- Volume
- Persistent Volume(持久化卷)
- Storage Class
- 本地持久化存儲
- 集群擴展
- 使用自定義資源擴展API
- 使用CRD擴展Kubernetes API
- Aggregated API Server
- APIService
- Service Catalog
- 資源調度
- QoS(服務質量等級)
- 用戶指南
- 資源對象配置
- 配置Pod的liveness和readiness探針
- 配置Pod的Service Account
- Secret配置
- 管理namespace中的資源配額
- 命令使用
- Docker用戶過度到kubectl命令行指南
- kubectl命令概覽
- kubectl命令技巧大全
- 使用etcdctl訪問kubernetes數據
- 集群安全性管理
- 管理集群中的TLS
- kubelet的認證授權
- TLS bootstrap
- 創建用戶認證授權的kubeconfig文件
- IP偽裝代理
- 使用kubeconfig或token進行用戶身份認證
- Kubernetes中的用戶與身份認證授權
- Kubernetes集群安全性配置最佳實踐
- 訪問Kubernetes集群
- 訪問集群
- 使用kubeconfig文件配置跨集群認證
- 通過端口轉發訪問集群中的應用程序
- 使用service訪問群集中的應用程序
- 從外部訪問Kubernetes中的Pod
- Cabin - Kubernetes手機客戶端
- Kubernetic - Kubernetes桌面客戶端
- Kubernator - 更底層的Kubernetes UI
- 在Kubernetes中開發部署應用
- 適用于kubernetes的應用開發部署流程
- 遷移傳統應用到Kubernetes中——以Hadoop YARN為例
- 最佳實踐概覽
- 在CentOS上部署Kubernetes集群
- 創建TLS證書和秘鑰
- 創建kubeconfig文件
- 創建高可用etcd集群
- 安裝kubectl命令行工具
- 部署master節點
- 安裝flannel網絡插件
- 部署node節點
- 安裝kubedns插件
- 安裝dashboard插件
- 安裝heapster插件
- 安裝EFK插件
- 生產級的Kubernetes簡化管理工具kubeadm
- 使用kubeadm在Ubuntu Server 16.04上快速構建測試集群
- 服務發現與負載均衡
- 安裝Traefik ingress
- 分布式負載測試
- 網絡和集群性能測試
- 邊緣節點配置
- 安裝Nginx ingress
- 安裝配置DNS
- 安裝配置Kube-dns
- 安裝配置CoreDNS
- 運維管理
- Master節點高可用
- 服務滾動升級
- 應用日志收集
- 配置最佳實踐
- 集群及應用監控
- 數據持久化問題
- 管理容器的計算資源
- 集群聯邦
- 存儲管理
- GlusterFS
- 使用GlusterFS做持久化存儲
- 使用Heketi作為Kubernetes的持久存儲GlusterFS的external provisioner
- 在OpenShift中使用GlusterFS做持久化存儲
- GlusterD-2.0
- Ceph
- 用Helm托管安裝Ceph集群并提供后端存儲
- 使用Ceph做持久化存儲
- 使用rbd-provisioner提供rbd持久化存儲
- OpenEBS
- 使用OpenEBS做持久化存儲
- Rook
- NFS
- 利用NFS動態提供Kubernetes后端存儲卷
- 集群與應用監控
- Heapster
- 使用Heapster獲取集群和對象的metric數據
- Prometheus
- 使用Prometheus監控kubernetes集群
- Prometheus查詢語言PromQL使用說明
- 使用Vistio監控Istio服務網格中的流量
- 分布式跟蹤
- OpenTracing
- 服務編排管理
- 使用Helm管理Kubernetes應用
- 構建私有Chart倉庫
- 持續集成與發布
- 使用Jenkins進行持續集成與發布
- 使用Drone進行持續集成與發布
- 更新與升級
- 手動升級Kubernetes集群
- 升級dashboard
- 領域應用概覽
- 微服務架構
- 微服務中的服務發現
- 使用Java構建微服務并發布到Kubernetes平臺
- Spring Boot快速開始指南
- Service Mesh 服務網格
- 企業級服務網格架構
- Service Mesh基礎
- Service Mesh技術對比
- 采納和演進
- 定制和集成
- 總結
- Istio
- 安裝并試用Istio service mesh
- 配置請求的路由規則
- 安裝和拓展Istio service mesh
- 集成虛擬機
- Istio中sidecar的注入規范及示例
- 如何參與Istio社區及注意事項
- Istio教程
- Istio免費學習資源匯總
- 深入理解Istio Service Mesh中的Envoy Sidecar注入與流量劫持
- 深入理解Istio Service Mesh中的Envoy Sidecar代理的路由轉發
- Linkerd
- Linkerd 使用指南
- Conduit
- Condiut概覽
- 安裝Conduit
- Envoy
- Envoy的架構與基本術語
- Envoy作為前端代理
- Envoy mesh教程
- SOFAMesh
- SOFAMesh中的Dubbo on x-protocol
- SOFAMosn
- 使用 SOFAMosn 構建 SOFAMesh
- 大數據
- Spark standalone on Kubernetes
- 運行支持Kubernetes原生調度的Spark程序
- Serverless架構
- 理解Serverless
- FaaS-函數即服務
- OpenFaaS快速入門指南
- 邊緣計算
- 人工智能