GlusterFS Kurulum ve Yapılandırma

Deniz TÜRKMEN
13 min readAug 7, 2023

--

GlusterFS-9 & Heketi-10 & Kubernets v1.25

Merhabalar,

Bu yazımda ubuntu 20.04 üzerine glusterfs, heketi ve kubernetes cluster’ımızı kurup glusterfs ile dynamic provisioning storage nasıl yapıldığını inceliycez. İlk olarak glusterfs, heketi ne olduğunu bakalım.

GlusterFS: Disk depolama kaynaklarını birden çok sunucudan tek bir küresel ad alanında toplayan, ölçeklenebilir,açık kaynaklı, dağıtılmış bir dosya sistemidir.Açık kaynaklı bir dosya sistemi olan GlusterFS, disk birimlerini Pod’lara bağlamayı sağlar. High Availability ve Disaster Recovery yapılar sunar. Fiziksel veya Bulut ortamlarında çalışabilir. HA Object Storage için Glusterfs en iyi çözümlerden biridir.

Heketi: GlusterFS disklerini yönetmek için kullanılabilecek bir RESTful tabanlı yönetim arabirimi sağlar. Glusterfs için oluşturulmuştur ve diskleri dinamik olarak yönetmeyi sağlar. Heketi üzerindeki işlemler için heketi-cli tool çalışmaktadır. heketi-cli ile API üzerinden haberleşerek çalışır kubernetes bulununan storage class’ınızı glusterfs e bağlanmasını sağlar.

GlusterFS kurulumu için en az 3 farklı VM veya fiziksel makineye ihtiyaçımız var.

Not: Best practice olarak önerilen 3 node ve üstüdür ama isterseniz 2 node’lu kurulumda yapabilirsiniz.

Glusterfs kurulumu yapmadan önce disk işlemlerini yapmamız gerekiyor. Glusterfs LVM türünde disk olmalıdır. Disk oluşturma işlemi için;

Not: Eğer LVM yüklemezseniz heketi topology oluşturmaya çalıştığınız disk hatası alırsınız.

Tüm Glusterfs kurulumu yapacağınız node’lar aşağıdaki komutları uygulamalısınız. Bu örnekte sdb disk’ini LVM yapıp glusterfs bağlanması sağlanacaktır.

sudo apt install -y lvm

sudo fdisk /dev/sdb
n
p
enter
t
L
8e
w

Kontrol için;

sudo sfdisk -l /dev/sdb

Disk işlemi bittiğine göre. Şimdide glusterfs kurulumuna geçebiliriz.

192.168.1.25 glusterfs-cluster-25 --> GlusterFS + Heketi
192.168.1.26 glusterfs-cluster-26 --> GlusterFS
192.168.1.27 glusterfs-cluster-27 --> GlusterFS
---
192.168.1.7 k8s-master-1 -> kubernetes master 1

Not: Heketi isterseniz farklı bir makineye de kurabilirsiniz.

GlusterFS kurulumu yapacağımız tüm node’ların host’una ekliyoruz. Üç node’umuz içinde aşağıdaki IP ve Hostname ekleyip , sonrasında kaydedip çıkıyoruz.

Not: Tüm glusterfs kurulumu yapacak node’ların /etc/host ‘una eklemeliyiz.

sudo vim /etc/hosts

192.168.1.25 glusterfs-cluster-25
192.168.1.26 glusterfs-cluster-26
192.168.1.27 glusterfs-cluster-27

Şimdide GlusterFS tüm nodelara kurulumu yapalım. Bunun için terminal ekranında sıra ile aşağıdaki komutları çalıştıralım.

# For Ubuntu Install
sudo apt install software-properties-common
sudo add-apt-repository ppa:gluster/glusterfs-9
sudo apt update
sudo apt install -y glusterfs-server

GlusterFS servisi başlatıp enable ettikten sonra servisin durumuna bakalım.

sudo systemctl start glusterd
sudo systemctl enable glusterd
sudo systemctl status glusterd

GlusterFS versiona bakmak için;

sudo gluster --version

GlusterFS servisini ilgili node’lara başarılı şekilde kurduğumuza göre şimdide bu node’ların birbiri ile iletişimize geçmesi için bağlanması gerekiyor. Bunun için GlusterFS ortamımızdaki main makine olan 192.168.1.25 glusterfs-cluster-25 makinesinden aşağıdaki komutları terminal ekranından çalıştırıyoruz.

sudo gluster peer probe glusterfs-cluster-26
sudo gluster peer probe glusterfs-cluster-27

Bağlantıyı kontrol etmek için;

sudo gluster peer status

