参考文档:

  1. Github project:https://github.com/heketi/heketi
  2. MANAGING VOLUMES USING HEKETI:https://access.redhat.com/documentation/en-us/red_hat_gluster_storage/3.3/html/administration_guide/ch05s02
  3. StorageClass:https://kubernetes.io/docs/concepts/storage/storage-classes/
  4. StorageClass(中文):https://k8smeetup.github.io/docs/concepts/storage/storage-classes/
  5. Dynamic Volume Provisioning:https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/

一.Heketi简介

1. 简介

Heketi是一个提供RESTful API管理GlusterFS卷的框架,便于管理员对GlusterFS进行操作:

  1. 可以用于管理GlusterFS卷的生命周期;
  2. 能够在OpenStack,Kubernetes,Openshift等云平台上实现动态存储资源供应(动态在GlusterFS集群内选择bricks构建volume);
  3. 支持GlusterFS多集群管理。

2. 框架

  1. Heketi支持GlusterFS多集群管理;
  2. 在集群中通过zone区分故障域。

二.环境

1. 环境

Kubernetes与GlusterFS集群已提前部署完成,请参考:

  1. Kubernetes:https://www.cnblogs.com/netonline/tag/kubernetes/
  2. 注意:GlusterFS只需要安装并启动即可,不必组建受信存储池(trusted storage pools)

Hostname

IP

Remark

kubenode1

172.30.200.21

 

kubenode2

172.30.200.22

 

kubenode3

172.30.200.23

 

heketi

172.30.200.80

selinux disabled

glusterfs01

172.30.200.81

 

glusterfs02

172.30.200.82

 

glusterfs03

172.30.200.83

 

2. 设置iptables

# 设置iptables,heketi默认以tcp8080端口提供RESTful API服务;
[root@heketi ~]# vim /etc/sysconfig/iptables
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT [root@heketi ~]# service iptables restart

三.部署heketi

1. 安装heketi

# 添加gluster yum源,默认yum源中无相关package;
# heketi:heketi服务
# heketi-client:heketi客户端/命令行工具
[root@heketi ~]# yum install -y centos-release-gluster
[root@heketi ~]# yum install -y heketi heketi-client

2. 配置heketi.json

# 注意红色字体是修改部分
[root@heketi ~]# vim /etc/heketi/heketi.json
{
# 默认端口tcp8080
"_port_comment": "Heketi Server Port Number",
"port": "", # 默认值false,不需要认证
"_use_auth": "Enable JWT authorization. Please enable for deployment",
"use_auth": true, "_jwt": "Private keys for access",
"jwt": {
"_admin": "Admin has access to all APIs",
"admin": {
"key": "admin@123"
},
"_user": "User only has access to /volumes endpoint",
"user": {
"key": "user@123"
}
}, "_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."
],
# mock:测试环境下创建的volume无法挂载;
# kubernetes:在GlusterFS由kubernetes创建时采用
"executor": "ssh", "_sshexec_comment": "SSH username and private key file information",
"sshexec": {
"keyfile": "/etc/heketi/heketi_key",
"user": "root",
"port": "",
"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"
],
# 默认设置为debug,不设置时的默认值即是warning;
# 日志信息输出在/var/log/message
"loglevel" : "warning"
}
}

3. 设置heketi免密访问GlusterFS

