Hugo Future Imperfect Slim

陈sir

因为技术能树点歪了而成为云计算架构师

kubernetes 集群中部署 glusterfs 与 heketi

deploy glusterfs and heketi in kubernetes

陈 sir

4 分钟

组件介绍

Heketi

Heketi提供了一个RESTful管理界面,可以用来管理GlusterFS卷的生命周期。 通过Heketi,就可以像使用OpenStack Manila,Kubernetes和OpenShift一样申请可以动态配置GlusterFS卷。Heketi会动态在集群内选择bricks构建所需的volumes,这样以确保数据的副本会分散到集群不同的故障域内。同时Heketi还支持任意数量的ClusterFS集群,以保证接入的云服务器不局限于单个GlusterFS集群。

Gluster-Kubernetes

Gluster-Kubernetes是一个可以将GluserFS和Hekiti轻松部署到Kubernetes集群的开源项目。另外也提供在Kubernetes中可以采用StorageClass来动态管理GlusterFS卷。

部署环境

服务器分配信息:

Hostname 服务器IP 存储IP 硬盘信息 容量G
master1 192.168.10.51 192.168.10.51 /dev/sdb 300G
node1 192.168.10.52 192.168.10.52 /dev/sdb 300G
node2 192.168.10.53 192.168.10.53 /dev/sdb 300G

部署步骤

安装依赖组件 (master1 node1 node2)

yum install -y centos-release-gluster
yum install -y glusterfs glusterfs-server glusterfs-fuse glusterfs-rdma glusterfs-geo-replication glusterfs-devel
systemctl start glusterd
systemctl enable glusterd

内核模块加载 (master1 node1 node2)

# 加载 glusterfs 所需的内核模块
touch /etc/sysconfig/modules/glusterfs.modules
echo '#!/bin/bash' >> /etc/sysconfig/modules/glusterfs.modules
echo "modprobe -- dm_snapshot" >> /etc/sysconfig/modules/glusterfs.modules
echo "modprobe -- dm_mirror" >> /etc/sysconfig/modules/glusterfs.modules
echo "modprobe -- dm_thin_pool" >> /etc/sysconfig/modules/glusterfs.modules
# 授权
chmod 755 /etc/sysconfig/modules/glusterfs.modules 

# 加载模块
bash /etc/sysconfig/modules/glusterfs.modules

校验模块加载

$lsmod |egrep "dm_snapshot|dm_mirror|dm_thin_pool"
dm_thin_pool           66298  0 
dm_persistent_data     75269  1 dm_thin_pool
dm_bio_prison          18209  1 dm_thin_pool
dm_snapshot            39104  0 
dm_bufio               28014  2 dm_persistent_data,dm_snapshot
dm_mirror              22289  0 
dm_region_hash         20813  1 dm_mirror
dm_log                 18411  2 dm_region_hash,dm_mirror
dm_mod                123941  14 dm_log,dm_mirror,dm_bufio,dm_thin_pool,dm_snapshot

获取部署文件 (master1 )

git clone https://github.com/gluster/gluster-kubernetes.git

修改配置文件 (master1 )

cp gluster-kubernetes/deploy/topology.json.sample gluster-kubernetes/deploy/topology.json

将 topology.json 修改为如下内容,注意 manage 的值必须和kubectl get node 中的的名称一样。

{
  "clusters": [
    {
      "nodes": [
        {
          "node": {
            "hostnames": {
              "manage": [
                "master1"
              ],
              "storage": [
                "192.168.10.50"
              ]
            },
            "zone": 1
          },
          "devices": [
            "/dev/sdb"
          ]
        },
        {
          "node": {
            "hostnames": {
              "manage": [
                "node1"
              ],
              "storage": [
                "192.168.10.51"
              ]
            },
            "zone": 1
          },
          "devices": [
            "/dev/sdb"
          ]
        },
        {
          "node": {
            "hostnames": {
              "manage": [
                "node2"
              ],
              "storage": [
                "192.168.10.52"
              ]
            },
            "zone": 1
          },
          "devices": [
            "/dev/sdb"
          ]
        }
      ]
    }
  ]
}

