Percona Operator for MongoDB

유재혁·2023년 11월 10일
0

1. NoSQL

1.1 NoSQL 이란?

"not only SQL", "non-SQL"으로도 불리는 NoSQL은 관계형 데이터베이스의 전통적인 구조 밖에서 데이터 저장 및 쿼리를 가능하게 하는 데이터베이스 설계 접근법입니다. NoSQL은 여전히 관계형 데이터베이스 관리 시스템(Relational Database Management System, RDBMS)에서 찾을 수 있는 데이터를 저장할 수 있지만 RDBMS와는 다른 방식으로 데이터를 저장합니다. 관계형 데이터베이스와 비관계형 데이터베이스 중 무엇을 사용할지에 대한 결정은 크게 컨텍스트의 영향을 받으며, 적용사례에 따라 달라집니다.

관계형 데이터베이스의 전형적인 테이블 구조 대신, NoSQL 데이터베이스는 JSON 문서와 같은 하나의 데이터 구조 안에 데이터를 보관합니다. 이러한 비관계형 데이터베이스 설계는 스키마가 필요하지 않으므로 일반적으로 비정형인 대규모 데이터 세트를 관리할 수 있는 신속한 확장성을 제공합니다.

NoSQL은 또한 분산 데이터베이스의 한 유형입니다. 즉, 정보가 다양한 서버에 복제 및 저장되며, 서버는 원격이거나 로컬일 수 있습니다. 그러므로 데이터의 가용성과 신뢰성이 유지됩니다. 데이터 중 일부가 오프라인 상태가 되어도 데이터베이스의 나머지 부분은 계속 실행될 수 있습니다.

요즘, 거의 모든 산업에서 기업들은 고속으로 대량의 데이터를 관리해야 하며, 최신 웹 애플리케이션을 실행하기 위해 신속하게 확장할 수 있어야 합니다. 클라우드, 빅데이터, 모바일 및 웹 애플리케이션 내에서 확장이 중시되는 이 시대에 NoSQL 데이터베이스는 필요한 속도와 확장성을 제공하며, 성능과 사용 편의성 때문에 널리 선택되고 있습니다.

1.2 NoSQL Database 유형

  • 키-값 저장소
  • 문서 저장소
  • 와이드-컬럼 저장소
  • 그래프 저장소
  • 인 메모리 저장소

mongoDB는 JSON 기반의 문서 저장소 유형
JSON document = {"id":"01", "languange":"java"}

2. MongoDB

2.1 MongoDB와 RDBMS 차이점


MongoDB와 RDBMS (Relational Database Management System)는 데이터를 저장하고 관리하는 데 사용되는 서로 다른 두 가지 데이터베이스입니다. 두 가지 주요 차이점은 다음과 같습니다.

데이터 모델 : MongoDB와 RDBMS 의 주요 차이점은 데이터를 저장하고 구성하는 방법입니다. MongoDB는 선택적 스키마와 함께 JSON과 유사한 문서에 데이터를 저장하는 문서 지향 데이터 모델을 사용합니다. 반면에 RDBMS 는 데이터가 고정된 스키마가 있는 테이블에 저장되는 테이블 형식 데이터 모델을 사용합니다.
확장 성 : MongoDB는 비용이 많이 드는 하드웨어 업데이트 없이 확장되는 데이터 및 읽기/쓰기 워크로드를 처리할 수 있는 방식으로 구성되어 있어 수요 증가에 따라 효율적으로 확장할 수 있습니다. RDBMS 도 확장할 수 있지만 일반적으로 더 복잡한 구성이 필요하고 추가 하드웨어를 사용해야 할 수도 있습니다.
인덱싱 : MongoDB와 RDBMS 모두 인덱싱을 지원하여 쿼리 및 검색 성능을 향상시킵니다. 그러나 지원되는 인덱스의 유형과 구현 방식은 둘 사이에서 다를 수 있습니다.
트랜잭션 : RDBMS 는 일반적으로 여러 작업을 단일 작업 단위로 처리하고 전체적으로 커밋하거나 롤백할 수 있는 트랜잭션을 지원합니다. MongoDB는 동일한 방식으로 트랜잭션을 지원하지 않지만 원자성 작업을 구현하기 위한 몇 가지 대안을 제공합니다.
언어 지원 : MongoDB와 RDBMS 모두 광범위한 프로그래밍 언어와 함께 사용할 수 있습니다. 그러나 지원되는 특정 언어와 사용 방식은 두 언어 간에 다를 수 있습니다.
MongoDB와 RDBMS 는 데이터를 저장하고 관리하기 위한 강력한 도구이지만 서로 다른 강점을 가지고 있으며 서로 다른 애플리케이션에 가장 적합합니다.

2.2 MongoDB 복제 방식

Replica Set에서는 마스터 - 슬레이브 대신,
주 노드(primary) - 보조(secondary) 노드 용어를 사용한다.

기본적인 Replica Set의 형태

MongoDB의 주 노드는 클라이언트 앱들의 쓰기/읽기 요청을 모두 받는다. 이 작업을 수행하고, 변화된 모든 내용을 운영 로그(oplog)에 남긴다. 보조 노드들은 oplog에 기록된 내용들을 동일하게 연산하여 주 노드와 항상 같은 데이터를 유지한다. 즉 운영 로그 전달을 통해 보조 노드가 동일한 연산을 수행하여 데이터의 정합성을 맞추는 방식이다.

주 노드의 교체

