Skip to content

gwiyeomgo/proglog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

compile1: protoc api/v1/log.proto --go_out=. --go_opt=paths=source_relative --proto_path=.

compile2: protoc --go_out=. --go_opt=paths=source_relative
--go-grpc_out=. --go-grpc_opt=paths=source_relative
api/v1/log.proto

log 라이브러리

한 사람이 한순간에 한 대의 컴퓨터에서만 사용 가능 그 사용자는 라이브러리의 api를 배우고 코드를 실행하며 자신의 디스크에 로그를 저장

grpc 로그 클라이언트 (grpc 서버 정의,grpc protobuf 컴파일하여 코드 생성)

로그라이브러리를 기반으로 여러 사람이 같은 데이터로 소통하는 서비스 grpc 는 보안 소켓 계층과 전송 계층 보안을 지원하여 클라이언트와 서버 사이를 오가는 모든 데이터를 암호화한다

grpc 란 관련이 있는 rpc 엔드포인트들을 묶은 그룹

컴파일러가 grpc 로그 클라이언트를 만들고 로그 서비스 api 를 구현할 준비 완료

protoc --go_out=. --go_opt=paths=source_relative \
        --go-grpc_out=. --go-grpc_opt=paths=source_relative \
        api/v1/log.proto

grpc 서버 생성

서비스 보안의 세단계

* 주고받는 데이터 암호화(중간자 공격 ex)도청)
    * 중간자 공격으로부터 막아주는,가장 널리 쓰이는 암호학 방법 TLS
    * TLS 는 단방향 인증으로 서버만 인증

go install github.com/cloudflare/cfssl/cmd/cfssl@latest

go install github.com/cloudflare/cfssl/cmd/cfssljson@latest ca-csr.json : ca 인증서 설정 ca-config.json : ca가 어떤 인증서를 발행할지 설정(정책 설정) server-csr.json : 서버 인증서 설정

* 클라이언트 인증 = 클라이언트가 누군지 확인
    * 애플리케이션에서 사용자명,비밀번호와 토큰의 조합으로 구현
* 인증한 클라이언트의 권한을 결정
    인증와 권한결정(인가)

https://github.com/casbin/casbin

환경변수

HOME

CONFIG_PATH : 인증서를 저장할 위치 CONFIG_DIR : 설정 파일들의 경로 ex) ./test

시스템 관측

(원격측정) 메트릭 시간의 경과에 따른 데이터 수치를 측정 얼마나 많은 수의 요청이 실패했는지,요청마다 처리 시간은 얼마나 소요되는지와 같으 수치 ex) 레이턴시,트래픽(초당 요청 처리 개수) 로그 시스템에 발생한 이벤트를 기록 트레이스 요청이 시스템 내부를 흘러가는 것을 추적 각각의 트레이스에 사용자 id 태그하면 사용자에게 문제가 발생했을때 해당 사용자의 요청을 빠르게 찾을 수 있다

서비스 디스커버리

  • 분산 서비스 (Distributed Service): 분산 서비스는 여러 개의 독립적인 컴포넌트나 모듈이 네트워크를 통해 통신하고 협력하여 하나의 기능을 제공하는 서비스를 나타냅니다. 여러 서비스 코드가 AWS에 각각 올라가고 서로 통신하며 하나의 웹 화면에서 데이터를 표시한다면, 이는 분산 서비스의 일종일 수 있습니다.

특히, HTTP API를 통해 데이터를 주고받고, 하나의 토큰을 사용하여 서비스 간 인증 및 권한 부여를 수행한다면, 이는 분산 서비스 아키텍처의 특징일 수 있습니다.

  • 독립형 서비스 (Monolithic Service): 독립형 서비스는 모든 기능이 단일 애플리케이션 또는 서비스 내에서 통합되어 있는 형태를 나타냅니다. 즉, 모든 기능이 단일 코드베이스로 작성되어 하나의 애플리케이션에서 제공됩니다. 여러 서비스 코드가 독립적으로 존재하지 않고, 하나의 웹 화면에서 모든 기능을 제공한다면, 이는 독립형 서비스입니다. 따라서, 여러 서비스 코드가 각각 AWS에 올라가고 서로 통신하여 하나의 웹 화면에서 데이터를 표시하고, 하나의 토큰으로 인증 및 권한 부여를 수행한다면, 이는 분산 서비스 아키텍처에 가까울 것으로 보입니다. 독립형 서비스는 모든 기능을 하나의 서비스 내에서 제공하는 구조를 의미합니다.

(질문) 분산 시스템에서 클러스터는 무슨일을해? 부하 분산 클라이언트 요청이 클러스터로 들어오면, 로드 밸런서가 각 서비스 인스턴스로 요청을 분배하여 과부하를 방지하고 응답 시간을 최적화합니다

고가용성 클러스터는 여러 서비스 인스턴스를 가동시키고, 하나의 인스턴스가 장애가 발생하더라도 다른 인스턴스가 요청을 처리할 수 있도록 하는 데 사용될 수 있습니다

