From 6c7ec3c09ae5451ec8a9783caa6fa83b44bdc27c Mon Sep 17 00:00:00 2001 From: Gorden Date: Fri, 16 Feb 2024 13:23:20 +0100 Subject: [PATCH] added readme --- mongodb/README.md | 595 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 595 insertions(+) create mode 100644 mongodb/README.md diff --git a/mongodb/README.md b/mongodb/README.md new file mode 100644 index 0000000..d57b339 --- /dev/null +++ b/mongodb/README.md @@ -0,0 +1,595 @@ +# mongodb Deployment on kubernetes + +QUELLE: https://phoenixnap.com/kb/kubernetes-mongodb + +## Introduction + +MongoDB is a general-purpose, document-based NoSQL database program. As with other non-relational database management systems, MongoDB focuses on scalability and the speed of queries. + +Kubernetes synergizes with MongoDB to create highly scalable and portable database deployments. These deployments are useful for working with a large amount of data and high loads. + +This tutorial will teach you how to deploy MongoDB on Kubernetes. The guide includes steps to run a standalone MongoDB instance and a replica set. + +## How to run MongoDB on Kubernetes. + +### Requirements +A Kubernetes cluster with kubectl. \ +Administrative access to your system. \ +>Note: MongoDB is part of the MEAN stack, a popular open-source software stack for web application development. Read about the differences between MEAN and LAMP stack. + +## Deploy a Standalone MongoDB Instance +MongoDB can be deployed on Kubernetes as a standalone instance. This deployment is not adequate for production use, but it is suitable for testing and some aspects of development. + +Follow the steps below to deploy a standalone MongoDB instance. + +### Step 1: Label the Node +Label the node that will be used for MongoDB deployment. The label is used later to assign pods to a specific node. + +To do so: + +1. List the nodes on your cluster: + +```bash +kubectl get nodes +``` + +2. Choose the deployment node from the list in the command output. + +3. Use kubectl to label the node with a key-value pair. + +```bash +#kubectl label nodes = +kubectl label nodes vmcon-node2 size=large +``` + +The output confirms that the label was added successfully. + +### Step 2: Create a StorageClass +A StorageClass helps pods provision persistent volume claims on the node. To create a StorageClass: + +1. Use a text editor to create a YAML file to store the storage class configuration. +```bash +nano StorageClass.yaml +``` + +2. Specify your storage class configuration in the file. The example below defines the mongodb-storageclass: +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: mongodb-storageclass +provisioner: kubernetes.io/no-provisioner +volumeBindingMode: WaitForFirstConsumer +allowVolumeExpansion: true +``` + +3. Save the changes and exit the editor. + +>Note: To make the process easier, store all the files in this tutorial in a single directory. + +### Step 3: Create Persistent Storage +Provision storage for the MongoDB deployment by creating a persistent volume and a persistent volume claim: + +1. Create a YAML file for persistent volume configuration. +```bash +nano PersistentVolume.yaml +``` + +2. In the file, allocate storage that belongs to the storage class defined in the previous step. Specify the node that will be used in pod deployment in the nodeAffinity section. The node is identified using the label created in Step 1. +```yaml +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. Create another YAML for the configuration of the persistent volume claim: +```bash +nano PersistentVolumeClaim.yaml +``` + +4. Define the claim named mongodb-pvc and instruct Kubernetes to claim volumes belonging to mongodb-storageclass. +```yaml +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: mongodb-pvc +spec: + storageClassName: mongodb-storageclass + accessModes: + - ReadWriteOnce + volumeMode: Filesystem + resources: + requests: + storage: 1Gi +``` + +### Step 4: Create a ConfigMap +The ConfigMap file stores non-encrypted configuration information used by pods. + +1. Create a YAML file to store deployment configuration: +```bash +nano ConfigMap.yaml +``` + +2. Use the file to store information about system paths, users, and roles. The following is an example of a ConfigMap file: +```yaml +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; + } + } + }); +``` + +### Step 5: Create a StatefulSet +A StatefulSet is a Kubernetes controller used to deploy stateful apps. Stateful app pods require unique identities because they communicate with other pods. + +To Create a StatefulSet: + +1. Use a text editor to create a YAML file: +```bash +nano StatefulSet.yaml +``` + +2. Insert deployment information in the file, including the MongoDB Docker image to be used. The file also references the previously created ConfigMap and PersistentVolumeClaim: +```yaml +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 +``` + +### Step 6: Create a Secret +The Secret object is used to store sensitive information about the deployment. + +1. Create a Secret YAML with your text editor. +```bash +nano Secret.yaml +``` + +2. Provide information for accessing the MongoDB database. +```yaml +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. Save the changes and exit. + +### Step 7: Create a MongoDB Service +To create a MongoDB Service: + +1. Create a headless service object. +```bash +nano Service.yaml +``` + +Headless service allows users to connect to pods directly. + +2. Add the service name and definition in the YAML file. +```yaml +apiVersion: v1 +kind: Service +metadata: + name: mongodb-test + labels: + app: database +spec: + clusterIP: None + selector: + app: database +``` + +3. Save changes and exit the file. + +### Step 8: Apply the MongoDB Configuration with Kustomize +Use Kustomize to apply the MongoDB configuration files easily: + +1. Create a kustomization.yaml file: +```bash +nano kustomization.yaml +``` + +2. In the resources section, list all the YAML files created in the previous steps: +```yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ConfigMap.yaml + - PersistentVolumeClaim.yaml + - PersistentVolume.yaml + - Secret.yaml + - Service.yaml + - StatefulSet.yaml + - StorageClass.yaml +``` + +Save the file in the same directory as the other files. + +3. Deploy MongoDB with the following command: +```bash +kubectl apply -k . +``` + +Applying the MongoDB configuration using Kustomize. + +4. Use kubectl to check if the pod is ready. +```bash +kubectl get pod +``` + +When the pod shows 1/1 in the READY column, proceed to the next step. + +### Step 9: Connect to MongoDB Standalone Instance +1. Connect to the MongoDB pod by using the following kubectl command: +```bash +kubectl exec -it mongodb-test-0 -- sh +``` + +2. When the # prompt appears, type: +```bash +mongo +``` + +MongoDB shell loads. + +3. Switch to the test database: +```bash +use test +``` + +4. Authenticate with the following command: +```bash +db.auth('test','password') +``` + +Number 1 in the output confirms the successful authentication. + +>Note: Read how MongoDB compares against Cassandra, another popular NoSQL solution. + +## Deploy a ReplicaSet +Deploying MongoDB as a ReplicaSet ensures that the specified number of pods are running at any given time. ReplicaSet deployments are recommended for production environments. + +### Step 1: Set up Role-Based Access Control (RBAC) +Enabling role-based access control is one of the Kubernetes security best practices. RBAC ensures that no user has more permissions than need. + +To set up RBAC: + +1. Create a YAML file with a text editor. +```bash +nano rbac.yaml +``` + +2. Provide access rules for your MongoDB deployment. The example below shows an RBAC YAML file: +```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. Save the file and apply it with kubectl: +```bash +kubectl apply -f rbac.yaml +``` + +### Step 2: Create a StatefulSet Deployment +1. Create a StatefulSet deployment YAML: +```bash +nano StatefulSet.yaml +``` + +2. Specify the number of replicas in the file, the MongoDB Docker image to be used, and provide a volume claim template for dynamic volume provision: +```yaml +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. Save the file and use kubectl apply to create a deployment: +```bash +kubectl apply -f StatefulSet.yaml +``` + +### Step 3: Create a Headless Service +To create a headless service: + +1. Create a service YAML file: +```bash +nano Service.yaml +``` + +2. Define a service that enables direct communication with pods: +```yaml +apiVersion: v1 +kind: Service +metadata: + name: mongo + namespace: default + labels: + name: mongo +spec: + ports: + - port: 27017 + targetPort: 27017 + clusterIP: None + selector: + app: mongo +``` + +3. Apply the YAML with kubectl. +```bash +kubectl apply -f Service.yaml +``` + +### Step 4: Set up Replication Host +To set up pod replication: + +1. Enter the pod using kubectl exec: +```bash +kubectl exec -it mongodb-replica-0 -n default -- mongo +``` +The MongoDB shell welcome message appears. + +2. Initiate the replication by typing the following command at the MongoDB shell prompt: +```bash +rs.initiate() +``` +The "ok" : 1 line shows that the initiation was successful. + +3. Define the variable called cfg. The variable executes rs.conf(). +```bash +var cfg = rs.conf() +``` + +4. Use the variable to add the primary server to the configuration: +```bash +cfg.members[0].host="mongodb-replica-0.mongo:27017" +``` +The output shows the name of the primary server. + +5. Confirm the configuration by executing the following command: +```bash +rs.reconfig(cfg) +``` +The "ok" : 1 line confirms the configuration was successful. + +6. Use the rs.add() command to add another pod to the configuration. +```bash +rs.add("mongodb-replica-1.mongo:27017") +``` +The output shows the replica was added. + +7. Check the status of the system by typing: +```bash +rs.status() +``` +The "members" section should show two replicas. The primary replica is listed at the top of the output. + +>Note: Bare Metal Cloud offers instances designed to support high-performance NoSQL databases such as MongoDB. The instances offer performance and isolation necessary for demanding workloads. \ No newline at end of file