Container Orchestration (Docker & Kubernetes)

강재민·2023년 8월 13일

1. MSA, Container, and Container Orchestration

Monolithic Architecture

  • 모든 서비스가 한 번에 재배포
  • 한 팀의 반영을 위하여 모든 팀이 대기
  • 지속적 딜리버리가 어려움

MSA Architecture

  • Concerns의 분리
  • 수평적인 개발
  • 쉬운 아웃소싱
  • 각 컴포넌트들의 Self Healing

컨테이너 기반 어플리케이션 설계 원칙

  • 이미지 불변성
    • 불변한 컨테이너 이미지는 모든 환경에서 사용되어야한다.
    • 각 환경에서, 컨테이너는 외부에 구성된 방법을 사용해야한다.
  • 높은 관측가능성
    • 컨테이너화된 어플리케이션은 헬스체크와 준비태세에 대한 API를 제공해야한다.
    • 어플리케이션은 외부 도구를 활용해서 중요한 이벤트를 로깅해야한다.
  • 일회성 프로세스
    • 한 번 사용한 컨테이너는 다시 사용하지 않아도 되어야 한다.
    • 빠르게 시작했다가 종료했을 때 쉽게 복구되어야한다.
  • Lifecycle Conformance
    • 컨테이너는 API를 제공해야하고 플랫폼의 이벤트를 받아들여야한다.
    • 컨테이너는 관리형 플랫폼 (도커스웜, 쿠버네티스)의 이벤트를 받아들여야한다.
  • Runtime 제한
    • 컨테이너의 리소스를 제어할 수 있어야한다.
  • 단일 기능의 원칙
    • 모든 컨테이너는 단일 기능을 다루어야한다.
    • 만약 컨테이너화된 마이크로서비스가 여러 개의 기능을 필요로 한다면, 사이드카와 init-containers patterns를 사용할 수 있다. 단, 여전히 하나의 기능을 다뤄야한다.
  • Self-Containment
    • 컨테이너는 빌드시간에 모든 의존성이 만들어져야한다.

컨테이너 기반 어플리케이션 설계 결론

  • 클라우드 네이티브는 마지막 상태에 가깝다
  • 컨테이너와 관련된 best practice
    • 잘게 쪼개진 이미지
    • 임의의 사용자 아이디 지원
    • 중요한 포트 마크
    • 영구 데이터 볼륨의 사용
    • 이미지에 메타데이터 설정

2. Kubernetes Architecture

Master Node

  • Master node는 Kubernetes 클러스터를 관리하며, 모든 관리자 업무의 시작점
  • 다양한 모듈이 확장성을 고려하여 기능별로 분리
  • CLI, GUI (Dashboard), APIs 등으로 Master node에 접근 가능

Master Node 구성요소

  • API server
  • Scheduler
  • Controller manager
  • Etcd. (distributed key-value store)
    • 장애 대비하여, 하나 이상의 Master node를 한 클러스터에 구성하여 안정성을 높임
    • 하나 이상의 Master node가 존재할 경우, HA모드로 그 중 하나가 리더로써 작동하고 나머지는 팔로워로 운영

API Server

  • 원하는 상태를 Key-Value 저장소에 저장하고 저장된 상태를 조회하는 작업 수행
  • 모든 administrative tasks는 master node에 있는 API server를 통해 수행
  • 사용자/운영자가 보낸 요청은 API server를 통해 처리되고, 실행 결과는 분산 키-값 저장소(Distributed key-value store)에 저장

Scheduler

  • Pod를 여러가지 조건(필요한 자원, 라벨)에 따라 적절한 노드에 할당해주는 모듈
  • Scheduler가 개별 worker node에게 업무를 분담
  • Scheduler는 각 worker node의 리소스 사용 정보를 가짐
  • "disk==ssd"와 같은 label이 설정된 worker node에 업무 부여하는 등 사용자/운영자가 설정한 제약에 대해 인지하고 있음
  • Scheduler는 Pods와 Services 단위로 업무 수행

