728x90
반응형

온톨로지 데이터베이스

  • 개념과 관계가 체계적으로 정의 및 구조화 된 것
  • 주로 특정 도메인에서의 객체나 개체간의 관계를 나타내는 데이터 구조
  • 자연어 처리, 검색 엔진, 지식 관리 시스템 등에서 많이 사용됨

온톨로지 구성요소

  1. 개념(Entity): 특정 도메인의 주요 항목
    • 차량, 사람, 도로
  2. 속성: 각 개념이 가지는 특성
    • 차량 - 제조사, 모델명
  3. 관계: 개념들 간 연결 및 상호작용
    • '사람'은 '차량'을 '소유'한다
  4. 규칙 및 제약: 개념과 관계에 대한 규칙 정의 -> 데이터의 일관성과 유효성 보장

온톨로지 구조 설계

  • 데이터 모델링: 개념(Entity), 속성, 관계, 규칙 구조화
    • RDF (Resource Description Framework), WOL (Web Ontology Language) 같은 표준 포맷 사용
  • 계층화: 개념을 계층적으로 구성 -> 데이터 구조 명확히 유지
    • 개념의 상하위 관계 정의
    • 특정 개념 그룹화

데이터베이스 및 자료 관리

  • 그래프 데이터베이스: 온톨로지의 관계성 때문에 그래프 DBMS 사용이 효과적
    • 그래프DB: 노드와 엣지 구조를 이용해 개념과 관계를 시각화 및 관리
    • Neo4j, Blazegraph, Amaonze Neptune,...
  • 문서형 데이터베이스: 개념과 관계가 매우 복잡하거나 변화가 잦은 경우 MongoDB 같은 문서형 DB
    • JSON-LD 같은 표준 사용해 문서 형태로 관리
  • 트리플 스토어: RDF 트리플을 저장하는 DBMS
    • RDF, SPARQL 쿼리 지원하여 데이터 추출 및 분석 용이
    • Apache Jena, Virtuoso,...

온톨로지 편집 및 관리 기능 개발

  • CRUD 기능: 개념, 속성, 관계를 생성, 조회, 수정, 삭제 할 수 있는 인터페이스 구현
  • 시각화 도구: 개념 및 관계를 그래프로 시각화하여 사용자 경험 향상
    • 노드-엣지 그래프 동적 생성
    • D3.js, Cytoscape.js 같은 시각화 라이브러리 활용
  • 버전 관리: 온톨로지 버전 관리 기능으로 변경 사항 추적. 필요시 이전 버전으로 롤백
  • SPARQL 쿼리 인터페이스: 사용자나 개발자가 SPARQL 쿼리를 통해 온톨로지 탐색 및 분석
    • SPARQL API 제공하는 것이 유용
728x90
반응형
728x90
반응형

계기

개발 진행 중, 체인 데이터가 깨지는 이슈가 발생하였으나 컨테이너의 health 체크 및 재시동에 이슈가 발생하였음
현재는 본인이 3년전에 세팅한 Docker Swarm 으로 컨테이너 오케스트레이션 중이나, 서비스 고도화로 인한 오케스트레이션해야 할 컨테이너가 다양해지고 많아짐
컨테이너 health 상태 체크 및 정상화에 대한 기능이 필요해짐
서비스 운영시의 서버 문제 발생 및 리소스 문제 대처를 위한 Auto Scaling 기능 역시 필요
이외에 무중단 배포 전략 수행을 위한 옵션 역시 필요함
이를 해결하기 위한 방안에 대하여 고민중, 회사에 제안할 내용의 초안을 작성해본다.


현 상태

  • Docker Swam을 통한 노드 컨테이너 오케스트레이션이 수행되고 있음
    • 오케스트레이션 대상이 블록체인 노드 8개 밖에 없었기에 kubernetes를 사용할 필요가 없어 보였음
  • 그러나 관리 및 오케스트레이션 해야 할 대상이 많고 다양해짐
    • 노드
    • Explorer
    • 어플리케이션들
      • 거래소
      • 지갑
    • DB
    • 게이트웨이
    • 모니터링 시스템
      • 자체 제작 Collector 및 대시보드
      • Prometheus
      • Grafana
  • Auto-Scaling, 리소스 할당에 대한 필요성 대두
  • 무중단 배포 전략 도입의 필요성 확인

