Encontrar o armazenamento ideal é um processo bastante complicado, tudo tem seus prós e contras. Obviamente, o líder nesta categoria é o CEPH, mas é um sistema bastante complexo, embora com uma funcionalidade muito rica. Para nós, esse sistema é redundante, uma vez que precisávamos de um armazenamento replicado simples no modo mestre-mestre por alguns terabytes. Tendo estudado muito material, decidiu-se testar o produto mais moderno do mercado para o circuito em que estamos interessados. Devido ao fato de não ter sido encontrada uma solução pronta para esse plano, gostaria de compartilhar minhas práticas recomendadas sobre este tópico e descrever os problemas que encontramos no processo de implantação.Metas
O que esperávamos do novo repositório:- Capacidade de trabalhar com um número par de nós para replicação.
- Fácil instalação, configuração, suporte
- O sistema deve ser adulto, testado pelo tempo e usuários
- Capacidade de expandir o espaço de armazenamento sem tempo de inatividade
- O armazenamento deve ser compatível com o Kubernetes
- Deve haver um failover automático quando um dos nós falha
É no último ponto que temos muitas perguntas.Desdobramento, desenvolvimento
Para implantação, duas máquinas virtuais foram criadas no CentOs 8. Cada uma delas é conectada através de um disco adicional com armazenamento.Preparação preliminar
Para o GlusterFS, você precisa alocar um disco separado com o XFS para que ele não afete o sistema de nenhuma maneira.Selecione a partição:$ fdisk /dev/sdb
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-16777215, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-16777215, default 16777215):
Created a new partition 1 of type ‘Linux’ and of size 8 GiB.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table. Syncing disks.
Formate no XFS e monte:$ mkfs.xfs /dev/sdb1
$ mkdir /gluster
$ mount /dev/sdb1 /gluster
E ainda por cima, solte a entrada em / etc / fstab para montar automaticamente o diretório na inicialização do sistema:/dev/sdb1 /gluster xfs defaults 0 0
Instalação
Em relação à instalação, muitos artigos foram escritos; nesse contexto, não iremos aprofundar o processo, apenas consideraremos o que vale a pena prestar atenção.Nos dois nós, instale e execute a versão mais recente glusterfs:$ wget -P /etc/yum.repos.d https://download.gluster.org/pub/gluster/glusterfs/LATEST/CentOS/glusterfs-rhel8.repo
$ yum -y install yum-utils
$ yum-config-manager --enable PowerTools
$ yum install -y glusterfs-server
$ systemctl start glusterd
Em seguida, você precisa informar ao glaster onde está o nó vizinho. Isso é feito com apenas um nó. Um ponto importante: se você possui uma rede de domínio, deve especificar o nome do servidor com o domínio; caso contrário, no futuro, precisará refazer tudo.$ gluster peer probe gluster-02.example.com
Se foi bem-sucedido, verificamos a conexão com o comando de ambos os servidores:$ gluster peer status
Number of Peers: 1
Hostname: gluster-02.example.com
Uuid: a6de3b23-ee31-4394-8bff-0bd97bd54f46
State: Peer in Cluster (Connected)
Other names:
10.10.6.72
Agora você pode criar um volume no qual iremos escrever.gluster volume create main replica 2 gluster-01.example.com:/gluster/main gluster-02.example.com:/gluster/main force
Onde:- main - nome Volume
- réplica - tipo Volume (mais detalhes podem ser encontrados na documentação oficial )
- 2 - número de réplicas
Execute o Volume e verifique seu desempenho:gluster volume start main
gluster volume status main
Para o volume replicado, é recomendável que você defina os seguintes parâmetros:$ gluster volume set main network.ping-timeout 5
$ gluster volume set main cluster.quorum-type fixed
$ gluster volume set main cluster.quorum-count 1
$ gluster volume set main performance.quick-read on
Com essas etapas simples, criamos um cluster GlusterFS. Resta conectar-se a ele e verificar o desempenho. O Ubuntu está instalado na máquina cliente, para a montagem você precisa instalar o cliente:$ add-apt-repository ppa:gluster/glusterfs-7
$ apt install glusterfs-client
$ mkdir /gluster
$ mount.glusterfs gluster-01.example.com:/main /gluster
O Gluster, quando conectado a um dos nós, fornece os endereços de todos os nós e se conecta automaticamente a todos. Se o cliente já estiver conectado, a falha de um dos nós não levará a uma parada. Mas se o primeiro nó estiver indisponível, não será possível conectar-se no caso de uma interrupção da sessão. Para fazer isso, ao montar, você pode passar o parâmetro backupvolfile indicando o segundo nó.mount.glusterfs gluster-01.example.com:/main /gluster -o backupvolfile-server=gluster-02.example.com
Um ponto importante: o gluster sincroniza os arquivos entre os nós apenas se as alterações ocorrerem no volume montado. Se você fizer alterações diretamente nos nós, o arquivo ficará fora de sincronia.Conecte-se ao Kubernetes
Nesse estágio, começaram as perguntas: “Como conectá-lo?”. E há várias opções. Considere-os.Heketi
O mais popular e recomendado é usar um serviço externo: heketi. O heketi é uma camada entre o kubernetes e o gluster, que permite gerenciar e trabalhar com armazenamento por meio de http. Mas heketi será esse único ponto de falha, porque serviço não está em cluster. A segunda instância deste serviço não poderá funcionar independentemente, porque quaisquer alterações são armazenadas no banco de dados local. A execução deste serviço no kubernetes também não é adequada, porque ele precisa de um disco estático no qual seu banco de dados será armazenado. Nesse sentido, essa opção acabou sendo a mais inadequada.Endpoint na Kubernetes
Se você possui o Kubernetes em sistemas com gerenciadores de pacotes, essa é uma opção muito conveniente. O ponto é que, para todos os servidores GlusteFS no Kubernetes, um Endpoint comum é criado. Um serviço está suspenso neste nó de extremidade e já estaremos montados nesse serviço. Para que essa opção funcione, é necessário instalar o glusterfs-client em cada nó do Kubernetes e garantir que ele possa ser montado. No Kubernetes, implante a seguinte configuração:apiVersion: v1
kind: Endpoints
metadata:
name: glusterfs-cluster
subsets:
- addresses:
- ip: 10.10.6.71
ports:
- port: 1
- addresses:
- ip: 10.10.6.72
ports:
- port: 1
---
apiVersion: v1
kind: Service
metadata:
name: glusterfs-cluster
spec:
ports:
- port: 1
Agora podemos criar uma implantação de teste simples e verificar como a montagem funciona. Abaixo está um exemplo de uma implantação de teste simples:apiVersion: apps/v1
kind: Deployment
metadata:
name: gluster-test
spec:
replicas: 1
selector:
matchLabels:
app: gluster-test
template:
metadata:
labels:
app: gluster-test
spec:
volumes:
- name: gluster
glusterfs:
endpoints: glusterfs-cluster
path: main
containers:
- name: gluster-test
image: nginx
volumeMounts:
- name: gluster
mountPath: /gluster
Esta opção não nos convinha, porque temos container-linux em todos os nós do Kubernetes. O gerenciador de pacotes não está lá, portanto, não foi possível instalar o gluster-client para montagem. Nesse sentido, foi encontrada a terceira opção, que foi decidida a sua utilização.GlusterFS + NFS + keepalived
Até recentemente, o GlusterFS oferecia seu próprio servidor NFS, mas agora o serviço externo nfs-ganesha é usado para NFS. Muito já foi escrito sobre isso, em conexão com isso, vamos descobrir como configurá-lo.O repositório deve ser registrado manualmente. Para fazer isso, no arquivo /etc/yum.repos.d/nfs-ganesha.repo, adicionamos:[nfs-ganesha]
name=nfs-ganesha
baseurl=https://download.nfs-ganesha.org/2.8/2.8.0/RHEL/el-8/$basearch/
enabled=1
gpgcheck=1
[nfs-ganesha-noarch]
name=nfs-ganesha-noarch
baseurl=https://download.nfs-ganesha.org/2.8/2.8.0/RHEL/el-8/noarch/
enabled=1
gpgcheck=1
E instale:yum -y install nfs-ganesha-gluster --nogpgcheck
Após a instalação, realizamos a configuração básica no arquivo /etc/ganesha/ganesha.conf.# create new
NFS_CORE_PARAM {
# possible to mount with NFSv3 to NFSv4 Pseudo path
mount_path_pseudo = true;
# NFS protocol
Protocols = 3,4;
}
EXPORT_DEFAULTS {
# default access mode
Access_Type = RW;
}
EXPORT {
# uniq ID
Export_Id = 101;
# mount path of Gluster Volume
Path = "/gluster/main";
FSAL {
# any name
name = GLUSTER;
# hostname or IP address of this Node
hostname="gluster-01.example.com";
# Gluster volume name
volume="main";
}
# config for root Squash
Squash="No_root_squash";
# NFSv4 Pseudo path
Pseudo="/main";
# allowed security options
SecType = "sys";
}
LOG {
# default log level
Default_Log_Level = WARN;
}
Precisamos iniciar o serviço, ativar nfs para o nosso volume e verificar se ele está ativado.$ systemctl start nfs-ganesha
$ systemctl enable nfs-ganesha
$ gluster volume set main nfs.disable off
$ gluster volume status main
Como resultado, o status deve indicar que o servidor nfs foi iniciado para o nosso volume. Você precisa montar e verificar.mkdir /gluster-nfs
mount.nfs gluster-01.example.com:/main /gluster-nfs
Mas essa opção não é tolerante a falhas, portanto, você precisa criar um endereço VIP que viaje entre nossos dois nós e ajude a mudar o tráfego se um dos nós cair.A instalação de keepalived no CentOs é feita imediatamente através do gerenciador de pacotes.$ yum install -y keepalived
Configuramos o serviço no arquivo /etc/keepalived/keepalived.conf:global_defs {
notification_email {
admin@example.com
}
notification_email_from alarm@example.com
smtp_server mail.example.com
smtp_connect_timeout 30
vrrp_garp_interval 10
vrrp_garp_master_refresh 30
}
#C , . , VIP .
vrrp_script chk_gluster {
script "pgrep glusterd"
interval 2
}
vrrp_instance gluster {
interface ens192
state MASTER # BACKUP
priority 200 # , 100
virtual_router_id 1
virtual_ipaddress {
10.10.6.70/24
}
unicast_peer {
10.10.6.72 #
}
track_script {
chk_gluster
}
}
Agora podemos iniciar o serviço e verificar se o VIP no nó aparece:$ systemctl start keepalived
$ systemctl enable keepalived
$ ip addr
1: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:50:56:97:55:eb brd ff:ff:ff:ff:ff:ff
inet 10.10.6.72/24 brd 10.10.6.255 scope global noprefixroute ens192
valid_lft forever preferred_lft forever
inet 10.10.6.70/24 scope global secondary ens192
valid_lft forever preferred_lft forever
Se tudo funcionou para nós, resta adicionar o PersistentVolume ao Kubernetes e criar um serviço de teste para verificar a operação.---
apiVersion: v1
kind: PersistentVolume
metadata:
name: gluster-nfs
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
server: 10.10.6.70
path: /main
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gluster-nfs
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
volumeName: "gluster-nfs"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: gluster-test
labels:
app: gluster-test
spec:
replicas: 1
selector:
matchLabels:
app: gluster-test
template:
metadata:
labels:
app: gluster-test
spec:
volumes:
- name: gluster
persistentVolumeClaim:
claimName: gluster-nfs
containers:
- name: gluster-test
image: nginx
volumeMounts:
- name: gluster
mountPath: /gluster
Com essa configuração, no caso de uma queda do nó principal, ele fica ocioso por cerca de um minuto até que a montagem caia no tempo limite e nos comutadores. Simples por um minuto para esse armazenamento, digamos que essa não seja uma situação regular e raramente a encontraremos, mas nesse caso o sistema alternará automaticamente e continuará funcionando, e seremos capazes de resolver o problema e realizar a recuperação sem se preocupar com o simples.Sumário
Neste artigo, examinamos três opções possíveis para conectar o GlusterFS ao Kubernetes. Em nossa versão, é possível adicionar um provisionador ao Kubernetes, mas ainda não precisamos dele. Resta adicionar os resultados dos testes de desempenho entre o NFS e o Gluster nos mesmos nós.Arquivos em 1Mb:sync; dd if=/dev/zero of=tempfile bs=1M count=1024; sync
Gluster: 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 2.63496 s, 407 MB/s
NFS: 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 5.4527 s, 197 MB/s
Arquivos em 1Kb:sync; dd if=/dev/zero of=tempfile bs=1K count=1048576; sync
Gluster: 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 70.0508 s, 15.3 MB/s
NFS: 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 6.95208 s, 154 MB/s
O NFS funciona da mesma forma para qualquer tamanho de arquivo, a diferença de velocidade não é particularmente perceptível, ao contrário do GlusterFS, que é muito degradado com arquivos pequenos. Mas, ao mesmo tempo, com tamanhos de arquivo grandes, o NFS mostra desempenho 2-3 vezes menor que o Gluster.