연구실 프로젝트 Season1 Ep6
오늘은 프로그래밍 언어 중 Go와 MongoDB에 대해서 다뤄보고자 한다.
Go와 MongoDB를 사용하는 이유는 다음과 같다.
Step1의 전체적인 로드맵이다.
쿠버네티스 환경 구성 => Cilium CNI 설정 및 Hubble 설정 => Micro Service Demo Deploy(나는 sock shop 사용) => Hubble을 사용해서 sock-shop의 네트워크 로그 수집 => 수집된 네트워크 로그를 Recording 해서 Mongo DB에 저장하기(Go& MongoDB)
이번 게시글과 다음 게시글의 목표는 "수집된 네트워크 로그를 Recording 하는 프로그램을 제작하고 해당 프로그램을 사용해서 로그를 Mongo DB에 저장하기"다.
<Go>
먼저 Go라는 언어에 대해서 소개해보고자 한다. ChatGPT에 물어봤다.
"Go는 Google에서 개발한 프로그래밍 언어로, 간결하고 성능이 좋은 코드를 작성할 수 있도록 설계되었습니다. Go는 다른 언어들과 달리 정적 타입 언어이며, 멀티코어 환경에서의 병렬 처리를 쉽게 할 수 있는 기능을 제공합니다. Go는 프로그래밍 언어로서 간결하고 읽기 쉬운 코드를 작성할 수 있도록 설계되었으며, 네트워크 프로그래밍, 시스템 프로그래밍, 웹 개발 등 다양한 분야에서 사용됩니다."
라고 한다. 파이썬이나 자바 같은 언어들은 프로그램 자체가 무거워서 네트워크 프로그래밍과 시스템 프로그래밍에 적당하지 않다고 알고 있다. 이번 기회에 go 언어를 사용해 볼 수 있었고 내가 의도하고자 하는 바에 맞는 프로그램은 다음과 같다. 우분투에 go 언어를 설치하는 과정은 인터넷에 많이 있으니 생략한다.
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/hubble-io/hubble-go-client/hubble"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// Create a struct to hold the logs
type Log struct {
Timestamp time.Time `bson:"timestamp"`
Message string `bson:"message"`
}
func main() {
// Set up MongoDB connection
client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
log.Fatal(err)
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
err = client.Connect(ctx)
if err != nil {
log.Fatal(err)
}
// Set up Hubble client
hubbleClient := hubble.NewClient("<access_token>")
// Set up a ticker to get logs every 10 seconds
ticker := time.NewTicker(10 * time.Second)
for range ticker.C {
// Get logs from Hubble
logs, _, err := hubbleClient.Logs.GetLogs(context.Background(), "sock-shop")
if err != nil {
log.Println(err)
continue
}
log.Printf("Retrieved %d logs from Hubble\n", len(logs))
// Insert logs into MongoDB
for _, log := range logs {
logData := Log{
Timestamp: log.Timestamp,
Message: log.Message,
}
_, err := client.Database("sock-shop").Collection("logs").InsertOne(ctx, logData)
if err != nil {
log.Println(err)
continue
}
}
fmt.Println("logs saved to mongodb!")
}
}
위 코드는 타이머를 이용하여 10초마다 Hubble API를 호출하여 sock-shop의 네트워크 로그를 얻어와 MongoDB에 저장한다.
먼저 MongoDB와의 연결을 설정하고, Hubble API에 접근할 수 있는 클라이언트를 생성한다. 그리고 타이머를 설정하여 10초마다 Hubble API를 호출하여 네트워크 로그를 얻어온다. 얻어온 로그들을 MongoDB에 저장한다.
코드를 실행하려면 MongoDB와 Hubble API에 접근할 수 있는 액세스 토큰이 필요하다. 액세스 토큰은 Hubble API 개발자 페이지에서 얻을 수 있으며, 그 자리에 있는 "<access_token>"을 액세스 토큰으로 대체해야 한다. 또한 Go 언어와 MongoDB Go 드라이버, Hubble-go-client 라이브러리를 설치해야 한다. 코드를 실행하면 터미널에서는 얻어온 로그의 수와 저장된 로그를 출력하며, MongoDB에는 "sock-shop" 데이터베이스에 "logs" 컬렉션에 저장된 네트워크 로그들이 저장된다.
Mongo DB 드라이버 설치
$ go get go.mongodb.org/mongo-driver/mongo
Hubble-go-client 라이브러리를 설치해야 하나 여기서 막혔다..
아마 grpc를 써서 해야 할 것 같다. 이쪽은 잘 모르니 다시 공부해서 오겠다.
알고 보니 Hubble은 현재 제공되는 API가 따로 없는 것 같다...!
<MongoDB>
SQL은 관계형 DB 즉 RDBMS를 관리하기 위한 프로그래밍 언어다. 관계 DB의 표준이다. 대중적으로 Oracle, MySQL이 있다.
NoSQL이란 관계형 DB보다 덜 엄격힌 일관성 모델을 제공한다. 해당 데이터 베이스는 빅데이터와 실시간 웹 애플리케이션에서 많이 사용된다. SQL 계열의 쿼리 언어도 가능하기 때문에 NoSQL은 SQL이 아니라는 뜻이 아니다. Not only SQL이다.
일반적인 성능과 확장성 측면에서는 NoSQL이 더 우수하다. 다만 ACID 트랜잭션(원자성 일관성 고립성 영구성)을 보장받기 어렵기 때문에 은행, 회사 같이 데이터에 민감한 곳에서는 엄격한 RDBMS를 사용하는 것이 낫다.
MongoDB란 C++로 작성된 오픈소스 문서지향 크로스 플랫폼 데이터베이스이다.
Document는 RDBMS의 Row(행) or 튜플과 동일한 개념이다.
{
"_id": "5f2ad6b54866e5109dd2367b"
"Object_Name": "MongoDB",
"IP": "127.0.0.1",
"time": "2023-01-15-01:05:17"
}
위와 같은 json 형태의 key-value 쌍으로 이루어진 데이터 구조를 하나의 Document라고 본다.
각 Document에 존재하는 "_id"는 유일한 값이다. Primary Key와 동일하다. RDBMS처럼 스키마가 정해진 게 없다. 따라서 document에 뭔가 추가해도 이상 없이 작동한다. RDBMS는 데이터의 형태가 스키마와 다르면 오류가 발생한다.
Collection은 Document의 그룹이다. RDBMS의 Table과 비슷한 개념이다.
Database는 Collection들의 물리적 컨테이너이자 상위 개념이다. RDBMS의 Database와 동일하다. Database는 1개 이상의 Collection을 가질 수 있다.
RDBMS에서 많이 사용되는 Join은 NoSQL에서 잘 사용되지 않고 1대다 관계일 때는 Document 내부에 서브 Document를 삽입하는 식으로 해결한다.
{
_id: POST_ID,
title: POST_TITLE,
content: POST_CONTENT,
username: POST_WRITER,
tags: [ TAG1, TAG2, TAG3 ],
comments: [
{
username: COMMENT_WRITER,
mesage: COMMENT_MESSAGE,
time: COMMENT_TIME
},
]
}
출처: https://velog.io/@ckstn0777/MongoDB란
MongoDB를 우분투 22.04에 설치하는 방법 역시 인터넷에 있기 때문에 스킵한다.
mongoDB 설치과정에서 libssl1.1을 설치하지 못하는 문제를 겪었는데 아래 글을 보고 해결했다.
https://techviewleo.com/install-mongodb-on-ubuntu-linux/
<몽고 DB 명령어 모음>
터미널에서 아래 명령어로 몽고디비를 실행시켜보자.
$ sudo systemctl start mongod
아래 명령어를 이용해 성공적으로 실행되었는지 확인할 수 있다.
$ sudo systemctl status mongod
MongoDB가 시스템 재부팅 후 시작되도록 설정할 수 있다
$ sudo systemctl enable mongod
필요에 따라 다음 명령어를 실행하여 MongoDB 프로세스를 중지할 수 있다.
$ sudo systemctl stop mongod
필요에 따라 다음 명령어를 실행하여 MongoDB를 다시 시작할 수 있다.
$ sudo systemctl restart mongod
mongoDB 6.0 부터는 클라이언트 접속명령어가 바뀌었다.
mongosh로 접속해야한다.
DB선택 or 생성 > use DB명
DB에서 collection 삭제 > db.network_logs.drop()
DB에서 collection 생성 > db.createCollection("network_logs")
DB에서 collection의 데이터 조회 > db.network_logs.find({})
DB에서 collection의 데이터 조회(조건) > db.network_logs.find({"time" = "12:55~~"})
DB에서 데이터 예쁘게 보여주기> db.network_logs.find({}).pretty()
https://doqtqu.tistory.com/281
https://lifeisgift.tistory.com/entry/mongo-crud-연산-명령어
'DevOps & Cloud' 카테고리의 다른 글
추천 프로젝트 By Chat GPT (0) | 2023.01.18 |
---|---|
7. 네트워크 로그 수집 자동화(Protobuf, gRPC) (0) | 2023.01.13 |
5. sock-shop 과 XQuartz (0) | 2023.01.12 |
4. Hubble (0) | 2023.01.12 |
3. Cilium (0) | 2023.01.11 |