Evet. Başarılı şekilde GlusterFS node’larımızı birbirine connection olmasını sağladık. Şimdide glusterfs kullanışlı komut listesine bakalım.

sudo gluster --help
sudo gluster volume help
sudo gluster volume list

Görüldüğü gibi şuan bir volume olmadığı için boş gelmektedir. volume help komutu ile yapabilceklerinizi karıştırmanızı tavsiye ederim.

Sıra geldi heketi kurmaya. Heketinin ihtiyaç duyduğu kernel paketlerini yüklemek ile başlayalım.

sudo apt -y install thin-provisioning-tools 
sudo su
for i in dm_snapshot dm_mirror dm_thin_pool; do
sudo modprobe $i
done

İlk olarak heketi indirip gerekli config ayarlarını yapalım.

sudo wget https://github.com/heketi/heketi/releases/download/v10.4.0/heketi-v10.4.0-release-10.linux.amd64.tar.gz
sudo tar -xvf heketi-v10.4.0-release-10.linux.amd64.tar.gz
sudo chmod +x heketi/{heketi,heketi-cli}
sudo cp heketi/{heketi,heketi-cli} /usr/bin
sudo mkdir -p /var/lib/heketi /etc/heketi /var/log/heketi

Heketi ve heketi cli versiyonunu kontrol etmel için;

sudo heketi --version
sudo heketi-cli --version

Şimdide bir tane heketi group ve user oluşturalım.

sudo groupadd --system heketi
sudo useradd -s /sbin/nologin --system -g heketi heketi

heketi.json dosyasını ayarlayalım.

sudo cp heketi/heketi.json /etc/heketi
sudo vim /etc/heketi/heketi.json
{
"_port_comment": "Heketi Server Port Number",
"port": "8080",

"_enable_tls_comment": "Enable TLS in Heketi Server",
"enable_tls": false,

"_cert_file_comment": "Path to a valid certificate file",
"cert_file": "",

"_key_file_comment": "Path to a valid private key file",
"key_file": "",


"_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_comment": "Set the admin key in the next line",
"key": "PASSWORD"
},
"_user": "User only has access to /volumes endpoint",
"user": {
"_key_comment": "Set the user key in the next line",
"key": "PASSWORD"
}
},

"_backup_db_to_kube_secret": "Backup the heketi database to a Kubernetes secret when running in Kubernetes. Default is off.",
"backup_db_to_kube_secret": false,

"_profiling": "Enable go/pprof profiling on the /debug/pprof endpoints.",
"profiling": false,

"_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."
],
"executor": "ssh",

"_sshexec_comment": "SSH username and private key file information",
"sshexec": {
"keyfile": "/etc/heketi/heketi_key",
"user": "root",
"port": " 22",
"fstab": "/etc/fstab"
},


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

"_refresh_time_monitor_gluster_nodes": "Refresh time in seconds to monitor Gluster nodes",
"refresh_time_monitor_gluster_nodes": 120,

"_start_time_monitor_gluster_nodes": "Start time in seconds to monitor Gluster nodes when the heketi comes up",
"start_time_monitor_gluster_nodes": 10,

"_loglevel_comment": [
"Set log level. Choices are:",
" none, critical, error, warning, info, debug",
"Default is warning"
],
"loglevel" : "debug",

"_auto_create_block_hosting_volume": "Creates Block Hosting volumes automatically if not found or exsisting volume exhausted",
"auto_create_block_hosting_volume": true,

"_block_hosting_volume_size": "New block hosting volume will be created in size mentioned, This is considered only if auto-create is enabled.",
"block_hosting_volume_size": 500,

"_block_hosting_volume_options": "New block hosting volume will be created with the following set of options. Removing the group gluster-block option is NOT recommended. Additional options can be added next to it separated by a comma.",
"block_hosting_volume_options": "group gluster-block",

"_pre_request_volume_options": "Volume options that will be applied for all volumes created. Can be overridden by volume options in volume create request.",
"pre_request_volume_options": "",

"_post_request_volume_options": "Volume options that will be applied for all volumes created. To be used to override volume options in volume create request.",
"post_request_volume_options": ""
}
}

heketi.json da bilmemiz gerekenler;

  • admin user şifresi belirlemeniz.
  • heketi port 8080 ama başka port’u da verebilirsiniz.
  • db loglarının tutulduğu konum

Not: Password yazan kısma kendi belirlediğiniz password girmelisiniz. Çünkü heketi-topology yüklerken gerekecektir.

Bu örnek için;

admin_password        ivd7dfORN7QNeKVO
user_password gZPgdZ8NtBNj6jfp

