Udostępnij przez


Przetestować obciążenie klastra MongoDB w usłudze Azure Kubernetes Service (AKS)

Po wdrożeniu klastra MongoDB na AKS z wykorzystaniem operatora Percona dla MongoDB i zainstalowaniu mongo-express na klastrze, aby umożliwić interakcję z MongoDB, przetestujesz odporność klastra MongoDB w kilku scenariuszach. Ten samouczek opiera się na wdrożeniu klastra MongoDB i weryfikacji klastra Bazy danych MongoDB omówionego w poprzednich przewodnikach.

Kompilowanie i uruchamianie przykładowej aplikacji klienckiej dla bazy danych MongoDB

W poniższych krokach pokazano, jak utworzyć przykładową aplikację kliencką dla MongoDB i przesłać obraz Docker aplikacji do Azure Container Registry. Przykładowa aplikacja kliencka używa platformy testowania obciążenia Locust do symulowania obciążenia w klastrze Bazy danych MongoDB. Ta aplikacja wstawia dokumenty do klastra bazy danych MongoDB i mierzy czas potrzebny na każdą operację wstawiania dokumentu. Aplikacja używa Faker biblioteki do generowania losowych nazw i działów dla dokumentów pracowników. Tę klasę można rozszerzyć, aby zaimplementować bardziej złożone operacje.

  1. Utwórz nowy katalog przy użyciu następującego polecenia:

    mkdir mongodb-locust-client
    cd mongodb-locust-client
    
  2. Utwórz requirements.txt plik w mongodb-locust-client katalogu przy użyciu następującego polecenia:

    cat > requirements.txt <<EOF
    locust
    pymongo
    Faker
    EOF
    
  3. Utwórz locustfile.py w mongodb-locust-client katalogu przy użyciu następującego polecenia:

    cat > locustfile.py <<EOF
    import os
    import random
    import logging
    import time
    import uuid
    from locust import User, task, constant_throughput, events, tag, between
    from pymongo import MongoClient
    from pymongo.errors import ServerSelectionTimeoutError
    from pymongo.errors import ConnectionFailure
    from faker import Faker
    
    # Set up Faker for generating random names and departments
    fake = Faker()
    
    # Configure logging
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger(__name__)
    
    # List of department names for random selection
    department_keywords = [
        "Accounting", "Marketing", "Human Resources", "Sales", "Research and Development",
        "IT", "Customer Support", "Legal", "Operations", "Finance", "Product Management",
        "Public Relations", "Engineering", "Data Science", "Business Development"
    ]
    
    class MongoDBLocust(User):
        # Set constant throughput (requests per second)
        wait_time = constant_throughput(20)
        # MongoDB connection details (make sure these are set correctly in your environment)
        host = "${MY_CLUSTER_NAME}-mongodb-mongos.mongodb.svc.cluster.local"
        port = "27017"
        username = os.getenv('MONGODB_USERNAME')
        password = os.getenv('MONGODB_PASSWORD')
    
        def __init__(self, *args, **kwargs):
            super(MongoDBLocust, self).__init__(*args, **kwargs)
            self.client = MongoDBClient(self.username, self.password)  # Initialize MongoDB client
    
        def on_stop(self):
            """Called when the simulated user stops, to close the MongoDB client."""
            self.client.close()
    
        @task
        @tag("insert")
        def insert_document(self):
            """Task to insert a document into MongoDB."""
            self.client.insert_document("insert_document")
    
    class MongoDBClient(object):
        """MongoDB client for managing database interactions."""
    
        def __init__(self, username, password):
            # Set MongoDB connection parameters
            self.host = "${MY_CLUSTER_NAME}-mongodb-mongos.mongodb.svc.cluster.local"
            self.port = "27017"
            self.username = username
            self.password = password
            self.client = MongoClient(f"mongodb://{self.username}:{self.password}@{self.host}:{self.port}/")
            self.db = self.client['employeeDB']
            self.collection = self.db['employees']
            self.document_id = None  # Placeholder for the inserted document ID
    
        def insert_document(self, task_name, command='INSERT'):
            """Insert a document into MongoDB and measure the time."""
            employee_id = str(uuid.uuid4())
            start_time = time.time()
            logger.info(f"{employee_id} - Start Time -> start_time: {start_time}")
            try:
                # Create a new fake employee document
                new_document = {
                    'Id': str(uuid.uuid4()),
                    'EmployeeId': employee_id,
                    'FirstName': fake.first_name(),
                    'LastName': fake.last_name(),
                    'Department': random.choice(department_keywords)
                }
                # Insert the document
                result = self.collection.insert_one(new_document)
                self.document_id = str(result.inserted_id)  # Store the document ID for future reads
    
                # Measure the time taken for the MongoDB operation (in milliseconds)
                total_time = (time.time() - start_time) * 1000  # Convert to ms
                logger.info(f"{employee_id} - Task - {task_name} -> total_time: {total_time} ms")
    
                # Fire the event to report the request
                events.request.fire(
                    request_type=command,
                    name=task_name,
                    response_time=total_time,
                    response_length=len(str(result))  # Length of the result returned by the operation
                )
            except Exception as e:
                total_time = (time.time() - start_time) * 1000  # Time taken with error
                logger.error(f"{employee_id} - Error in {task_name}: {e} -> total_time: {total_time} ms")
                events.request.fire(
                    request_type=command,
                    name=task_name,
                    response_time=total_time,
                    response_length=0,  # No response in case of error
                    exception=e
                )
            logger.info(f"{employee_id} - End Time -> end time: {time.time()}")
        def close(self):
            """Close the MongoDB connection."""
            self.client.close()
    
    EOF
    
  4. Utwórz plik Dockerfile w mongodb-locust-client katalogu przy użyciu następującego polecenia. Plik Dockerfile tworzy obraz platformy Docker dla przykładowej aplikacji klienckiej, używa python:3.10-slim-bullseye obrazu jako obrazu podstawowego i instaluje wymagane zależności dla aplikacji.

    cat > Dockerfile <<EOF
    # Use a slim Python image as the base
    FROM python:3.10-slim-bullseye
    
    # Install wget and gnupg
    RUN apt-get update && apt-get install -y wget gnupg
    
    # Add MongoDB GPG Key and repository
    RUN wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | tee /etc/apt/trusted.gpg.d/mongodb.asc && \
        echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/debian bullseye/mongodb-org/6.0 main" | tee /etc/apt/sources.list.d/mongodb-org-6.0.list
    
    # Update APT sources and install MongoDB Shell (mongosh)
    RUN apt-get update && apt-get install -y mongodb-mongosh
    
    # Copy your application files
    COPY requirements.txt ./
    COPY locustfile.py ./
    
    # Install Python dependencies
    RUN pip install --upgrade pip && pip install --no-cache-dir -r requirements.txt
    
    EOF
    
  5. Zbuduj obraz Docker dla przykładowej aplikacji klienckiej przy użyciu polecenia az acr build. Pamiętaj, aby zastąpić $MY_ACR_REGISTRY nazwą swojego Azure Container Registry.

    az acr build --image mongodb-locust-client --registry $MY_ACR_REGISTRY .
    