주 노드와 보조 노드 사이에 주기적으로 주고받는 heartbeat 신호를 통해 주 노드가 정상적이지 않은 상황이라는 것을 발견하면, 나머지 보조 노드들의 투표(election)을 통해 새로운 주 노드를 선발한다. 원래의 주 노드가 정상 상태로 돌아오게 되면, 다시금 주 노드의 역할을 맡게 된다.

Case 1) 주 노드 서버가 정상인 경우

Case 2) 주 노드 서버가 정상 작동하지 않는 경우
보조 노드들은 자신들의 health 상태와 미리 지정된 Priority 값을 판단하여 어떤 보조 노드가 주 노드로 승격될 것인지에 대한 투표를 한다. 만약 동일한 점수가 나오면 가장 최근에 반영된 데이터를 반영한 보조 노드가 승격 대상이다.

투표가 끝나기 전까지 Read 수행은 보조 노드를 통해 가능하도록 미리 설정할 수 있지만, 주 노드가 없는 상태이므로 Write 수행은 불가능하다. 기본 설정이라면 투표 시간은 12초를 넘기지 않는다. MongoDB 3.6 이상 버전의 드라이버들은 주노드가 정상 상황이 아닌 경우 실패한 Write 연산을 retry 하는 기능이 있다.

결정권자(Arbiter)

결정권자는 주 노드의 데이터를 복제하지 않는다. 데이터가 없기 때문에 주 노드가 될 수 없다. 결정권자의 역할은 heartbeat을 통해 각 노드의 상태를 확인하고, 유사시 투표에만 참가한다.

2.3 MongoDB 샤딩(Sharding)

샤딩 이란?
샤딩은 여러 장비에 걸쳐 데이터를 분할하는 과정을 뜻한다. 각 장비에 데이터의 서브셋을 넣음으로써, 더 많은 수의 덜 강력한 장비로 더 많은 데이터를 저장하고 더 많은 부하를 처리할 수 있다. 컬렉션을 분할한 조각 데이터(청그)를 저장하며, 복제 세트로 구성될 수 있다.

  • 더 자주 접근하는 데이터를 성능이 더 좋은 하드웨어에 배치할 수 있다.
  • 지역에 따라 데이터셋을 분할해 주로 접근하는 애플리케이션 서버와 가까운 컬렉션에서 도큐먼트의 서브셋을 찾을 수 있다. ex) 사용자가 특정 로케일(locale)을 기반으로 할때

    샤딩은 개발 및 운영 측면에서 몽고DB를 구성하는 가장 어렵고 복잡한 방법이다. 모니터링할 구성 요소가 많고, 클러스터에서 데이터가 자동으로 옮겨 다니기 때문이다.

몽고DB 에서의 자동 샤딩

몽고DB는 애플리케이션에서 구조를 추상화하고 시스템 관리를 간단하게 하는 자동 샤딩을 지원한다. 몽고DB가 샤드에 걸쳐 데이터 분산을 자동화하므로 용량을 추가하고 제거하기 쉽다.

클러스터 구성 요소

몽고DB 샤딩을 통해, 많은 장비(샤드)의 클러스터를 생성하고, 각 샤드에 데이터 서브셋을 넣음으로써 데이터를 쪼갤 수 있다. 샤딩의 목적은 2개, 3개, 10개, 심지어 1000개의 샤드 클러스터가 하나의 장비처럼 보이게 하는 것이다. 이러한 세부 사항을 애플케이션으로부터 숨기기 위해, 샤드 앞단에 있는 mongos라는 라우팅 프로세스를 실행한다.

mongos

어떤 샤드가 어떤 데이터를 포함하는지 알려주는 '컨텐츠 목차'가 있다. 애플리케이션은 라우터에 연결해 정상적으로 요청을 발행할 수 있다. 라우터는 어떤 데이터가 어떤 샤드에 있는지 알기 때문에 요청을 적절한 샤드로 전달할 수 있다. 요청에 대한 응답이 있으면 라우터는 응답을 수집하고 필요하다면 통합하여 애플리케이션으로 되돌려보낸다.

Mongos - 다수 구성된 샤드의 인터페이스 역할, 클라이언트 요청의 올바른 샤드로 라우팅
Config Servers - 전체 클러스터의 메타 데이터, 구성 설정을 저장하는 서버

3. MongoDB 실습

3.1 Percona Operator for MongoDB Install

root@rook-01:~/mongodb# kubectl apply --server-side -f https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/crd.yaml
customresourcedefinition.apiextensions.k8s.io/perconaservermongodbbackups.psmdb.percona.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/perconaservermongodbrestores.psmdb.percona.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/perconaservermongodbs.psmdb.percona.com serverside-applied

root@rook-01:~/mongodb# kubectl get crd | grep psmdb
perconaservermongodbbackups.psmdb.percona.com         2023-11-10T01:21:49Z
perconaservermongodbrestores.psmdb.percona.com        2023-11-10T01:21:49Z
perconaservermongodbs.psmdb.percona.com               2023-11-10T01:21:59Z

root@rook-01:~/mongodb# kubectl create ns psmdb
namespace/psmdb created

## kubectl-ns 설치 필요
# curl -O https://raw.githubusercontent.com/weibeld/kubectl-ns/master/kubectl-ns
# chmod +x kubectl-ns
# install kubectl-ns /usr/local/bin/
# git clone https://github.com/junegunn/fzf.git ~/.fzf
# ~/.fzf/install
# source ~/.bashrc
# kubectl-ns // namespace psmdb로 변경



