Saya menjalankan cluster Kubernetes di AWS dan perlu mengonfigurasi Database MongoDB 4.2 yang direplikasi. Saya menggunakan StatefulSets agar Pod lain (misalnya, REST API NodeJS Pod) dapat dengan mudah terhubung ke instance mongo (contoh dsn: "mongodb://mongo-0.mongo,mongo-1.mongo,mongo-2. mongo:27017/aplikasi").

Mongo-configmap.yaml (menyediakan skrip shell untuk melakukan inisialisasi replikasi pada pembuatan wadah mongo):

apiVersion: v1
kind: ConfigMap
metadata:
  name: mongo-init
data:
  init.sh: |
    #!/bin/bash
    # wait for the readiness health check to pass 
    until ping -c 1 ${HOSTNAME}.mongo; do
      echo "waiting for DNS (${HOSTNAME}.mongo)..."
      sleep 2
    done
    until /usr/bin/mongo --eval 'printjson(db.serverStatus())'; do
      echo "connecting to local mongo..."
      sleep 2
    done
    echo "connected to local."
    HOST=mongo-0.mongo:27017
    until /usr/bin/mongo --host=${HOST} --eval 'printjson(db.serverStatus())'; do
      echo "connecting to remote mongo..."
      sleep 2
    done
    echo "connected to remote."
    if [[ "${HOSTNAME}" != 'mongo-0' ]]; then
      until /usr/bin/mongo --host=${HOST} --eval="printjson(rs.status())" \
            | grep -v "no replset config has been received"; do
        echo "waiting for replication set initialization"
        sleep 2
      done
      echo "adding self to mongo-0"
      /usr/bin/mongo --host=${HOST} --eval="printjson(rs.add('${HOSTNAME}.mongo'))"
    fi
    if [[ "${HOSTNAME}" == 'mongo-0' ]]; then
      echo "initializing replica set"
      /usr/bin/mongo --eval="printjson(rs.initiate(\
          {'_id': 'rs0', 'members': [{'_id': 0, \
           'host': 'mongo-0.mongo:27017'}]}))"
    fi
    echo "initialized"
    while true; do
      sleep 3600
    done

Mongo-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: mongo
  labels:
    app: mongo
spec:
  clusterIP: None
  ports:
  - port: 27017
  selector:
    app: mongo

Mongo-statefulset.yaml (2 kontainer di dalam satu Pod, 1 untuk DB aktual, yang lain untuk inisialisasi replikasi):

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongo
  labels:
    app: mongo
spec:
  selector:
    matchLabels:
      app: mongo
  serviceName: "mongo"
  replicas: 3
  template:
    metadata:
      labels:
        app: mongo
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: mongodb
        image: mongo:4.2
        command:
        - mongod
        args:
        - --replSet
        - rs0
        - "--bind_ip_all"
        ports:
        - containerPort: 27017
          name: web
        volumeMounts:
        - name: database
          mountPath: /data/db
        livenessProbe:
          exec:
            command:
            - /usr/bin/mongo
            - --eval
            - db.serverStatus()
          initialDelaySeconds: 10
          timeoutSeconds: 10
      - name: init-mongo
        image: mongo:4.2
        command:
        - bash
        - /config/init.sh
        volumeMounts:
        - name: config
          mountPath: /config
      volumes:
      - name: config
        configMap:
          name: "mongo-init"
  volumeClaimTemplates:
  - metadata:
      name: database
      annotations:
        volume.beta.kubernetes.io/storage-class: mongodb-storage
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 5Gi

Setelah menerapkan konfigurasi ini, 3 pod mongo mulai berjalan (mongo-0, mongo-1, mongo-2). Namun, pod lain tidak dapat terhubung ke pod mongo ini. Melihat lebih jauh ke dalam pod mongo-0 (harus menjadi contoh utama) mengungkapkan bahwa replikasi tidak berfungsi.

kubectl exec -it mongo-0 -- /bin/bash

Kemudian jalankan 'mongo' untuk memulai shell mongo, dan memasukkan 'rs.status()' ke dalam shell mongo menghasilkan output berikut:

{
    "info" : "run rs.initiate(...) if not yet done for the set",
    "ok" : 0,
    "errmsg" : "no replset config has been received",
    "code" : 94,
    "codeName" : "NotYetInitialized"
}
0
Andi R. 24 Maret 2020, 01:42

2 jawaban

Jawaban Terbaik

Rupanya, gambar mongo-4.x tidak disertai dengan 'ping' yang diinstal, oleh karena itu, skrip lainnya tidak dieksekusi. Menambahkan dua baris ini ke skrip di mongo-configmap.yaml memperbaiki masalah:

apt-get update
apt-get install iputils-ping --yes
1
Andi R. 25 Maret 2020, 12:09

Setelah mulai menjalankan semua pod, lalu tekan perintah ini

 kubectl exec -it mongo-0 -- /bin/bash

(di sini mongo-0 adalah nama pod)

Sekarang mulai mongo shell,

mongo

Sekarang periksa pod dimulai atau tidak

rs.status()

Jika tidak, mulai dan jadikan itu yang utama dengan menekan perintah ini satu per satu

rs.initiate()

var cfg = rs.conf()

cfg.members[0].host=”mongo-0.mongo:27017”

(ini adalah mongo-0 adalah nama pod dan mongo adalah nama serive.)

Sekarang konfigurasi ulang simpul utama

rs.reconfig(cfg)

Tambahkan semua budak ke simpul utama

rs.add(“mongo-1.mongo:27017”)

rs.add(“mongo-2.mongo:27017”)

(ini adalah mongo-1 dan mongo-2 adalah nama pod dan mongo adalah nama serive.)

Sekarang periksa status

rs.status()

Sekarang keluar dari shell utama dan pergi ke node sekunder (budak)

exit

exit

kubectl exec -it mongo-1 -- /bin/bash

mongo

rs.secondaryOk()

Periksa status dan keluar

rs.status()
exit
exit

Sekarang lakukan hal yang sama untuk node sekunder (slave) lainnya

0
Amit Rathee 21 Oktober 2020, 12:44