제안

  • 컨테이너 오케스트레이터(Orchestrator)를 Kubernetes로 변경
    • 더욱 안정적 시스템 운영
    • Auto Scaling

구상

  • 노드 구성
    • Master
    • Worker Nodes
      • Explorer
      • Chain Nodes - 7 nodes
      • DataBase
      • Monitoring
      • Trade Application
      • Wallet Application
  • Pods 단위
    • Explorer pod
    • Blockchain Nodes pod
    • Database pod
    • Services
      • Trade Application
      • Wallet Application
      • etc...
    • Monitoring pod
      • Prometheus
      • Grafana
      • 자체 제작 Collecter, Dashboard
728x90
반응형
728x90
반응형

계기

최근 새로운 솔루션 개발 및 데모를 위한 과정에서 많은 이슈들을 경험하였다.
이를 과정에서 현 개발 환경 및 서버 환경의 분리가 필요함을 느꼈다.
때문에 회사에 새로운 서버 구성을 제안하기 위한 초안을 정리해 본다.

현 상태

* 개발 서버에서 모든 서비스의 배포와 테스트가 진행되고 있음
* 로컬 환경에서도 개발 서버의 DB를 보며 개발을 진행하고 있으며, 데모 시에 사용하는 DB 역시 개발 서버에서 수행됨
    * 개발 진행 중 테이블 구조를 바꾸는 경우도 발생하여 데모에 이슈를 야기하기도 함
* 따라서 개발서버는 새로운 기능 배포 및 테스트 용도
* QA 서버를 따로 배포하여, 운영 서버와 동일한 환경에서 데모 및 QA 수행이 필요해 보임

제안

* 운영 서버
* 개발 서버
    * 개발 수행 및 기능 테스트를 위한 서버
* QA 서버 (스테이징 서버)
    * 운영서버와 동일한 환경으로 세팅하여, 운영서버 배포 전 QA 용도로 사용
    *  QA 수행 및 데모 시의 문제를 확인함
        * DB 변동에 의한 데모 및 테스트 문제가 여러번 발생함
        * 로컬 환경에서도 개발 서버를 바라보기 때문에 더 문제가 발생
            * 따라서 DB, 서버, 클라이언트, Explorer(blockscout) 등을 배포해 테스트하는 서버 필요
728x90
반응형
728x90
반응형

OpenTelemetry(OTel)

OpenTelemetry란?

  • Traces, Metrics, Logs 와 같은 데이터 instrumenting, generating, collecting, exporting 할 수 있는 Observability Framework.
  • 데이터를 수집, 변환 및 벡엔드 전송을 위한 표준화된 SDK / API / OTel Collector 제공을 목표로 함.
  • OTLP: OpenTelemetry Protocol
  • Prometheus, OTLP, Jaeger, Zipkin 등 매우 다양하고 많이 있음
    • Loki: Log 데이터의 Receiver
    • Prometheus: Metrics 에 대한 Receiver
    • Grafana Tempo: Trace에 대한 Receiver

필요한 이유

  • 표준화 된 데이터 수집 / 내보내기 / 관리가 가능해짐
    • 확장 및 이전이 용이해짐
  • 시스템 운영에 필요한 정보들을 직접 수집 및 모니터링이 가능함
  • 데이터 관리자 중앙집중화 되어 관리가 용이함
    • 특히 MSA 와 같은 분산 시스템에서 효과적임

용어 정리

  • Traces
    • 어플리케이션 / 클러스터 등에서 수행된 동작들 간의 지연(Latency)와 관계에 대한 데이터
  • Metrics
    • 시계열 데이터. 즉 시간의 순서에 따라 기록되는 숫자 및 통계적 데이터
    • 일정 시간마다 수집됨
    • 수치 값을 통해 이상 징후 감지 가능
  • Logs
    • 요청이 수행되는 동안 시스템의 임의의 시점에서 발생한 이벤트에 대한 데이터
    • 일반적으로 timestamp와 context payload를 포함함
    • json, binary 등의 형태로 기록됨
  • Observability
    • 아웃풋을 설명함으로써 시스템 내부 상태를 이해할 수 있게 하는 것을 의미
      • Traces, Metrics, Logs와 같은 telemetry data를 통해 시스템 내부 상태를 이해하게 됨을 의미
    • 즉, 코드는 반드시 traces, metrics, logs 와 같은 데이터를 산출해야 하고 observability 백엔드로 전송해야만 함