# 选择ssh执行器,heketi服务器需要免密登陆GlusterFS集群的各节点;
# -t:秘钥类型;
# -q:安静模式;
# -f:指定生成秘钥的目录与名字,注意与heketi.json的ssh执行器中"keyfile"值一致;
# -N:秘钥密码,””即为空
[root@heketi ~]# ssh-keygen -t rsa -q -f /etc/heketi/heketi_key -N "" # heketi服务由heketi用户启动,heketi用户需要有新生成key的读赋权,否则服务无法启动
[root@heketi ~]# chown heketi:heketi /etc/heketi/heketi_key # 分发公钥;
# -i:指定公钥
[root@heketi ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@172.30.200.81
[root@heketi ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@172.30.200.82
[root@heketi ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@172.30.200.83

4. 启动heketi

# 通过yum安装heketi,默认的systemd文件有1处错误;
# /usr/lib/systemd/system/heketi.service文件的”-config=/etc/heketi/heketi.json”应该修改为”--config=/etc/heketi/heketi.json”;
# 否则启动时报”Error: unknown shorthand flag: 'c' in -config=/etc/heketi/heketi.json“错,导致服务无法启动
[root@heketi ~]# systemctl enable heketi
[root@heketi ~]# systemctl restart heketi
[root@heketi ~]# systemctl status heketi

# 验证
[root@heketi ~]# curl http://localhost:8080/hello

四.设置GlusterFS集群

1. 创建topology.json文件

# 通过topology.json文件定义组建GlusterFS集群;
# topology指定了层级关系:clusters-->nodes-->node/devices-->hostnames/zone;
# node/hostnames字段的manage填写主机ip,指管理通道,在heketi服务器不能通过hostname访问GlusterFS节点时不能填写hostname;
# node/hostnames字段的storage填写主机ip,指存储数据通道,与manage可以不一样;
# node/zone字段指定了node所处的故障域,heketi通过跨故障域创建副本,提高数据高可用性质,如可以通过rack的不同区分zone值,创建跨机架的故障域;
# devices字段指定GlusterFS各节点的盘符(可以是多块盘),必须是未创建文件系统的裸设备
[root@heketi ~]# vim /etc/heketi/topology.json
{
"clusters": [
{
"nodes": [
{
"node": {
"hostnames": {
"manage": [
"172.30.200.81"
],
"storage": [
"172.30.200.81"
]
},
"zone": 1
},
"devices": [
"/dev/sdb"
]
},
{
"node": {
"hostnames": {
"manage": [
"172.30.200.82"
],
"storage": [
"172.30.200.82"
]
},
"zone": 2
},
"devices": [
"/dev/sdb"
]
},
{
"node": {
"hostnames": {
"manage": [
"172.30.200.83"
],
"storage": [
"172.30.200.83"
]
},
"zone": 3
},
"devices": [
"/dev/sdb"
]
}
]
}
]
}

2. 通过topology.json组建GlusterFS集群

# GlusterFS集群各节点的glusterd服务已正常启动,但不必组建受信存储池;
# heketi-cli命令行也可手动逐层添加cluster,node,device,volume等;
# “--server http://localhost:8080”:localhost执行heketi-cli时,可不指定;
# ”--user admin --secret admin@123 “:heketi.json中设置了认证,执行heketi-cli时需要带上认证信息,否则报”Error: Invalid JWT token: Unknown user”错
[root@heketi ~]# heketi-cli --server http://localhost:8080 --user admin --secret admin@123 topology load --json=/etc/heketi/topology.json

# 查看heketi topology信息,此时volume与brick等未创建;
# 通过”heketi-cli cluster info“可以查看集群相关信息;
# 通过”heketi-cli node info“可以查看节点相关信息;
# 通过”heketi-cli device info“可以查看device相关信息
[root@heketi ~]# heketi-cli --user admin --secret admin@123 topology info

五.K8S集群动态挂载GlusterFS存储

1. 基于StorageClass的动态存储流程

kubernetes共享存储供应模式:

  1. 静态模式(Static):集群管理员手工创建PV,在定义PV时需设置后端存储的特性;
  2. 动态模式(Dynamic):集群管理员不需要手工创建PV,而是通过StorageClass的设置对后端存储进行描述,标记为某种"类型(Class)";此时要求PVC对存储的类型进行说明,系统将自动完成PV的创建及与PVC的绑定;PVC可以声明Class为"",说明PVC禁止使用动态模式。

基于StorageClass的动态存储供应整体过程如下图所示:

  1. 集群管理员预先创建存储类(StorageClass);
  2. 用户创建使用存储类的持久化存储声明(PVC:PersistentVolumeClaim);
  3. 存储持久化声明通知系统,它需要一个持久化存储(PV: PersistentVolume);
  4. 系统读取存储类的信息;
  5. 系统基于存储类的信息,在后台自动创建PVC需要的PV;
  6. 用户创建一个使用PVC的Pod;
  7. Pod中的应用通过PVC进行数据的持久化;
  8. 而PVC使用PV进行数据的最终持久化处理。

2. 定义StorageClass

# provisioner:表示存储分配器,需要根据后端存储的不同而变更;
# reclaimPolicy: 默认即”Delete”,删除pvc后,相应的pv及后端的volume,brick(lvm)等一起删除;设置为”Retain”时则保留数据,需要手工处理
# resturl:heketi API服务提供的url;
# restauthenabled:可选参数,默认值为”false”,heketi服务开启认证时必须设置为”true”;
# restuser:可选参数,开启认证时设置相应用户名;
# secretNamespace:可选参数,开启认证时可以设置为使用持久化存储的namespace;
# secretName:可选参数,开启认证时,需要将heketi服务的认证密码保存在secret资源中;
# clusterid:可选参数,指定集群id,也可以是1个clusterid列表,格式为”id1,id2”;
# volumetype:可选参数,设置卷类型及其参数,如果未分配卷类型,则有分配器决定卷类型;如”volumetype: replicate:3”表示3副本的replicate卷,”volumetype: disperse:4:2”表示disperse卷,其中‘4’是数据,’2’是冗余校验,”volumetype: none”表示distribute卷#
[root@kubenode1 ~]# mkdir -p heketi
[root@kubenode1 ~]# cd heketi/
[root@kubenode1 heketi]# vim gluster-heketi-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gluster-heketi-storageclass
provisioner: kubernetes.io/glusterfs
reclaimPolicy: Delete
parameters:
resturl: "http://172.30.200.80:8080"
restauthenabled: "true"
restuser: "admin"
secretNamespace: "default"
secretName: "heketi-secret"
volumetype: "replicate:2" # 生成secret资源,其中”key”值需要转换为base64编码格式
[root@kubenode1 heketi]# echo -n "admin@123" | base64 # 注意name/namespace与storageclass资源中定义一致;
# 密码必须有“kubernetes.io/glusterfs” type
[root@kubenode1 heketi]# cat heketi-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: heketi-secret
namespace: default
data:
# base64 encoded password. E.g.: echo -n "mypassword" | base64
key: YWRtaW5AMTIz
type: kubernetes.io/glusterfs

# 创建secret资源
[root@kubenode1 heketi]# kubectl create -f heketi-secret.yaml # 创建storageclass资源;
# 注意:storageclass资源创建后不可变更,如修改只能删除后重建
[root@kubenode1 heketi]# kubectl create -f gluster-heketi-storageclass.yaml

# 查看storageclass资源
[root@kubenode1 heketi]# kubectl describe storageclass gluster-heketi-storageclass

3. 定义PVC

1)定义PVC

# 注意“storageClassName”的对应关系
[root@kubenode1 heketi]# vim gluster-heketi-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: gluster-heketi-pvc
spec:
storageClassName: gluster-heketi-storageclass
# ReadWriteOnce:简写RWO,读写权限,且只能被单个node挂载;
# ReadOnlyMany:简写ROX,只读权限,允许被多个node挂载;
# ReadWriteMany:简写RWX,读写权限,允许被多个node挂载;
accessModes:
- ReadWriteOnce
resources:
requests:
# 注意格式,不能写“GB”
storage: 1Gi # 创建pvc资源
[root@kubenode1 heketi]# kubectl create -f gluster-heketi-pvc.yaml

2)查看k8s资源

# 查看PVC,状态为”Bound”;
# “Capacity”为2G,是因为同步创建meta数据
[root@kubenode1 heketi]# kubectl describe pvc gluster-heketi-pvc

# 查看PV详细信息,除容量,引用storageclass信息,状态,回收策略等外,同时给出GlusterFS的Endpoint与path;
[root@kubenode1 heketi]# kubectl get pv
[root@kubenode1 heketi]# kubectl describe pv pvc-532cb8c3-cfc6-11e8-8fde-005056bfa8ba

# 查看endpoints资源,可以从pv信息中获取,固定格式:glusterfs-dynamic-PVC_NAME;
# endpoints资源中指定了挂载存储时的具体地址
[root@kubenode1 heketi]# kubectl describe endpoints glusterfs-dynamic-gluster-heketi-pvc

3)查看heketi

