본문 바로가기

DevOps & Cloud

7. 네트워크 로그 수집 자동화(Protobuf, gRPC)

728x90
반응형

연구실 프로젝트 Season1 Ep7

 

원래는 gRPC와 protobuf를 사용해서 cilium hubble과 통신해서 로그를 DB에 넣어주는 프로그램을 작성하려 했다.

아직 gRPC와 protobuf 및 네트워크에 대한 개념이 명확하지 않아서 어려운 부분이 좀 있다. 해당 부분은 공부가 더 필요하다.

 

hubble_pb2_grpc.py 를 생성하는 명령어

 

$ python3 -m grpc_tools.protoc --proto_path=/home/ubuntu/pyproject --grpc_python_out=. hubble.proto

 

 

hubble_pb2.py를 생성하는 명령어

 

$ python3 -m grpc_tools.protoc --proto_path=/home/ubuntu/pyproject --python_out=. hubble.proto

 

아래 코드는 hubble.proto이다.

syntax = "proto3";

message Log {
  string namespace = 1;
  string pod_name = 2;
  string pod_ip = 3;
  string container_name = 4;
  string container_id = 5;
  string source = 6;
  string log = 7;
  int64 timestamp = 8;
}

 

<임시방편>

 

$ timeout 10m hubble observe flows --output=jsonpb | mongoimport --db logs --collection network_logs

 

임시방편으로 hubble 기본 명령어가 작동한다. json 형태로 mongoDB에 넣어준다.

해당 명령어는 "hubble observe flows의 실행순간 결과를 jsonpb 형식으로 내보내서 MongoDB의 DB명 logs에 존재하는 network_logs라는 컬렉션에 넣고 해당 프로세스를 10분 뒤 종료해라"라는 의미다.

 

import subprocess
import time

cnt = 1
print("Network flows collecting..")

while True:
    #네트워크 플로우 수집
    command_flow = "timeout 9s hubble observe flows --output=jsonpb | mongoimport --db logs --collection network_flows"
	subprocess.run(command_flow, shell=True)
    
    #네트워크 엔드포인트 수집
    #command_endpoint = "timeout 9s hubble observe endpoints --output=jsonpb | mongoimport --db logs --collection network_endpoints"
	#subprocess.run(command_endpoint, shell=True)
    
    time.sleep(10)

    cnt = cnt+1

    if cnt % 200 == 0:
        print("cycle: " + str(cnt) + " done!")

        try:
            command2 = "hubble status"
            command3 = "cilium hubble port-forward&"
            command4 = "lsof -i :4245"
            output = subprocess.run(command4, shell=True, capture_output=True)
            if 'COMMAND' in str(output.stdout):
                print('port 4245 is already in use')
            else:
                subprocess.run(command2, shell=True)
                subprocess.run(command3, shell=True)
        except:
            break

 

찾아보니 Cilium의 Hubbble은 별도의 API를 제공하지 않는 것 같다. 정확히는 옛날에는 제공했던 것 같은데 지금은 제공하지 않는 것 같다. gRPC와 protobuf를 갖고 열심히 씨름했으나 아직 잘 작동하지 않는다. 찾아낸 대체법은 위와 같다.

 

subprocess.run()을 사용해서 command_flow의 명령을 cli 상에서 10초에 한 번씩 실행하는 기능을 갖는다. command_flow가 작동만 하면 네트워크 플로우를 jsonpb 형식으로 mongoDB에 넣어준다. 따라서 결론적으로 10초마다 네트워크 플로우를 수집해서 몽고 DB에 넣어주는 프로그램이 만들어졌다. 물론 서버와 직접 통신하는 것보다 오버헤드도 많고 속도도 느릴 것이다. 그러나 일단 작동을 해야 다음 단계로 넘어갈 수 있기 때문에 이렇게 진행해 봤다. 그리고 4시간 정도 실행해 보면서 메모리와 CPU 사용량을 체크해 봤는데 크게 문제가 될 것 같지는 않다. 참고로 jsonpb 형식은 protobuf 타입으로 데이터를 받아와서 json 형태로 변환하는 것이라고 한다.

 

네트워크 엔드포인트를 수집하는 코드도 넣어놨지만 이게 필요한지 아직 모르겠어서 주석처리 해놓고 보류했다.

 

하다 보니 특정 시간이 길어지면 중간에 cilium hubble의 포트포워딩이 끊기는 경우가 생겨서 30분 정도에 한 번씩 포트포워딩을 체크하는 코드도 넣어줬다. 이제 주말 동안 nohup으로 백그라운드로 실행시키면서 계속 데이터를 DB에 쌓아볼 것이다.

 

주의 사항:

파이썬 파일도 nohup으로 실행, cilium hubble 및 포트포워딩도 nohup으로 실행해줘야 한다.

파이썬 프로그램만 nohup으로 실행하면 터미널이 꺼졌을 때 cilium hubble이 종료돼 버려서 정상적으로 작동하지 않는다.

 

<ps -ef를 통해서 프로세스가 정상작동함을 확인할 수 있고 네트워크 데이터도 DB에 잘 쌓이고 있다.>

 

터미널 세션을 종료했다가 한참 시간이 지난 후 다시 연결해 봤다.

파이썬 프로그램이 정상적으로 작동하고 cat nohup.out을 통해서 로그를 확인해 본 결과 네트워크 플로우 데이터도 DB에 잘 쌓이고 있다.

 

<nohup 관련 명령어 모음>

nohup python3 logger_final.py& #파이썬 파일 실행 및 로그 생성(&)

nohup cilium hubble enable --ui> /dev/null 2>&1 & #cilium hubble 실행 및 로그 생성X

nohup cilium hubble port-forward&> /dev/null 2>&1 & #hubble 포트 포워드 및 로그 생성X

sudo nohup service mongod start> /dev/null 2>&1 &

cp /dev/null nohup.out #로그 초기화


###nohup 프로세스 종료 방법###

ps -ef #해당 명령어로 실행중인 프로세스의 PID를 조회 한다.

kill -9 PID #-9는 강제 종료 명령어다 이렇게 하면 프로세스가 강제 종료 된다.

 

728x90
반응형

'DevOps & Cloud' 카테고리의 다른 글

8. 데이터 파이프라인  (0) 2023.01.20
추천 프로젝트 By Chat GPT  (0) 2023.01.18
6. Go & Mongo DB  (0) 2023.01.13
5. sock-shop 과 XQuartz  (0) 2023.01.12
4. Hubble  (0) 2023.01.12