아키텍처

  • 개별 언어별 SDK
  • 데이터 수집
  • 변환 및 데이터 내보내기

OpenTelemetry Collector

  • 원격 측정 데이터(Metrics / Traces / Logs) 수신 및 처리
  • 이후 OpenTelemetry 백엔드로 데이터 내보내기
  • 구성
    • Receivers
      • gRPC / HTTP 통해 데이터 수신
      • 하나 이상의 Receivers 구성 가능
    • Processors
      • 수신한 데이터를 OpenTelemetry 보내기 전 데이터 처리
    • Exporters
      • 데이터를 하나 이상의 OpenTelemetry 백엔드로 내보내기
      • 하나 이상의 Exporter 사용 가능

단점

  • 기능 및 옵션의 다양화로 인한 러닝 커브 존재
  • 직접 데이터 수집 및 관리하기 때문에 운영 및 관리에 대한 부담이 증가

OpenTelemetry Collector 데모

728x90
반응형

'데브옵스 devOps > Monitoring' 카테고리의 다른 글

[PROMETHEUS] 프로메테우스  (2) 2024.10.17
728x90
반응형

Deployment

  • 파드들을 관리함을 의미
  • rolling update, rollback, scaling 과 같은 기능을 제공
  • web server, APIs, microservices에 적합하게 만듬
apiVersion: apps/v1  
kind: Deployment                        // Deployment 정의 
metadata:  
    name: webapp-deployment  
spec:  
    replicas: 3                         // 3개의 레플리카(인스턴스) - 아래 파드들
    selector:  
        matchLabels:  
            app: my-webapp  
    template:  
        metadata:  
            labels:  
                app: my-webapp  
        spec:  
            containers:  
            - name: webapp  
              image: nginx:latest  
              ports:  
                - containerPort: 80  
              envFrom:  
                - configMapRef:  
                    name: webapp-config  
            - name: database  
              image: mongo:latest  
              env:  
                - name: MONGO_INITDB_ROOT_USERNAME  
                  valueFrom:   
                    secretKeyRef:  
                        name: db-credentials  
                        key: username  
                - name: MONGO_INITDB_ROOT_PASSWORD  
                  valueFrom:  
                    secretKeyRef:  
                        name: db-credentials  
                        key: password  
              volumeMounts:  
                - name: db-data  
                  mountPath: /data/db  
    volumes:  
        - name: db-data  
          persistentVolumeClaim:  
          claimName: database-pvc  

---  

apiVersion: v1  
kind: Service  
metadata:  
    name: webapp-service  
spec:  
    selector:  
        app: my-webapp  
    ports:  
        - protocol: TCP  
          port: 80  
          targetPort: 80  

---  

apiVersion: v1  
kind: ConfigMap  
metadata:  
    name: webapp-config  
data:  
    WEBAPP_ENV: "production"  
    DATABASE_URL: "mongodb://database-service:27017/mydb"  

---  

apiVersion: v1  
kind: Secret  
metadata:  
    name: db-credentials  
type: Opaque  
data:  
    username: <base64-encoded-username>  
    password: <base64-encoded-password>  

---  

apiVersion: v1  
kind: PersistentVolumeClaim  
metadata:  
    name: database-pvc  
spec:  
    accessModes:  
        - ReadWriteOnce  
    resources:  
        requests:  
            storage: 1Gi
728x90
반응형
728x90
반응형

VOLUME

  • 파드 내의 모든 컨테이너가 접근 가능한 디렉토리
  • 컨테이너에서 스토리지(storage)를 분리시켜 컨테이너 재시작/재스케쥴과 별개로 데이터를 영속 관리 가능하게 함
apiVersion: v1  
kind: Pod  
metadata:  
    name: webapp-with-db  
    labels:  
    app: my-webapp  
spec:  
    containers:  
    - name: webapp  
      image: nginx:latest 
      ports:  
        - containerPort: 80  
      envFrom:  
        - configMapRef:  
            name: webapp-config  
    - name: database  
      image: mongo:latest  
      env:  
        - name: MONGO_INITDB_ROOT_USERNAME  
          valueFrom:  
            secretKeyRef:  
                name: db-credentials  
                key: username  
        - name: MONGO_INITDB_ROOT_PASSWORD  
          valueFrom:  
            secretKeyRef:  
                name: db-credentials  
                key: password  
          volumeMounts:  
            - name: db-data                  
              mountPath: /data/db              // 데이터 볼륨을 /data/db 마운트한다
    volumes:  
    - name: db-data                            // db-data 볼륨에 영구히 저장된다
      persistentVolumeClaim:  
      claimName: database-pvc                 