修改daemonset 文件

---
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: glusterfs
  labels:
    glusterfs: daemonset
  annotations:
    description: GlusterFS DaemonSet
    tags: glusterfs
spec:
  template:
    metadata:
      name: glusterfs
      labels:
        glusterfs: pod
        glusterfs-node: pod
    spec:
      nodeSelector:
        storagenode: glusterfs
      hostNetwork: true
      tolerations: #因为master 节点不能被调度,所以此处要添加容忍
        - key: node-role.kubernetes.io/master
          operator: Exists
          effect: NoSchedule
      containers:
      - image: gluster/gluster-centos:latest
        imagePullPolicy: IfNotPresent
        name: glusterfs
        ............

修改 heketi-deployment.yaml

---
kind: Service
apiVersion: v1
metadata:
  name: heketi
  labels:
    glusterfs: heketi-service
    heketi: service
  annotations:
    description: Exposes Heketi Service
spec:
  selector:
    glusterfs: heketi-pod
  ports:
  - name: heketi
    port: 8080
    targetPort: 8080
  type: NodePort # 添加nodeport 如果想用ingress,可以不用修改此文件,略过这一步

修改 gk-deploy 文件(官方bug),在文件中搜索 –show-all 将

  heketi_pod=$(${CLI} get pod --no-headers --show-all --selector="heketi" | awk '{print $1}')

改为

if [[ "${CLI}" =~ ^kubectl ]]; then
  heketi_pod=$(${CLI} get pod --no-headers --selector="heketi" | awk '{print $1}')
else 
  heketi_pod=$(${CLI} get pod --no-headers --show-all --selector="heketi" | awk '{print $1}')
fi

修改 heketi.json.template, 主要添加admin key 与 user key

{
	"_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" : "openstack"
		},
		"_user" : "User only has access to /volumes endpoint",
		"user" : {
			"key" : "openstack"
		}
	},

	"_glusterfs_comment": "GlusterFS Configuration",
	"glusterfs" : {

		"_executor_comment": "Execute plugin. Possible choices: mock, kubernetes, ssh",
		"executor" : "${HEKETI_EXECUTOR}",

		"_db_comment": "Database file name",
		"db" : "/var/lib/heketi/heketi.db",

		"kubeexec" : {
			"rebalance_on_expansion": true
		},

		"sshexec" : {
			"rebalance_on_expansion": true,
			"keyfile" : "/etc/heketi/private_key",
			"port" : "${SSH_PORT}",
			"user" : "${SSH_USER}",
			"sudo" : ${SSH_SUDO}
		}
	},

	"backup_db_to_kube_secret": false
}

开始部署

./gk-deploy -g -n glusterfs -c kubectl --admin-key openstack --user-key openstack

验证安装

创建 storage class

创建storageclass.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: glusterfs-storage
provisioner: kubernetes.io/glusterfs
parameters:
  resturl: HEKETI_URL
  clusterid: CLUSTERID
  restauthenabled: "true"
  restuser: "admin" # 此处需要与heketi 实际配置匹配
  # secretNamespace: "default"
  # secretName: "heketi-secret"
  #如果使用 secret 可以用如下命令新建对应的secret 
  # kubectl create secret generic heketi-secret \
  # --type="kubernetes.io/glusterfs" --from-literal=key='openstack' \
  # --namespace=default
  # 对应的yaml为 https://github.com/kubernetes/examples/blob/master/staging/persistent-volume-provisioning/glusterfs/glusterfs-secret.yaml
  restuserkey: "openstack" # 此处需要与heketi 实际配置匹配
  gidMin: "40000" #存储类的 GID 范围的最小值和最大值。此范围内的唯一值 (GID)将用于动态预配卷。这些是可选值。如果未指定,则卷将预配值介于 2000-2147483647 之间,该值分别默认为 gidMin 和 gidMax。
  gidMax: "50000"
  # volumetype: "replicate:3" #Replica volume
  # volumetype: disperse:4:2  #Disperse/EC volume
  # volumetype: none  #Distribute volume

