Kubernetes

※ Docker 등 Container에 대한 기본 설명은 제외하였습니다.


K8s의 구조

  • Master에 API 서버와 상태 저장소를 두고, 각 Node(서버)의 에이전트(Kublet)와 통신하는 구조

K8s의 구조 : Master

  • K8s 클러스터 관리하는 역할
  • 노드의 상황을 파악
  • 컨테이너를 어떤 노드에서 가동할지 선택
  • etcd 분산 저장소를 사용하여 클러스터의 정보를 저장

K8s 구조 (By.Lukša)

Master

 API Server

  • API 서버는 모든 요청을 처리하는 마스터의 핵심
  • 모든 컴포넌트들은 API 서버를 통해서 커뮤니케이션함
  • 인증 및 인가 기능 보유

Scheduler

  • 컨테이너를 어떤 노드에서 가동할지 결정하는 컴포넌트
  • 노드들의 정보를 파악하고 컨테이너를 가동할 적합한 노드 선택

Controller Manager

  • K8s 클러스터의 상태를 감시
  • 시스템의 상태 감시 및 유지
  • 요청된 상태와 현재 시스템의 상태의 차이 감시

etcd 

  • 분산 key-value 저장소
  • 클러스터의 모든 설정, 상태 데이터 저장
  • 스케줄러와 컨트롤러 매니저 등이 API 서버를 통해 etcd의 데이터 조회 및 갱신
  • 마스터에서 분리하여 독자적으로 분리 가능

K8s의 구조 : Node

  • 컨테이너가 가동되는 서버
  • 다수의 노드로 클러스터를 구성
  • 클라우드의 경우 가상머신이 노드가 됨 ex.) ec2...

K8s 구조 (By.Rancher Admin)

Node

Kubelet

  • 실제로 컨테이너를 생성하는 주체
  • 마스터로부터 생성 요청을 받으면 컨테이너를 생성
  • 컨테이너의 상태를 감시하는 역할 수행
  • 컨테이너의 상태를 API 서버로 전송

Kube proxy

  • 각 노드에서 실행되는 네트워크 프록시
  • 노드의 네트워크 규칙을 유지 및 관리
  • 내부 네트워크 세션, 클러스터 외부에서 내부로 네트워크 통신

Pod

  • 한 개 또는 여러 개의 컨테이너의 묶음

 


K8s Object

  • Container, Network 등 분산에 필요한 필요 요소의 추상화

K8s Object

Object

Replica Set

  • Pod를 한 개 이상 복제하여 관리
  • Pod를 생성하고 개수 유지를 위해서 ReplicaSet을 사용해야 함

Daemon Set

  • 클러스터 전체에 Pod를 띄울 때 사용하는 Controller
  • 항상 모든 Node에 특정 Pod가 실행됨
  • 새로운 Node가 추가되면 자동으로 Pod 실행됨
  • 로그 수집기, 모니터링 에이전트 등 실행하는 용도

Stateful Set

  • K8s 대부분의 Object는 Stateless
  • StatefulSet은 상태를 유지하는 Pod를 위한 Object
  • Volume을 사용해서 데이터 저장, Pod 재기동 시에도 유지 가능
  • DB 등을 컨테이너화 할 때 사용 가능

Pod

  • K8s에서 배포할 수 있는 가장 작은 단위
  • 한 개 이상의 컨테이너와 스토리지, 네트워크 속성을 가짐
  • Pod에 속한 컨테이너는 스토리지와 네트워크를 공유하고 서로 localhost로 접근 가능

Service

  • 네트워크와 관련된 Object
  • Pod 간 연결 및 Pod와 외부 네트워크를 연결
  • 여러 개의 Pod에 대한 내부 로드밸런서
  • 내부 DNS에 서비스 등록하여 서비스 디스커버리 역할도 함
  • Pod에 대한 L4 로드밸런싱 수행
  • Cluster IP, Node Port, Load Balancer 등 옵션 지정 가능

Deployment

  • K8s에서 실제 배포를 진행하는 기본 단위
  • 배포 Revision 관리 및 Roll Back 등 다양한 옵션 제공

Ingress

  • 외부 트래픽을 받는 Object
  • Http/ Https 등 L7 레벨로 라우팅 규칙, 로드벨런싱 규칙 등도 포함
  • Service도 외부로 노출 가능하지만 L4 레벨만 가능