# volume与brick已经创建;
# 主挂载点(通信)在glusterfs01节点,其余两个节点备选;
# 两副本的情况下,glusterfs03节点并未创建brick
[root@heketi ~]# heketi-cli --user admin --secret admin@123 topology info

4)查看GlusterFS节点

# 以glusterfs01节点为例
[root@glusterfs01 ~]# lsblk

[root@glusterfs01 ~]# df -Th

# 查看volume的具体信息:2副本的replicate卷;
# 另有”vgscan”,”vgdisplay”也可查看逻辑卷组信息等
[root@glusterfs01 ~]# gluster volume list
[root@glusterfs01 ~]# gluster volume info vol_308342f1ffff3aea7ec6cc72f6d13cd7

4. Pod挂载存储资源

# 设置1个volume被pod引用,volume的类型为”persistentVolumeClaim”
[root@kubenode1 heketi]# vim gluster-heketi-pod.yaml
kind: Pod
apiVersion: v1
metadata:
name: gluster-heketi-pod
spec:
containers:
- name: gluster-heketi-container
image: busybox
command:
- sleep
- ""
volumeMounts:
- name: gluster-heketi-volume
mountPath: "/pv-data"
readOnly: false
volumes:
- name: gluster-heketi-volume
persistentVolumeClaim:
claimName: gluster-heketi-pvc # 创建pod
[root@kubenode1 heketi]# kubectl create -f gluster-heketi-pod.yaml

