使用glusterfs做持久化存储

构建gluster镜像

gluster集群可以直接安装在物理机上,也可以通过docker构建集群,还可以通过 k8s部署。为了方便学习研究,本文采取docker的形式构建一个gluster的集群。

首先,通过Dockerfile构建一个gluster的镜像(可以在amd64或aarch64架构上构建):

Dockerfile
FROM ubuntu:20.04
MAINTAINER zhujia "magicletters@qq.com"

RUN export DEBIAN_FRONTEND=noninteractive; \
    export DEBCONF_NONINTERACTIVE_SEEN=true; \
    echo 'tzdata tzdata/Areas select Asia' | debconf-set-selections; \
    echo 'tzdata tzdata/Zones/Asia select Shanghai' | debconf-set-selections; \
    apt update && apt full-upgrade -y && apt install -y --no-install-recommends \
    glusterfs-server \
    && rm -rf /var/lib/apt/lists/*

ENTRYPOINT ["/usr/sbin/glusterd", "-N", "--log-file=/dev/stdout"]

构建gluster集群

# 配置hosts
tee -a /etc/hosts > /dev/null << EOF
192.168.0.2     k8s-master
192.168.0.3     k8s-node1
192.168.0.4     k8s-node2
192.168.0.5     k8s-node3
EOF

mkdir -p /data/glusterfs/lib -p /data/glusterfs/vols

docker run -d --net=host --privileged=true --name=gluster \
-v /data/glusterfs/lib:/var/lib/glusterd \
-v /data/glusterfs/vols:/data \
registry.cn-chengdu.aliyuncs.com/h2o-arm64/glusterfs

docker exec -it gluster /bin/bash

gluster peer probe k8s-node1
gluster peer probe k8s-node2
gluster peer probe k8s-node3

配置 volume

GlusterFS中的volume的模式有很多中,包括以下几种:

  • 分布卷(默认模式):即DHT, 也叫 分布卷: 将文件以hash算法随机分布到 一台服务器节点中存储。

  • 复制模式:即AFR, 创建volume 时带 replica x 数量: 将文件复制到 replica x 个节点中。

  • 条带模式:即Striped, 创建volume 时带 stripe x 数量: 将文件切割成数据块,分别存储到 stripe x 个节点中 ( 类似raid 0 )。

  • 分布式条带模式:最少需要4台服务器才能创建。 创建volume 时 stripe 2 server = 4 个节点: 是DHT 与 Striped 的组合型。

  • 分布式复制模式:最少需要4台服务器才能创建。 创建volume 时 replica 2 server = 4 个节点:是DHT 与 AFR 的组合型。

  • 条带复制卷模式:最少需要4台服务器才能创建。 创建volume 时 stripe 2 replica 2 server = 4 个节点: 是 Striped 与 AFR 的组合型。

  • 三种模式混合: 至少需要8台 服务器才能创建。 stripe 2 replica 2 , 每4个节点 组成一个 组。

在此我们使用默认的分布卷模式请勿在生产环境上使用该模式,容易导致数据丢失。

# 创建分布卷
gluster volume create pg-data transport tcp k8s-master:/data/pg-data k8s-node1:/data/pg-data k8s-node2:/data/pg-data k8s-node3:/data/pg-data force

gluster volume create pg-data replica 2 transport tcp server1:/exp1 server2:/exp2 server3:/exp3 server4:/exp4


# 启动 分布卷
gluster volume start pg-data

Glusterfs调优

# 开启 指定 volume 的配额
$ gluster volume quota k8s-volume enable

# 限制 指定 volume 的配额
$ gluster volume quota k8s-volume limit-usage / 1TB

# 设置 cache 大小, 默认32MB
$ gluster volume set k8s-volume performance.cache-size 4GB

# 设置 io 线程, 太大会导致进程崩溃
$ gluster volume set k8s-volume performance.io-thread-count 16

# 设置 网络检测时间, 默认42s
$ gluster volume set k8s-volume network.ping-timeout 10

# 设置 写缓冲区的大小, 默认1M
$ gluster volume set k8s-volume performance.write-behind-window-size 1024MB

Kubernetes中配置glusterfs

# 在k8s节点上安装客户端
apt install -y glusterfs-client

配置 endpoints

gluster-endpoints.yaml
apiVersion: v1
kind: Endpoints
metadata:
  name: glusterfs-cluster
subsets:
- addresses:
  - ip: 192.168.0.2
  ports:
  - port: 1
- addresses:
  - ip: 192.168.0.3
  ports:
  - port: 1
- addresses:
  - ip: 192.168.0.4
  ports:
  - port: 1
- addresses:
  - ip: 192.168.0.5
  ports:
  - port: 1

配置 service

gluster-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: glusterfs-cluster
spec:
  ports:
  - port: 1

创建测试 pod

postgres-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: gluster-postgres
spec:
  capacity:
    storage: 80Gi
  accessModes:
    - ReadWriteMany
  glusterfs:
    endpoints: "glusterfs-cluster"
    path: "pg-data"
    readOnly: false
postgres-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: glusterfs-pg-db
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 80Gi
postgres-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-config
  labels:
    app: postgres
data:
  POSTGRES_DB: mydb
  POSTGRES_USER: appuser
  POSTGRES_PASSWORD: userpasswd
postgres-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pg-db
  labels:
    app: pg-db
spec:
  selector:
    matchLabels:
      app: pg-db
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: pg-db
    spec:
      containers:
        - image: postgres:12.3
          imagePullPolicy: IfNotPresent
          name: postgres
          ports:
            - containerPort: 5432
          envFrom:
            - configMapRef:
                name: postgres-config
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: postgredb
      volumes:
        - name: postgredb
          persistentVolumeClaim:
            claimName: glusterfs-pg-db
postgres-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: pg-db
  labels:
    app: pg-db
spec:
  type: NodePort
  ports:
    - port: 5432
      targetPort: 5432
      nodePort: 30001
  selector:
    app: pg-db