Others

  • ConfifMap, Secret : 설정정보 저장 등 Pod 참조
  • Job, CronJab : 배치 관리
  • Label, Selector : 자원 관리 위해 Labeling

 


K8s Manifest File

  • 선언적 설정을 위한 YAML/JSON 형태의 파일

Manifest File

YAML or JSON

YAML

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.20.1
    ports:
    - containerPort: 80

Json

{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "nginx"
  },
  "spec": {
    "containers": [
      {
        "name": "nginx",
        "image": "nginx:1.20.1",
        "ports": [
          {
            "containerPort": "80"
          }
        ]
      }
    ]
  }
}

apiVersion

  • K8s API 버전 정보 기술

kind

  • Object의 종류 기술 (Pod, Service...)

metadata.name

  • Object 이름을 기술

spec

  • Object 상세 정보 기술
  • 포트 등 환경 정보 기술

 


K8s 사용


K8s 사용

유/무료 설치형 배포판

  • Red Hat OpenShift
  • Pivotal PKS
  • Rancher
  • Kubeadm

Cloud Managed Kubernetes

  • EKS
  • GKE
  • AKS
  • NCloud K8s Service


 

'Architecture' 카테고리의 다른 글

K8s 2) 쿠버네티스 구축  (0) 2024.05.18
Kafka 3) MSK Cluster 모니터링 메트릭  (2) 2024.01.11
Kafka 2) 모니터링  (2) 2024.01.11
Kafka 1) 연결 모니터링  (2) 2024.01.11
MSA 5) MSA 분리 전략 : 도메인 주도 설계  (0) 2023.11.01

도메인 주도 설계 (DDD)


서비스 분리와 도메인 주도 설계

  • DDD는 MSA의 서비스를 식별할 수 있는 도구를 제공
  • DDD 중 전략적 설계가 MSA의 서비스를 식별하는데 도움

도메인이란?

  • 소프트웨어를 개발하는 대상 영역
  • 복잡한 비즈니스나 현실세계의 문제

도메인 주도 설계란?

  • 복잡한 현실세계의 문제를 해결할 좋은 SW를 만들기 위한 기법
  • 도메인 주도 설계는 도메인의 이해를 최우선시 하는 모델링 기법
  • 전문가와 개발자의 커뮤니케이션이 중요
  • 도메인과 도메인 모델 그리고 코드를 밀접하게 연관 시킴 (언어의 통일)
  • 도메인 모델 - 동일한 관점에서 이해할 수 있고, 공유할 수 있도록 단순화 (다이아그램 사용)
  • 코드에 도메인의 의미가 녹아 있도록 구현

DDD의 필요성 : Big Ball of Mud

  • 요구사항 추출 -> 분석 -> 설계 -> 구현
  • 계속되는 추가 요구사항
  • 중요한 것과 덜 중요한, 혹은 중요하지 않은 것들이 하나의 큰 덩어리로 얽히게 됨

Big Ball of Mud (CodeOpinion참조)

  • 각 클래스(엔티티)의 의미 파악 어려움

DDD의 필요성 : Big Ball of Mud 원인 by Vaughn Vernon

  • 조직에서 SW 설계에 충분한 노력을 들이지 않음
  • 개발자는 도메인 보다 기술에 너무 몰두, 많은 문제를 기술적으로만 해결하려 함
  • 도메인의 이해 없이 개발자 상상의 나래가 표출됨

 


전략적 설계

마이크로서비스 도출을 위해서 비즈니스 상 전략적으로 중요한 것을 찾아 중요도에 따라 이를 나눔

 


전략적 설계의 필요성

  • 애자일 프로젝트 관리 시스템을 개발 사례
  • 설계 초기에는 핵심이 되는 부분을 설계
  • Big Ball of Mud 방지

서브 도메인

  • 전체 비즈니스 도메인을 이해 가능한 하위 영역으로 분리 필요
  • 전체의 큰 도메인을 분리함
  • 핵심 서브 도메인, 지원 서브 도메인 (비즈니스 도메인), 일반 서브 도메인(큰 공수 없는 도메인)으로 분리

바운디드 컨텍스트

  • 유비쿼터스 언어로 표현이 됨
  • 의미적으로 동일한 맥락의 경계라는 것은 응집도 높은 일을 한다는 것
  • 바운디드 컨텍스트 마다 각각 분리된 소프트웨어의 코드 산출