5. 验证

# 在容器的挂载目录中创建文件
[root@kubenode1 heketi]# kubectl exec -it gluster-heketi-pod /bin/sh
/ # cd /pv-data
/pv-data # echo "This is a file!" >> a.txt
/pv-data # echo "This is b file!" >> b.txt
/pv-data # ls

# 在GlusterFS节点对应挂载目录查看创建的文件;
# 挂载目录通过”df -Th”或”lsblk”获取
[root@glusterfs01 ~]# df -Th
[root@glusterfs01 ~]# cd /var/lib/heketi/mounts/vg_af339b60319a63a77b05ddbec1b21bbe/brick_d712f1543476c4198d3869c682cdaa9a/brick/
[root@glusterfs01 brick]# ls
[root@glusterfs01 brick]# cat a.txt
[root@glusterfs01 brick]# cat b.txt

6. 验证StorageClass的ReclaimPolicy

# 删除Pod应用后,再删除pvc
[root@kubenode1 heketi]# kubectl delete -f gluster-heketi-pod.yaml
[root@kubenode1 heketi]# kubectl delete -f gluster-heketi-pvc.yaml # k8s资源
[root@kubenode1 heketi]# kubectl get pvc
[root@kubenode1 heketi]# kubectl get pv
[root@kubenode1 heketi]# kubectl get endpoints

# heketi
[root@heketi ~]# heketi-cli --user admin --secret admin@123 topology info

# GlusterFS节点
[root@glusterfs01 ~]# lsblk
[root@glusterfs01 ~]# df -Th
[root@glusterfs01 ~]# gluster volume list