Testowanie klastra Bazy danych MongoDB w usłudze AKS

Utwórz zasobnik klienta Locust MongoDB

W poniższej sekcji utworzysz zasobnik klienta Locust MongoDB w klastrze AKS. Ten pod używa obrazu Docker, który utworzyłeś wcześniej, w celu symulacji obciążenia w klastrze MongoDB. Poniższa specyfikacja używa hasła i nazwy użytkownika z zewnętrznej tajemnicy utworzonej w poprzednim samouczku.

  1. Utwórz zasobnik klienta Locust bazy danych MongoDB za pomocą polecenia kubectl apply.

    kubectl apply -n mongodb -f - <<EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mongodb-locust-client
      labels:
        app: mongodb-locust-client
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mongodb-locust-client
      template:
        metadata:
          labels:
            app: mongodb-locust-client
        spec:
          nodeSelector:
            kubernetes.azure.com/agentpool: "systempool"  # Ensure pods are scheduled on the system node pool
          containers:
            - name: mongodb-locust-client
              image: $MY_ACR_REGISTRY.azurecr.io/mongodb-locust-client
              command: ["locust", "-f", "/locustfile.py", "--host=http://${MY_CLUSTER_NAME}-mongodb-mongos.mongodb.svc.cluster.local:27017/"]
              env:
                - name: MONGODB_USERNAME
                  valueFrom:
                    secretKeyRef:
                      name: ${AKS_MONGODB_SECRETS_NAME}  # Name of your external secret
                      key: MONGODB_DATABASE_ADMIN_USER  # Key for the admin username
                - name: MONGODB_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: ${AKS_MONGODB_SECRETS_NAME}  # Name of your external secret
                      key: MONGODB_DATABASE_ADMIN_PASSWORD  # Key for the admin password
    EOF
    

    Przykładowe wyjście:

    deployment.apps/mongodb-locust-client created
    
  2. Pobierz nazwę podu klienta MongoDB przy użyciu polecenia kubectl get pods.

    kubectl get pods -n $AKS_MONGODB_NAMESPACE
    

    Przykładowe wyjście:

    NAME                                                READY   STATUS    RESTARTS   AGE
    ... // Additional pods
    mongodb-locust-client-564695f8f-q6745               1/1     Running   0          5d8h
    ... // Additional pods
    
  3. Zanotuj nazwę zasobnika z prefiksem mongodb-locust-client . Ten zasobnik łączy się z klastrem MongoDB w celu wykonania poleceń bazy danych MongoDB.

