MySQL 中的数据是关键信息,是有状态的,不可能随着 MySQL pod 的销毁而被销毁,所以数据必须要外接到一个可靠的存储系统中,目前已经有了 Ceph 系统,所以这里就只考虑如何将 Ceph 作为外部存储的情况,毕竟没有条件去尝试其他存储方案。
本文从最简单的 k8s 连接 ceph 方式开始, 并过渡到 PV(Persistent Volume) 和 PVC(Persistent Volume Claim)方式,本系列文章后面还会介绍使用 StorageClass 的动态连接方式。
1. 概念介绍和环境信息
1.1 PV(Persistent Volume)简介:
PV 是集群提供的一种存储资源,是实际可用的磁盘。和挂 PV 的 Pod 有着独立的生命周期,Pod 销毁后,PV 可以继续存在,以此来实现持久化存储。
1.2 PVC(Persistent Volume Claim)简介:
PVC 是用户使用存储资源的声明,和 Pod 这一概念类似,Pod 消耗的是 Node 上的计算资源,PVC 消耗的是 PV 资源。
1.3 环境信息
本文在 Ubuntu 物理机环境下,使用 kubeadm 部署 Kubernetes,连接已经部署好的 Ceph 集群,后文会对部署过程做详细说明。
- 操作系统:Ubuntu 16.04
- Ceph:Luminous 12.2
- Kubernetes:v1.10.2
- Docker:v1.13.1
2. 使用 keyring 文件连接 RBD
首先让我们用最基础的方式连接 Ceph,以下就是 yaml 文件,简要介绍一下关键字段:
- monitors: 连接的 Ceph monitor 地址,注意要更改成环境中对应的 Ceph monitor 地址。
- keyring:Ceph 集群认证所需的密钥,这里以本地文件的形式挂载进去。这个文件的内容就是 ceph 集群里 /etc/ceph/ceph.client.admin.keyring 文件的内容。
- imageformat:建议使用 2,1 是更老的格式。
- imagefeatures:磁盘文件的特性,Ubuntu 16.04 和 CentOS7.4 的内核版本目前支持的特性较少,建议只填写 layering,如果要使用其他特性,需升级内核版本。
- pool:Ceph 中的 pool。
- image:Ceph RBD 创建的镜像名称。
$ cat mysql-deployment.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: ROOT_PASSWORD
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: rbdpd
mountPath: /var/lib/mysql
volumes:
- name: rbdpd
rbd:
monitors:
- '192.168.56.106:6789'
pool: rbd
image: foo
fsType: ext4
readOnly: false
user: admin
imageformat: "2"
imagefeatures: "layering"
keyring: /etc/ceph/keyring
在执行该 yaml 文件之前,我们需要先在 RBD 中创建名为 foo 的镜像,不然 pod 无法创建成功。
# rbd create foo --size 2048M
# rbd list
foo
# rbd feature disable foo exclusive-lock, object-map, fast-diff, deep-flatten
此时再执行 $ kubectl create -f mysql-deployment.yaml
就可以了。
3. 使用 secret 连接 RBD
直接挂载密钥文件既不正规,也不安全,我们可以使用 Kubernetes 的 secret 来加密密钥文件。
先获取加密后的密钥字符串:
$ ceph auth get-key client.admin | base64
<keyring string>
将 <keyring string> 填写进 ceph-secret.yaml 文件中的 key 字段:
$ cat ceph-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: ceph-secret
type: "kubernetes.io/rbd"
data:
key: <keyring string>
创建该 secret:
kubectl create -f ceph-secret.yaml
最后修改 mysql-deployment.yaml 对应字段:
$ cat mysql-deployment.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: ROOT_PASSWORD
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: rbdpd
mountPath: /var/lib/mysql
volumes:
- name: rbdpd
rbd:
monitors:
- '192.168.56.106:6789'
pool: rbd
image: foo
fsType: ext4
readOnly: false
user: admin
imageformat: "2"
imagefeatures: "layering"
secretRef:
name: ceph-secret
$ kubectl apply -f mysql-deploy.yaml
4. 使用 PV 和 PVC 连接 RBD
好,最后就是使用 PVC 和 PV 挂载 RBD 镜像了。
先是 PV 文件:
$ cat volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
claimRef:
name: mysql-pvc
namespace: default
persistentVolumeReclaimPolicy: Recycle
rbd:
monitors:
- 192.168.56.106:6789
pool: rbd
image: foo
user: admin
fsType: ext4
readOnly: false
secretRef:
name: ceph-secret
然后是 PVC:
$ cat volume-claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
最后挂载在 MySQL 上
$ cat mysql-deployment.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: ROOT_PASSWORD
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pvc
到这里 MySQL 就成功的使用 ceph RBD 作为持久化存储方案,部署在了 k8s 环境里,不过这还是很初级的方案,毕竟在挂载之前还需要手动在 RBD 中创建镜像,太不 cloud native 了,接下来的文章将演示如何动态的使用 RBD 镜像。