Şimdide tüm glusterfs birbirine password sormadan bağlanması için ssh_keygen oluşturmalıyız ve bu ssh userları root user ayarı yapmak zorundasınız.

Not: Heketi adımlarını sadece heketi kurduğumuz makine de yapıyoruz.

sudo ssh-keygen -f /etc/heketi/heketi_key -t rsa -N ''
cd /etc/heketi
ll
sudo chown heketi:heketi /etc/heketi/heketi_key*

heketi group’una ekmeyide unutmuyoruz ( chown) ile.

Şimdide bu oluşturduğumuz public ssh-keygen ni tüm glusterfs node’larına authorized_keys eklemeliyiz. Bunun için;

sudo su 
for i in glusterfs-cluster-25 glusterfs-cluster-26 glusterfs-cluster-27; do
ssh-copy-id -i /etc/heketi/heketi_key.pub root@$i
done

3 makine içinde yes ve sonrasında root şifrelerini girmeliyiz.

Kontrol etmek için;

sudo ssh -i /etc/heketi/heketi_key root@glusterfs-cluster-25
sudo ssh -i /etc/heketi/heketi_key root@glusterfs-cluster-26
sudo ssh -i /etc/heketi/heketi_key root@glusterfs-cluster-27

Not: Bu işlemleri yapmadan heketi servisini oluşturur ve başlatmaya çalışırsanız hata alırsınız.

Heketi env dosyasını indirelim.

sudo wget -O /etc/heketi/heketi.env https://raw.githubusercontent.com/heketi/heketi/master/extras/systemd/heketi.env
sudo chown -R heketi:heketi /var/lib/heketi /var/log/heketi /etc/heketi

Son olarak heketi service oluşturalım.

sudo vim /etc/systemd/system/heketi.service
[Unit]
Description=Heketi Server
[Service]
Type=simple
WorkingDirectory=/var/lib/heketi
EnvironmentFile=-/etc/heketi/heketi.env
User=heketi
ExecStart=/usr/bin/heketi --config=/etc/heketi/heketi.json
Restart=on-failure
StandardOutput=syslog
StandardError=syslog
[Install]
WantedBy=multi-user.target

heketi servisinde bilmemiz gerekenler;

  • environment file: env file yolunu göstermeliyiz
  • user: hangi user heketi config dosyalarını kullanıyorsa onu tanımlamalıyız.

Heketi servis reload, enable ve start edip bakalım.

sudo systemctl start heketi
sudo systemctl daemon-reload
sudo systemctl enable heketi
sudo systemctl status heketi

Son olarak ta heketi portunu kontrol edelim.

sudo apt update
sudo apt install -y net-tools
# Check
sudo netstat -tuplen | grep LISTEN | grep heketi

Heketi servisini test etmek için;

sudo apt update
sudo apt install -y curl
curl http://glusterfs-cluster-25:8080/hello

Evet. başarılı şekilde heketi service imizi oluşturduk. Şimdide topology oluşturalım.

sudo vim /etc/heketi/topology.json
{
"clusters": [
{
"nodes": [
{
"node": {
"hostnames": {
"manage": [
"glusterfs-cluster-25"
],
"storage": [
"192.168.1.25"
]
},
"zone": 1
},
"devices": [
"/dev/sdb1"
]
}, {
"node": {
"hostnames": {
"manage": [
"glusterfs-cluster-26"
],
"storage": [
"192.168.1.26"
]
},
"zone": 1
},
"devices": [
"/dev/sdb1"
]
}, {
"node": {
"hostnames": {
"manage": [
"glusterfs-cluster-27"
],
"storage": [
"192.168.1.27"
]
},
"zone": 1
},
"devices": [
"/dev/sdb1"
]
}
]
}
]
}

Topology config te bilmemiz gerekenler;

  • GlusterFS dahil olan tüm node’ların hostname, Ip adresi ve zone türüdür.

Topology kaydedip çıktından sonra heketi user ve roups izni verelin.

sudo chown -R heketi:heketi /var/lib/heketi /var/log/heketi /etc/heketi

Topology oluşturmak için;

sudo heketi-cli topology load --user admin --secret heketi_admin_secret --json=/etc/heketi/topology.json 

Not: Burada Ok görmelisiniz. Eğer disk’iniz mount olmazsa başka bir hata alırsınız.

Heketi cli-user,passwprd ve host bilgilerini bashrc ekleyelim. Bunu /etc/heketi/heketi.env altında yapabilirsiniz.

sudo vim ~/.bashrc
export HEKETI_CLI_SERVER=http://192.168.1.25:8080
export HEKETI_CLI_USER=admin
export HEKETI_CLI_KEY="ivd7dfORN7QNeKVO"
source ~/.bashrc