Przekierowanie portu dla zasobnika klienta Locust bazy danych MongoDB

  • Przekieruj port 8089 w celu uzyskania dostępu do interfejsu sieci Web Locust na komputerze lokalnym przy użyciu polecenia kubectl port-forward. Pamiętaj, aby zastąpić mongodb-locust-client-564695f8f-q6745 nazwą podu klienta MongoDB utworzonego w poprzedniej sekcji.

    kubectl -n $AKS_MONGODB_NAMESPACE port-forward mongodb-locust-client-564695f8f-q6745 8089:8089
    

Uzyskiwanie dostępu do interfejsu sieci Web Locust

  • Aby uzyskać dostęp do portalu internetowego Locust, przejdź do http://localhost:8089 w swojej przeglądarce internetowej. Interfejs webowy Locust umożliwia skonfigurowanie liczby użytkowników i szybkości ich dodawania na potrzeby testu obciążeniowego. Możesz również wyświetlić statystyki testu obciążeniowego w czasie rzeczywistym.

    Zrzut ekranu przedstawiający stronę internetową z pulpitem nawigacyjnym testu Locust.

Połącz się z konsolą MongoDB i zidentyfikuj członka głównego.

  1. Połącz się z podem klienta MongoDB przy użyciu następującego polecenia. Pamiętaj, aby zastąpić mongodb-locust-client-564695f8f-q6745 nazwą utworzonego wcześniej podu klienta MongoDB.

    kubectl -n $AKS_MONGODB_NAMESPACE exec -it mongodb-locust-client-564695f8f-q6745 -- /bin/bash
    
  2. Po nawiązaniu połączenia z zasobnikiem użyj następującego polecenia, aby połączyć się z MongoDB shell. Upewnij się, że masz poprawne wartości dla ${MY_CLUSTER_NAME}, ${databaseAdmin} i ${databaseAdminPassword} jak uzyskano w kroku 3 poprzedniego samouczka.

    mongosh --host ${MY_CLUSTER_NAME}-mongodb-rs0-0.${MY_CLUSTER_NAME}-mongodb-rs0.mongodb.svc.cluster.local --port 27017 -u ${databaseAdmin} -p ${databaseAdminPassword} --authenticationDatabase admin
    
  3. Po nawiązaniu połączenia z powłoką bazy danych MongoDB użyj następującego polecenia, aby zidentyfikować podstawowy zestaw replik bazy danych MongoDB:

    rs.status()
    

    Przykładowe wyjście:

    {
      set: 'rs0',
      ... // Additional details
      members: [
        {
          _id: 0,
          name: 'cluster-aks-mongodb-rs0-0.cluster-aks-mongodb-rs0.mongodb.svc.cluster.local:27017',
          health: 1,
          state: 2,
          stateStr: 'SECONDARY',
          uptime: 207037,
          ... // Additional details for the first member
        },
        {
          _id: 1,
          name: 'cluster-aks-mongodb-rs0-1.cluster-aks-mongodb-rs0.mongodb.svc.cluster.local:27017',
          health: 1,
          state: 1,
          stateStr: 'PRIMARY',
          uptime: 207033,
          ... // Additional details for the second member
        },
        {
          _id: 2,
          name: 'cluster-aks-mongodb-rs0-2.cluster-aks-mongodb-rs0.mongodb.svc.cluster.local:27017',
          health: 1,
          state: 2,
          stateStr: 'SECONDARY',
          uptime: 207033,
          ... // Additional details for the third member
        }
      ],
      ...
    }
    
  4. Z danych wyjściowych zanotuj członka ze stanem PRIMARY. W tym przykładzie członek z name: cluster-aks-mongodb-rs0-1 jest podstawowym członkiem zestawu replik MongoDB. Usuwasz podstawowego członka w następnym kroku, aby zasymulować awarię podu MongoDB.