root@rook-01:~/mongodb# kubectl apply -f https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/rbac.yaml
role.rbac.authorization.k8s.io/percona-server-mongodb-operator created
serviceaccount/percona-server-mongodb-operator created
rolebinding.rbac.authorization.k8s.io/service-account-percona-server-mongodb-operator created

root@rook-01:~/mongodb# curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/operator.yaml

root@rook-01:~/mongodb# k apply -f operator.yaml
deployment.apps/percona-server-mongodb-operator created

root@rook-01:~/mongodb# kubectl get deploy,pod
NAME                                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/percona-server-mongodb-operator   1/1     1            1           29s

NAME                                                   READY   STATUS    RESTARTS   AGE
pod/percona-server-mongodb-operator-56ffcf8d96-bvkmd   1/1     Running   0          29s

## 각자 닉네임 변수 지정
root@rook-01:~/mongodb# MYNICK=yoojh5099
root@rook-01:~/mongodb# echo "export MYNICK=yoojh5099" >> /etc/profile

root@rook-01:~/mongodb# curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/secrets.yaml
root@rook-01:~/mongodb# cat secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: my-cluster-name-secrets
type: Opaque
stringData:
  MONGODB_BACKUP_USER: backup
  MONGODB_BACKUP_PASSWORD: backup123456
  MONGODB_DATABASE_ADMIN_USER: databaseAdmin
  MONGODB_DATABASE_ADMIN_PASSWORD: databaseAdmin123456
  MONGODB_CLUSTER_ADMIN_USER: clusterAdmin
  MONGODB_CLUSTER_ADMIN_PASSWORD: clusterAdmin123456
  MONGODB_CLUSTER_MONITOR_USER: clusterMonitor
  MONGODB_CLUSTER_MONITOR_PASSWORD: clusterMonitor123456
  MONGODB_USER_ADMIN_USER: userAdmin
  MONGODB_USER_ADMIN_PASSWORD: userAdmin123456
  PMM_SERVER_API_KEY: apikey
  PMM_SERVER_USER: admin
  PMM_SERVER_PASSWORD: admin

root@rook-01:~/mongodb# cat secrets.yaml | sed -e "s/my-cluster-name/$MYNICK/" | kubectl apply -f -
secret/yoojh5099-secrets created

root@rook-01:~/mongodb# kubectl get secret $MYNICK-secrets
root@rook-01:~/mongodb# kubectl get secret $MYNICK-secrets -o json | jq .data
{
  "MONGODB_BACKUP_PASSWORD": "YmFja3VwMTIzNDU2",
  "MONGODB_BACKUP_USER": "YmFja3Vw",
  "MONGODB_CLUSTER_ADMIN_PASSWORD": "Y2x1c3RlckFkbWluMTIzNDU2",
  "MONGODB_CLUSTER_ADMIN_USER": "Y2x1c3RlckFkbWlu",
  "MONGODB_CLUSTER_MONITOR_PASSWORD": "Y2x1c3Rlck1vbml0b3IxMjM0NTY=",
  "MONGODB_CLUSTER_MONITOR_USER": "Y2x1c3Rlck1vbml0b3I=",
  "MONGODB_DATABASE_ADMIN_PASSWORD": "ZGF0YWJhc2VBZG1pbjEyMzQ1Ng==",
  "MONGODB_DATABASE_ADMIN_USER": "ZGF0YWJhc2VBZG1pbg==",
  "MONGODB_USER_ADMIN_PASSWORD": "dXNlckFkbWluMTIzNDU2",
  "MONGODB_USER_ADMIN_USER": "dXNlckFkbWlu",
  "PMM_SERVER_API_KEY": "YXBpa2V5",
  "PMM_SERVER_PASSWORD": "YWRtaW4=",
  "PMM_SERVER_USER": "YWRtaW4="
}

# 클러스터 생성 : 복제 세트(3개 파드) replsets(rs0, size 3)
curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/cr.yaml

curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/cluster1.yaml
cat cluster1.yaml | yh
cat cluster1.yaml | sed -e "s/my-cluster-name/$MYNICK/" | kubectl apply -f - && kubectl get psmdb -w

# 클러스터 생성 정보 확인 : 약자 psmdb
kubectl get perconaservermongodbs
root@rook-01:~/mongodb# kubectl get psmdb
NAME        ENDPOINT                                STATUS   AGE
yoojh5099   yoojh5099-rs0.psmdb.svc.cluster.local   ready    3m38s

# 클러스타 파드 정보 확인
root@rook-01:~/mongodb# kubectl get sts,pod -owide
NAME                             READY   AGE    CONTAINERS   IMAGES
statefulset.apps/yoojh5099-rs0   3/3     4m1s   mongod       percona/percona-server-mongodb:6.0.9-7

NAME                                                   READY   STATUS    RESTARTS   AGE     IP               NODE      NOMINATED NODE   READINESS GATES
pod/percona-server-mongodb-operator-56ffcf8d96-bvkmd   1/1     Running   0          9m38s   10.244.140.226   rook-02   <none>           <none>
pod/yoojh5099-rs0-0                                    1/1     Running   0          4m      10.244.140.224   rook-02   <none>           <none>
pod/yoojh5099-rs0-1                                    1/1     Running   0          2m56s   10.244.125.228   rook-03   <none>           <none>
pod/yoojh5099-rs0-2                                    1/1     Running   0          2m9s    10.244.155.116   rook-01   <none>           <none>
root@rook-01:~/mongodb# kubectl get svc,ep
NAME                    TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)     AGE
service/yoojh5099-rs0   ClusterIP   None         <none>        27017/TCP   4m3s