Heketi cli kullanışlı komutlarına bakalım. Bizim için önemli olan admin user ve clusterid. Çünkü kubernetes dynamic storage oluştururken lazım olacaktır.

heketi-cli --help
heketi-cli cluster list

ClusterID bizim için çok önemlidir.

heketi-cli node list

heketi-cli node info ID
heketi-cli topology info
heketi-cli cluster info clusterid

glusterfs servis logları;

sudo tail -f /var/log/glusterfs/glusterd.log

Son olarak heketi ile bir volume oluşturalım ve glıusterfs node’larına yazılıp yazılmadığını kontrol edelim.

heketi-cli volume create --size=1

Kontrol edelim;

heketi-cli volume list

Görüldüğü gibi glusterfs default volume “vol_” prefix ile oluşturulmuştur.

heketi-cli topology info

Görüldüğü gibi 3 glusterfs node’una volume başarılı şekilde oluşturulmuştur. Ek olarak volume list bakarsanız;

sudo gluster volume list

Şimdide hızlıca bir kubernetes cluster’ı kuralım.

OS upgrade and reboot machine
``` bash
sudo apt update
sudo apt -y full-upgrade

```

Install kubelet, kubeadm and kubectl
``` bash
sudo apt install curl apt-transport-https -y
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg|sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/k8s.gpg
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt update

## List of package command
sudo apt list kubeadm -a

## Installation latest version command below
sudo apt install kubelet kubeadm kubectl -y

## Specific version installation
sudo apt install -y kubelet=1.25.1-00 kubeadm=1.25.1-00 kubectl=1.25.1-00

## Check version
kubelet --version
kubectl version
kubeadm version

## hold
sudo apt-mark hold kubelet kubeadm kubectl

```

##Disable Swap Space
``` bash
## Temporary
sudo swapoff -a

## Permanently
sudo vim /etc/fstab
# swapfile -> adding in front of swapfile #

## Confirm setting is correct
sudo mount -a
free -h

```

Enable kernel modules and configure sysctl
``` bash
# Enable kernel modules
sudo modprobe overlay
sudo modprobe br_netfilter

# Add some settings to sysctl
sudo tee /etc/sysctl.d/kubernetes.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

# Reload sysctl
sudo sysctl --system

```

Install Container runtime (Master and Worker nodes)
``` bash
## Instalation containerd

# Configure persistent loading of modules
sudo tee /etc/modules-load.d/k8s.conf <<EOF
overlay
br_netfilter
EOF

# Load at runtime
sudo modprobe overlay
sudo modprobe br_netfilter

# Ensure sysctl params are set
sudo tee /etc/sysctl.d/kubernetes.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

# Reload configs
sudo sysctl --system

# Install required packages
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates

# Add Docker repo
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

# Install containerd
sudo apt update
sudo apt install -y containerd.io

# Configure containerd and start service
sudo su -
mkdir -p /etc/containerd
containerd config default>/etc/containerd/config.toml

# restart containerd
sudo systemctl restart containerd
sudo systemctl enable containerd
sudo systemctl status containerd


# To use the systemd cgroup driver, set plugins.cri.systemd_cgroup = true
cat /etc/containerd/config.toml | grep SystemdCgroup
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml

```