---  

apiVersion: v1  
kind: Service  
metadata:  
    name: webapp-service  
spec:  
    selector:  
        app: my-webapp  
    ports:  
      - protocol: TCP  
        port: 80  
        targetPort: 80  

---  

apiVersion: v1  
kind: ConfigMap  
metadata:  
    name: webapp-config  
data:  
    WEBAPP_ENV: "production"  
    DATABASE_URL: "mongodb://database-service:27017/mydb"  

---  

apiVersion: v1  
kind: Secret  
metadata:  
    name: db-credentials                   
type: Opaque  
data:  
    username: <base64-encoded-username>    
    password: <base64-encoded-password>

---

apiVersion: v1  
kind: PersistentVolumeClaim                // PVC - 스토리지 요구사항 정의
metadata:  
    name: database-pvc  
spec:  
    accessModes:  
        - ReadWriteOnce  
resources:  
    requests:  
        storage: 1Gi                       // 스토리지 요구사항 상세. 1Gi 짜리 스토리지
728x90
반응형
728x90
반응형

Secrets

  • 민감 정보 저장에 사용
  • 기본 base64 인코딩이 default
  • 파드에서 파일로 마운팅되거나 환경 변수로 사용할 수 있음
apiVersion: v1  
kind: Pod  
metadata:  
    name: webapp-with-db  
    labels:  
    app: my-webapp  
spec:  
    containers:  
    - name: webapp  
      image: nginx:latest 
      ports:  
        - containerPort: 80  
      envFrom:  
        - configMapRef:  
            name: webapp-config  
    - name: database  
      image: mongo:latest  
      env:  
        - name: MONGO_INITDB_ROOT_USERNAME  
          valueFrom:  
            secretKeyRef:  
                name: db-credentials  
                key: username  
        - name: MONGO_INITDB_ROOT_PASSWORD  
          valueFrom:  
            secretKeyRef:  
                name: db-credentials  
                key: password  

---  

apiVersion: v1  
kind: Service  
metadata:  
    name: webapp-service  
spec:  
    selector:  
        app: my-webapp  
    ports:  
      - protocol: TCP  
        port: 80  
        targetPort: 80  

---  

apiVersion: v1  
kind: ConfigMap  
metadata:  
    name: webapp-config  
data:  
    WEBAPP_ENV: "production"  
    DATABASE_URL: "mongodb://database-service:27017/mydb"  

---  

apiVersion: v1  
kind: Secret  
metadata:  
    name: db-credentials                   // Secret 명칭
type: Opaque  
data:  
    username: <base64-encoded-username>    // 실제 base64 로 인코딩 된 값
    password: <base64-encoded-password>
728x90
반응형
728x90
반응형

Config Map

  • 파드에 환경변수 / 설정 파일로 마운트 된 내용들을 저장하는 용도
  • 컨테이너 이미지로부터 설정을 분리할 수 있으며, 컨테이너를 재빌드 할 필요 없이 설정을 업데이트 하기 용이하다
apiVersion: v1  
kind: Pod  
metadata:  
    name: webapp-with-db  
    labels:  
        app: my-webapp  
spec:  
    containers:  
    - name: webapp  
      image: nginx:latest  
      ports:  
        - containerPort: 80  
      envFrom:    
        - configMapRef:            // ConfigMap 참조
              name: webapp-config  
    - name: database  
      image: mongo:latest  

---  

apiVersion: v1  
kind: Service  
metadata:  
    name: webapp-service  
spec:  
    selector:  
        app: my-webapp  
    ports:  
    - protocol: TCP  
      port: 80  
      targetPort: 80  

---  

apiVersion: v1  
kind: ConfigMap                  // ConfigMap 설정
metadata:  
    name: webapp-config  
data:  
    WEBAPP_ENV: "production"  
    DATABASE_URL: "mongodb://database-service:27017/mydb"
728x90
반응형
728x90
반응형