서브도메인과 바운디드 컨텍스트의 관계

  • 서브 도메인은 Problem Space
  • 바운디드 컨텍스트는 Solution Space
  • Problem Space : 해결해야 하는 도메인 -  서브 도메인들의 집합
  • Solution Space : 해결책을 실제 구현 - 바운디드 컨텍스트들의 집합
  • 보통 하나의 서브도메인은 하나의 바운디드 컨텍스트를 갖는 1:1
  • 서브도메인이 하나 이상의 바운디드 컨텍스트가 매핑 가능 (ex). 상품 - 연관상품, 쿠폰, 할인정보 등)

유비쿼터스 언어와 바운디드 컨텍스트의 관계

  • 제품 책임자와 도메인 전문가 그리고 개발자 간 언어의 통일이 중요
  • SW 개발의 가장 큰 문제 중 하나 (개발언어 x,  사용언어 o)
  • 개발자가 아닌 사람도 도메인 모델 및 코드를 보고 이해할 수 있어야 함
  • 컨텍스트에 따라 비슷해 보이는 언어들이 실제로는 다를 수 있음
  • 각 문맥 별로 상품의 이름을 명확하게 재정의할 필요가 있음

       ex) - 카탈로그 컨텍스트에서의 상품은 Product

             - 재고 컨텍스트에서의 상품은 Stock

             - 주문 컨텍스트에서의 상품은 OrderedItem

 


결론

개발자가 아닌 사람이 이름만 딱 봐도 무엇인지 알 수 있도록 설계를 하자.



 

'Architecture' 카테고리의 다른 글

Kafka 2) 모니터링  (2) 2024.01.11
Kafka 1) 연결 모니터링  (2) 2024.01.11
MSA 4) MSA 분리 전략 : 분리 원칙  (0) 2023.11.01
MSA 3) MSA 역량/성숙도 모델  (4) 2023.10.18
MSA 2) Microservice Architecture 에 대해서  (0) 2023.10.18

분리 원칙


작고 분리가 쉬운 서비스로 워밍업

  • MSA 성공적 전환 위해서는 다양한 사전 준비사항이 존재함

       - Cloud, Deployment Pipeline, Container, Monitoring 등

  • 본격적 MSA 분리 전 간단한 서비스 분리하여 역량 내재화
  • 한 두개 정도 간단한 서비스 분리하여 필요한 인프라, 프로세스 구축
  • 작은 Pilot 서비스 선택
  • 신규 서비스 -> 기존 Monolith 로의 의존성이 없거나 적은 서비스
  • 신규 서비스 -> 기존 Monolith 의존성이 존재하면 Monolith 변경에 영향을 받음

핵심 기능의 분리

  • 핵심 기능은 다른 기능들과 결합도가 높음
  • 도메인 경계가 명확하지 않을 가능성 높음
  • 분리할 핵심 기능의 도메인을 명확하게 해야 함
  • 비즈니스 팀 구조를 기반으로 분리
  • 도메인 주도 설계 적용

데이터의 분리

  • 워밍업을 위해 DB 분리 없이 코드만 분리 가능
  • Anti-Pattern 중 하나가 서비스 별 공유 DB를 갖는 것
  • 독립 된 저장소 및 데이터 Migration 전략 수립이 동반 되어야 함

분리 대상 선정

  • First Step은 조직의 목표를 명확히 해야 함
  • 히스토리를 파악하여 기능 별 빈도 분석
  • 프로젝트 로드맵을 기반으로 향후에 크게 수정 될 것 선정

코드의 재사용 vs 재개발

  • 기술 부채 및 노후된 기술
  • 오랜 기간 유지보수 된 코드의 문제점
  • 요구사항 파악하여 비즈니스 도메인 명확화

진화적인 서비스 분리

  • 서비스의 크기를 고려해야 함
  • 원칙 - Go Macro, then Micro
  • 우선 크게 분리하고 필요한 경우 재설계를 통해 더 작게 분리

반복/점진적 분리

  • Monolith -> MSA 전환은 여정이 험난함
  • 한번에 하나씩 단계적 분리
  • 하나의 작은 기능을 신규 서비스로 분리
  • 클라이언트로 부터의 Request를 신규 서비스로 전환 - Proxy 필요

Strangler PAttern Progression (akf 참조)

  • Monolith에서 Method 호출하던 의존성 모두 신규 서비스로 전환
  • Monolith 내부의 기존 코드는 잠시 유지 후 반드시 제거

 

결론

완벽한 정답은 없겠지만

참고 시, 언젠가 반드시 도움이 될 가능성이 높다.

 

 

+ Recent posts