Introducción
MongoDB es un programa de base de datos NoSQL de propósito general basado en documentos. Al igual que con otros sistemas de gestión de bases de datos no relacionales, MongoDB se centra en la escalabilidad y la velocidad de las consultas.
Kubernetes hace sinergia con MongoDB para crear implementaciones de bases de datos altamente escalables y portátiles. Estas implementaciones son útiles para trabajar con una gran cantidad de datos y cargas elevadas.
Este tutorial le enseñará cómo implementar MongoDB en Kubernetes. La guía incluye pasos para ejecutar una instancia MongoDB independiente y un conjunto de réplicas.
Requisitos
- Un clúster de Kubernetes con kubectl.
- Acceso administrativo a su sistema.
Implementar una instancia MongoDB independiente
MongoDB se puede implementar en Kubernetes como una instancia independiente. Esta implementación no es adecuada para uso en producción, pero sí para pruebas y algunos aspectos del desarrollo.
Siga los pasos a continuación para implementar una instancia MongoDB independiente.
Paso 1:etiquetar el nodo
Etiquete el nodo que se usará para la implementación de MongoDB. La etiqueta se usa más adelante para asignar pods a un nodo específico.
Para hacerlo:
1. Enumere los nodos en su clúster:
kubectl get nodes
2. Elija el nodo de implementación de la lista en la salida del comando.
3. Use kubectl para etiquetar el nodo con un par clave-valor.
kubectl label nodes <node> <key>=<value>
El resultado confirma que la etiqueta se agregó correctamente.
Paso 2:crear una clase de almacenamiento
StorageClass ayuda a los pods a aprovisionar reclamos de volumen persistentes en el nodo. Para crear una StorageClass:
1. Use un editor de texto para crear un archivo YAML para almacenar la configuración de la clase de almacenamiento.
nano StorageClass.yaml
2. Especifique su configuración de clase de almacenamiento en el archivo. El siguiente ejemplo define la mongodb-storageclass
:
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: mongodb-storageclass
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
3. Guarde los cambios y salga del editor.
Paso 3:Crear almacenamiento persistente
Proporcione almacenamiento para la implementación de MongoDB mediante la creación de un volumen persistente y una reclamación de volumen persistente:
1. Cree un archivo YAML para la configuración de volumen persistente.
nano PersistentVolume.yaml
2. En el archivo, asigne almacenamiento que pertenezca a la clase de almacenamiento definida en el paso anterior. Especifique el nodo que se usará en la implementación del pod en nodeAffinity
sección. El nodo se identifica mediante la etiqueta creada en el Paso 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. Cree otro YAML para la configuración del reclamo de volumen persistente:
nano PersistentVolumeClaim.yaml
4. Defina el reclamo llamado mongodb-pvc
e indicar a Kubernetes que reclame volúmenes pertenecientes a mongodb-storageclass
.
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mongodb-pvc
spec:
storageClassName: mongodb-storageclass
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
Paso 4:crear un mapa de configuración
El archivo ConfigMap almacena información de configuración no cifrada utilizada por los pods.
1. Cree un archivo YAML para almacenar la configuración de implementación:
nano ConfigMap.yaml
2. Utilice el archivo para almacenar información sobre las rutas del sistema, los usuarios y las funciones. El siguiente es un ejemplo de un archivo 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;
}
}
});
Paso 5:Crear un StatefulSet
Conjunto de estado es un controlador de Kubernetes que se utiliza para implementar aplicaciones con estado. Los pods de aplicaciones con estado requieren identidades únicas porque se comunican con otros pods.
Para crear un StatfulSet :
1. Use un editor de texto para crear un archivo YAML:
nano StatefulSet.yaml
2. Inserte la información de implementación en el archivo, incluida la imagen de MongoDB Docker que se utilizará. El archivo también hace referencia al ConfigMap
creado previamente y 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
Paso 6:Crea un secreto
El objeto secreto se utiliza para almacenar información confidencial sobre la implementación.
1. Crea un YAML secreto con tu editor de texto.
nano Secret.yaml
2. Proporcione información para acceder a la base de datos 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. Guarde los cambios y salga.
Paso 7:Cree un servicio MongoDB
Para crear un servicio MongoDB:
1. Cree un objeto de servicio sin cabeza.
nano Service.yaml
El servicio sin cabeza permite a los usuarios conectarse directamente a los pods.
2. Agregue el nombre y la definición del servicio en el archivo YAML.
apiVersion: v1
kind: Service
metadata:
name: mongodb-test
labels:
app: database
spec:
clusterIP: None
selector:
app: database
3. Guarde los cambios y salga del archivo.
Paso 8:Aplicar la configuración de MongoDB con Kustomize
Utilice Kustomize para aplicar fácilmente los archivos de configuración de MongoDB:
1. Cree un kustomization.yaml
archivo:
nano kustomization.yaml
2. En los resources
sección, enumere todos los archivos YAML creados en los pasos anteriores:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ConfigMap.yaml
- PersistentVolumeClaim.yaml
- PersistentVolume.yaml
- Secret.yaml
- Service.yaml
- StatefulSet.yaml
- StorageClass.yaml
Guarde el archivo en el mismo directorio que los demás archivos.
3. Implemente MongoDB con el siguiente comando:
kubectl apply -k .
4. Use kubectl para comprobar si el pod está listo.
kubectl get pod
Cuando el pod muestra 1/1
en el READY
columna, continúe con el siguiente paso.
Paso 9:Conéctese a la instancia independiente de MongoDB
1. Conéctese al pod de MongoDB mediante el siguiente comando kubectl:
kubectl exec -it mongodb-test-0 -- sh
2. Cuando el #
aparece el mensaje, escriba:
mongo
Se carga el shell de MongoDB.
3. Cambie a la base de datos de prueba:
use test
4. Autenticarse con el siguiente comando:
db.auth('[username]','[password]')
Número 1
en la salida confirma la autenticación exitosa.
Implementar un conjunto de réplicas
Implementación de MongoDB como un ReplicaSet asegura que la cantidad especificada de pods se esté ejecutando en un momento dado. Se recomiendan implementaciones de ReplicaSet para entornos de producción.
Paso 1:configurar el control de acceso basado en roles (RBAC)
Habilitar el control de acceso basado en roles es una de las mejores prácticas de seguridad de Kubernetes. RBAC garantiza que ningún usuario tenga más permisos de los necesarios.
Para configurar RBAC:
1. Cree un archivo YAML con un editor de texto.
nano rbac.yaml
2. Proporcione reglas de acceso para su implementación de MongoDB. El siguiente ejemplo muestra un archivo RBAC YAML:
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. Guarde el archivo y aplíquelo con kubectl:
kubectl apply -f rbac.yaml
Paso 2:Cree una implementación StatefulSet
1. Cree un YAML de implementación de StatefulSet:
nano StatefulSet.yaml
2. Especifique la cantidad de réplicas en el archivo, la imagen Docker de MongoDB que se usará y proporcione una plantilla de reclamo de volumen para la provisión de volumen dinámico:
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. Guarde el archivo y use kubectl apply para crear una implementación:
kubectl apply -f StatefulSet.yaml
Paso 3:Crear un servicio sin cabeza
Para crear un servicio sin encabezado:
1. Cree un archivo YAML de servicio:
nano Service.yaml
2. Defina un servicio que permita la comunicación directa con los pods:
apiVersion: v1
kind: Service
metadata:
name: mongo
namespace: default
labels:
name: mongo
spec:
ports:
- port: 27017
targetPort: 27017
clusterIP: None
selector:
app: mongo
3. Aplicar YAML con kubectl.
kubectl apply -f Service.yaml
Paso 4:configurar el host de replicación
Para configurar la replicación de pods:
1. Ingrese al pod usando kubectl exec
:
kubectl exec -it mongodb-replica-0 -n default -- mongo
Aparece el mensaje de bienvenida del shell de MongoDB.
2. Inicie la replicación escribiendo el siguiente comando en el indicador de shell de MongoDB:
rs.initiate()
El "ok" : 1
línea muestra que la iniciación fue exitosa.
3. Defina la variable llamada cfg
. La variable ejecuta rs.conf()
.
var cfg = rs.conf()
4. Use la variable para agregar el servidor principal a la configuración:
cfg.members[0].host="mongodb-replica-0.mongo:27017"
El resultado muestra el nombre del servidor principal.
5. Confirme la configuración ejecutando el siguiente comando:
rs.reconfig(cfg)
El "ok" : 1
línea confirma que la configuración fue exitosa.
6. Utilice el rs.add()
comando para agregar otro pod a la configuración.
rs.add("mongodb-replica-1.mongo:27017")
El resultado muestra que se agregó la réplica.
7. Verifique el estado del sistema escribiendo:
rs.status()
Los "members"
La sección debe mostrar dos réplicas. La réplica principal aparece en la parte superior de la salida.
La réplica secundaria está debajo de la réplica principal.
La implementación de ReplicaSet de MongoDB está configurada y lista para operar.