NAME                      ENDPOINTS                                                        AGE
endpoints/yoojh5099-rs0   10.244.125.228:27017,10.244.140.224:27017,10.244.155.116:27017   4m3s
root@rook-01:~/mongodb# kubectl df-pv

 PV NAME                                   PVC NAME                     NAMESPACE  NODE NAME  POD NAME         VOLUME MOUNT NAME  SIZE  USED    AVAILABLE  %USED  IUSED  IFREE     %IUSED
 pvc-42d55079-12ba-454d-be48-c01f76164808  mongod-data-yoojh5099-rs0-2  psmdb      rook-01    yoojh5099-rs0-2  mongod-data        99Gi  1696Mi  98Gi       1.66   226    52428062  0.00
 pvc-3ceacd1e-6105-4566-9959-f8e374842255  mongod-data-yoojh5099-rs0-1  psmdb      rook-03    yoojh5099-rs0-1  mongod-data        99Gi  1694Mi  98Gi       1.66   192    52428096  0.00
 pvc-37fcb569-761a-44e3-89a8-13df53a6e599  mongod-data-yoojh5099-rs0-0  psmdb      rook-02    yoojh5099-rs0-0  mongod-data        99Gi  1377Mi  98Gi       1.35   112    52428176  0.00

root@rook-01:~/mongodb# kubectl get pvc,pv
NAME                                                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS       AGE
persistentvolumeclaim/mongod-data-yoojh5099-rs0-0   Bound    pvc-37fcb569-761a-44e3-89a8-13df53a6e599   3Gi        RWO            nfs-storageclass   4m9s
persistentvolumeclaim/mongod-data-yoojh5099-rs0-1   Bound    pvc-3ceacd1e-6105-4566-9959-f8e374842255   3Gi        RWO            nfs-storageclass   3m5s
persistentvolumeclaim/mongod-data-yoojh5099-rs0-2   Bound    pvc-42d55079-12ba-454d-be48-c01f76164808   3Gi        RWO            nfs-storageclass   2m18s

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS        CLAIM                               STORAGECLASS       REASON   AGE
persistentvolume/pvc-1932857f-49bf-41e0-b94c-c7187fb68a66   2Gi        RWO            Delete           Terminating   mysql-cluster/datadir-mycluster-2   local-path                  18d
persistentvolume/pvc-2fd5b199-4b2f-4ff2-9941-eacd1623f182   2Gi        RWO            Delete           Bound         mysql-cluster/datadir-mycluster-0   local-path                  18d
persistentvolume/pvc-37fcb569-761a-44e3-89a8-13df53a6e599   3Gi        RWO            Delete           Bound         psmdb/mongod-data-yoojh5099-rs0-0   nfs-storageclass            4m9s
persistentvolume/pvc-3ceacd1e-6105-4566-9959-f8e374842255   3Gi        RWO            Delete           Bound         psmdb/mongod-data-yoojh5099-rs0-1   nfs-storageclass            3m5s
persistentvolume/pvc-42d55079-12ba-454d-be48-c01f76164808   3Gi        RWO            Delete           Bound         psmdb/mongod-data-yoojh5099-rs0-2   nfs-storageclass            2m18s
persistentvolume/pvc-c746bca6-2fd1-4d0d-a7a7-00633d5d50f1   2Gi        RWO            Delete           Bound         mysql-cluster/datadir-mycluster-1   local-path                  18d

# mongodb 이미지 버전 확인
root@rook-01:~/mongodb# kubectl get perconaservermongodbs $MYNICK -o jsonpath={.spec.image} ; echo
percona/percona-server-mongodb:6.0.9-7

3.2 헤드리스 서비스 접속 정보 확인

# 헤드리스 서비스 확인 : ClusterIP None
root@rook-01:~/mongodb# kubectl get svc,ep
NAME                    TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)     AGE
service/yoojh5099-rs0   ClusterIP   None         <none>        27017/TCP   6m35s

NAME                      ENDPOINTS                                                        AGE
endpoints/yoojh5099-rs0   10.244.125.228:27017,10.244.140.224:27017,10.244.155.116:27017   6m35s

# 엔드포인트 슬라이스 정보 확인 
root@rook-01:~/mongodb# kubectl describe endpointslices
Name:         yoojh5099-rs0-nfwzv
Namespace:    psmdb
Labels:       app.kubernetes.io/instance=yoojh5099
              app.kubernetes.io/managed-by=percona-server-mongodb-operator
              app.kubernetes.io/name=percona-server-mongodb
              app.kubernetes.io/part-of=percona-server-mongodb
              app.kubernetes.io/replset=rs0
              endpointslice.kubernetes.io/managed-by=endpointslice-controller.k8s.io
              kubernetes.io/service-name=yoojh5099-rs0
              service.kubernetes.io/headless=
Annotations:  endpoints.kubernetes.io/last-change-trigger-time: 2023-11-10T02:14:59Z
AddressType:  IPv4
Ports:
  Name     Port   Protocol
  ----     ----   --------
  mongodb  27017  TCP
