k8s使用glusterfs(静态供给、动态供给)、glusterfs的安装与使用

前言

环境:centos7.9 、k8s 1.22.17
glusterfs的官网:https://docs.gluster.org/en/latest
glusterfs于 v1.25 弃用,具体可以查看https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes

注意注意了:k8s中可以使用静态、动态的方式供给glusterfs存储资源,但是两者的配置不相同,如果是静态,那么直接挂盘,创建lvm,创建文件系统,挂载,安装glusterfs集群,创建卷,k8s使用gluster即可。但是动态方式的话,需要结合heketi服务+glusterfs,由heketi服务管理、创建glusterfs集群,k8s中配置存储类指定heketi即可。heketi服务要求glusterfs服务器的磁盘必须是裸盘,不能是格式化的文件系统或lvm,这有点坑。所以这一点需要注意了。

主机准备

准备3台虚拟机或物理机,用于安装glusterfs文件系统作为storage服务器,并单独挂载一个磁盘用于存放数据,因为GlusterFS不建议共享根目录。
这里我使用的是3台虚拟机。

192.168.100.128
192.168.100.129
192.168.100.130

配置主机名、关闭防火墙、关闭selinux

略过,太简单了,自己做。

挂载磁盘

这里我们3台虚拟机都添加一块10G的磁盘。
在虚拟机页面添加磁盘后可以不用重启,使用下面的命令来在线扫描总线就能看到主机添加的磁盘了:

#在线识别磁盘
ls /sys/class/scsi_host/host*/scan				#查看有几个设备
echo "- - -" > /sys/class/scsi_host/host0/scan
echo "- - -" > /sys/class/scsi_host/host1/scan
echo "- - -" > /sys/class/scsi_host/host2/scan
#创建lv,用于给glusterfs使用的,命令如下
pvcreate /dev/sdb								#将新加的磁盘创建为pv
vgcreate GlusterFS /dev/sdb						#创建vg卷组,名为GlusterFS 
lvcreate -n GlusterFS -l +100%FREE  GlusterFS	#创建lv,名为GlusterFS,并分配卷组GlusterFS的100%空间给lv
mkfs.xfs /dev/GlusterFS/GlusterFS				#将lv格式化为xfs格式的文件系统
mkdir /GlusterFS								#创建挂载目录
mount /dev/GlusterFS/GlusterFS /GlusterFS	
vim /etc/fstab 
mount -a
df -Th

安装glusterfs服务端

在3个虚拟机上都要安装glusterfs服务端,具体可以参考https://blog.csdn.net/MssGuo/article/details/122182719,这里大概讲一下安装步骤:

#配置glusterfs的yum源
cat > /etc/yum.repos.d/glusterfs.repo <<EOF
[glusterfs]
name=glusterfs
baseurl=https://buildlogs.centos.org/centos/7/storage/x86_64/gluster-9/	
enabled=1
gpgcheck=0
EOF

#注意,官方有个https://buildlogs.centos.org/centos/7/storage/x86_64/gluster-10/的yum源,
# 但是发现使用这个10的后yum install glusterfs-server的时候显示没有glusterfs-server可用包,,只有glusterfs等客端端的包
#所以这里还是使用9的yum源
#安装glusterfs-server
yum install glusterfs-server
systemctl start glusterd.service
systemctl enable  glusterd.service
systemctl status  glusterd.service

glusterfs的端口

gluster守护进程端口24007,每创建一个逻辑卷,就会启动一个进程和端口,进程端口默认是49152,以此类推,第二个卷端口就是49153。

[root@node1 ~]# netstat  -lntup | grep gluster
tcp  0  0 0.0.0.0:24007  0.0.0.0:*   LISTEN  118886/glusterd   		#gluster守护进程的端口

分布式集群的结构

分布式集群一般有两种结构:

有中心节点:中心节点一般指管理节点;
无中心节点:所有节点又管理又做事,glusterfs属于这种模式;

这里我们主要使用的是中心节点的结构。

组成glusterfs集群

