640 lines
24 KiB
Markdown
640 lines
24 KiB
Markdown
# 在 OpenShift 中使用 GlusterFS 做持久化存储
|
||
|
||
在本文中,我们将介绍容器存储的首选以及如何部署它。 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 环境。
|
||
|
||
确保你的 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
|
||
[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
|
||
```
|
||
|
||
该 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 中进行选择:
|
||
|
||
![创建存储](../images/create-gluster-storage.png)
|
||
|
||
![容器存储](../images/container-storage.png)
|
||
|
||
让我们做点更有趣的事情,在 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 ...),确保应用程序可移植性,并避免云供应商锁定。
|
||
|
||
---
|
||
|
||
本文由译自 Daniel Messer(Technical Marketing Manager Storage @RedHat)和Keith Tenzer(Solutions Architect @RedHat)共同撰写文章,原文已无法访问。
|