Service

  • Service는 파드들의 그룹에 접근하기 위한 안정적인 엔드포인트를 정의한 것
  • 어플리케이션을 클러스터 내의 다른 파드들에 노출시거나 외부 클라이언트에 노출시킬 수 있다.
  • Load Balancing과 자동 스케일링 기능을 제공하여, 어플리케이션이 매우 사용 가능한 상태로 남게 해 준다
apiVersion: v1  
kind: Pod  
metadata:  
    name: webapp-with-db  
    labels:  
        app: my-webapp  
spec:  
    containers:  
    - name: webapp  
      image: nginx:latest  
      ports:  
        - containerPort: 80  
    - name: database  
      image: mongo:latest  

---  

apiVersion: v1  
kind: Service  
metadata:  
    name: webapp-service  
spec:  
    selector:            // 서비스 내의 파드를 선택한다
        app: my-webapp  // 파드가 해당 label을 metadata로 가진 이상, service는 이 파드를 타겟한다.
    ports:  
    - protocol: TCP   
      port: 80  
      targetPort: 80.   // 파드의 포트. 

Ingress

  • 클러스터 내에서 파드끼리 내부 통신을 가능하게 함
  • 즉, 서비스를 클러스터 외부 클라이언트에 노출시킴
  • 어플리케이션의 외부 엔트리 포인로서 동작
  • 들어오는 트래픽에 대해 라우팅 규칙과 로드 밸런싱을 설정할 수 있게 함
  • Ingress 사용을 위해서는 클러스터 내에 Ingress Controller가 배포되어야 함
apiVersion: networking.k8s.io/v1  
kind: Ingress  
metadata:  
    name: webapp-ingress  
spec:  
    rules:  
    - host: mywebapp.example.com       // 클러스터 외부에서 접근할 수 있는 도메인
      http:                            
        paths:                         // 라우팅 규칙을 정의하는 부분
        - path: /  
          pathType: Prefix  
          backend:                     // 트래픽이 포워딩 되어야 하는 타겟 서비스 정의
            service:  
                name: webapp-service  
                port:  
                    number: 80
728x90
반응형
728x90
반응형

메인 컴포넌트

#nodes #pods #노드 #파드 #쿠버네티스 #kubernetes #k8ss

노드와 파드

  • 노드
    • 노드는 컨테이너가 배포되고 구동되는 Worker Machine이다.
    • 각 노드는 클러스터 내에서 개별 노드를 의미하고, 물리/가상 머신이다.
    • 노드는 실제 workload를 구동시키고 필요 자원을 제공하는 역할이다.
  • 파드
    • 최소 배포 가능한 단위
    • 하나 혹은 강하게 결합된 컨테이너를 의미함
    • 파드 내의 컨테이너들은 같은 네트워크 네임스페이스를 공유한다
      • 이는 localhost 상에서 서로 소통할 수 있게 함
    • 파드는 클러스터에서 하나의 프로세스 인스턴스를 의미함
apiVersion: v1  
kind: Pod  
metadata:  
    name: webapp-with-db       // 파드 이름
    labels:  
        app: my-webapp  
spec:  
    containers:  
    - name: webapp            // 컨테이너 명
      image: nginx:latest     // 컨테이너 이미지 명
      ports:  
        - containerPort: 80   // 컨테이너 포트
    - name: database  
      image: mongo:latest
  • 왜 컨테이너가 아니라 파드를 사용하는가
    • Grouping Containers
      • 컨테이너들을 논리적으로 그룹화 한다.
      • 스케줄링, 스케일링, 관리를 간단화시킨다.
    • Shared Resources
      • 파드 내의 컨테이너들은 동일한 네트워크 네임스페이스를 공유함
      • 파드 내의 컨테이너들은 동일한 볼륨을 공유할 수 있다.
      • 따라서 서로 소통하기 더욱 쉬워진다
    • Amotic Unit
      • 파드는 배포의 원자 단위이다.
      • 어플리케이션 관리 혹은 스케일링 시, 파드 레벨로 수행한다 (컨테이너 개별 적용말고)
    • Scheduling and Affinity
      • 쿠버네티스는 파드를 노드에 스케줄하지, 각각 컨테이너를 스케줄하지 않는다.
      • 따라서 서로 연간되어있는 파드 내의 컨테이너들은 동일한 노드에 위치하게 된다
728x90
반응형

+ Recent posts