Controller Manager

  • Kubernetes Cluster에 있는 모든 오프젝트의 상태를 관리하는 모듈
  • Contoller manager는 Kubernetes Cluster의 상태를 조절하는 non-terminating control loops 관리
  • 각각의 control loops는 자신이 관리하는 객체의 desired state를 알고 그 객체들의 현 상태를 API서버를 통해서 모니터링
  • 제어 루프에서 관리하는 객체의 현 상태가 원하는 상태와 다르면, 제어 루프는 수정 단계를 수행하여 현 상태와 원하는 상태를 일치시키는 작업 수행
  • Kubernetes release 1.6, kube-controller-manage와 cloud-controller-manager로 세분

Etcd

  • RAFT* 알고리즘을 이용한 클러스터 상태를 저장하는 key-value 저장소
  • 단순 R/W기능 외, Watch기능이 있어, 상태가 변경되면 트리거 로직 실행 가능
  • 클러스터의 모든 설정, 상태가 저장되므로 Cluster Backup Restore 유리
  • Etcd는 오직 API 서버와 통신하고, 다른 모듈은 API 서버를 통해 etcd 접근

*RAFT 알고리즘: 분산 환경에서 상태를 공유하는 알고리즘,

Etcd - State 관리

  • Kubernetes는 etcd를 사용해 클러스터의 상태를 저장

  • etcd는 'Raft Consensus Algorithm'을 기반으로 하는 distributed key-value store

    • Raft는 장치의 집합으로써 몇몇 구성원에 장애가 발생하여도 살아남아 일관적인 집단으로 작동할 수 있도록 해줌
  • etcd는 Go 프로그래밍 언어로 작성

  • Kubenetes에서는 클러스터의 상태를 저장하는 기능 말고도 Subnets, ConfigMaps, Secrets 등을 저장하기도 함

Worker Node

  • 마스터 서버와 통신하면서 필요한 Pod를 생성하고 네트워크와 볼륨을 설정
  • Worker node는 Master node에 의해 관리되며, Pod를 이용 어플리케이션을 실행
  • Pod는 Kubernetes의 스케줄링 단위
  • 하나 이상의 컨테이너의 논리적 집합이며, 항상 같이 스케줄링 됨

Worker Node 구성요소

  • Container runtime
    • 컨테이너의 lifecycle을 관리/실행 하기위한 Worker node상의 Container runtime
      • (runtimes: containerd, cri-o, RKT, LXD)
  • kubelet
    • Node에 할당된 Pod의 생명 주기를 관리
    • kubelet은 master node와 통신하기 위해 worker node에서 작동하는 에이전트
    • Pod설정을 수신하고 해당 Pod와 관련된 컨테이너를 실행
    • 항상 컨테이너가 정상 작동하는지 확인
    • Kubelet은 Container Runtime Interface(CRI)를 이용하여 컨테이너 런타임에 연결
      • CRI는 protocol buffer, gRPC API, and libraries 등을 포함
    • Kubelet이 명령을 받으면 Docker runtime을 통해 Container를 생성하거나 삭제
    • Docker이외의 여러 컨테이너 기술이 나오면서 매번 kubelet 코드를 수정하는 번거로움에 따라, kubelet과 Container runtime 사이에 표준 인터페이스가 제정되었는데, 이를 CRI Shim이라 함
    • 새로운 Container runtime은 CRI Shim 스펙에 맞춰 CRI 컴포넌트를 구현
    • Docker shim
      • Docker shim은 Worker node에 설치된 Docker를 이용하여 컨테이너를 생성
      • 내부적으로는 Docker는 containerd를 이용해 컨테이너를 관리
    • CRI-O
      • Container Runtime 표준화
      • 각 Container마다 CRI Shim을 개발해야 하는 비용적 이슈에서 CRI-O 등장
      • Container runtime이 OCI(Open Container Initiative)에서 정의한 표준을 따르면 CRI-O를 CRI shim 으로 사용 가능
  • kube-proxy
    • Kubelet이 Pod를 관리한다면, Proxy는 Pod로 연결되는 네트워크를 관리
    • 초기, kube-proxy가 프록시 서버로 동작하면서 실제 요청을 받아 각 Pod로 포워딩
      • 성능 이슈로 iptables를 설정하는 방식으로 변경, 최근엔 IPVS 지원 시작
    • 애플리케이션에 액세스하기 위해 포드에 직접 연결하는 대신 "서비스"라는 논리적 구성을 연결 엔드포인트로 사용
      • Service 그룹과 관련된 Pod에 접속 시 자동으로 Load Balancin됨
    • kube-proxy는 Network proxy로서 각각의 Worker node에서 작동하며, 각각의 Service endpoint를 생성/삭제하기 위해 API server를 지속적으로 Listening
      • kube-proxy는 각 Service endpoint에 접근할 수 있는 경로 설정