Endpoints:
  - Addresses:  10.244.140.224
    Conditions:
      Ready:    true
    Hostname:   yoojh5099-rs0-0
    TargetRef:  Pod/yoojh5099-rs0-0
    NodeName:   rook-02
    Zone:       <unset>
  - Addresses:  10.244.125.228
    Conditions:
      Ready:    true
    Hostname:   yoojh5099-rs0-1
    TargetRef:  Pod/yoojh5099-rs0-1
    NodeName:   rook-03
    Zone:       <unset>
  - Addresses:  10.244.155.116
    Conditions:
      Ready:    true
    Hostname:   yoojh5099-rs0-2
    TargetRef:  Pod/yoojh5099-rs0-2
    NodeName:   rook-01
    Zone:       <unset>
Events:         <none>

# netshoot 이미지로 netdebug 파드에 zsh 실행
root@rook-01:~/mongodb# kubectl run -it --rm netdebug --image=nicolaka/netshoot --restart=Never -- zsh

 netdebug  ~  MYNICK=yoojh5099
 netdebug  ~  nslookup $MYNICK-rs0
Server:         10.96.0.10
Address:        10.96.0.10#53

Name:   yoojh5099-rs0.psmdb.svc.cluster.local
Address: 10.244.155.116
Name:   yoojh5099-rs0.psmdb.svc.cluster.local
Address: 10.244.125.228
Name:   yoojh5099-rs0.psmdb.svc.cluster.local
Address: 10.244.140.224
 netdebug  ~  nslookup -type=srv $MYNICK-rs0
Server:         10.96.0.10
Address:        10.96.0.10#53

yoojh5099-rs0.psmdb.svc.cluster.local   service = 0 33 27017 yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local.
yoojh5099-rs0.psmdb.svc.cluster.local   service = 0 33 27017 yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local.
yoojh5099-rs0.psmdb.svc.cluster.local   service = 0 33 27017 yoojh5099-rs0-2.yoojh5099-rs0.psmdb.svc.cluster.local.

3.3 복제 셋 확인

## MongoDB CLINET 사전 준비
root@rook-01:~/mongodb# curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/myclient.yaml
root@rook-01:~/mongodb# VERSION=4.4.24-23 envsubst < myclient.yaml | kubectl apply -f -
daemonset.apps/myclient created
root@rook-01:~/mongodb# kubectl get pod -l name=mongodb -owide
NAME             READY   STATUS    RESTARTS   AGE   IP               NODE      NOMINATED NODE   READINESS GATES
myclient-8988r   1/1     Running   0          39s   10.244.155.117   rook-01   <none>           <none>
myclient-w84ms   1/1     Running   0          39s   10.244.125.231   rook-03   <none>           <none>
myclient-wcrcb   1/1     Running   0          39s   10.244.140.229   rook-02   <none>           <none>

# [터미널2] 클러스터 접속(CLUSTER_USER)
root@rook-01:~# kubectl exec ds/myclient -it -- mongo --quiet "mongodb+srv://clusterAdmin:clusterAdmin123456@$MYNICK-rs0.psmdb.svc.cluster.local/admin?replicaSet=rs0&ssl=false"

# 복제 셋 정보 확인 : 구성원 상태 확인
rs0:PRIMARY> rs.status()['members']
[
        {
                "_id" : 0,
                "name" : "yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
                "health" : 1,
                "state" : 1,
                "stateStr" : "PRIMARY",
                "uptime" : 12114,
                "optime" : {
                        "ts" : Timestamp(1699594509, 2),
                        "t" : NumberLong(1)
                },
                "optimeDate" : ISODate("2023-11-10T05:35:09Z"),
                "lastAppliedWallTime" : ISODate("2023-11-10T05:35:09.540Z"),
                "lastDurableWallTime" : ISODate("2023-11-10T05:35:09.540Z"),
                "syncSourceHost" : "",
                "syncSourceId" : -1,
                "infoMessage" : "",
                "electionTime" : Timestamp(1699582473, 2),
                "electionDate" : ISODate("2023-11-10T02:14:33Z"),
                "configVersion" : 8,
                "configTerm" : 1,
                "self" : true,
                "lastHeartbeatMessage" : ""
        },
        {
                "_id" : 1,
                "name" : "yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
                "health" : 1,
                "state" : 2,
                "stateStr" : "SECONDARY",
                "uptime" : 12024,
                "optime" : {
                        "ts" : Timestamp(1699594509, 2),
                        "t" : NumberLong(1)
                },
                "optimeDurable" : {
                        "ts" : Timestamp(1699594509, 2),
                        "t" : NumberLong(1)
                },
                "optimeDate" : ISODate("2023-11-10T05:35:09Z"),
                "optimeDurableDate" : ISODate("2023-11-10T05:35:09Z"),
                "lastAppliedWallTime" : ISODate("2023-11-10T05:35:09.540Z"),
                "lastDurableWallTime" : ISODate("2023-11-10T05:35:09.540Z"),
                "lastHeartbeat" : ISODate("2023-11-10T05:35:10.499Z"),
                "lastHeartbeatRecv" : ISODate("2023-11-10T05:35:12.073Z"),
                "pingMs" : NumberLong(0),
                "lastHeartbeatMessage" : "",
                "syncSourceHost" : "yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
                "syncSourceId" : 0,
                "infoMessage" : "",
                "configVersion" : 8,
                "configTerm" : 1
        },
        {
                "_id" : 2,
                "name" : "yoojh5099-rs0-2.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
                "health" : 1,
                "state" : 2,
                "stateStr" : "SECONDARY",
                "uptime" : 11993,
                "optime" : {
                        "ts" : Timestamp(1699594509, 2),
                        "t" : NumberLong(1)
                },
                "optimeDurable" : {
                        "ts" : Timestamp(1699594509, 2),
                        "t" : NumberLong(1)
                },
                "optimeDate" : ISODate("2023-11-10T05:35:09Z"),
                "optimeDurableDate" : ISODate("2023-11-10T05:35:09Z"),
                "lastAppliedWallTime" : ISODate("2023-11-10T05:35:09.540Z"),
                "lastDurableWallTime" : ISODate("2023-11-10T05:35:09.540Z"),
                "lastHeartbeat" : ISODate("2023-11-10T05:35:10.479Z"),
                "lastHeartbeatRecv" : ISODate("2023-11-10T05:35:11.275Z"),
                "pingMs" : NumberLong(0),
                "lastHeartbeatMessage" : "",
                "syncSourceHost" : "yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
                "syncSourceId" : 1,
                "infoMessage" : "",
                "configVersion" : 8,
                "configTerm" : 1
        }
]

