
MySQL 中的數(shù)據(jù)是關(guān)鍵信息,是有狀態(tài)的,不可能隨著 MySQL pod 的銷毀而被銷毀,所以數(shù)據(jù)必須要外接到一個可靠的存儲系統(tǒng)中,目前已經(jīng)有了 Ceph 系統(tǒng),所以這里就只考慮如何將 Ceph 作為外部存儲的情況,畢竟沒有條件去嘗試其他存儲方案。
本文從最簡單的 k8s 連接 ceph 方式開始, 并過渡到 PV(Persistent Volume) 和 PVC(Persistent Volume Claim)方式,本系列文章后面還會介紹使用 StorageClass 的動態(tài)連接方式。
1. 概念介紹和環(huán)境信息
1.1 PV(Persistent Volume)簡介:
PV 是集群提供的一種存儲資源,是實際可用的磁盤。和掛 PV 的 Pod 有著獨立的生命周期,Pod 銷毀后,PV 可以繼續(xù)存在,以此來實現(xiàn)持久化存儲。
1.2 PVC(Persistent Volume Claim)簡介:
PVC 是用戶使用存儲資源的聲明,和 Pod 這一概念類似,Pod 消耗的是 Node 上的計算資源,PVC 消耗的是 PV 資源。
1.3 環(huán)境信息
本文在 Ubuntu 物理機(jī)環(huán)境下,使用 kubeadm 部署 Kubernetes,連接已經(jīng)部署好的 Ceph 集群,后文會對部署過程做詳細(xì)說明。
- 操作系統(tǒng):Ubuntu 16.04
- Ceph:Luminous 12.2
- Kubernetes:v1.10.2
- Docker:v1.13.1
2. 使用 keyring 文件連接 RBD
首先讓我們用最基礎(chǔ)的方式連接 Ceph,以下就是 yaml 文件,簡要介紹一下關(guān)鍵字段:
- monitors: 連接的 Ceph monitor 地址,注意要更改成環(huán)境中對應(yīng)的 Ceph monitor 地址。
- keyring:Ceph 集群認(rèn)證所需的密鑰,這里以本地文件的形式掛載進(jìn)去。這個文件的內(nèi)容就是 ceph 集群里 /etc/ceph/ceph.client.admin.keyring 文件的內(nèi)容。
- imageformat:建議使用 2,1 是更老的格式。
- imagefeatures:磁盤文件的特性,Ubuntu 16.04 和 CentOS7.4 的內(nèi)核版本目前支持的特性較少,建議只填寫 layering,如果要使用其他特性,需升級內(nèi)核版本。
- pool:Ceph 中的 pool。
- image:Ceph RBD 創(chuàng)建的鏡像名稱。
$ 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
在執(zhí)行該 yaml 文件之前,我們需要先在 RBD 中創(chuàng)建名為 foo 的鏡像,不然 pod 無法創(chuàng)建成功。
# rbd create foo --size 2048M
# rbd list
foo
# rbd feature disable foo exclusive-lock, object-map, fast-diff, deep-flatten
此時再執(zhí)行 $ kubectl create -f mysql-deployment.yaml 就可以了。
3. 使用 secret 連接 RBD
直接掛載密鑰文件既不正規(guī),也不安全,我們可以使用 Kubernetes 的 secret 來加密密鑰文件。
先獲取加密后的密鑰字符串:
$ ceph auth get-key client.admin | base64
<keyring string>
將 <keyring string> 填寫進(jìn) ceph-secret.yaml 文件中的 key 字段:
$ cat ceph-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: ceph-secret
type: "kubernetes.io/rbd"
data:
key: <keyring string>
創(chuàng)建該 secret:
kubectl create -f ceph-secret.yaml
最后修改 mysql-deployment.yaml 對應(yīng)字段:
$ 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 環(huán)境里,不過這還是很初級的方案,畢竟在掛載之前還需要手動在 RBD 中創(chuàng)建鏡像,太不 cloud native 了,接下來的文章將演示如何動態(tài)的使用 RBD 鏡像。