StatefulSet do Kubernetes: Implantando MongoDB com Armazenamento Persistente

Este guia detalha a implantação de um cluster MongoDB altamente disponível no Kubernetes usando StatefulSet e GlusterFS para armazenamento persistente. A configuração elimina pontos únicos de falha, oferece escalabilidade dinâmica e garante a integridade dos dados.

Pré-requisitos

  • Cluster Kubernetes operacional (consulte guias de instalação anteriores).
  • GlusterFS integrado ao Kubernetes com Heketi (consulte guia de implantação do GlusterFS).

Arquitetura da Implantação

Utilizaremos um StatefulSet para gerenciar três réplicas do MongoDB. Cada pod terá seu próprio volume persistente provisionado dinamicamente pelo GlusterFS, garantindo que os dados sobrevivam a reinicializações de pods.

1. Configuração da StorageClass

Primeiro, criamos um Secret parra autenticação com o Heketi e a StorageClass.

# heketi-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: heketi-secret
  namespace: heketi
data:
  key: YWRtaW4xMjM=
type: kubernetes.io/glusterfs

$ kubectl create -f heketi-secret.yaml
# storageclass-fast.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
parameters:
  resturl: "http://10.254.82.26:8080"
  clusterid: "d96022e907f82045dcc426a752adc47c"
  restauthenabled: "true"
  restuser: "admin"
  secretName: "heketi-secret"
  secretNamespace: "default"
  volumetype: "replicate:3"
provisioner: kubernetes.io/glusterfs
reclaimPolicy: Delete

$ kubectl create -f storageclass-fast.yaml
$ kubectl get storageclasses/fast

2. Autorização do ServiceAccount

O container sidecar precisa de permissões para gerenciar outros pods. Criamos um ClusterRoleBinding para a conta de serviço padrão.

# defaultaccount.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: default-cluster-admin
subjects:
  - kind: ServiceAccount
    name: default
    namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

$ kubectl apply -f defaultaccount.yaml

3. Criação do StatefulSet e Headless Service

O StatefulSet gerencia os pods do MongoDB e inclui a definição do service headless.

# statefulset-mongo.yaml
apiVersion: v1
kind: Service
metadata:
  name: mongo
  labels:
    name: mongo
spec:
  ports:
  - port: 27017
    targetPort: 27017
  clusterIP: None
  selector:
    role: mongo
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: mongo
spec:
  serviceName: "mongo"
  replicas: 3
  template:
    metadata:
      labels:
        role: mongo
        environment: test
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: mongo
          image: mongo:3.4
          command:
            - mongod
            - "--replSet"
            - rs0
            - "--bind_ip"
            - 0.0.0.0
            - "--smallfiles"
            - "--noprealloc"
          ports:
            - containerPort: 27017
          volumeMounts:
            - name: mongo-persistent-storage
              mountPath: /data/db
        - name: mongo-sidecar
          image: cvallance/mongo-k8s-sidecar
          env:
            - name: MONGO_SIDECAR_POD_LABELS
              value: "role=mongo,environment=test"
            - name: KUBERNETES_MONGO_SERVICE_NAME
              value: "mongo"
  volumeClaimTemplates:
  - metadata:
      name: mongo-persistent-storage
      annotations:
        volume.beta.kubernetes.io/storage-class: "fast"
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 2Gi

$ kubectl create -f statefulset-mongo.yaml

Nota: Se houver problemas para baixar as imagens, faça pull manualmente e carregue nos nodes.

4. Verificação da Implantação

$ kubectl get pod -l role=mongo
NAME      READY   STATUS    RESTARTS   AGE
mongo-0   2/2     Running   0          9m44s
mongo-1   2/2     Running   0          7m51s
mongo-2   2/2     Running   0          6m1s

$ kubectl get pvc

$ kubectl exec -ti mongo-0 -- mongo
rs0:PRIMARY> rs.status()

A saída mostrará os três membros do cluster com seus nomes DNS no formato: mongo-0.mongo.default.svc.cluster.local.

5. Gerenciamento do Cluster

5.1 Escalonamento

Para adicionar um novo nó ao cluster, aumente o número de réplicas do StatefulSet.

$ kubectl scale statefulset mongo --replicas=4
$ kubectl get pod -l role=mongo
NAME      READY   STATUS    RESTARTS   AGE
mongo-0   2/2     Running   0          105m
mongo-1   2/2     Running   0          103m
mongo-2   2/2     Running   0          101m
mongo-3   2/2     Running   0          50m

5.2 Recuperação de Falhas

Se um pod falhar, o StatefulSet o recriará automaticamente usando o mesmo PVC, preservando a identidade e os dados.

$ kubectl delete pod mongo-0
$ kubectl exec -ti mongo-0 -- mongo
rs0:PRIMARY> rs.status()

Após a exclusão, o pod é recraido e se junta ao cluster como um membro SECONDARY. Um novo PRIMARY é eleito automaticamente.

Tags: kubernetes statefulset mongodb GlusterFS StorageClass

Publicado em 7-23 23:30