Scenariusze testowania odporności

Skrypt bazy danych jest nadal wykonywany w pierwszym oknie terminalu, ale w drugim oknie terminalu można użyć następujących skryptów, aby zasymulować scenariusze awarii i obserwować zachowanie klastra Bazy danych MongoDB.

Scenariusz 1: Symulowanie usunięcia StatefulSet

  1. Wyświetl listę wszystkich zestawów stanowych przy użyciu kubectl get polecenia .

    kubectl get sts -n $AKS_MONGODB_NAMESPACE
    

    Przykładowe wyjście:

    NAME                         READY   AGE
    cluster-aks-mongodb-cfg      3/3     5d21h
    cluster-aks-mongodb-mongos   3/3     5d18h
    cluster-aks-mongodb-rs0      3/3     3h26m
    
  2. Usuń zestaw stanowy o nazwie cluster-aks-mongodb-rs0 przy użyciu kubectl delete polecenia .

    kubectl delete sts -n $AKS_MONGODB_NAMESPACE cluster-aks-mongodb-rs0
    
  3. Po usunięciu zestawu stanowego sprawdź pulpit nawigacyjny testu locust, aby obserwować zachowanie klastra MongoDB.

    Zrzut ekranu strony internetowej pokazujący pulpit nawigacyjny testu Locust po usunięciu zestawu stanowego.

  4. Pobierz dzienniki zasobnika Operatora Percona przy użyciu polecenia kubectl logs. Pamiętaj, aby zastąpić <percona-operator-pod> nazwą twojego zasobnika Percona Operator.

    kubectl logs -n $AKS_MONGODB_NAMESPACE <percona-operator-pod>
    

    Operator percona powinien ponownie utworzyć zestaw stanowy, a klaster MongoDB powróci do normalnego działania, jak pokazano w następujących przykładowych danych wyjściowych:

    ...
    2024-11-29T13:48:07.427Z        ERROR   failed to reconcile cluster     {"controller": "psmdb-controller", "object": {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID": "2e037504-d213-4bf7-a2b8-5af396b2d16c", "replset": "rs0", "error": "dial: ping mongo: server selection error: context deadline exceeded, current topology: { Type: ReplicaSetNoPrimary, ...
    ...
    2024-11-29T13:48:37.678Z        INFO    Warning: Reconciler returned both a non-zero result and a non-nil error. The result will  always be ignored if the error is non-nil and the non-nil error causes reqeueuing with exponential backoff. For more details, see:  https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/reconcile#Reconciler   {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "2e037504-d213-4bf7-a2b8-5af396b2d16c"}
    2024-11-29T13:48:37.678Z        ERROR   Reconciler error        {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "2e037504-d213-4bf7-a2b8-5af396b2d16c", "error": "create pbm object: create PBM connection to cluster-aks-mongodb-rs0-0. cluster-aks-mongodb-rs0.mongodb.svc.cluster.local:27017,cluster-aks-mongodb-rs0-1.cluster-aks-mongodb-rs0.mongodb.svc.cluster. local:27017,cluster-aks-mongodb-rs0-2.cluster-aks-mongodb-rs0.mongodb.svc.cluster.local:27017: create mongo connection: ping: server  selection error: server selection timeout, ...
    ...
    2024-11-29T13:48:38.210Z        INFO    Waiting for the pods    {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "2d970945-86b2-4c10-a610-7f7c42ad9a9f", "replset": "rs0", "size": 3, "pods": 1}
    2024-11-29T13:48:38.437Z        INFO    Cluster state changed   {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "2d970945-86b2-4c10-a610-7f7c42ad9a9f", "previous": "error", "current": "initializing"}
    2024-11-29T13:48:38.955Z        INFO    Waiting for the pods    {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "f2f803cb-d5f4-4851-9a05-71d46d95ca6d", "replset": "rs0", "size": 3, "pods": 1}
    2024-11-29T13:48:40.102Z        INFO    Waiting for the pods    {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "76accdff-7d7a-4ba8-9914-ff8793226dd5", "replset": "rs0", "size": 3, "pods": 1}
    2024-11-29T13:48:43.964Z        INFO    Waiting for the pods    {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "c49f50e7-881e-469c-bdf5-aaf925436097", "replset": "rs0", "size": 3, "pods": 1}
    2024-11-29T13:48:49.736Z        INFO    Waiting for the pods    {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "5b52ce2e-e07e-43e8-8ca0-b6850a4d8823", "replset": "rs0", "size": 3, "pods": 1}
    2024-11-29T13:48:55.560Z        INFO    Waiting for the pods    {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "95a26aff-b022-4543-a22e-0d50ea292190", "replset": "rs0", "size": 3, "pods": 2}
    2024-11-29T13:48:56.466Z        INFO    Waiting for the pods    {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "9f64bdb1-e616-44ab-a480-7eaf813db73e", "replset": "rs0", "size": 3, "pods": 2}
    2024-11-29T13:49:01.279Z        INFO    Waiting for the pods    {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "0281130b-b13e-4ab2-bd68-0b4cb6d01c84", "replset": "rs0", "size": 3, "pods": 2}
    2024-11-29T13:49:07.027Z        INFO    Waiting for the pods    {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "a3caedd1-ead3-406b-8ce3-056c7cd875dc", "replset": "rs0", "size": 3, "pods": 2}
    2024-11-29T13:49:12.783Z        INFO    Waiting for the pods    {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "8a82eb0c-8b26-4542-a4b5-f7e13e030d1e", "replset": "rs0", "size": 3, "pods": 2}
    2024-11-29T13:49:28.521Z        ERROR   failed to reconcile cluster     {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "22fc8c4d-30d5-4bf6-b405-720533f1d8d2", "replset": "rs0", "error": "dial: ping mongo: server selection error: context deadline  exceeded, current topology: { Type: ReplicaSetNoPrimary, ...
    ...
    2024-11-29T13:49:32.472Z        INFO    Fixing member tags      {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "8ff97dc9-b024-4cd9-b411-c3ffaf225e14", "replset": "rs0"}
    2024-11-29T13:49:39.065Z        ERROR   failed to reconcile cluster     {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "28438ddb-77a1-48b0-8390-277c4687a97b", "replset": "rs0", "error": "create system users: failed to get mongo client: ping mongo:  connection() error occurred during connection handshake: dial tcp: lookup cluster-aks-mongodb-rs0-1.cluster-aks-mongodb-rs0.mongodb. svc.cluster.local on 10.0.0.10:53: no such host", ...
    ...
    2024-11-29T13:49:40.424Z        ERROR   failed to reconcile cluster     {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "cfec8e33-d0c9-4adf-afe9-bc6dcbf711ba", "replset": "rs0", "error": "dial: ping mongo: connection() error occurred during connection  handshake: ...
    ...
    2024-11-29T13:49:45.433Z        INFO    Cluster state changed   {"controller": "psmdb-controller", "object":  {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":  "0765ea5f-52d8-44e2-a680-c7d082dd88e1", "previous": "initializing", "current": "ready"}
    

Scenariusz 2. Symulowanie błędu zasobnika bazy danych MongoDB

  1. Zidentyfikuj podstawowy zestaw replik MongoDB, a następnie usuń go przy użyciu polecenia kubectl delete w celu symulowania awarii poda MongoDB. Pamiętaj, aby zastąpić cluster-aks-mongodb-rs0-1 nazwą członka z danych wyjściowych rs.status() polecenia.

    kubectl delete pod cluster-aks-mongodb-rs0-1 -n $AKS_MONGODB_NAMESPACE
    
  2. Zestaw replik bazy danych MongoDB powinien wybrać nowy element podstawowy, aby kontynuować obsługę żądań. Można zweryfikować nowego głównego członka, łącząc się z powłoką MongoDB i wykonując polecenie rs.status(). Połącz się z podem klienta MongoDB przy użyciu następującego polecenia. Pamiętaj, aby zastąpić mongodb-locust-client-564695f8f-q6745 nazwą zasobnika z danych wyjściowych poprzedniego polecenia.

    kubectl -n $AKS_MONGODB_NAMESPACE exec -it mongodb-locust-client-564695f8f-q6745 -- /bin/bash
    
  3. Po nawiązaniu połączenia z zasobnikiem użyj następującego polecenia, aby połączyć się z MongoDB shell. Upewnij się, że masz poprawne wartości dla ${MY_CLUSTER_NAME}, ${databaseAdmin} i ${databaseAdminPassword} jak uzyskano w kroku 3 poprzedniego samouczka.

    mongosh --host ${MY_CLUSTER_NAME}-mongodb-rs0-0.${MY_CLUSTER_NAME}-mongodb-rs0.mongodb.svc.cluster.local --port 27017 -u ${databaseAdmin} -p ${databaseAdminPassword} --authenticationDatabase admin
    
  4. Po nawiązaniu połączenia z powłoką bazy danych MongoDB użyj następującego polecenia, aby zidentyfikować podstawowy zestaw replik bazy danych MongoDB:

    rs.status()
    

    Przykładowe wyjście:

    {
      set: 'rs0',
      ... // Additional details
      members: [
        {
          _id: 0,
          name: 'cluster-aks-mongodb-rs0-0.cluster-aks-mongodb-rs0.mongodb.svc.cluster.local:27017',
          health: 1,
          state: 2,
          stateStr: 'PRIMARY',
          uptime: 207037,
          ... // Additional details for the first member
        },
        {
          _id: 1,
          name: 'cluster-aks-mongodb-rs0-1.cluster-aks-mongodb-rs0.mongodb.svc.cluster.local:27017',
          health: 1,
          state: 1,
          stateStr: 'SECONDARY',
          uptime: 207033,
          ... // Additional details for the second member
        },
        {
          _id: 2,
          name: 'cluster-aks-mongodb-rs0-2.cluster-aks-mongodb-rs0.mongodb.svc.cluster.local:27017',
          health: 1,
          state: 2,
          stateStr: 'SECONDARY',
          uptime: 207033,
          ... // Additional details for the third member
        }
      ],
      ...
    }
    

    Powinieneś zobaczyć, że członek ze stanem PRIMARY zmienił się na SECONDARY, a inny członek ze stanem SECONDARY zmienił się na PRIMARY:

    Zrzut ekranu przedstawiający stronę internetową z pulpitem nawigacyjnym testu Locust po usunięciu podu.

  5. Pobierz dzienniki zasobnika Operatora Percona przy użyciu polecenia kubectl logs. Pamiętaj, aby zastąpić <percona-operator-pod> nazwą twojego zasobnika Percona Operator.

    kubectl logs -n $AKS_MONGODB_NAMESPACE <percona-operator-pod>
    

    Operator percona powinien ponownie utworzyć zestaw stanowy, a klaster MongoDB powróci do normalnego działania, jak pokazano w następujących przykładowych danych wyjściowych:

    ...
    2024-11-29T14:02:17.151Z        INFO    StatefulSet is not up to date   {"controller": "psmdb-controller", "object": {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID": "b1b1b1b1-cccc-dddd-eeee-f2f2f2f2f2f2", "sts": "cluster-aks-mongodb-rs0"}
    2024-11-29T14:02:17.189Z        INFO    StatefulSet is not up to date   {"controller": "psmdb-controller", "object":   {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":   "b1b1b1b1-cccc-dddd-eeee-f2f2f2f2f2f2", "sts": "cluster-aks-mongodb-rs0"}
    2024-11-29T14:02:17.405Z        INFO    Cluster state changed   {"controller": "psmdb-controller", "object":   {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":   "b1b1b1b1-cccc-dddd-eeee-f2f2f2f2f2f2", "previous": "ready", "current": "initializing"}
    2024-11-29T14:02:18.448Z        INFO    StatefulSet is not up to date   {"controller": "psmdb-controller", "object":   {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":   "c2c2c2c2-dddd-eeee-ffff-a3a3a3a3a3a3", "sts": "cluster-aks-mongodb-rs0"}
    2024-11-29T14:02:18.489Z        INFO    StatefulSet is not up to date   {"controller": "psmdb-controller", "object":   {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":   "c2c2c2c2-dddd-eeee-ffff-a3a3a3a3a3a3", "sts": "cluster-aks-mongodb-rs0"}
    2024-11-29T14:02:23.359Z        INFO    StatefulSet is not up to date   {"controller": "psmdb-controller", "object":   {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":   "d3d3d3d3-eeee-ffff-aaaa-b4b4b4b4b4b4", "sts": "cluster-aks-mongodb-rs0"}
    2024-11-29T14:02:23.402Z        INFO    StatefulSet is not up to date   {"controller": "psmdb-controller", "object":   {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":   "d3d3d3d3-eeee-ffff-aaaa-b4b4b4b4b4b4", "sts": "cluster-aks-mongodb-rs0"}
    2024-11-29T14:02:29.341Z        INFO    StatefulSet is not up to date   {"controller": "psmdb-controller", "object":   {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":   "e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5", "sts": "cluster-aks-mongodb-rs0"}
    2024-11-29T14:02:29.377Z        INFO    StatefulSet is not up to date   {"controller": "psmdb-controller", "object":   {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":   "e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5", "sts": "cluster-aks-mongodb-rs0"}
    2024-11-29T14:03:01.246Z        INFO    Cluster state changed   {"controller": "psmdb-controller", "object":   {"name":"cluster-aks-mongodb","namespace":"mongodb"}, "namespace": "mongodb", "name": "cluster-aks-mongodb", "reconcileID":   "f5f5f5f5-aaaa-bbbb-cccc-d6d6d6d6d6d6", "previous": "initializing", "current": "ready"}
    

Następny krok