MongoDB 소개
- NoSQL
- NoSQL 종류 : Key-Value Store(Redis), Wide Column Store(HBase, Cassandra), Document Store(mongoDB, CouchDB), Graph Store(Neo4j)
MongoDB 기본개념
- 기본 단위는 도큐먼트이며, 관계형 데이터베이스의 행과 유사함
- 컬렉션은 관계형 데이터베이스의 테이블과 같다
- 모든 도큐먼트는 컬렉션 내에 고유한 특수키인 "_id"를 가진다
- 복제 세트에는 프라이머리 Primary, 세컨더리 Secondary, 아비터 Arbiter 구성원이 있다.
- 프라이머리 : 클라이언트와 읽기 및 쓰기 작업
- 세컨더리 : 프라이머리 구성원의 정보를 동기화
- 아비터 : 정보를 저장하지는 않고 복제 세트의 복구를 돕는다
Operator 설치
https://www.percona.com/doc/kubernetes-operator-for-psmongodb/kubernetes.html
# CRD 설치
git clone -b v1.12.0 https://github.com/percona/percona-server-mongodb-operator
cd percona-server-mongodb-operator
kubectl apply --server-side -f deploy/crd.yaml
kubectl get crd
# 실습 편리를 위해서 네임스페이스 변경
kubens psmdb
# RBAC 생성
kubectl apply -f deploy/rbac.yaml
# 오퍼레이터 생성
kubectl apply -f deploy/operator.yaml
MYNICK=my-cluster-name
# 계정 정보를 위한 secret 생성 : base64 decode 로 값을 보자
kubectl apply -f deploy/operator.yaml
kubectl get secret $MYNICK-secrets
kubectl get secret $MYNICK-secrets -o json | jq
# 클러스터 생성 : 복제 세트(3개 파드)
MYCLUSTERNAME=$MYNICK envsubst < ~/DOIK/4/mycluster1.yaml | kubectl apply -f -
~/DOIK/4/mycluster1.yaml
기본만 배포
- rs0 - 3개
- nonvoting: false
- arbiter: false
- sharding: false
- mongos: 3 이지만, sharding과 연결되어 사용하지 않음
- backup: false
apiVersion: psmdb.percona.com/v1-12-0
kind: PerconaServerMongoDB
metadata:
name: ${MYCLUSTERNAME}-db
finalizers:
- delete-psmdb-pods-in-order
spec:
crVersion: 1.12.0
image: percona/percona-server-mongodb:5.0.7-6
imagePullPolicy: Always
allowUnsafeConfigurations: false
updateStrategy: SmartUpdate
upgradeOptions:
versionServiceEndpoint: https://check.percona.com
apply: 5.0-recommended
schedule: "0 2 * * *"
setFCV: false
secrets:
users: ${MYCLUSTERNAME}-secrets
encryptionKey: ${MYCLUSTERNAME}-mongodb-encryption-key
pmm:
enabled: false
image: percona/pmm-client:2.27.0
serverHost: monitoring-service
replsets:
- name: rs0
size: 3
affinity:
antiAffinityTopologyKey: "kubernetes.io/hostname"
podDisruptionBudget:
maxUnavailable: 1
expose:
enabled: false
exposeType: ClusterIP
resources:
limits:
cpu: "300m"
memory: "0.5G"
requests:
cpu: "300m"
memory: "0.5G"
volumeSpec:
persistentVolumeClaim:
resources:
requests:
storage: 5Gi
nonvoting:
enabled: false
size: 3
affinity:
antiAffinityTopologyKey: "kubernetes.io/hostname"
podDisruptionBudget:
maxUnavailable: 1
resources:
limits:
cpu: "300m"
memory: "0.5G"
requests:
cpu: "300m"
memory: "0.5G"
volumeSpec:
persistentVolumeClaim:
resources:
requests:
storage: 5Gi
arbiter:
enabled: false
size: 1
affinity:
antiAffinityTopologyKey: "kubernetes.io/hostname"
sharding:
enabled: false
configsvrReplSet:
size: 3
affinity:
antiAffinityTopologyKey: "kubernetes.io/hostname"
podDisruptionBudget:
maxUnavailable: 1
expose:
enabled: false
exposeType: ClusterIP
resources:
limits:
cpu: "300m"
memory: "0.5G"
requests:
cpu: "300m"
memory: "0.5G"
volumeSpec:
persistentVolumeClaim:
resources:
requests:
storage: 5Gi
mongos:
size: 3
affinity:
antiAffinityTopologyKey: "kubernetes.io/hostname"
podDisruptionBudget:
maxUnavailable: 1
resources:
limits:
cpu: "300m"
memory: "0.5G"
requests:
cpu: "300m"
memory: "0.5G"
expose:
exposeType: ClusterIP
backup:
enabled: false
image: percona/percona-backup-mongodb:1.7.0
serviceAccountName: percona-server-mongodb-operator
pitr:
enabled: false
compressionType: gzip
compressionLevel: 6
HeadLess 접속 정보 확인
kubectl get svc,ep
kubectl run -it --rm netdebug --image=nicolaka/netshoot --restart=Never -- zsh
nslookup $MYNICK-db-rs0
nslookup $MYNICK-db-rs0-0.nunu-db-rs0
nslookup $MYNICK-db-rs0-1.nunu-db-rs0
nslookup $MYNICK-db-rs0-2.nunu-db-rs0
복제 테스트
client 3개 생성
myclient.yaml
apiVersion: v1
kind: Pod
metadata:
name: ${PODNAME}
labels:
app: myclient
spec:
nodeName: k8s-m
containers:
- name: ${PODNAME}
image: percona/percona-server-mongodb:${VERSION}
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
MYNICK=
IMGVER=$(kubectl get perconaservermongodbs $MYNICK-db -o jsonpath={.spec.image} | cut -d ':' -f 2)
for ((i=1; i<=3; i++)); do PODNAME=myclient$i VERSION=$IMGVER envsubst < ~/DOIK/4/myclient.yaml | kubectl apply -f - ; done
# [터미널1] 프라이머리 파드 접속(doik)
kubectl exec -it myclient1 -- mongo --quiet "mongodb://doik:qwe123@$MYNICK-db-rs0-0.$MYNICK-db-rs0.psmdb.svc/admin?ssl=false"
rs0:PRIMARY> use doik
rs0:PRIMARY> db.test.insertOne({ reptest: 1 })
rs0:PRIMARY> db.test.find()
rs0:PRIMARY> db.test.count()
# [터미널2] 세컨더리 파드1 접속(doik)
kubectl exec -it myclient2 -- bash -il
--------------------------------------
# 변수 지정
MYNICK=<각자 자신의 닉네임>
MYNICK=gasida
echo $'rs.secondaryOk()\nuse doik\ndb.test.count()' | mongo --quiet "mongodb://doik:qwe123@$MYNICK-db-rs0-1.$MYNICK-db-rs0.psmdb.svc/admin?ssl=false"
while true; do echo $'rs.secondaryOk()\nuse doik\ndb.test.count()' | mongo --quiet "mongodb://doik:qwe123@$MYNICK-db-rs0-1.$MYNICK-db-rs0.psmdb.svc/admin?ssl=false" | grep -v Error; date; sleep 1; done
--------------------------------------
# [터미널3] 세컨더리 파드2 접속(doik)
kubectl exec -it myclient3 -- bash -il
--------------------------------------
# 변수 지정
MYNICK=<각자 자신의 닉네임>
MYNICK=gasida
echo $'rs.secondaryOk()\nuse doik\ndb.test.count()' | mongo --quiet "mongodb://doik:qwe123@$MYNICK-db-rs0-2.$MYNICK-db-rs0.psmdb.svc/admin?ssl=false"
while true; do echo $'rs.secondaryOk()\nuse doik\ndb.test.count()' | mongo --quiet "mongodb://doik:qwe123@$MYNICK-db-rs0-2.$MYNICK-db-rs0.psmdb.svc/admin?ssl=false" | grep -v Error; date; sleep 1; done
--------------------------------------
# [터미널1] 프라이머리 파드 접속(doik) : 대량의 도큐먼트 생성 및 복제 확인
rs0:PRIMARY> for (i=0; i<1000; i++) {db.test.insert({count: i, "created_at" : new Date()})}
rs0:PRIMARY> db.test.find({},{_id:0})
느낀점
- Operator를 사용하면 쉽게 몽고 DB 클러스터를 구성할 수 있습니다.
- 쉽게 구성되는 만큼 장애날 상황들에 대해 많은 테스트가 필요할 것 같습니다.
'스터디 > DOIK' 카테고리의 다른 글
Percona Operator for MongoDB - 옵션 변경 (0) | 2022.06.24 |
---|---|
기본 Object - Pod (0) | 2022.06.05 |
K8S MySQL Operator 설치 - DOIK 스터디 2주차 (0) | 2022.06.01 |
K8S Operator 패턴 - DOIK 스터디 2주차 (0) | 2022.06.01 |