3台虚拟机都安装好glusterfs-server软件并启动之后,需要将这3节点组成集群,那么这3台storage服务器是如何组成一个集群的呢?
答:我们只需要在其中1台storage服务器上通过1条命令来连接另外2台storage服务器即可,这样就可以让这3台storage服务器组成一个集群了。

#在任意一台服务器上执行以下命令来组成集群:
gluster peer probe 192.168.100.129						#第2台服务器的IP,当然也可以指定主机名
peer probe: success
gluster peer probe 192.168.100.130						#第3台服务器的IP,当然也可以指定主机名
peer probe: success
gluster peer status										#查看已连接的主机状态
Number of Peers: 2										#这里看到有2个peers,但自己本身也是一个peer

Hostname: 192.168.100.129
Uuid: 40d1508f-f6b4-4059-8bd3-9334f6814f71
State: Peer in Cluster (Connected)

Hostname: 192.168.100.130
Uuid: 6b4a0de8-8f13-4ecf-89e6-efea569edff8
State: Peer in Cluster (Connected)

创建存储卷

glusterfs集群创建完成之后,那么这个glusterfs集群是如何共享存储呢?
答:创建逻辑卷,简称卷,就是每台storage服务器都捐点存储空间出来组成一个卷,就好像小时候捐钱一样;我们知道glusterfs是文件型存储,那么共享捐出来的就是目录。
glusterfs的逻辑卷类型有很多种,详情可以参考官网:https://docs.gluster.org/en/latest/Administrator-Guide/Setting-Up-Volumes/#arbiter-configuration-for-replica-volumes
这里为了最大化利用我的磁盘空间,创建的分布式卷,企业线上环境不能使用分布式逻辑卷,因为分布式类型卷没有高可用性,分布式卷把数据分散到各个服务器上,不具备副本,一旦有一个服务器数据丢失,整个卷的数据就崩了。

#创建分布式卷.不指定卷的类型,默认就是分布式卷
[root@master ~]# gluster volume create glusterfs-data 192.168.100.128:/GlusterFS 192.168.100.129:/GlusterFS 192.168.100.130:/GlusterFS
volume create: glusterfs-data: failed: The brick 192.168.100.128:/GlusterFS is a mount point. Please create a sub-directory under the mount point and use that as the brick directory. Or use 'force' at the end of the command if you want to override this behavior.
# 上面命令提示我的/GlusterFS是一个挂载点,建议使用子目录进行共享,可以加force强制创建。这里我的gluster就是供k8s使用的,所以干脆在/GlusterFS目录下创建要给k8s-data目录得了
mkdir /GlusterFS/k8s-data	#在3台服务器上都创建k8s-data目录

#继续创建分布式卷,成功
[root@master ~]# gluster volume create glusterfs-data 192.168.100.128:/GlusterFS/k8s-data 192.168.100.129:/GlusterFS/k8s-data 192.168.100.130:/GlusterFS/k8s-data
volume create: glusterfs-data: success: please start the volume to access data

启动卷

上面创建卷之后提示我们启动卷,我们先看下gluster volume的常用命令:

gluster volume help									#查看帮助信息
gluster volume list									#列出全部的卷
[root@master ~]# gluster volume info glusterfs-data	#查看指定卷的信息
Volume Name: glusterfs-data
Type: Distribute									#卷的类型
Volume ID: 8c29092d-e52b-4199-914e-f24d8c2e36eb
Status: Created										#状态是创建
Snapshot Count: 0
Number of Bricks: 3									#Bricks数量
Transport-type: tcp
Bricks:
Brick1: 192.168.100.128:/GlusterFS/k8s-data			#Bricks信息
Brick2: 192.168.100.129:/GlusterFS/k8s-data			#Bricks信息
Brick3: 192.168.100.130:/GlusterFS/k8s-data			#Bricks信息
Options Reconfigured:
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
[root@master ~]# gluster volume start glusterfs-data	#启动指定的卷
volume start: glusterfs-data: success
[root@master ~]#
[root@master ~]# gluster volume status all		#查看全部卷的状态
Status of volume: glusterfs-data
Gluster process                             TCP Port  RDMA Port  Online  Pid
------------------------------------------------------------------------------
Brick 192.168.100.128:/GlusterFS/k8s-data   49152     0          Y       91414	#可以看到,glusterfs-data卷启动了49152端口
Brick 192.168.100.129:/GlusterFS/k8s-data   49152     0          Y       46123
Brick 192.168.100.130:/GlusterFS/k8s-data   49152     0          Y       96450
 