通过Heketi管理GlusterFS为K8S集群提供持久化存储的更多相关文章

  1. kubectl管理多个k8s集群

    #把每个k8s集群的json配置文件放到/root/.kube/目录下,改为不同名字,通过--kubeconfig实现不同集群操作 kubectl --kubeconfig=/root/.kube/m ...

  2. 强大多云混合多K8S集群管理平台Rancher入门实战

    @ 目录 概述 定义 为何使用 其他产品 安装 简述 规划 基础环境 Docker安装 Rancher安装 创建用户 创建集群 添加Node节点 配置kubectl 创建项目和名称空间 发布应用 偏好 ...

  3. 使用Rancher Server部署本地多节点K8S集群

    当我第一次开始我的Kubernetes之旅时,我一直在寻找一种设置本地部署环境的方式.很多人常常会使用minikube或microk8s,这两者非常适合新手在单节点集群环境下进行操作.但当我已经了解了 ...

  4. k8s集群搭建笔记(细节有解释哦)

    本文中所有带引号的命令,请手动输入引号,不知道为什么博客里输入引号,总是自动转换成了中文 基本组成 pod:k8s 最小单位,类似docker的容器(也许) 资源清单:资源.资源清单语法.pod生命周 ...

  5. 万级K8s集群背后etcd稳定性及性能优化实践

    背景与挑战 随着腾讯自研上云及公有云用户的迅速增长,一方面,腾讯云容器服务TKE服务数量和核数大幅增长, 另一方面我们提供的容器服务类型(TKE托管及独立集群.EKS弹性集群.edge边缘计算集群.m ...

  6. 万级K8s集群背后 etcd 稳定性及性能优化实践

    1背景与挑战随着腾讯自研上云及公有云用户的迅速增长,一方面,腾讯云容器服务TKE服务数量和核数大幅增长, 另一方面我们提供的容器服务类型(TKE托管及独立集群.EKS弹性集群.edge边缘计算集群.m ...

  7. k8s集群介绍

    Kubernetes集群组件 一个典型的Kubernetes集群由多个工作节点和一个集群控制节点,以及一个集群状态存储系统etcd组成.其中Master节点负责整个集群管理工作,为集群提供管理接口,并 ...

  8. Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录

    0.目录 整体架构目录:ASP.NET Core分布式项目实战-目录 k8s架构目录:Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录 一.感谢 在此感谢.net ...

  9. Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列之集群部署环境规划(一)

    0.前言 整体架构目录:ASP.NET Core分布式项目实战-目录 k8s架构目录:Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录 一.环境规划 软件 版本 ...

随机推荐

  1. MySQL 的 CURD 操作

    0. 说明 CURD 操作通常是使用关系型数据库系统中的结构化查询语言(Structured Query Language,SQL)完成的 CURD 定义了用于处理数据的基本原子操作 CURD 代表创 ...

  2. MySQL基础之 如何删除主键

    我们在一个表中设置了主键之后,那么如何删除主键呢? 删除主键的语法是: ALTER TABLE TABLE_NAME DROP PRIMARY KEY; 在这里我们要考虑两种情况: 1.可以直接使用d ...

  3. Django有关的所有命令

    1. Django的安装 pip install django ==1.11.11 pip install -i yuan django==1.11.11 2. 创建项目 django-admin s ...

  4. 1-100求和 sum(range(101))

    print(sum(range(101))) s = 0for i in range(101): s += iprint(s)  

  5. IOS和安卓不同浏览器常见bug

    一.IOS自带safari浏览器 1.safari不支持fixed.input输入框 iOS下的 Fixed + Input 调用键盘的时候fixed无效问题 拖动页面时 header 和 foote ...

  6. jQuery1.9+ 废弃的函数和方法 升级Jquery版本遇到的问题

    面临问题 很久没关注JQuery了,今天突然想升级一下系统中使用的jquery版本,突然发现,升级JQuery版本到1.9之后出现了很多问题,比如:$.browser is undefined.突然就 ...

  7. python第三十八课——面向对象(一)

    1.面向对象:(思想) 面向:看.关注.瞅 对象:个体.实体.实例.结果单词:object在python中一些皆对象 面向过程:(思想) 面向:看.关注.瞅 过程:经过.经历.从头到尾 使用一些生活中 ...

  8. 理解传说中的roll、yaw、pitch

    三维中 Yaw, pitch and roll 的区分(图片)                    yaw 航偏                                         pi ...

  9. Python2.7-copy_reg

    copy_reg 模块,提供了在 pickle 或是 copy 特定对象时,可以运行一个指定的函数,作为对象的构造器 模块方法: copy_reg.constructor(object):声明一个可调 ...

  10. JavaScript模块化思想之入门篇

    在写正文之前先写一点废话,从我大三下学期正式接触前端到现在,已经六个月了.自己从HTML,CSS,简单的JS验证开始,一点点开始走入前端的世界.越发的感觉前端这一领域散发着无穷的魅力,也许这和我真心喜 ...