Initialize control plane (run on first master node)
``` bash
## br_netfilter module is loaded
lsmod | grep br_netfilter

## Enable kubelet service
sudo systemctl enable kubelet

## Pull container images
sudo kubeadm config images pull

## If you have multiple CRI sockets, please use --cri-socket to select one:
## Containerd
sudo kubeadm config images pull --cri-socket /run/containerd/containerd.sock

## Bootstrap with shared endpoint (DNS name for control plane API)
sudo vim /etc/hosts
IP_Addreses Dns_Name

192.168.1.7 kubernetes.glusterfs.deniz.master.internal
192.168.1.7 k8s-master-1

# Create cluster
sudo kubeadm init --control-plane-endpoint="kubernetes.glusterfs.deniz.master.internal:6443" --apiserver-advertise-address=192.168.1.7 --node-name k8s-master-1 --pod-network-cidr=192.168.0.0/24

# To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Kubernetes master node’umuzu kontrol edelim.

kubectl get nodes -owide

Conatainer network interface yükleyelim. (WeaveNet )

kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml

CNI yükledikten sonra tekrar kontrol ettiğimizde;

kubectl get nodes -owide

Başarılı şekilde kubernetes cluster’ımız kurulumu gerçekleştirdik. Glusterfs var olan kubernetes cluster’ımıza static ve dynamic olarak bağlayabiliriz. Biz burada dynamic provision yapacağız.

Ilk olarak heketi cluster’ımızı kontrol edelim.

heketi-cli cluster list

Tüm kubernetes nodelarına master ve worker glusterfs-client paketini kuruyoruz.

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:gluster/glusterfs-9
sudo apt install glusterfs-client -y

Not: Glusterfs versiyonu ne ise glusterfs-client versiyonu aynı olmaldır.

Şimdide bir tane k8s-secret oluşturalım. Secret bildiğiniz gibi base64 formatında key-value ekleyebilirsiniz. Bunun için /etc/heketi/heketi.json dosyasındaki admin password’unu base64 türünde eklemelisiniz.

echo -n "PASSWORD" | base64

#For this example,
echo -n "ivd7dfORN7QNeKVO" | base64

#Check
echo -n "aXZkN2RmT1JON1FOZUtWTw==" | base64 -d
apiVersion: v1
kind: Secret
metadata:
name: heketi-secret
namespace: default
type: "kubernetes.io/glusterfs"
data:
# echo -n "ivd7dfORN7QNeKVO" | base64
key: aXZkN2RmT1JON1FOZUtWTw==
type: kubernetes.io/glusterfs
kubectl apply -f gluster-heketi-secret.yaml 

kubectl get secret

Görüldüğü gibi secret oluşturduk. Şimdide Storage oluşturalım.

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gluster-heketi
provisioner: kubernetes.io/glusterfs
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true
parameters:
resturl: "http://192.168.1.25:8080"
restuser: "admin"
secretName: "heketi-secret"
secretNamespace: "default"
volumetype: "replicate:2"
volumenameprefix: "k8s-dev"
clusterid: "c4bf3993b3c7ef4c98ca73006620770a"

---

Storage.yaml bilmemiz gerekenler;

  • resturl: heketi kurulu olduğ makine IP:Port
  • restuser: heketi.json içersindeki user
  • volumetype: kaç replica tutulacağı
  • volumenameprefix: oluşturulan volume prefix
  • clusterid: En önemlisi clusterid dir. “heketi-cli cluster list” baktığınızda gelen unique id dir.
kubectl apply -f gluster-heketi-storage.yaml 
kubectl get sc

Son olarakta bir tane persistent volume claims oluşturalım.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gluster-pvc
annotations:
volume.beta.kubernetes.io/storage-class: gluster-heketi
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
kubectl apply -f gluster-heketi-pvc.yaml 
kubectl get pvc
kubectl get pv

Evet görüldüğü gibi pvc bound oldu. Şimdide bir tane pod oluşturalım. Sonrasında glusterfs node’larmızdan kontrol edelim.

apiVersion: v1
kind: Pod
metadata:
name: gluster-pod
labels:
name: gluster-pod
spec:
containers:
- name: gluster-pod
image: busybox
command: ["sleep", "60000"]
volumeMounts:
- name: gluster-vol
mountPath: /usr/share/busybox
readOnly: false
volumes:
- name: gluster-vol
persistentVolumeClaim:
claimName: gluster-pvc
kubectl apply -f gluster-heketi-pod.yaml 
kubectl get pods

Evet görüldüğü gibi pod’umuzda persistent volume claims bağlandı. Son olarak glusterfs kontrol edelim.

sudo gluster volume list

Baktığımızda gördüğünüz gibi bizim volume-prefix’imiz alan bir tane volume oluşturulmuş.

sudo gluster volume info

Son dedim ama son bir şey daha pod’un içerisine girerek pvc bağladığımız /usr/share/busybox yere test isminde bir dosya oluşturup içerisine rastgele bir şey yazalım.

kubectl get pods
kubectl exec -it gluster-pod -- sh

Şimdide glusterfs yüklü olduğu 192.168.1.25 makinesine gidelim.

sudo gluster volume info

Evet görüldüğü gibi biz replicayı storageclass objemizde 2 olarak ayarladığımız için 2 node yazmış.


Brick1: 192.168.1.25:/var/lib/heketi/mounts/vg_c272f5ab5dad8e2f4d5f0f90f3e60ab4/brick_61dabf5d22a792b100ac53bf22ca66bf/brick

İlgili folder’a gittiğimizde;

sudo su
cd /var/lib/heketi/mounts/vg_c272f5ab5dad8e2f4d5f0f90f3e60ab4/brick_61dabf5d22a792b100ac53bf22ca66bf/brick
cat test

Başarılı şekilde state sağlamış olduk. Github kurulum dosyaları buradan ulaşabilirsiniz.

--

--