Freqüentemente, usamos o NFS como armazenamento de back-end para teste porque é fácil de implantar. Mas na produção, não vamos escolher NFS, mais Ceph, Glusterfs, etc., hoje vamos mostrar como usar Glusterfs em kubernetes.
Um, instale o Glusterfs
1.1. Planejamento
1.2, instalação
我们这里采用的是YUM安装,有兴趣的也可以用其他安装方式,比如源码安装
(1) 、 配置 hosts (/ etc / hosts)
10.1.10.129 glusterfs-node01
10.1.10.130 glusterfs-node02
10.1.10.128 glusterfs-master
(2), instalação YUM
# yum install centos-release-gluster -y
# yum install -y glusterfs glusterfs-server glusterfs-fuse glusterfs-rdma
(3), iniciar e configurar a inicialização automática após a inicialização
# systemctl start glusterd.service && systemctl enable glusterd.service
(4) Se o firewall estiver aberto, você precisa configurar o firewall
# 如果需要可以加iptables
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 24007 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 24008 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 2222 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state NEW -m multiport --dports 49152:49251 -j ACCEPT
(5) Adicionar o nó ao cluster
# gluster peer probe glusterfs-master
# gluster peer probe glusterfs-node01
# gluster peer probe glusterfs-node02
(6) Verifique o status do cluster
# gluster peer status
Number of Peers: 2
Hostname: k8s-node01
Uuid: bb59f0ee-1901-443c-b721-1fe3a1edebb4
State: Peer in Cluster (Connected)
Other names:
glusterfs-node01
10.1.10.129
Hostname: glusterfs-node02
Uuid: a0d1448a-d0f2-432a-bb45-b10650db106c
State: Peer in Cluster (Connected)
Other names:
10.1.10.130
1.3, teste
(1) Criar volume
# 创建数据目录,节点都要操作
# mkdir /data/gluster/data -p
# gluster volume create glusterfs_volume replica 3 master:/data/gluster/data node1:/data/gluster/data node2:/data/gluster/data force
(2), ver volume
# gluster volume info
Volume Name: glusterfs_volume
Type: Replicate
Volume ID: 53bdad7b-d40f-4160-bd42-4b70c8278506
Status: Created
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: master:/data/gluster/data
Brick2: node1:/data/gluster/data
Brick3: node2:/data/gluster/data
Options Reconfigured:
transport.address-family: inet
storage.fips-mode-rchecksum: on
nfs.disable: on
performance.client-io-threads: off
(3), volume inicial
# gluster volume start glusterfs_volume
(4) Instale o cliente
# yum install -y glusterfs glusterfs-fuse
(5) Monte
# mount -t glusterfs glusterfs-master:glusterfs_volume /mnt
1.4, afinação
# 开启 指定 volume 的配额
$ gluster volume quota k8s-volume enable
# 限制 指定 volume 的配额
$ gluster volume quota k8s-volume limit-usage / 1TB
# 设置 cache 大小, 默认32MB
$ gluster volume set k8s-volume performance.cache-size 4GB
# 设置 io 线程, 太大会导致进程崩溃
$ gluster volume set k8s-volume performance.io-thread-count 16
# 设置 网络检测时间, 默认42s
$ gluster volume set k8s-volume network.ping-timeout 10
# 设置 写缓冲区的大小, 默认1M
$ gluster volume set k8s-volume performance.write-behind-window-size 1024MB
Dois, teste em k8s
2.1, teste simples
(1), configurar endpoints
# curl -O https://raw.githubusercontent.com/kubernetes/examples/master/volumes/glusterfs/glusterfs-endpoints.json
Modifique glusterfs-endpoints.json para configurar as informações do cluster GlusterFS
{
"kind": "Endpoints",
"apiVersion": "v1",
"metadata": {
"name": "glusterfs-cluster"
},
"subsets": [
{
"addresses": [
{
"ip": "10.1.10.128"
}
],
"ports": [
{
"port": 2020
}
]
}
]
}
port可以随意写,ip为GlusterFS的IP地址
Crie um arquivo de configuração
# kubectl apply -f glusterfs-endpoints.json
# kubectl get ep
NAME ENDPOINTS AGE
glusterfs-cluster 10.1.10.128:2020 7m26s
kubernetes 10.1.10.128:6443 27d
(2), configurar o serviço
curl -O https://raw.githubusercontent.com/kubernetes/examples/master/volumes/glusterfs/glusterfs-service.json
Modifique o arquivo de configuração, só modifiquei a porta aqui
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "glusterfs-cluster"
},
"spec": {
"ports": [
{"port": 2020}
]
}
}
Criar objeto de serviço
# kubectl apply -f glusterfs-service.json
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
glusterfs-cluster ClusterIP 10.254.44.189 <none> 2020/TCP 10m
kubernetes ClusterIP 10.254.0.1 <none> 443/TCP 27d
(3) Criar teste de pod
curl -O https://raw.githubusercontent.com/kubernetes/examples/master/volumes/glusterfs/glusterfs-pod.json
Modifique o arquivo de configuração, modifique o caminho sob os volumes para o nome do volume que criamos acima
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "glusterfs"
},
"spec": {
"containers": [
{
"name": "glusterfs",
"image": "nginx",
"volumeMounts": [
{
"mountPath": "/mnt/glusterfs",
"name": "glusterfsvol"
}
]
}
],
"volumes": [
{
"name": "glusterfsvol",
"glusterfs": {
"endpoints": "glusterfs-cluster",
"path": "glusterfs_volume",
"readOnly": true
}
}
]
}
}
Crie um objeto Pod
# kubectl apply -f glusterfs-pod.yaml
# kubectl get pod
NAME READY STATUS RESTARTS AGE
glusterfs 1/1 Running 0 51s
pod-demo 1/1 Running 8 25h
# kubectl exec -it glusterfs -- df -h
Filesystem Size Used Avail Use% Mounted on
overlay 17G 2.5G 15G 15% /
tmpfs 64M 0 64M 0% /dev
tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 2.5G 15G 15% /etc/hosts
10.1.10.128:glusterfs_volume 17G 5.3G 12G 31% /mnt/glusterfs
shm 64M 0 64M 0% /dev/shm
tmpfs 910M 12K 910M 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 910M 0 910M 0% /proc/acpi
tmpfs 910M 0 910M 0% /proc/scsi
tmpfs 910M 0 910M 0% /sys/firmware
Podemos ver pela situação de montagem do disco que a montagem foi bem-sucedida.
2.2, teste de PV estático
(1) Criar pv (glusterfs-pv.yaml)
apiVersion: v1
kind: PersistentVolume
metadata:
name: glusterfs-pv
spec:
capacity:
storage: 5Mi
accessModes:
- ReadWriteMany
glusterfs:
endpoints: glusterfs-cluster
path: glusterfs_volume
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: glusterfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Mi
Crie objetos pv e pvc
# kubectl apply -f glusterfs-pv.yaml
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
glusterfs-pv 5Mi RWX Retain Bound default/glusterfs-pvc 15s
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
glusterfs-pvc Bound glusterfs-pv 5Mi RWX 18s
Do acima, podemos ver que a vinculação foi bem-sucedida e você pode escrever um pod para teste.
2.3, teste de PV dinâmico
Aqui, precisamos usar heketi para gerenciar Glusterfs.
Heketi fornece uma rica API RESTful para gerenciar volumes Glusterfs. Heketi pode gerenciar vários clusters ao mesmo tempo, cada cluster é composto de vários nós, cada nó é uma máquina física, para ser mais preciso um disco vazio. Então, cada dispositivo vazio tem vários blocos e o volume é composto por vários blocos, mas um volume não pode ser composto por nós. O diagrama esquemático é mostrado abaixo.
参考文档:https://blog.csdn.net/DevOps008/article/details/80757974
2.3.1, instale Heketi
(1), instalação
# yum -y install heketi heketi-client
(2) 、 配置 heketi (/etc/heketi/heketi.json)
{
"_port_comment": "Heketi Server Port Number",
"port": "48080", # 请求端口,默认是8080
"_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": "admin@P@ssW0rd" # 管理员密码
},
"_user": "User only has access to /volumes endpoint",
"user": {
"key": "user@P@ssW0rd" # 普通用户密码
}
},
"_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/hekeit/private_key", # ssh私钥目录
"user": "root", # ssh用户
"port": "22", # ssh端口
"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"
],
"loglevel" : "debug"
}
}
Descrição: Heketi é usado para gerenciar o cluster, onde o local de configuração está no executor, e seus métodos de gerenciamento são os seguintes:
-
zombar
-
ssh
- governadores
Mock, como o nome indica, é um teste. Neste modo, você pode verificar seus próprios arquivos de configuração. Mas neste modo, embora você possa ver que o nó foi adicionado com sucesso e o volume foi criado com sucesso, esses volumes não estão disponíveis Incapaz de montar. Portanto, se você quiser usá-lo no ambiente SVT ou PROD, deverá usar o modo ssh ou kubernetes. Estamos usando o modo ssh aqui.
(3), configuração sem senha
# ssh-keygen -t rsa -q -f /etc/heketi/private_key -N ""
# ssh-copy-id -i /etc/heketi/private_key.pub [email protected]
# ssh-copy-id -i /etc/heketi/private_key.pub [email protected]
# ssh-copy-id -i /etc/heketi/private_key.pub [email protected]
(4) Comece heketi
# systemctl enable heketi.service && systemctl start heketi.service
# 测试
# curl http://10.1.10.128:48080/hello
Hello from Heketi
(5), configure a topologia
As informações de topologia são usadas para permitir que Heketi confirme os nós de armazenamento, discos e clusters que podem ser usados, e o domínio de falha do nó deve ser determinado por ele mesmo. Um domínio de falha é um valor inteiro atribuído a um grupo de nós que compartilham o mesmo switch, fonte de alimentação ou qualquer outro componente que faria com que eles falhassem simultaneamente. É necessário confirmar quais nós constituem um cluster.Heketi usa essa informação para garantir que as cópias sejam criadas em domínios de falha, proporcionando redundância de dados.Heketi suporta vários clusters de armazenamento Gluster.
Preste atenção aos seguintes pontos ao configurar a topologia Heketi:
-
O cluster GlusterFS pode ser definido por meio do arquivo topology.json;
-
A topologia especifica o relacionamento hierárquico: clusters -> nós -> nó / dispositivos -> nomes de host / zona;
-
Recomenda-se preencher o ip do host para manage no campo node / hostnames, que se refere ao canal de gerenciamento.Note que o hostname não pode ser preenchido quando o servidor heketi não pode acessar o nó ClusterFS através do hostname;
-
Recomenda-se preencher o ip do host para armazenamento no campo node / hostnames, que se refere ao canal de armazenamento de dados, que pode ser diferente de manage.Recomenda-se que a rede de gerenciamento do ambiente de produção e a rede de armazenamento sejam separadas;
-
O campo nó / zona especifica o domínio de falha em que o nó está localizado. Heketi melhora a alta disponibilidade de dados criando réplicas em domínios de falha. Por exemplo, é possível distinguir o valor da zona por meio de racks diferentes para criar um domínio de falha através de racks;
- O campo de dispositivos especifica a letra da unidade de cada nó do GlusterFS (vários discos são possíveis), e deve ser um dispositivo bruto sem um sistema de arquivos criado.
以文字内容来源:https://www.cnblogs.com/itzgr/p/11913342.html#_labelTop
O arquivo de configuração é o seguinte (/etc/heketi/topology.json)
{
"clusters": [
{
"nodes": [
{
"node": {
"hostnames": {
"manage": [
"10.1.10.128"
],
"storage": [
"10.1.10.128"
]
},
"zone": 1
},
"devices": [
"/dev/sdb1" # 必须是未创建文件系统的裸磁盘
]
},
{
"node": {
"hostnames": {
"manage": [
"10.1.10.129"
],
"storage": [
"10.1.10.129"
]
},
"zone": 1
},
"devices": [
"/dev/sdb1"
]
},
{
"node": {
"hostnames": {
"manage": [
"10.1.10.130"
],
"storage": [
"10.1.10.130"
]
},
"zone": 1
},
"devices": [
"/dev/sdb1"
]
}
]
}
]
}
重要说明:devices字段指定GlusterFS各节点的盘符(可以是多块盘),必须是未创建文件系统的裸设备
Visto que você precisa escrever o nome de usuário, senha, etc. toda vez que usar o comando heketi-cli, nós o escreveremos na variável de ambiente para facilitar a operação.
# echo "export HEKETI_CLI_SERVER=http://10.1.10.128:48080" >> /etc/profile.d/heketi.sh
# echo "alias heketi-cli='heketi-cli --user admin --secret admin@P@ssW0rd'" >> ~/.bashrc
# source /etc/profile.d/heketi.sh
# source ~/.bashrc
# echo $HEKETI_CLI_SERVER
http://10.1.10.128:48080
(6), crie um cluster
# heketi-cli --server $HEKETI_CLI_SERVER --user admin --secret admin@P@ssW0rd topology load --json=/etc/heketi/topology.json
Creating cluster ... ID: cca360f44db482f03297a151886eea19
Allowing file volumes on cluster.
Allowing block volumes on cluster.
Creating node 10.1.10.128 ... ID: 5216dafba986a087d7c3b1e11fa36c05
Adding device /dev/sdb1 ... OK
Creating node 10.1.10.129 ... ID: e384286825957b60213cc9b2cb604744
Adding device /dev/sdb1 ... OK
Creating node 10.1.10.130 ... ID: 178a8c6fcfb8ccb02b1b871db01254c2
Adding device /dev/sdb1 ... OK
(7) Ver informações do cluster
# 查看集群列表
# heketi-cli cluster list
Clusters:
Id:cca360f44db482f03297a151886eea19 [file][block]
# 查看集群详细信息
# heketi-cli cluster info cca360f44db482f03297a151886eea19
# 查看节点信息
# heketi-cli node list
# 查看节点详细信息
# heketi-cli node info 68f16b2d54acf1c18e354ec46aa736ad
2.3.2, crie um teste de volume
# heketi-cli volume create --size=2 --replica=2
Name: vol_4f1a171ab06adf80460c84f2132e96e0
Size: 2
Volume Id: 4f1a171ab06adf80460c84f2132e96e0
Cluster Id: cca360f44db482f03297a151886eea19
Mount: 10.1.10.129:vol_4f1a171ab06adf80460c84f2132e96e0
Mount Options: backup-volfile-servers=10.1.10.130,10.1.10.128
Block: false
Free Size: 0
Reserved Size: 0
Block Hosting Restriction: (none)
Block Volumes: []
Durability Type: replicate
Distribute Count: 1
Replica Count: 2
# heketi-cli volume list
Id:4f1a171ab06adf80460c84f2132e96e0 Cluster:cca360f44db482f03297a151886eea19 Name:vol_4f1a171ab06adf80460c84f2132e96e0
# heketi-cli volume info 4f1a171ab06adf80460c84f2132e96e0
Name: vol_4f1a171ab06adf80460c84f2132e96e0
Size: 2
Volume Id: 4f1a171ab06adf80460c84f2132e96e0
Cluster Id: cca360f44db482f03297a151886eea19
Mount: 10.1.10.129:vol_4f1a171ab06adf80460c84f2132e96e0
Mount Options: backup-volfile-servers=10.1.10.130,10.1.10.128
Block: false
Free Size: 0
Reserved Size: 0
Block Hosting Restriction: (none)
Block Volumes: []
Durability Type: replicate
Distribute Count: 1
Replica Count: 2
# 挂载
# mount -t glusterfs 10.1.10.129:vol_4f1a171ab06adf80460c84f2132e96e0 /mnt
# 删除
# heketi-cli volume delete 4f1a171ab06adf80460c84f2132e96e0
2.3.3, teste em k8s
(1) Crie o segredo que precisa ser usado (heketi-secret.yaml)
apiVersion: v1
kind: Secret
metadata:
name: heketi-secret
data:
key: YWRtaW5AUEBzc1cwcmQ=
type: kubernetes.io/glusterfs
A chave deve ser transcodificada em base 64. O comando é o seguinte:
echo -n "admin@P@ssW0rd" | base64
(2) Crie storageclass (heketi-storageclass.yaml)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: heketi-storageclass
parameters:
resturl: "http://10.1.10.128:48080"
clusterid: "cca360f44db482f03297a151886eea19"
restauthenabled: "true" # 若heketi开启认证此处也必须开启auth认证
restuser: "admin"
secretName: "heketi-secret" # name/namespace与secret资源中定义一致
secretNamespace: "default"
volumetype: "replicate:3"
provisioner: kubernetes.io/glusterfs
reclaimPolicy: Delete
Descrição:
provisionador: indica o alocador de armazenamento, que precisa ser alterado de acordo com o armazenamento de back-end diferente;
reclaimPolicy: O padrão é "Excluir". Depois que o pvc for excluído, o volume de PV e back-end, tijolo (lvm), etc. correspondentes serão excluídos juntos; quando definido como "Reter", os dados serão retidos e manualmente o processamento é necessário se ele precisar ser excluído;
resturl: o url fornecido pelo serviço heketi API;
restauthenabled: parâmetro opcional, o valor padrão é "false", deve ser definido como "true" quando o serviço heketi está habilitado para autenticação;
restuser: parâmetro opcional, defina o nome de usuário correspondente quando a autenticação é ligada;
secretNamespace: parâmetro opcional, pode ser definido para usar namespace de armazenamento persistente quando a autenticação é ativada;
secretName: parâmetro opcional Ao habilitar a autenticação, a senha de autenticação do serviço heketi precisa ser armazenada no recurso secreto;
clusterid: parâmetro opcional, especifique o id do cluster, também pode ser uma lista de clusterid, o formato é "id1, id2";
- volumetype: parâmetros opcionais, defina o tipo de volume e seus parâmetros, se o tipo de volume não for alocado, o distribuidor determina o tipo de volume; por exemplo, "volumetype: replicate: 3" significa um volume replicado com 3 cópias, "volumetype: disperse : 4: 2 "" Significa dispersar o volume, onde '4' são os dados, '2' é a verificação de redundância, "volumetype: nenhum" significa distribuir o volume
(3) Criar pvc (heketi-pvc.yaml)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: heketi-pvc
annotations:
volume.beta.kubernetes.io/storage-class: heketi-storageclass
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
(4) Verifique as informações de sc e pvc
# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
heketi-storageclass kubernetes.io/glusterfs Delete Immediate false 6m53s
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
glusterfs-pvc Bound glusterfs-pv 5Mi RWX 26h
heketi-pvc Bound pvc-0feb8666-6e7f-451d-ae6f-7f205206b225 1Gi RWO heketi-storageclass 82s
(5) Crie o pod e monte o pvc (heketi-pod.yaml)
kind: Pod
apiVersion: v1
metadata:
name: heketi-pod
spec:
containers:
- name: heketi-container
image: busybox
command:
- sleep
- "3600"
volumeMounts:
- name: heketi-volume
mountPath: "/pv-data"
readOnly: false
volumes:
- name: heketi-volume
persistentVolumeClaim:
claimName: heketi-pvc
Crie um objeto Pod e veja o resultado
# kubectl apply -f heketi-pod.yaml
# kubectl get pod
NAME READY STATUS RESTARTS AGE
glusterfs 1/1 Running 0 26h
heketi-pod 1/1 Running 0 2m55s
Grave um arquivo no pod para teste
# kubectl exec -it heketi-pod -- /bin/sh
/ # cd /pv-data/
/pv-data # echo "text" > 1111.txt
/pv-data # ls
1111.txt
Verifique o nó de armazenamento para ver se há um arquivo que gravamos no pod
# cd /var/lib/heketi/mounts/vg_bffb11849513dded78f671f64e76750c/brick_6ff640a2d45a7f146a296473e7145ee7
[root@k8s-master brick_6ff640a2d45a7f146a296473e7145ee7]# ll
total 0
drwxrwsr-x 3 root 2000 40 Feb 7 14:27 brick
[root@k8s-master brick_6ff640a2d45a7f146a296473e7145ee7]# cd brick/
[root@k8s-master brick]# ll
total 4
-rw-r--r-- 2 root 2000 5 Feb 7 14:27 1111.txt
Terminar