Task Status of Volume glusterfs-data
------------------------------------------------------------------------------
There are no active volume tasks
[root@master ]# netstat -lntup | grep gluster			#查看端口
tcp        0      0 0.0.0.0:49152   0.0.0.0:*  LISTEN    91414/glusterfsd   #卷的端口 
tcp        0      0 0.0.0.0:24007   0.0.0.0:*  LISTEN    88420/glusterd     #守护进程端口
[root@master ]# ps -ef | grep gluster		#查看进程
root      88420      1  0 12月22 ?      00:00:02 /usr/sbin/glusterd -p /var/run/glusterd.pid --log-level INFO
root      91414      1  0 13:40 ?        00:00:00 /usr/sbin/glusterfsd -s 192.168.100.128 --volfile-id glusterfs-data.192.168.100.128.GlusterFS-k8s-data -p /var/run/gluster/vols/glusterfs-data/192.168.100.128-GlusterFS-k8s-data.pid -S /var/run/gluster/ff6877b3973ae742.socket --brick-name /GlusterFS/k8s-data -l /var/log/glusterfs/bricks/GlusterFS-k8s-data.log --xlator-option *-posix.glusterd-uuid=0c8e4a79-7458-44f7-beef-ffe54938480f --process-name brick --brick-port 49152 --xlator-option glusterfs-data-server.listen-port=49152
root     101726  39323  0 13:54 pts/0    00:00:00 grep --color=auto gluster

k8s使用glusterfs作为后端存储(静态供给glusterfs存储)

官网使用glusterfs示例:https://github.com/kubernetes/examples/tree/master/volumes/glusterfs
在k8s所有节点上都安装glusterfs的客户端:

