2023. 11. 12. 01:55ㆍDOIK@CloudNet
- cloudnet에서 주관하는 쿠버네티스 데이터베이스 오퍼레이터 스터디 2기 내용입니다
- 목적: 다양한 db 오퍼레이터 실습으로 eks 환경에서 DB 배포 및 운영을 위한 다양한 DB 오퍼레이터 실습
이번주에는 Kubernates 환경에서 MongDB를 배포하고 관련 내용을 조금 정리해 보았다.
1. NoSQL이란?
MongoDB는 대표적인 NoSQL DB이다. 잠시 NoSQL에 대해 알아보고 마저 MongoDB 이야기를 이어가보자.
- NoSQL은 DBMS를 분류하는 기준으로, 가장 큰 특징은 고정된 schema 가 존재하지 않는 것이다.
- 대부분의 경우 SQL을 사용하지만, 케이스마다 특화된 NoSQL이 있어 고도화하기 좋다.
Document DB: MongoDB
- 데이터를 JSON 형태로 저장하므로 원하는 형태로 저장할 수 있다.
Key-Value DB: Cassandra
- 데이터를 저장하기 전에 액세스 방식을 구성해야 해서 러닝커브가 높지만 매우 빠르다
Graph DB
- document-column 방식이 아니라 노드간의 연결인 entity를 저장하는 방식으로, SNS에 유리하다.
2. MongoDB란?
- 데이터를 JSON format으로 저장하므로 비정형 데이터 관리에 용이하다.
- 고정 스키마가 없으므로 필요에 따라 필드 추가 및 제거가 용이하다.
- 그러나 반대로 고정 스키마가 없으므로 복잡한 JOIN 연산은 수행하기 어렵다.
- 분산 확장(scale-out) 이 용이하다(sharding)
- 별도 primary key가 필요하지 않다(collection내 _id 가 primary key 역할을 함)
- SQL의 table == MongoDB의 collection
3. Sharding
기본적인 아이디어: 테이블이 너무 커져서 CRUD가 느려진다
→ 그러면 테이블을 쪼개서 병렬처리가 가능하게 하자!
(MongoDB는 이 shard 사이에서 데이터 일관성을 지키기 위해 설정 서버를 둠)
- 쪼갠 테이블을 shard라고 부르고 이 나누는 기준을 shard key라고 한다. 이때 shard key는 인덱스 필수.
- shard는 라우터를 통해서만 애플리케이션과 정보를 교환할 수 있음.
- sharding 수행 시 고려사항: 어떻게 테이블을 쪼개고 read 할지를 고려해서 적절한 방법론을 선택해야 한다.
4. MongoDB 오퍼레이터 실습
- 오퍼레이터로는 Percona 를 사용한다 (MongoDB 자체 커뮤니티 오퍼레이터는 sharding을 지원하지 않아서 percona 사용)
기본 설치
1. CRD 설치
- CRD(Custom Resource Definitions): 특정 애플리케이션 및 시스템 특화 리소스 정의 및 사용
- 스터디장님이 만들어주신 .yaml 파일 실행을 통해 설치한다
#CRD 설치
kubectl apply --server-side -f https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/crd.yaml
#CRD 중 psmdb를 포함한 내용만 확인
kubectl get crd | grep psmdb
2. namespace 생성 및 변경
- namespace: 클러스터 내 리소스의 논리적 구분.
#namespace 생성
kubectl create ns psmdb
#실습 편의를 위한 namespace 변경(필수)
kubectl get pod
kubectl ns psmdb
namespace 를 변경하고 나면 N/A 에서 psmdb로 기본 설정이 바뀐 것을 확인할 수 있다(4번째 command부터)
3. RBAC, 오퍼레이터 설치
- RBAC(Role-Based Access Control): 권한구분을 통한 보안관리
- percona operator에 필요한 권한과 정보를 또 가시다님께서 .yaml로 배포해 주셨다.
# RBAC 설치
kubectl apply -f https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/rbac.yaml
kubectl get-all -n psmdb
# 오퍼레이터 설치
curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/operator.yaml
cat operator.yaml | yh
kubectl apply -f operator.yaml
kubectl get deploy,pod
kubectl get-all -n psmdb
- RBAC 설치
- 오퍼레이터 설치
오퍼레이터가 배포되어 Pod 1개에서 돌아가고 있는 모습을 볼 수 있다.
4. 닉네임 지정 및 secret 생성
- 이때 소문자만 가능한 것 같다(대문자를 포함했다가 오류가 발생함)
# /etc/profile 에 내 닉네임 저장(계속 사용됨)
MYNICK=hithere
echo "export MYNICK=hithere" >> /etc/profile
# secret 파일 가져오기
curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/secrets.yaml
# 가져온 .yaml 에서 계정 정보(닉네임) 바꿔서 배포하기
cat secrets.yaml | sed -e "s/my-cluster-name/$MYNICK/" | kubectl apply -f -
# secret 정보 확인
kubectl get secret $MYNICK-secrets -o json | jq .data
- cluster admin, user admin, database admin 3개의 역할이 생성된 것을 확인한다.
Replica Set 클러스터 구성
배포: 3개의 파드(복제세트) 를 가진 클러스터가 생성되는 것을 확인한다.
# 클러스터 파일 받기
curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/cluster1.yaml
# 배포 (약 3분 소요)
cat cluster1.yaml | sed -e "s/my-cluster-name/$MYNICK/" | kubectl apply -f - && kubectl get psmdb -w
# 모니터링(다른 터미널)
watch kubectl get psmdb,sts,pod,svc,ep,pvc
cat 으로 cluster 를 확인할때 replset이 3개로 구성되어 있다.
배포가 잘 되었다. 와!
3개의 pod가 모두 statefulset으로 잘 배포되었고 pvc가 하나씩 붙어 동작하고 있음을 확인한다. 이때 primary pod는 rs0-0이다.
cluster IP가 none인 것으로 headless 임을 확인할 수 있고, headless 임으로 개별 ip/domain으로 접속할 수 있다.
affinity: replicaset pod 배포 시 antiAffinityTopologykey 를 kubernates의 hostname으로 설정했는데, 복제 pod들이 서로 떨어지라는 뜻이다.
# mongodb 이미지 버전 확인
kubectl get perconaservermongodbs $MYNICK -o jsonpath={.spec.image} ; echo
percona/percona-server-mongodb:6.0.9-7
# (옵션) 설치 리소스 확인
kubectl get-all --namespace=psmdb
# 10분 내의 동작만 확인
kubectl get-all --since 10m
# cluster 동작만 확인
kubectl get-all --only-scope=cluster
#삭제
cat cluster1.yaml | sed -e "s/my-cluster-name/$MYNICK/" | kubectl delete -f -
위 command들을 사용하면 cluster 동작 정보, MongoDB 버전 등을 확인할 수 있다.
--since, --only-scope 옵션이 매우 유용하다.
(너무 길어서 터미널 스샷 생략)
MongoDB 배포 및 접근
MongoDB 위한 클러스터 배포
# 가시다님의 yaml 파일 받아오기
curl -s -O https://raw.githubusercontent.com/gasida/DOIK/main/psmdb/myclient.yaml
# 내용 확인
cat myclient.yaml | yh
# 환경설정 변경 및 해당 변경사항 클러스터에 반영
VERSION=4.4.24-23 envsubst < myclient.yaml | kubectl apply -f -
# 변경된 pod 상태 확인
kubectl get pod -l name=mongodb -owide
환경설정 변경 내용을 해설하면
- VERSION=4.4.24-23: 말 그대로 버전을 이 범위 내에서 지정.
- envsubst: myclient.yaml 파일의 해당 내용(여기서는 버전) 을 변경해서 파일에 적용한다
- kubectl apply -f -: config의 변경 내용을 클러스터에 적용한다.
- CLUSTER_USER 로 접속해서 MongoDB config를 확인하고 클러스터에 접속한다
# secrets.yaml 에서 패스워드 확인
cat secrets.yaml | yh
# admin user로 접속
kubectl exec ds/myclient -it -- mongo --quiet "mongodb+srv://userAdmin:userAdmin123456@$MYNICK-rs0.psmdb.svc.cluster.local/admin?replicaSet=rs0&ssl=false"
admin user 접근 명령어를 해설하면
- exec ds/myclient --it demo set인 myclient로 shell실행을 실행하라 (--it: 컨테이너와 연결하고 상호작용을 활성화)
- --mongo --quiet : mongoDB on :실행상황 띄우지 말고 mongo를 실행하라
- "mongodb+srv://clusterAdmin:clusterAdmin123456@$MYNICK-rs0.psmdb.svc.cluster.local/admin?replicaSet=rs0&ssl=false" :
- mongodb+srv:// SRV 라는 방식을 가지고 MongoDB와의 connection을 시작한다
- clusterAdmin:clusterAdmin123456 : 자격증명(cluster_user_id:cluster_user_pw)
- @$MYNICK-rs0.psmdb.svc.cluster.local/ : replicaset에 접근하기 위한 서비스명
- admin?replicaSet=rs0&ssl=false : , 접근하는 테이블은 기본 생성되는 admin, ssl 인증 생략, 접근하는 replicaset: rs0
→rs0에 primary 로 접근을 완료했다. 이제 터미널이 mongo terminal로 바뀐 것을 볼 수 있다.
MongoDB 사용
MongoDB는 진짜로(?!) json format을 사용한다
# user 생성
db.createUser({user:"doik", pwd:"qwe123", roles: ["userAdminAnyDatabase", "dbAdminAnyDatabase", "readWriteAnyDatabase"]})
# 복제 정보 확인
rs.status()
# cluster_user로 접속
kubectl exec ds/myclient -it -- mongo --quiet "mongodb+srv://clusterAdmin:clusterAdmin123456@$MYNICK-rs0.psmdb.svc.cluster.local/admin?replicaSet=rs0&ssl=false"
admin_user로 접속했을 때는 사용자를 추가할 수 있었지만 복제 정보는 확인할 수 없었다. 따라서 cluster user로 접속해서 rs.status() 정보를 확인하면 확인할 수 있다.
CRUD
위에서 생성한 user로 재접속한 후 CRUD action을 수행한다
#위에서 생성한 user로 접속
kubectl exec ds/myclient -it -- mongo --quiet "mongodb+srv://doik:qwe123@$MYNICK-rs0.psmdb.svc.cluster.local/admin?replicaSet=rs0&ssl=false"
#작업할 DB 선택
use doik
#콜렉션(테이블) 생성(사이즈 제한)
db.createCollection("test", {capped:true, size:10000})
#존재하는 테이블 확인
show collections
#생성한 test 테이블 내 데이터 확인
db.test.find()
#값 하나 삽입
db.test.insertOne({hello:"world"})
#통계정보 조회
db.test.stats()
# make a collection(table)
db.createCollection("users")
# drop a table
db.users.drop()
# CREATE
db.users.insertOne(
{name: "hithere", status: "tired"}
)
db.users.insertMany([
{name: "heyyou", status: "sleepy"},
{name: "wassap", status: "drowsy"},
{name: "whyme", status: "surprised"}
])
# READ (search)
db.users.find()
db.users.find({status:"tired"})
# UPDATE $set, $inc
db.users.updateMany({age: {$gt:30}}, {$set: {status:"B}}}) #if(age>30): status=B
#DELETE
de.employees.deleteMany({status:"A"})
하면서 든 생각
신기하다 NoSQL의 세상...!
확실히 json format을 사용할 수 있다는 점이 큰 장점으로 느껴졌고, 데이터에 자유도가 큰 만큼 MongoDB를 사용할 때 로직에서는 유효성검사를 더욱 철저히 해야겠다는 생각이 들었다. 또한 오늘 처음으로 멤버 경험발표를 들을 수 있어서 감사하다.
Reference
- https://www.youtube.com/watch?v=Q_9cFgzZr8Q
- https://www.youtube.com/watch?v=y42TXZKFfqQ
- https://aws.amazon.com/ko/what-is/database-sharding/
'DOIK@CloudNet' 카테고리의 다른 글
[DOIK2] 쿠버네티스 오퍼레이터 @stackable (2) | 2023.11.26 |
---|---|
[DOIK2] 쿠버네티스 오퍼레이터 @Kafka (0) | 2023.11.19 |
[DOIK2] 쿠버네티스 오퍼레이터 @PostgreSQL (0) | 2023.11.05 |
[DOIK2] 쿠버네티스 오퍼레이터 @MySQL (1) | 2023.10.29 |
[DOIK2] 쿠버네티스 배포 및 기초 지식 (0) | 2023.10.22 |