* gRPC: Google에서 처음 개발한 공개 원격 프로시져 호출(RPC) 시스템, 인터페이스 설명언어로 프로토콜 버퍼 사용
* Protobuf: protocol buffer 줄임말로 크기를 줄인 직렬화 데이터 구조 (이진 메시지 형식)

3. Service Mesh: Istio for Advanced Services Control

Service Mesh - Service to Service Communicator

  • Service Mesh는 마이크로서비스 간의 통신을 담당하는 요소
  • 통신 및 네트워크 기능을 비지니스 로직과 분리한 네트워크 통신 인프라
  • 서비스간 통신을 위해서는 Service Discovery, Fault Tolerance, Traffic Routing, Security 등의 기능 필요

API Gateway vs. Service Mesh

  • API Gateway는 마이크로서비스 그룹의 외부 경계에 위치하여 역할을 수행하지만, Service Mesh는 경계 내부에서 그 역할을 수행
API GatewayService Mesh
라우팅 주체서버요청하는 서비스
라우팅 구성요소별도의 네트워크를 도입하는 독립적인 API Gateway 구성요소Service 내 SideCar로 Local network 스택의 일부가 됨
로드 밸런싱단일 엔드포인트를 제공하고, API Gateway내 로드밸런싱을 담당하는 구성요소에 요청을 redirection하여 해당 구성요소가 처리함Service Registry에서 서비스 목록을 수신함. Sidecar에서 로드밸런싱 알고리즘을 통해 수행함
네트워크외부 인터넷과 내부 서비스 네트워크 사이에 위치함내부 서비스 네트워크 사이에 위치하며, 응용프로그램의 네트워크 경계 내에서만 통신을 가능하게 함
트레이싱API에 대한 사용자 및 공급자에 대한 모든 호출에 대해 수집되고 분석됨Mesh 내 모든 마이크로서비스 구성요소에 대해 분석가능

Istio Service Mesh key features

  • 향상된 라우팅과 배포 전략
    • Traffic Routing Controls
    • Canary Deploy
    • A/B Testing, Shadow Deploy
  • 향상된 회복력
    • 서비스간 호출 실패에 대한 재시도
    • Circuit Breaking / Rate Limiting
    • Pool Ejection
    • Health Check & Service Discovery
  • 향상된 보안
    • TLS based Inter Microservices Communication
    • Service Authentication & Authorization
    • Whitelist and Blacklist
  • 향상된 관측
    • Distributed Tracig and Measure

      Service Discovery, Load balancing, Dynamic Request Routing, Circuit Breaking, 암호화, 보안, Health check, Retry and Timeout, Metric 수집


  • L7레이어를 사용, 성능이 높음
  • Code 변경 없이 Cross-cutting 이슈를 다루어 줌
  • Main 서비스의 재배포 없이 Sidecar를 관리 가능함

0개의 댓글