Introduzione
MongoDB è un programma di database NoSQL generico basato su documenti. Come con altri sistemi di gestione di database non relazionali, MongoDB si concentra sulla scalabilità e sulla velocità delle query.
Kubernetes si sinergizza con MongoDB per creare implementazioni di database altamente scalabili e portatili. Queste distribuzioni sono utili per lavorare con una grande quantità di dati e carichi elevati.
Questo tutorial ti insegnerà come distribuire MongoDB su Kubernetes. La guida include i passaggi per eseguire un'istanza MongoDB autonoma e un set di repliche.
Requisiti
- Un cluster Kubernetes con kubectl.
- Accesso amministrativo al tuo sistema.
Distribuisci un'istanza MongoDB autonoma
MongoDB può essere distribuito su Kubernetes come istanza autonoma. Questa distribuzione non è adeguata per l'uso in produzione, ma è adatta per il test e alcuni aspetti dello sviluppo.
Segui i passaggi seguenti per distribuire un'istanza MongoDB autonoma.
Fase 1:etichetta il nodo
Etichetta il nodo che verrà utilizzato per la distribuzione di MongoDB. L'etichetta viene utilizzata in seguito per assegnare i pod a un nodo specifico.
Per farlo:
1. Elenca i nodi nel tuo cluster:
kubectl get nodes
2. Scegli il nodo di distribuzione dall'elenco nell'output del comando.
3. Usa kubectl per etichettare il nodo con una coppia chiave-valore.
kubectl label nodes <node> <key>=<value>
L'output conferma che l'etichetta è stata aggiunta correttamente.
Fase 2:crea una StorageClass
StorageClass aiuta i pod a fornire attestazioni di volume persistenti sul nodo. Per creare una StorageClass:
1. Usa un editor di testo per creare un file YAML in cui archiviare la configurazione della classe di archiviazione.
nano StorageClass.yaml
2. Specificare la configurazione della classe di archiviazione nel file. L'esempio seguente definisce la mongodb-storageclass
:
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: mongodb-storageclass
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
3. Salva le modifiche ed esci dall'editor.
Fase 3:crea memoria persistente
Effettua il provisioning dello spazio di archiviazione per la distribuzione di MongoDB creando un volume persistente e un'attestazione di volume persistente:
1. Crea un file YAML per la configurazione del volume persistente.
nano PersistentVolume.yaml
2. Nel file, allocare lo spazio di archiviazione che appartiene alla classe di archiviazione definita nel passaggio precedente. Specifica il nodo che verrà utilizzato nella distribuzione del pod in nodeAffinity
sezione. Il nodo viene identificato utilizzando l'etichetta creata nel Passaggio 1 .
apiVersion: v1
kind: PersistentVolume
metadata:
name: mongodb-pv
spec:
capacity:
storage: 2Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: mongodb-storageclass
local:
path: /mnt/data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: size
operator: In
values:
- large
3. Crea un altro YAML per la configurazione della richiesta di volume persistente:
nano PersistentVolumeClaim.yaml
4. Definire l'attestazione denominata mongodb-pvc
e incarica Kubernetes di rivendicare i volumi appartenenti a mongodb-storageclass
.
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mongodb-pvc
spec:
storageClassName: mongodb-storageclass
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
Fase 4:crea una mappa di configurazione
Il file ConfigMap memorizza le informazioni di configurazione non crittografate utilizzate dai pod.
1. Crea un file YAML per archiviare la configurazione della distribuzione:
nano ConfigMap.yaml
2. Utilizzare il file per memorizzare informazioni su percorsi di sistema, utenti e ruoli. Quello che segue è un esempio di un file ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: mongodb-configmap
data:
mongo.conf: |
storage:
dbPath: /data/db
ensure-users.js: |
const targetDbStr = 'test';
const rootUser = cat('/etc/k8-test/admin/MONGO_ROOT_USERNAME');
const rootPass = cat('/etc/k8-test/admin/MONGO_ROOT_PASSWORD');
const usersStr = cat('/etc/k8-test/MONGO_USERS_LIST');
const adminDb = db.getSiblingDB('admin');
adminDb.auth(rootUser, rootPass);
print('Successfully authenticated admin user');
const targetDb = db.getSiblingDB(targetDbStr);
const customRoles = adminDb
.getRoles({rolesInfo: 1, showBuiltinRoles: false})
.map(role => role.role)
.filter(Boolean);
usersStr
.trim()
.split(';')
.map(s => s.split(':'))
.forEach(user => {
const username = user[0];
const rolesStr = user[1];
const password = user[2];
if (!rolesStr || !password) {
return;
}
const roles = rolesStr.split(',');
const userDoc = {
user: username,
pwd: password,
};
userDoc.roles = roles.map(role => {
if (!~customRoles.indexOf(role)) {
return role;
}
return {role: role, db: 'admin'};
});
try {
targetDb.createUser(userDoc);
} catch (err) {
if (!~err.message.toLowerCase().indexOf('duplicate')) {
throw err;
}
}
});
Fase 5:crea uno StatefulSet
StatefulSet è un controller Kubernetes utilizzato per distribuire app con stato. I pod di app con stato richiedono identità univoche perché comunicano con altri pod.
Per creare un StatefulSet :
1. Usa un editor di testo per creare un file YAML:
nano StatefulSet.yaml
2. Inserire le informazioni sulla distribuzione nel file, inclusa l'immagine Docker MongoDB da utilizzare. Il file fa riferimento anche alla ConfigMap
creata in precedenza e PersistentVolumeClaim
:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb-test
spec:
serviceName: mongodb-test
replicas: 1
selector:
matchLabels:
app: database
template:
metadata:
labels:
app: database
selector: mongodb-test
spec:
containers:
- name: mongodb-test
image: mongo:4.0.8
env:
- name: MONGO_INITDB_ROOT_USERNAME_FILE
value: /etc/k8-test/admin/MONGO_ROOT_USERNAME
- name: MONGO_INITDB_ROOT_PASSWORD_FILE
value: /etc/k8-test/admin/MONGO_ROOT_PASSWORD
volumeMounts:
- name: k8-test
mountPath: /etc/k8-test
readOnly: true
- name: mongodb-scripts
mountPath: /docker-entrypoint-initdb.d
readOnly: true
- name: mongodb-configmap
mountPath: /config
readOnly: true
- name: mongodb-data
mountPath: /data/db
nodeSelector:
size: large
volumes:
- name: k8-test
secret:
secretName: mongodb-secret
items:
- key: MONGO_ROOT_USERNAME
path: admin/MONGO_ROOT_USERNAME
mode: 0444
- key: MONGO_ROOT_PASSWORD
path: admin/MONGO_ROOT_PASSWORD
mode: 0444
- key: MONGO_USERNAME
path: MONGO_USERNAME
mode: 0444
- key: MONGO_PASSWORD
path: MONGO_PASSWORD
mode: 0444
- key: MONGO_USERS_LIST
path: MONGO_USERS_LIST
mode: 0444
- name: mongodb-scripts
configMap:
name: mongodb-configmap
items:
- key: ensure-users.js
path: ensure-users.js
- name: mongodb-configmap
configMap:
name: mongodb-configmap
items:
- key: mongo.conf
path: mongo.conf
- name: mongodb-data
persistentVolumeClaim:
claimName: mongodb-pvc
Fase 6:crea un segreto
L'oggetto Secret viene utilizzato per archiviare informazioni riservate sulla distribuzione.
1. Crea un YAML segreto con il tuo editor di testo.
nano Secret.yaml
2. Fornire informazioni per l'accesso al database MongoDB.
apiVersion: v1
kind: Secret
metadata:
name: mongodb-secret
type: Opaque
data:
MONGO_ROOT_USERNAME: YWRtaW4K
MONGO_ROOT_PASSWORD: cGFzc3dvcmQK
MONGO_USERNAME: dGVzdAo=
MONGO_PASSWORD: cGFzc3dvcmQK
MONGO_USERS_LIST: dGVzdDpkYkFkbWluLHJlYWRXcml0ZTpwYXNzd29yZAo=
3. Salva le modifiche ed esci.
Fase 7:crea un servizio MongoDB
Per creare un servizio MongoDB:
1. Creare un oggetto di servizio senza testa.
nano Service.yaml
Il servizio Headless consente agli utenti di connettersi direttamente ai pod.
2. Aggiungi il nome del servizio e la definizione nel file YAML.
apiVersion: v1
kind: Service
metadata:
name: mongodb-test
labels:
app: database
spec:
clusterIP: None
selector:
app: database
3. Salva le modifiche ed esci dal file.
Fase 8:applica la configurazione di MongoDB con Kustomize
Usa Kustomize per applicare facilmente i file di configurazione di MongoDB:
1. Crea un kustomization.yaml
file:
nano kustomization.yaml
2. Nelle resources
sezione, elenca tutti i file YAML creati nei passaggi precedenti:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ConfigMap.yaml
- PersistentVolumeClaim.yaml
- PersistentVolume.yaml
- Secret.yaml
- Service.yaml
- StatefulSet.yaml
- StorageClass.yaml
Salva il file nella stessa directory degli altri file.
3. Distribuisci MongoDB con il seguente comando:
kubectl apply -k .
4. Usa kubectl per verificare se il pod è pronto.
kubectl get pod
Quando il pod mostra 1/1
nel READY
colonna, vai al passaggio successivo.
Passaggio 9:connessione all'istanza autonoma di MongoDB
1. Connettiti al pod MongoDB utilizzando il seguente comando kubectl:
kubectl exec -it mongodb-test-0 -- sh
2. Quando il #
viene visualizzato il messaggio, digitare:
mongo
Caricamenti della shell di MongoDB.
3. Passa al database dei test:
use test
4. Autenticarsi con il seguente comando:
db.auth('[username]','[password]')
Numero 1
nell'output conferma l'avvenuta autenticazione.
Distribuire un ReplicaSet
Distribuzione di MongoDB come ReplicaSet assicura che il numero specificato di pod sia in esecuzione in un dato momento. Le distribuzioni di ReplicaSet sono consigliate per gli ambienti di produzione.
Passaggio 1:imposta il controllo degli accessi in base al ruolo (RBAC)
L'abilitazione del controllo degli accessi basato sui ruoli è una delle best practice per la sicurezza di Kubernetes. RBAC garantisce che nessun utente abbia più autorizzazioni del necessario.
Per impostare RBAC:
1. Crea un file YAML con un editor di testo.
nano rbac.yaml
2. Fornisci le regole di accesso per la tua distribuzione MongoDB. L'esempio seguente mostra un file YAML RBAC:
apiVersion: v1
kind: ServiceAccount
metadata:
name: mongo-account
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: mongo-role
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["*"]
- apiGroups: [""]
resources: ["deployments"]
verbs: ["list", "watch"]
- apiGroups: [""]
resources: ["services"]
verbs: ["*"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: mongo_role_binding
subjects:
- kind: ServiceAccount
name: mongo-account
namespace: default
roleRef:
kind: ClusterRole
name: mongo-role
apiGroup: rbac.authorization.k8s.io
3. Salva il file e applicalo con kubectl:
kubectl apply -f rbac.yaml
Passaggio 2:crea una distribuzione StatefulSet
1. Crea un YAML di distribuzione StatefulSet:
nano StatefulSet.yaml
2. Specificare il numero di repliche nel file, l'immagine Docker MongoDB da utilizzare e fornire un modello di attestazione del volume per il provisioning dinamico del volume:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb-replica
namespace: default
spec:
serviceName: mongo
replicas: 2
selector:
matchLabels:
app: mongo
template:
metadata:
labels:
app: mongo
selector: mongo
spec:
terminationGracePeriodSeconds: 30
serviceAccount: mongo-account
containers:
- name: mongodb
image: docker.io/mongo:4.2
env:
command: ["/bin/sh"]
args: ["-c", "mongod --replSet=rs0 --bind_ip_all"]
resources:
limits:
cpu: 1
memory: 1500Mi
requests:
cpu: 1
memory: 1000Mi
ports:
- name: mongo-port
containerPort: 27017
volumeMounts:
- name: mongo-data
mountPath: /data/db
volumeClaimTemplates:
- metadata:
name: mongo-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
3. Salva il file e usa kubectl apply per creare una distribuzione:
kubectl apply -f StatefulSet.yaml
Fase 3:crea un servizio senza testa
Per creare un servizio headless:
1. Crea un file YAML del servizio:
nano Service.yaml
2. Definisci un servizio che consenta la comunicazione diretta con i pod:
apiVersion: v1
kind: Service
metadata:
name: mongo
namespace: default
labels:
name: mongo
spec:
ports:
- port: 27017
targetPort: 27017
clusterIP: None
selector:
app: mongo
3. Applica YAML con kubectl.
kubectl apply -f Service.yaml
Fase 4:configura l'host di replica
Per configurare la replica del pod:
1. Inserisci il pod utilizzando kubectl exec
:
kubectl exec -it mongodb-replica-0 -n default -- mongo
Viene visualizzato il messaggio di benvenuto della shell MongoDB.
2. Avviare la replica digitando il seguente comando al prompt della shell di MongoDB:
rs.initiate()
Il "ok" : 1
riga mostra che l'avvio è stato eseguito correttamente.
3. Definisci la variabile chiamata cfg
. La variabile esegue rs.conf()
.
var cfg = rs.conf()
4. Utilizzare la variabile per aggiungere il server primario alla configurazione:
cfg.members[0].host="mongodb-replica-0.mongo:27017"
L'output mostra il nome del server primario.
5. Confermare la configurazione eseguendo il seguente comando:
rs.reconfig(cfg)
Il "ok" : 1
conferma che la configurazione è andata a buon fine.
6. Usa rs.add()
comando per aggiungere un altro pod alla configurazione.
rs.add("mongodb-replica-1.mongo:27017")
L'output mostra che la replica è stata aggiunta.
7. Verificare lo stato del sistema digitando:
rs.status()
Il "members"
la sezione dovrebbe mostrare due repliche. La replica primaria è elencata nella parte superiore dell'output.
La replica secondaria si trova sotto la replica primaria.
La distribuzione ReplicaSet di MongoDB è configurata e pronta per funzionare.