스케일링 트래픽이 증가하면 새로운 서비스 인스턴스를 동적으로 추가하여 대규모 트래픽을 처리

장애 감지 및 관리 클러스터는 서비스 인스턴스의 상태를 모니터링하고, 장애가 발생한 경우 이를 감지하고 적절한 조치를 취함

보안 및 인증 인증 및 권한 부여를 관리하고, 보안 정책을 적용하여 서비스의 안전성을 유지

  • 서비스 디스커버리 클러스터 내에서 실행 중인 서비스 인스턴스를 동적으로 찾아서 해당 서비스와 연결하는 과정

서비스 디스커버리는 클라이언트가 분산 시스템 내의 서비스를 찾고 연결할 수 있도록 돕는 역할을 하며, 로드 밸런서는 서비스 인스턴스 간의 트래픽을 분산하여 부하를 균형있게 분배하는 역할

AWS에서는 Amazon Route 53와 같은 DNS 서비스를 사용하여 서비스 디스커버리를 구현 가능 AWS의 로드 밸런서와 Amazon Route 53을 사용하면, 서비스 디스커버리를 직접 Golang 코드로 구현할 필요가 없을 수 있습니다

  • 로드 밸런서 (Load Balancer): AWS의 로드 밸런서를 사용하면 클라이언트 요청을 여러 서비스 인스턴스로 분산할 수 있습니다. 로드 밸런서는 요청을 동적으로 관리하고 서비스 인스턴스의 가용성을 관리하는 역할을 수행합니다. 따라서 클라이언트 애플리케이션은 서비스 인스턴스의 IP 주소나 포트 번호를 직접 알 필요 없이 로드 밸런서의 엔드포인트에 요청을 보낼 수 있습니다.
  • Amazon Route 53 (DNS 서비스): Amazon Route 53을 사용하면 DNS를 통해 서비스 디스커버리와 관련된 기능을 구현할 수 있습니다. Route 53를 사용하면 도메인 이름을 사용하여 서비스를 찾을 수 있으며, Route 53의 상태 확인 기능을 활용하여 서비스의 가용성을 모니터링하고 실패한 인스턴스를 자동으로 제거할 수 있습니다. 해당 기능들이 서비스 디스커버리와 관련된 많은 작업을 자동화하고 단순화할 수 있다

근데 왜? 디비에 따로 logrus 로 기록한 로그를 db 에 넣지?

AWS에서는 Amazon CloudWatch Logs와 같은 로깅 서비스를 사용하고 로그 데이터를 MySQL 데이터베이스에 따로 저장하고 있는 경우, 이는 로깅 데이터를 중복으로 저장?

//https://pkg.go.dev/github.com/grpc-ecosystem/go-grpc-middleware#section-readme //grpc_middleware 사용

go get -u go.uber.org/zap go get go.opencensus.io/trace@v0.24.0

https://github.com/census-instrumentation/opencensus-go

$ go get -u go.opencensus.io

요약하면, Route 53과 Nginx를 사용하여 서비스 디스커버리를 대신할 수 있지만, 이는 수동 작업과 복잡성을 증가시킬 수 있습니다. 서비스 디스커버리 솔루션을 고려하는 것이 훨씬 간편하고 신뢰성 있을 수 있으며, AWS에서는 서비스 디스커버리를 위한 서비스인 AWS Cloud Map도 제공하고 있으므로 고려할 가치가 있습니다.

AWS Elastic Kubernetes Service (EKS)는 컨테이너 오케스트레이션을 위한 관리형 Kubernetes 서비스입니다. Kubernetes는 마이크로서비스 아키텍처를 구현하고 관리하는 데 매우 유용한 플랫폼이며, 여러 인스턴스에서 여러 개의 서비스 코드를 실행하는 데 사용할 수 있습니다.

EKS 클러스터 내에 여러 인스턴스가 있는 경우, 각 인스턴스는 워커 노드로 사용됩니다. 이러한 워커 노드는 컨테이너를 실행하는 데 사용됩니다. 따라서 여러 인스턴스에서 여러 개의 서비스 코드를 실행할 수 있습니다.

마이크로서비스 아키텍처를 사용하는 경우, 각 마이크로서비스를 개별적인 컨테이너로 패키징하고 Kubernetes 클러스터에서 실행할 수 있습니다. Kubernetes는 컨테이너를 관리하고 스케일링하며 네트워킹을 관리하는 데 도움이 되며, 이것이 마이크로서비스 아키텍처의 핵심 이점 중 하나입니다.

따라서 EKS 클러스터를 사용하여 서버가 1개 이상인 여러 인스턴스에서 여러 개의 서비스 코드를 실행하고 마이크로서비스 아키텍처를 배포할 수 있습니다. 이를 통해 서비스의 확장성과 가용성을 향상시킬 수 있습니다.

github.com/hashicorp/serf/serf