# 복제 셋 정보 확인* : 간략히 확인, 자주 확인하는 명령어
rs0:PRIMARY> db.isMaster()
{
        "topologyVersion" : {
                "processId" : ObjectId("654d91be65f6a103594dd132"),
                "counter" : NumberLong(13)
        },
        "hosts" : [
                "yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
                "yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
                "yoojh5099-rs0-2.yoojh5099-rs0.psmdb.svc.cluster.local:27017"
        ],
        "setName" : "rs0",
        "setVersion" : 8,
        "ismaster" : true,
        "secondary" : false,
        "primary" : "yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
        "tags" : {
                "podName" : "yoojh5099-rs0-0",
                "serviceName" : "yoojh5099"
        },
        "me" : "yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
        "electionId" : ObjectId("7fffffff0000000000000001"),
        "lastWrite" : {
                "opTime" : {
                        "ts" : Timestamp(1699594525, 1),
                        "t" : NumberLong(1)
                },
                "lastWriteDate" : ISODate("2023-11-10T05:35:25Z"),
                "majorityOpTime" : {
                        "ts" : Timestamp(1699594525, 1),
                        "t" : NumberLong(1)
                },
                "majorityWriteDate" : ISODate("2023-11-10T05:35:25Z")
        },
        "maxBsonObjectSize" : 16777216,
        "maxMessageSizeBytes" : 48000000,
        "maxWriteBatchSize" : 100000,
        "localTime" : ISODate("2023-11-10T05:35:28.898Z"),
        "logicalSessionTimeoutMinutes" : 30,
        "connectionId" : 22390,
        "minWireVersion" : 0,
        "maxWireVersion" : 17,
        "readOnly" : false,
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1699594525, 1),
                "signature" : {
                        "hash" : BinData(0,"LhHJ2BN60o79+ST9QB2jMmKDkaY="),
                        "keyId" : NumberLong("7299651142684770308")
                }
        },
        "operationTime" : Timestamp(1699594525, 1)
}

# 오피로그 정보 확인 : 크기, 연산 시간
rs0:PRIMARY> rs.printReplicationInfo()
configured oplog size:   5048.650146484375MB
log length start to end: 12067secs (3.35hrs)
oplog first event time:  Fri Nov 10 2023 02:14:33 GMT+0000 (UTC)
oplog last event time:   Fri Nov 10 2023 05:35:40 GMT+0000 (UTC)
now:                     Fri Nov 10 2023 05:35:46 GMT+0000 (UTC)

# 동기화 상태 확인 : 세컨더리 구성원이 프라이머리의 어디까지 정보를 동기화했는지 확인
rs0:PRIMARY> rs.printSecondaryReplicationInfo()
source: yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local:27017
        syncedTo: Fri Nov 10 2023 05:35:56 GMT+0000 (UTC)
        0 secs (0 hrs) behind the primary
source: yoojh5099-rs0-2.yoojh5099-rs0.psmdb.svc.cluster.local:27017
        syncedTo: Fri Nov 10 2023 05:35:56 GMT+0000 (UTC)
        0 secs (0 hrs) behind the primary

# 복제 옵션 정보 확인
rs0:PRIMARY> rs.conf()
{
        "_id" : "rs0",
        "version" : 8,
        "term" : 1,
        "members" : [
                {
                        "_id" : 0,
                        "host" : "yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 2,
                        "tags" : {
                                "podName" : "yoojh5099-rs0-0",
                                "serviceName" : "yoojh5099"
                        },
                        "secondaryDelaySecs" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 1,
                        "host" : "yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 2,
                        "tags" : {
                                "podName" : "yoojh5099-rs0-1",
                                "serviceName" : "yoojh5099"
                        },
                        "secondaryDelaySecs" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 2,
                        "host" : "yoojh5099-rs0-2.yoojh5099-rs0.psmdb.svc.cluster.local:27017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 2,
                        "tags" : {
                                "podName" : "yoojh5099-rs0-2",
                                "serviceName" : "yoojh5099"
                        },
                        "secondaryDelaySecs" : NumberLong(0),
                        "votes" : 1
                }
        ],
        "protocolVersion" : NumberLong(1),
        "writeConcernMajorityJournalDefault" : true,
        "settings" : {
                "chainingAllowed" : true,
                "heartbeatIntervalMillis" : 2000,
                "heartbeatTimeoutSecs" : 10,
                "electionTimeoutMillis" : 10000,
                "catchUpTimeoutMillis" : -1,
                "catchUpTakeoverDelayMillis" : 30000,
                "getLastErrorModes" : {

                },
                "getLastErrorDefaults" : {
                        "w" : 1,
                        "wtimeout" : 0
                },
                "replicaSetId" : ObjectId("654d920965f6a103594dd169")
        }
}

