GlusterFS + Heketi Kurulumu (Kubernetes Dynamic Volume Provisioning)

Arif KIZILTEPE
5 min readSep 10, 2022

--

Kubernetes ortamımızda çalıştıracağımız her uygulama stateless olmuyor bazen stateful uygulamalar oluşturmamız gerekiyor. Bu durumda bizim kubernetes üzerinde persistent volumes tanımları yaparak uygulamalarımızın datalarını burada tutmamız gerekiyor. GlusterFS ise bize HA disk yönetimi sağlıyor ve bunu kubernetes ortamına bağlayabiliyoruz.

Bu yazıda kullanacağım ortamı detaylarını aşağıdaki yazılarımdan okuyarak inceleyebilirsiniz.

1. GlusterFS Kurulumu

# OS DEBIAN 10
# /etc/hosts
10.30.90.18 VTGENK8SGUS01
10.30.90.19 VTGENK8SGUS02
10.30.90.20 VTGENK8SGUS03
# 300GB /dev/sdc

Tüm sunuculara glusterfs kurulumu yapıyoruz.

wget -O - https://download.gluster.org/pub/gluster/glusterfs/9/rsa.pub | apt-key add -DEBID=$(grep 'VERSION_ID=' /etc/os-release | cut -d '=' -f 2 | tr -d '"')DEBVER=$(grep 'VERSION=' /etc/os-release | grep -Eo '[a-z]+')DEBARCH=$(dpkg --print-architecture)echo deb https://download.gluster.org/pub/gluster/glusterfs/LATEST/Debian/${DEBID}/${DEBARCH}/apt ${DEBVER} main > /etc/apt/sources.list.d/gluster.listapt update && apt install glusterfs-server

VTGENK8SGUS01 sunucusundan aşağıdaki komutları çalıştırarak 3 sunucunun birbirleri ile haberleşmesini sağlıyoruz.

gluster peer probe VTGENK8SGUS02gluster peer probe VTGENK8SGUS03

Kontrol etmek için.

gluster peer status

2. Heketi Kurulumu

Heketi Glusterfs ortamımızı kubernetes topolojisine bağlamamıza yarayan bir operatördür.

Heketi uygulamasını VTGENK8SGUS01 üzerine yapacağız. Heketi uygulaması indirilir ve gerekli dizinlere taşınır.

wget https://github.com/heketi/heketi/releases/download/v10.4.0/heketi-v10.4.0-release-10.linux.amd64.tar.gzchmod +x heketi/{heketi,heketi-cli}cp heketi/{heketi,heketi-cli} /usr/local/binmkdir -p /var/lib/heketi /etc/heketi /var/log/heketi

/etc/heketi/heketi.json dosyası oluşturulur ve aşağıdaki config yazılır. YOUR_SECRET yazan alanları kendi bilgileriniz ile doldurun.

{
"_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": "YOUR_SECRET"
},
"_user": "User only has access to /volumes endpoint",
"user": {
"key": "YOUR_SECRET"
}
},
"_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 uygulaması için gerekli kernel modülleri yüklenir.

for i in dm_snapshot dm_mirror dm_thin_pool; do
sudo modprobe $i
done

Heketi uygulaması için ssh key oluşturulur ve 3 glusterfs sunucusuna key eklenir.

ssh-keygen -f /etc/heketi/heketi_key -t rsa -N ''chown heketi:heketi /etc/heketi/heketi_key*for i in VTGENK8SGUS01 VTGENK8SGUS02 VTGENK8SGUS03; do
ssh-copy-id -i /etc/heketi/heketi_key.pub root@$i
done

/etc/systemd/system/heketi.service dosyası oluşturulur ve aşağıdaki konfig eklenir.

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

Uygulama başlatılır.

systemctl daemon-reload
systemctl enable --now heketi

Şimdi heketi operatörü ile glusterfs üzerinde cluster oluşturacağız. Bunun için /etc/heketi/topology.json dosyası oluşturulur ve aşağıdaki config eklenir.

{
"clusters": [
{
"nodes": [
{
"node": {
"hostnames": {
"manage": [
"VTGENK8SGUS01"
],
"storage": [
"10.30.90.18"
]
},
"zone": 1
},
"devices": [
"/dev/sdc"
]
}, {
"node": {
"hostnames": {
"manage": [
"VTGENK8SGUS02"
],
"storage": [
"10.30.90.19"
]
},
"zone": 1
},
"devices": [
"/dev/sdc"
]
}, {
"node": {
"hostnames": {
"manage": [
"VTGENK8SGUS03"
],
"storage": [
"10.30.90.20"
]
},
"zone": 1
},
"devices": [
"/dev/sdc"
]
}
]
}
]
}

Config dosyasını kullanarak cluster oluşturulur.

heketi-cli topology load --json=/etc/heketi/topology.jsonheketi-cli cluster list

3. Kubernetes Konfigürasyon ve Test

Oluşturduğumuz cluster storage yapısını kubernetes topolojisine entegre etmek için Kubernetes StorageClass oluşturmamız gerekiyor. Bu işlem öncesinde Heketi cluster id ve heketi.json içerisinde belirttiğimiz admin şifresinin base64 çıktısı gerekiyor.

heketi-cli cluster listecho -n "PASSWORD" | base64

Kubernetes üzerinde secret oluşturuyoruz.

cat <<EOF > gluster-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: heketi-secret
namespace: default
type: "kubernetes.io/glusterfs"
data:
# echo -n "PASSWORD" | base64
key: cGFzc3dvcmQ=
EOF
kubectl apply -f gluster-secret.yaml

StorageClass oluşturulur.

cat <<EOF > gluster-storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gluster-heketi
provisioner: kubernetes.io/glusterfs
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true
parameters:
resturl: "http://10.30.90.18:8080"
restuser: "admin"
secretName: "heketi-secret"
secretNamespace: "default"
volumetype: "replicate:3"
volumenameprefix: "k8s-test"
clusterid: "8a1dc03e9f7c71191796422adsd281b"
EOF
kubectl apply -f gluster-storageclass.yaml

Evet oluşturduğumuz HA storage kubernetes ortamımıza bağlandı. Şimdi bunu test etmek için pvc ve bir adet pod oluşturalım.

cat <<EOF > gluster-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gluster-pvc
annotations:
volume.beta.kubernetes.io/storage-class: gluster-heketi
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
EOF
kubectl apply -f gluster-pvc.yaml
cat <<EOF > glusterfs-demo-pod.yaml
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: glusterfs-pvc
EOF
kubectl apply -f glusterfs-demo-pod.yaml

Heketi sunucusundan aşağıdaki komutu çalıştırdığımızda istediğimiz volume oluştuğunu görüyoruz.

heketi-cli volume list

--

--

No responses yet