然后应用

kubectl apply -f storageclass.yaml

创建 PVC

pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: glusterfs-claim
  annotations:
    volume.beta.kubernetes.io/storage-class: glusterfs-storage  #storage-class的名字
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

应用

kubectl apply -f pvc.yaml
kubectl get pvc,pv

创建一个pod 使用pvc

nginx-test.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-test
  labels:
    name: nginx-test
spec:
  containers:
  - name: nginx-test
    image: nginx
    ports:
    - name: web
      containerPort: 80
    volumeMounts:
    - name: gluster-vol1
      mountPath: /usr/share/nginx/html
  volumes:
    - name: gluster-vol1
      persistentVolumeClaim:
        claimName: glusterfs-claim
kubectl apply -f nginx-test.yaml
# 在nginx 中添加内容,然后访问
kubectl exec -it nginx-test bash
cd /usr/share/nginx/html
echo "hellow gluster fs " >> index.html
ls
exit
kubectl forward nginx-test 1880:80
curl localhost:1880

安装失败问题

裸磁盘创建 device 失败

解决方法

1 先卸载安装

./gk-deploy -g --abort

2 清除 vg

[root@master1 deploy]# dmsetup ls
vg_d2ebbc4fc88ce69037db2da2b0a533f7-brick_90a958336d0e5b54b6f5643487805938      (253:6)
vg_d2ebbc4fc88ce69037db2da2b0a533f7-tp_90a958336d0e5b54b6f5643487805938-tpool   (253:4)
vg_d2ebbc4fc88ce69037db2da2b0a533f7-tp_90a958336d0e5b54b6f5643487805938_tdata   (253:3)
vg_d2ebbc4fc88ce69037db2da2b0a533f7-tp_90a958336d0e5b54b6f5643487805938_tmeta   (253:2)
vg_d2ebbc4fc88ce69037db2da2b0a533f7-tp_90a958336d0e5b54b6f5643487805938 (253:5)
# 注意顺序不能错,必须先brick 然后,不带任何字符的,然后 tpool ,tdata tmeta
$dmsetup remove vg_d2ebbc4fc88ce69037db2da2b0a533f7-brick_90a958336d0e5b54b6f5643487805938

$dmsetup remove vg_d2ebbc4fc88ce69037db2da2b0a533f7-tp_90a958336d0e5b54b6f5643487805938

$dmsetup remove vg_d2ebbc4fc88ce69037db2da2b0a533f7-tp_90a958336d0e5b54b6f5643487805938-tpool

$dmsetup remove vg_d2ebbc4fc88ce69037db2da2b0a533f7-tp_90a958336d0e5b54b6f5643487805938_tdata

$dmsetup remove vg_d2ebbc4fc88ce69037db2da2b0a533f7-tp_90a958336d0e5b54b6f5643487805938_tmeta

3 删除 gluster 相关文件

rm -rf /var/lib/glusterd

4 重置裸盘

$dd if=/dev/zero of=/dev/sdb bs=1k count=1
blockdev --rereadpt /dev/sdb

5 重启

pvc一直pending

此时有两种可能

  1. 网络不通
  2. storageclass 定义出现问题,或者heketi创建的集群出现问题

第一种情况,

检查网络是否畅通,进入一个pod 去 telnet 或者 ping heketi server的ip, 如果能平通,进一步访问

curl http://<heketi-server-ip>:<heketi-server-port>/hello

如何能拿到返回,说明网络是通的。

第二种情况

一般是heketi 初始化集群出现问题,需要删除heketi 的db,然后重新topology load 初始化集群,这个情况非常麻烦,甚至可能需要删除原先存在的volume。通过lsblk 命令查看gluster集群node的块存储情况,理论上应该是一样的,如果不一样,恭喜,需要重新初始化所有的glusterd systemd服务。

最新文章

查看更多

分类

关于

时光记录