4. 샤딩

4.1 샤딩 정보 확인

# 클러스터 생성 : 복제 셋 2개(rs-0, rs1), mongos(파드 3개), cfg(파드 3개) >> 6분 정도 소요
root@rook-01:~/mongodb# kubectl get secret $MYNICK-secrets
NAME                TYPE     DATA   AGE
yoojh5099-secrets   Opaque   13     3h36m
root@rook-01:~/mongodb# curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/cluster2.yaml
root@rook-01:~/mongodb# cat cluster2.yaml | sed -e "s/my-cluster-name/$MYNICK/" | kubectl apply -f -
perconaservermongodb.psmdb.percona.com/yoojh5099 configured

root@rook-01:~/mongodb# kubectl get psmdb,sts,pod,svc,ep,pvc,pv
NAME                                               ENDPOINT                                   STATUS   AGE
perconaservermongodb.psmdb.percona.com/yoojh5099   yoojh5099-mongos.psmdb.svc.cluster.local   ready    94m

NAME                                READY   AGE
statefulset.apps/yoojh5099-cfg      3/3     94m
statefulset.apps/yoojh5099-mongos   3/3     92m
statefulset.apps/yoojh5099-rs0      3/3     94m
statefulset.apps/yoojh5099-rs1      3/3     94m

NAME                                                   READY   STATUS      RESTARTS   AGE
pod/myclient-8988r                                     1/1     Running     0          4h19m
pod/myclient-w84ms                                     1/1     Running     0          4h19m
pod/myclient-wcrcb                                     1/1     Running     0          4h19m
pod/netdebug                                           0/1     Completed   0          5h7m
pod/percona-server-mongodb-operator-56ffcf8d96-bvkmd   1/1     Running     0          5h20m
pod/yoojh5099-cfg-0                                    1/1     Running     0          94m
pod/yoojh5099-cfg-1                                    1/1     Running     0          93m
pod/yoojh5099-cfg-2                                    1/1     Running     0          93m
pod/yoojh5099-mongos-0                                 1/1     Running     0          92m
pod/yoojh5099-mongos-1                                 1/1     Running     0          91m
pod/yoojh5099-mongos-2                                 1/1     Running     0          91m
pod/yoojh5099-rs0-0                                    1/1     Running     0          94m
pod/yoojh5099-rs0-1                                    1/1     Running     0          93m
pod/yoojh5099-rs0-2                                    1/1     Running     0          93m
pod/yoojh5099-rs1-0                                    1/1     Running     0          94m
pod/yoojh5099-rs1-1                                    1/1     Running     0          93m
pod/yoojh5099-rs1-2                                    1/1     Running     0          92m

NAME                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)     AGE
service/yoojh5099-cfg      ClusterIP   None             <none>        27017/TCP   94m
service/yoojh5099-mongos   ClusterIP   10.103.197.163   <none>        27017/TCP   92m
service/yoojh5099-rs0      ClusterIP   None             <none>        27017/TCP   94m
service/yoojh5099-rs1      ClusterIP   None             <none>        27017/TCP   94m

NAME                         ENDPOINTS                                                        AGE
endpoints/yoojh5099-cfg      10.244.125.239:27017,10.244.140.246:27017,10.244.155.122:27017   94m
endpoints/yoojh5099-mongos   10.244.125.241:27017,10.244.140.223:27017,10.244.155.124:27017   92m
endpoints/yoojh5099-rs0      10.244.125.238:27017,10.244.140.238:27017,10.244.155.121:27017   94m
endpoints/yoojh5099-rs1      10.244.125.240:27017,10.244.140.241:27017,10.244.155.123:27017   94m