第一、先在k8s所有节点上都安装glusterfs的客户端(主要是为了有mount.glusterfs这个命令)
1、添加FUSE内核模块:
modprobe fuse
2、查看fuse是否已经加载:
dmesg | grep -i fuse
[    0.611413] fuse init (API version 7.26)
3、安装依赖:
sudo yum -y install openssh-server wget fuse fuse-libs openib libibverbs
4、放行防火墙(这里我的虚拟机是关闭了防火墙,所以没有做这一步,请参考`https://docs.gluster.org/en/latest/Administrator-Guide/Setting-Up-Clients/#installing-on-red-hat-package-manager-rpm-distributions`5、 安装glusterfs客户端:
yum install  glusterfs glusterfs-fuse glusterfs-rdma
第二、k8s创建资源对象使用glusterfs存储(下面创建的资源都默认在default默认命名空间)
1、创建glusterfs-endpoints
可以参考: https://github.com/kubernetes/examples/blob/master/volumes/glusterfs/glusterfs-endpoints.yaml
vim glusterfs-endpoints.yaml
apiVersion: v1
kind: Endpoints
metadata:
  name: glusterfs-cluster
subsets:
- addresses:
  - ip: 192.168.100.128		#填写glusterfs IP地址
  ports:
  - port: 49152				#填写卷的端口(官网说在端口字段中提供任何有效值(从1到65535)都可以,所以这个端口有些网上教程写1的)
- addresses:
  - ip: 192.168.100.129		#填写glusterfs IP地址
  ports:
  - port: 49152				#填写卷的端口
- addresses:
  - ip: 192.168.100.130		#填写glusterfs IP地址
  ports:
  - port: 49152				#填写卷的端口

kubectl create -f glusterfs-endpoints.yaml
2、为这些端点创建一个service,以便它们能够持久,不需要标签选择器
vim glusterfs-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: glusterfs-cluster	#名字要与Endpoints名字一样才能进行管理
spec:
  ports:
  - port: 49152

kubectl create -f glusterfs-service.yaml
3、创建pv,pvc,pv中定义glusterfs的信息
apiVersion: v1
kind: PersistentVolume
metadata:
  name: glusterfs-pv
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: ""
  glusterfs:						#定义gluster的信息
    endpoints: glusterfs-cluster 	#指定glusterfs的endpoint
    endpointsNamespace: default		#指定glusterfs的endpoint的所属命名空间
    path: glusterfs-data			#指定glusterfs的卷名称
    readOnly: false   
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: glusterfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Filesystem
  resources:
    requests:
      storage: 5Gi
  storageClassName: ""
---
4、创建deployment、service
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - name: nginx 
          containerPort: 80
        volumeMounts:
        - name: pvc-volume				
          mountPath: /var/log/nginx		#持久化nginx的日志
      volumes:
      - name: pvc-volume
        persistentVolumeClaim:
          claimName: glusterfs-pvc 
          readOnly: false
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  sessionAffinity: None
  type: ClusterIP
---
经验证,静态glusterfs供给正常,查看glusterfs节点上/GlusterFS/k8s-data目录:
[root@node2 ~]# ll /GlusterFS/k8s-data/
总用量 8
-rw-r--r-- 2 root root 6310 1223 14:48 error.log

恢复初始化环境

k8s动态供给glusterfs存储,需要结合Heketi 服务来使用,Heketi 服务就是用于管理glusterfs集群的,可以创建gluster集群、创建管理卷等,但是Heketi 服务需要使用裸盘,而不是文件系统,所以这里需要恢复下我的环境。

#停止卷
gluster volume stop glusterfs-data
#删除卷
gluster volume delete glusterfs-data

#删除peers
gluster peer detach 192.168.100.129
gluster peer detach 192.168.100.130

#卸载lv,删除lv
umount /dev/GlusterFS/GlusterFS
lvremove /dev/GlusterFS/GlusterFS
vgremove GlusterFS
pvremove /dev/sdb
#删除挂载信息
vim /etc/fstab 


#靠,后面发现还是不行,白做了,后面Heketi初始化的时候报错了,说磁盘初始化过了,看来只能删除磁盘,重新挂一块裸盘了
#删除/dev/sdb,重新添加磁盘了。

安装Heketi 服务(实现k8s动态供给glusterfs存储需要用到Heketi 服务)

heketi是为glusterfs集群提供RESTFUL API的,通过restful风格对glusterfs集群进行管理控制。
在k8s官方文档中写到,要使用glusterfs作为后端动态供给存储,在存储类中要配置heketi的接口,并不是直接配置glusterfs的,所以我们需要安装Heketi 服务。
Heketi 服务的安装方式分为3种,OpenShift集群安装、Standalone独立单机安装、Kubernetes安装 ,我们采用Standalone独立单机安装方式。https://github.com/heketi/heketi/blob/master/docs/admin/readme.md、https://github.com/heketi/heketi/blob/master/docs/admin/install-standalone.md

#在线yum安装heketi服务端和客户端工具,heketi 也是在glusterfs源里面的,如果没有glusterfs源,参考上面的配置glusterfs的yum源
yum install  heketi heketi-client

#离线安装。参考官方网站https://github.com/heketi/heketi/releases,下载heketi二进制包并将服务配置为systemd管理启动即可

创建hekti用户并配置免密登录

创建免密登录的用户,因为官网要求heketi主机要能免密登录到glusterfs的主机上,这里我不在创建一个heketi用户,直接使用root用户,如果是非root用户,需要有sudo权限。

#使用root用户做免密登录
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.100.128
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.100.129
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.100.130

#如果使用的是heketi用户,需要在每个gluste节点上创建hekti用户
#给heketisudo权限echo "heketi    ALL=(ALL)       NOPASSWD: ALL" >> /etc/sudoers
#在heketi主机上安装heketi后默认就有heketi用户,但是这个用户没有home目录,也没有shell,
#所以可以先删除heketi用户在创建heketi用户,同时还需要修改文件的权限,如/etc/heketi/heketi.json属主权限等等因为默认是root权限,不修改等下启动有问题

修改heketi配置文件

通过`systemctl  status heketi.service;cat /usr/lib/systemd/system/heketi.service` 可以知道,heketi配置文件为/etc/heketi/heketi.json
#修改配置文件
官方文档`https://github.com/heketi/heketi/blob/master/docs/admin/server.md`
vim /etc/heketi/heketi.json
{
  "_port_comment": "Heketi Server Port Number",
  "port": "7890",	#Heketi服务端口,默认是8080,可以自定义

  "_use_auth": "Enable JWT authorization. Please enable for deployment",
  "use_auth": true,	#是否使用JWT authorization,设置为true

  "_jwt": "Private keys for access",
  "jwt": {
    "_admin": "Admin has access to all APIs",
    "admin": {
      "key": "admin123456"	#配置admin的密码
    },
    "_user": "User only has access to /volumes endpoint",
    "user": {
      "key": "admin123456"	#配置普通账号的密码
    }
  },

  "_glusterfs_comment": "GlusterFS Configuration",
  "glusterfs": {
    "_executor_comment": [		#这个是注释说明而已,解释了3中命令执行器,不用改
      "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."
    ],
    "executor": "ssh",					#命令执行器配置为ssh

    "_sshexec_comment": "SSH username and private key file information",
    "sshexec": {						#命令执行器为ssh方式,改下面这段
      "keyfile": "/root/.ssh/id_rsa",	#ssh的密钥
      "user": "root",					#ssh的用户,我使用的是root用户
      "port": "22",						#ssh的端口
      "fstab": "/etc/fstab"				#存储挂载点的fstab文件,保持默认即可
    },

    "_kubeexec_comment": "Kubernetes configuration",
    "kubeexec": {							#命令执行器没有用到kubernetes,不用改
      "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",		#heketi数据库文件,保持默认

    "_loglevel_comment": [
      "Set log level. Choices are:",
      "  none, critical, error, warning, info, debug",
      "Default is warning"
    ],
    "loglevel" : "warning"					#定义日志几级别
  }
}

启动heketi服务

#修改运行heketi服务的用户,默认是heketi用户,yum安装的时候默认创建了heketi用户,
#但是我们使用ssh的是root用户,所以需要修改一下运行heketi服务的用户
vim /usr/lib/systemd/system/heketi.service
User=root	#改为root

#启动heketi
systemctl daemon-reload 
systemctl start  heketi
systemctl enable heketi
systemctl status heketi
lsof  -i:7890

测试hekeit

curl http://192.168.100.128:7890/hello
Hello from Heketi

配置hekeit-cli客户端工具的环境变量

echo 'export HEKETI_CLI_SERVER=http://192.168.100.128:7890' >> ~/.bash_profile	#永久设置环境变量
echo 'export HEKETI_CLI_USER=admin'  >> ~/.bash_profile							#永久设置环境变量
echo 'export HEKETI_CLI_KEY=admin123456'  >> ~/.bash_profile						#永久设置环境变量
source  ~/.bash_profile															#立即生效

设置hekeit的topology文件

官网说必须向Heketi提供关于系统拓扑结构的信息。这允许Heketi决定使用哪些节点、磁盘和集群。
https://github.com/heketi/heketi/blob/master/docs/admin/topology.md
可以使用命令行客户端创建一个集群,然后向该集群添加节点,然后向每个节点添加磁盘。如果使用命令行,这个过程可能相当乏味。因此,命令行客户端支持使用拓扑文件将这些信息加载到Heketi,该拓扑文件描述集群、集群节点和每个节点上的磁盘信息。

#使用topology文件示例
heketi-cli topology load --json=<topology>	
#编写topology文件,这个拓扑文件是一个JSON格式的文件,描述要添加到Heketi的集群、节点和磁盘
官网示例:https://github.com/heketi/heketi/blob/master/client/cli/go/topology-sample.json
#手动编写一个拓扑文件
vim  /etc/heketi/topology.json 
{
    "clusters": [
        {
            "nodes": [
                {
                    "node": {				#配置glusterfs节点1的信息,包括IP地址,磁盘设备
                        "hostnames": {
                            "manage": [
                                "192.168.100.128"		
                            ],
                            "storage": [
                                "192.168.100.128"
                            ]
                        },
                        "zone": 1
                    },
                    "devices": [
                        {
                            "name": "/dev/sdb",			#磁盘设备,必须是裸盘
                            "destroydata": false
                        }
                    ]
                },
                {
                    "node": {
                        "hostnames": {
                            "manage": [
                                "192.168.100.129"
                            ],
                            "storage": [
                                "192.168.100.129"
                            ]
                        },
                        "zone": 1
                    },
                    "devices": [
                        {
                            "name": "/dev/sdb",
                            "destroydata": false
                        }
                    ]
                },
                {
                    "node": {
                        "hostnames": {
                            "manage": [
                                "192.168.100.130"
                            ],
                            "storage": [
                                "192.168.100.130"
                            ]
                        },
                        "zone": 1
                    },
                    "devices": [
                        {
                            "name": "/dev/sdb",
                            "destroydata": false
                        }
                    ]
                }
            ]
        }
    ]
}

#通过拓扑文件加载glusterfs节点到Heketi
[root@master heketi]# heketi-cli topology load --json=/etc/heketi/topology.json --server=http://192.168.100.128:7890 --user=admin --secret=admin123456
	Found node 192.168.100.128 on cluster f5dca07fd4e2edbe2e0b0ce5161a1cf7
		Adding device /dev/sdb ... OK
	Found node 192.168.100.129 on cluster f5dca07fd4e2edbe2e0b0ce5161a1cf7
		Adding device /dev/sdb ... OK
	Found node 192.168.100.130 on cluster f5dca07fd4e2edbe2e0b0ce5161a1cf7
		Found device /dev/sdb
[root@master heketi]# 

#查看信息,因为前面在/root/.bash_profile文件加了heketi-cli 客户端工具的环境变量,所以这里不用在写--server等参数
heketi-cli topology info

创建卷

发现好像不用创建卷,k8s可以直接使用。这里不创建卷。

k8s使用glusterfs作为后端存储(动态供给glusterfs存储)

上面,我们手动创建pv的形式实现了使用glusterfs作为后端存储,可是每次都要管理员手动创建pv很不现实,所以我们要实现采用动态供应存储的方式来实现k8s使用glusterfs存储:

1、创建一个srecrt,用户保存heketi服务的用户的密码,仅密码而已;
2、创建存储类;
3、一个制备器(Provisioner),k8s内置了glusterfs类型的Provisioner驱动,所以这里不用自己单独创建了;
4、创建pvc;
5、创建deployment,pod使用pvc进行数据持久化;

参考官网链接来创建:https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/
查看官方文档得知,k8s虽然内置了glusterfs的Provisioner(目前k8s说明会于1.25版本弃用glusterfs),但是创建存储类中的参数使用到了Heketi 服务,由Heketi 服务提供glusterfs。

1、创建secret,仅存储密码

vim heketi-secret.yaml			#创建secret,主要用于保存heketi服务的admin用户密码
apiVersion: v1
kind: Secret
metadata:
  name: heketi-secret
  namespace: default
data:
  # base64 encoded password. E.g.: echo -n "admin23456" | base64
  key: YWRtaW4xMjM0NTY=			#这个是heketi服务的admin用户密码admin123456,仅密码而已
type: kubernetes.io/glusterfs

#创建成功
kubectl apply -f heketi-secret.yaml		

2、创建存储类

官网参考文档:https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/#glusterfs
vim glusterfs-storageclass.yaml						#创建存储类	
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: glusterfs-storageclass						#存储名称
provisioner: kubernetes.io/glusterfs				#指定存储类的provisioner,这个provisioner是k8s内置的驱动程序
reclaimPolicy: Retain								#pvc删除,pv采用何种方式处理,这里是保留
volumeBindingMode: Immediate						#卷的绑定模式,表示创建pvc立即绑定pv
allowVolumeExpansion: true							#是否运行卷的扩容,配置为true才能实现扩容pvc
parameters:											#glusterfs的配置参数
  resturl: "http://192.168.118.140:7890"			#heketi服务的地址和端口
  clusterid: "0cb591249e2542d0a73c6a9c8351baa2"		#集群id,在heketi服务其上执行heketi-cli cluster list能看到
  restauthenabled: "true"							#Gluster REST服务身份验证布尔值,用于启用对 REST 服务器的身份验证
  restuser: "admin"									#heketi的用户admin
  secretNamespace: "default"						#secret所属的密码空间
  secretName: "heketi-secret"						#secret,使用secret存储了heketi的用户admin的登陆密码
  volumetype: "none"								#卷的类型,none表示分布式卷,还有其他类型的卷,详见官网参考文档

#创建成功
kubectl apply -f glusterfs-storageclass.yaml		

4、创建pvc

vim glusterfs-pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  labels:
    pvc: glusterfs
  name: glusterfs-pvc
  namespace: default
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 600Mi							#申请容量大小为600M
  storageClassName: glusterfs-storageclass		#指定使用的存储类

#创建成功
kubectl apply -f glusterfs-pvc.yaml 
#查看是否自动创建了pv,已经自动创建了pv,但是发现pvc、pv都变成了1Gi,这点不清楚为什么会这样,pvc明明定义的是600Mi,暂且不纠结这个问题
kubectl  get pvc -l pvc=glusterfs
NAME            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS             AGE
glusterfs-pvc   Bound    pvc-ca9f6b42-0db5-4ff2-b58d-0141575deb10   1Gi        RWX            glusterfs-storageclass   41s
kubectl  get pv  pvc-ca9f6b42-0db5-4ff2-b58d-0141575deb10
NAME   										CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM     STORAGECLASS    REASON   AGE
pvc-ca9f6b42-0db5-4ff2-b58d-0141575deb10    1Gi        	  RWX         Retain           Bound    default/glusterfs-pvc   glusterfs-storageclass            56s

5、创建deployment,使用pvc进行数据持久化

vim glusterfs-deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - name: nginx 
          containerPort: 80
        volumeMounts:
        - name: pvc-volume                              
          mountPath: /var/log/nginx             #持久化nginx的日志
      volumes:
      - name: pvc-volume
        persistentVolumeClaim:
          claimName: glusterfs-pvc 
          readOnly: false
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: default
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  sessionAffinity: None
  type: NodePort
---
#创建deployment资源
kubectl apply -f glusterfs-deployment.yaml 
网页访问nginx,模拟产生nginx日志。

6、探究日志数据落盘到哪里了
在任意一个节点执行lsblk我们发现如下情况:

[root@matser ~]# cat /etc/fstab		#自动挂载了

在这里插入图片描述

[root@node2 brick]# lsblk   #多了很多分区

在这里插入图片描述
/dev/sdb原本是一个没有格式化过的裸盘,现在却出现了挂载点,进入挂载点查看:

[root@node2 ~]# cd /var/lib/heketi/mounts/vg_f97dfb47e6aabb8dd41dd8405eb43cbf/brick_5d745e35a34df306e1e90ddc90f3085f
[root@node2 brick_5d745e35a34df306e1e90ddc90f3085f]# ls
brick
[root@node2 brick_5d745e35a34df306e1e90ddc90f3085f]# cd brick/
[root@node2 brick]# ls
access.log  error.log
[root@node2 brick]# echo "TEST"  >> access.log		#测试使用
#从上面我们看到,数据已经持久化到磁盘上了。
#下面来测试,删除deploymnet全部的pod,重新创建一个pod,查看pod能否读到之前的日志
[root@matser ~]# kubectl scale deployments.apps nginx --replicas=0
[root@matser ~]# kubectl get deployments.apps nginx
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   0/0     0            0           29m
[root@matser ~]# kubectl scale deployments.apps nginx --replicas=2
[root@matser ~]# kubectl  get pods -l app=nginx
NAME                     READY   STATUS    RESTARTS   AGE
nginx-78d9766679-cht5f   1/1     Running   0          53s
nginx-78d9766679-s7pft   1/1     Running   0          53s
[root@matser ~]# 
#直接进入pod查看日志,我们发现日志还是之前的日志,有TEST字样,说明日志持久化成功了
[root@matser ~]# kubectl  exec  -it nginx-78d9766679-cht5f -- cat /var/log/nginx/access.log
.............
10.244.219.64 - - [23/Dec/2022:14:50:13 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36" "-"
10.244.219.64 - - [23/Dec/2022:14:50:13 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36" "-"
TEST

社区上有个项目可以实现在k8s集群上安装Heketi和glusterfs: https://github.com/gluster/gluster-kubernetes

总结

1、glusterfs文件系统创建和使用;
2、k8s中可以使用静态供给glusterfs存储和动态供给glusterfs存储两种方式来使用glusterfs,但是这两种方式配置差别很大,
3、k8s静态供给glusterfs存储:正常创建lvm,挂载磁盘,创建挂载点,安装glusterfs文件系统,创建卷,k8s通过创建endpoint,endpoint中定义glusterfs的ip和卷端口,pv中配置endpoint来使用gluster的卷,创建pvc,创建pod挂载pvc使用数据持久化;
4、k8s动态供给glusterfs存储:不需要创建lvm,只能是裸盘,没有格式化过,没有分区,没有创建过文件系统的裸盘,安装glusterfs文件系统,不需创建peers,不需要创建卷,安装heketi服务,由heketi服务管理、创建glusterfs集群,不需要heketi创建卷,创建好gluster集群即可,k8s创建存储类,配置存储类指定heketi相关信息,创建pvc,pvc指定存储类,存储类会自动创建pv,创建pod挂载pvc使用数据持久化;

思考

k8s于 v1.25 版本弃用glusterfs,glusterfs是否还受欢迎;
pvc申请的容量大小明明是600Mi,怎么创建出来的却是1Gi呢;
k8s动态供给glusterfs存储时,heketi要求硬盘必须是裸盘,既然是裸盘,那就不需要我们参加创建文件系统,那文件随机挂载的吗?数据在落盘是背后的glusterfs逻辑是什么?
heketi要求硬盘必须是裸盘,那一块被格式化过的硬盘就真的没有办法使用了吗,这样岂不是很浪费硬件资源。

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
k8s搭配GlusterFS可以实现静态存储。在静态供给glusterfs存储的情况下,需要进行以下步骤: 1. 首先,准备好主机环境,包括配置主机名、关闭防火墙、关闭selinux等。\[1\] 2. 挂载磁盘并安装glusterfs服务端。可以使用glusterfs端口分布式集群的结构组成来创建存储卷。\[1\] 3. 启动卷,并将k8s配置为使用glusterfs作为后端存储。这样,就可以静态供给glusterfs存储了。\[1\] 需要注意的是,静态供给glusterfs存储的配置与动态供给glusterfs存储的配置不同。在静态供给的情况下,直接挂盘、创建lvm、创建文件系统、挂载、安装glusterfs集群、创建卷,然后k8s使用gluster即可。\[2\] 总结起来,通过在k8s中配置静态供给glusterfs存储,可以实现静态存储的需求。 #### 引用[.reference_title] - *1* *2* [k8s使用glusterfs静态供给动态供给)、glusterfs安装使用](https://blog.csdn.net/MssGuo/article/details/128409865)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [K8s存储与GlusterFS实战](https://blog.csdn.net/qq_35029061/article/details/127131348)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值