서프는 클러스터 멤버십을 관리한다 서비스 노드 간 통신을 위해 가볍고 효율적인 가십 프로토콜을 사용 각각의 서비스 인스턴스가 서프 노드로서 작동한다

가십 프로토콜 (Gossip Protocol) 이란 분산 환경에서 메시지를 전달하는 커뮤니케이션 방식 https://medium.com/@heonjang.lee96/gossip-프로토콜이란-906500c3de4b

  1. 각 서버에 서프 노드를 생성
  2. 각 서프 노드에 다른 노드들의 요청을 듣고 연결을 받아들일 주소를 설정
  3. 각 서프 노드에 다른 노드들의 주소를 설정하고 그들의 클러스터에 조인한다
  4. 서프의 클러스터 디스커버리 이벤트를 처리한다. 노드가 클러스터에 조인하거나 실패하는 이벤트가 있다

go get github.com/hashicorp/serf@latest

풀 기반 시스템 로그와 메시지 시스템에 적합 한 클라이언트는 데이터를 스트림으로 계속해서 보내고 또 다른 클라이언트는 24시간마다 배치 프로세스로 데이터를 처리할 수 있다 서버 간 복제에서는 최신 데이터를 최소한의 레이턴시로 같은 서버에 복제한다 그래서 풀 베이스와 푸시 베이스 시스템이 차이가 없다 하지만 풀 베이스 복제시 합의가 필요하다

합의알고리즘 주방장 분산 서비스가 몇몇 실패를 겪더라도 공유하는 상태에 대해 동의하는 도구 서버들은 리더와 팔로워 관계로 나누어 팔로워가 리더의 데이터만 복제하도록 한다 레프트를 이용해서 리더 선출과 복제를 한다

etcd = 키-값 저장소 => 사용하는 분산 합의 알고리즘 래프트 쿠버네티스,카프카에서 사용

https://seongjin.me/raft-consensus-algorithm/

https://shortstories.gitbook.io/studybook/go/go-channel-c0ac-c6a9-d574-c11c-ae30-b2e4-b9ac-ae30

producer 생산자 consumer 소비자

  • 리더 선출

래프트 클러스터에는 하나의 리더와 여러 팔로워 서버가 있다

선출한 리더가 로그를 팔로워에게 복제하고 로그자체에 특정 작업을 하는 것이 더욱 중요 래프트는 합의를 디더 선출과 로그 복제로 나누었다

래프트를 사용해 명령의 로그들을 복제

엔진엑스 (Nginx)와 같은 리버스 프록시 서버를 사용하여 서비스 디스커버리와 관련된 몇 가지 작업을 수행할 수 있지만 엔진엑스의 구성 파일은 실시간으로 업데이트되지 않음 서비스 디스커버리

go get github.com/hashicorp/raft@latest

다중화? 하나의 포트에서 여러 서비스 제공 래프트? grpc가 클라이언트를 인증하기 위해서 핸드셰이크를 할 때의 정보가 필요하다는 것이다. 핸드셰이크를 하기 전에 다중화해야 하고 grpc 연결에서 래프트 연결인지를 알아내는 방법이 필요

  • 로컬에서 쿠버네티스로 배포

  • 에이전트 명령줄 인터페이스 cli 만들어 서비스 실행

  • 쿠버네티스와 헬름을 준다

  • 우리 서비스가 로컬 머신과 클라우드 플랫폼에서 오케스트레이션을 할 수 있다

  • 로컬 머신에서 서비스를 담은 클러스터를 실행

  • 배포나 서비스 업그레이드와 같은 반복 잡업일 때는 헬름 패키지 매니저나 오퍼레이터를 사용

도커 이미지 만들기

헬름 = 쿠버네티스에 서비스를 분산하고 설치하는 패키지 매니저 서비스 개발자가 서비스의 헬름 차트를 만들고 공유하면 사람들이 서비스를 사용할 수 있다 차트 = 헴름 패키지 릴리즈 = 실행 중인 차트 인스턴스 저장소 = 차트를 공유하거나,차트를 실행하는 곳 https://helm.sh/ko/docs/intro/install/ curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

brew install helm

예시로 helm 으로 비트나미라는 차트 저장소를 설치해보자 https://charts.bitnami.com

helm repo add bitnami https://charts.bitnami.com/bitnami 비트나미 저장소를 추가하고 helm search repo bitnami 확인 helm install my-nginx bitnami/nginx 엔진엑스 차트(nginx)를 설치

엔직엑스 = 웹 서버이자 프록시 서버

helm list

헬름을 이용하여 엔진엑스 클러스터를 쉽게 설치하고 설정할 수 있다

삭제 helm uninstall my-nginx

__

helm template proglog deploy/proglog

helm install proglog deploy/proglog kubectl get pods 파드 목록 볼 수 있음

쿠드 또는 서비스의 포트를 컴퓨터의 포트로 포워딩하게 하기 로드밸런서가 없어도 쿠버네티스 내부의 서비스에 요청을 보낼 수 있음

kubectl port-forward pod/proglog-0 8400