NAME                                                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS       AGE
persistentvolumeclaim/mongod-data-yoojh5099-cfg-0   Bound    pvc-b8f3bc27-af6f-4418-b256-be896a7b09ce   3Gi        RWO            nfs-storageclass   94m
persistentvolumeclaim/mongod-data-yoojh5099-cfg-1   Bound    pvc-77f02240-47ae-48ba-9fb7-35e6d35dab7a   3Gi        RWO            nfs-storageclass   93m
persistentvolumeclaim/mongod-data-yoojh5099-cfg-2   Bound    pvc-a6b9a807-a854-4ca6-93f9-4f679e421955   3Gi        RWO            nfs-storageclass   93m
persistentvolumeclaim/mongod-data-yoojh5099-rs0-0   Bound    pvc-ec5211d2-8390-48ed-aa1f-a802aedd1a39   3Gi        RWO            nfs-storageclass   94m
persistentvolumeclaim/mongod-data-yoojh5099-rs0-1   Bound    pvc-8cce3b0b-a823-4dff-b9cf-480f4480e4f0   3Gi        RWO            nfs-storageclass   93m
persistentvolumeclaim/mongod-data-yoojh5099-rs0-2   Bound    pvc-30ded14b-d55b-490f-87ed-f51f1c6fd1f8   3Gi        RWO            nfs-storageclass   93m
persistentvolumeclaim/mongod-data-yoojh5099-rs1-0   Bound    pvc-dce20a6f-ec48-4a9d-b907-4a32e171db87   3Gi        RWO            nfs-storageclass   94m
persistentvolumeclaim/mongod-data-yoojh5099-rs1-1   Bound    pvc-33402b1c-8c54-47e0-ae33-2aef70ed0463   3Gi        RWO            nfs-storageclass   93m
persistentvolumeclaim/mongod-data-yoojh5099-rs1-2   Bound    pvc-d008eb7f-2e0b-4f3d-a49f-b73d4d524e49   3Gi        RWO            nfs-storageclass   92m

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS        CLAIM                               STORAGECLASS       REASON   AGE
persistentvolume/pvc-1932857f-49bf-41e0-b94c-c7187fb68a66   2Gi        RWO            Delete           Terminating   mysql-cluster/datadir-mycluster-2   local-path                  18d
persistentvolume/pvc-2fd5b199-4b2f-4ff2-9941-eacd1623f182   2Gi        RWO            Delete           Bound         mysql-cluster/datadir-mycluster-0   local-path                  18d
persistentvolume/pvc-30ded14b-d55b-490f-87ed-f51f1c6fd1f8   3Gi        RWO            Delete           Bound         psmdb/mongod-data-yoojh5099-rs0-2   nfs-storageclass            93m
persistentvolume/pvc-33402b1c-8c54-47e0-ae33-2aef70ed0463   3Gi        RWO            Delete           Bound         psmdb/mongod-data-yoojh5099-rs1-1   nfs-storageclass            93m
persistentvolume/pvc-77f02240-47ae-48ba-9fb7-35e6d35dab7a   3Gi        RWO            Delete           Bound         psmdb/mongod-data-yoojh5099-cfg-1   nfs-storageclass            93m
persistentvolume/pvc-8cce3b0b-a823-4dff-b9cf-480f4480e4f0   3Gi        RWO            Delete           Bound         psmdb/mongod-data-yoojh5099-rs0-1   nfs-storageclass            93m
persistentvolume/pvc-a6b9a807-a854-4ca6-93f9-4f679e421955   3Gi        RWO            Delete           Bound         psmdb/mongod-data-yoojh5099-cfg-2   nfs-storageclass            93m
persistentvolume/pvc-b8f3bc27-af6f-4418-b256-be896a7b09ce   3Gi        RWO            Delete           Bound         psmdb/mongod-data-yoojh5099-cfg-0   nfs-storageclass            94m
persistentvolume/pvc-c746bca6-2fd1-4d0d-a7a7-00633d5d50f1   2Gi        RWO            Delete           Bound         mysql-cluster/datadir-mycluster-1   local-path                  18d
persistentvolume/pvc-d008eb7f-2e0b-4f3d-a49f-b73d4d524e49   3Gi        RWO            Delete           Bound         psmdb/mongod-data-yoojh5099-rs1-2   nfs-storageclass            92m
persistentvolume/pvc-dce20a6f-ec48-4a9d-b907-4a32e171db87   3Gi        RWO            Delete           Bound         psmdb/mongod-data-yoojh5099-rs1-0   nfs-storageclass            94m
persistentvolume/pvc-ec5211d2-8390-48ed-aa1f-a802aedd1a39   3Gi        RWO            Delete           Bound         psmdb/mongod-data-yoojh5099-rs0-0   nfs-storageclass            94m

# mongos 라우터 접속 서비스 정보 확인
root@rook-01:~/mongodb# kubectl get svc,ep $MYNICK-mongos
NAME                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)     AGE
service/yoojh5099-mongos   ClusterIP   10.103.197.163   <none>        27017/TCP   93m

NAME                         ENDPOINTS                                                        AGE
endpoints/yoojh5099-mongos   10.244.125.241:27017,10.244.140.223:27017,10.244.155.124:27017   93m

# [터미널1] 클러스터 접속(ADMIN_USER)
root@rook-01:~/mongodb# kubectl exec ds/myclient -it -- mongo --quiet "mongodb://userAdmin:userAdmin123456@$MYNICK-mongos.psmdb.svc.cluster.local/admin?ssl=false"
mongos> db
admin
mongos> show dbs
admin   0.000GB
config  0.004GB
mongos> db.createUser({user: "doik" , pwd: "qwe123" , roles: [ "userAdminAnyDatabase", "dbAdminAnyDatabase","readWriteAnyDatabase"]})
Successfully added user: {
        "user" : "doik",
        "roles" : [
                "userAdminAnyDatabase",
                "dbAdminAnyDatabase",
                "readWriteAnyDatabase"
        ]
}

# 샤드 클러스터 상태 확인 : 기본 정보, 샤드 정보, 밸런서 정보, 샤딩 설정이 된 컬렉션 정보, 청크 정보 등 출력
mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("654dc58e07e083766e790112")
  }
  shards:
        {  "_id" : "rs0",  "host" : "rs0/yoojh5099-rs0-0.yoojh5099-rs0.psmdb.svc.cluster.local:27017,yoojh5099-rs0-1.yoojh5099-rs0.psmdb.svc.cluster.local:27017,yoojh5099-rs0-2.yoojh5099-rs0.psmdb.svc.cluster.local:27017",  "state" : 1,  "topologyTime" : Timestamp(1699595812, 6) }
        {  "_id" : "rs1",  "host" : "rs1/yoojh5099-rs1-0.yoojh5099-rs1.psmdb.svc.cluster.local:27017,yoojh5099-rs1-1.yoojh5099-rs1.psmdb.svc.cluster.local:27017,yoojh5099-rs1-2.yoojh5099-rs1.psmdb.svc.cluster.local:27017",  "state" : 1,  "topologyTime" : Timestamp(1699595813, 5) }
  active mongoses:
        "6.0.9-7" : 3
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours:
                No recent migrations
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:

profile
클라우드 엔지니어

0개의 댓글

관련 채용 정보