본문 바로가기
코드프레소 체험단/MSA

[마이크로서비스 아키텍처 : 패턴과 핵심 기술] MSA를 위한 기술 - Container, Docker, Kubernets

by 의정부핵꿀밤 2022. 5. 29.
728x90

< Container와 Docker >

 

Container

  • 컨테이너 도입 이전의 문제점
    • Application을 다른 서버에 배포했더니 동작이 다르다
    • 옛날에 설치한 서버와 최근에 설치한 서버 OS, 라이브러리 등의 버전을 완전히 맞추기가 어렵다
    • 같은 미들웨어를 10대를 설치했는데 1-2대의 서버에서만 이상 동작을 한다
  • 위의 문제점들은 인프라의 가변성이 근본적인 문제이다
    • Application은 다른 것에 의존한다 - 운영체제, CPU, 언어 런타임, 라이브러리 등등
    • Application이 의존하고 있는, Application을 둘러 싸고 있는 환경의 차이를 없애는 것이 중요하다
    • 이러한 문제들을 Container를 통해 해결이 가능하다!
  • Container란 외부 환경으로부터 격리된(isolated) 프로세스이다
  • Application을 표준화된 단위로 패키징하여 동일한 방법으로 배포하기 위한 기술이다
  • 패키지 내에는 Application Code 뿐만 안리ㅏ 외부 환경을 하나로 패키징한다
    • Runtime
    • Libraries
    • Configuration
    • etc .

 

 

 

Docker

  • Container를 사용하기 쉽도록 서비스화 한 것이 바로 도커다
  • 컨테이너 기반의 오픈소스 가상화 플랫폼
  • 다양한 프로그램, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공한다
  • 프로그램의 배포 및 관리를 단순하게 해준다
  • Docker의 등장
    • 2013년에 dotCloud라는 회사에서 오픈소스로 공개하였다
    • 이후 Docekr.Inc로 사명을 변경하였다
    • 공개 후 약 5년간 전세계 인프라의 판도를 바꿔놓았다
    • 향후 10년간 패러다임을 바꿀 가장 중요한 기술 중 하나로 선정되었다

 

 

주요 패러다임 전환

  • 2020년까지 전세계 글로벌 기업의 50% 이상이 운영환경에서 도커를 사용할 것이다 - 가트너

 

 

 

Docker 특징

  1. 높은 확장성
    • Docker만 설치되어 있으면 컨테이너 사용이 가능하다
    • OS 환경, 클라우드 벤더 등에 종속적이지 않다
    • 쉽고 빠르게 서버 환경 구축이 가능하다
    • 도커를 사용하게 되면 인스턴스를 provisioning 한 후 해야할 일이 도커 설치 뿐이다!
    • OS 위에 도커만 설치되어 있다면 도커 위에 어떤 프로그랭이든 설치가 가능하다
    • 또한 도커를 사용하면 동일한 인스턴스를 수없이 만들 수 있다
  2. 표준화 가능
    • 이전 기술들을 동일한 인터페이스로 배포하고 관리가 가능해진다
    • Java, Python, Nodejs 등 서로 다른 App 들을 동일한 방식으로 실행이 가능하다
    • 이종 기술이라도 배포 및 운영 과정이 동일하다
  3. 재현 가능한 이미지
    • 기존의 가상 머신 이미지는 재현이 어렵다
      • 이미지를 그대로 만들 수 없다
      • 이미지라는 결과만 존재하다
      • 이미지를 만드는 절차가 없다
    • Docker 이미지는 Dockerfile이라는 파일에 이미지가 어떻게 만들어지는지 기술한다
    • 따라서 100% 재현이 가능하다!

 

 

 

Matrix from Hell

  • 기존 서비스에선 환경 별로 배포를 따로 해야하는 어려움이 있었다

 

  • 그러나 도커를 사용하게 되면 이러한 어려움들이 해결 가능하다
  • 모든 이종 기술들을 도커 컨테이너 단위로 패키징해서 배포하면 동일한 인터페이스로 배포/실행/관리가 가능해진다
  • CI/CD 과정 또한 단순해진다

 

  • 뿐만 아니라 미들웨어도 동일한 인터페이스로 실행이 가능해진다

 

 

 

Docker on Windows

  • 2가지 유형의 컨테이너가 존재한다
    1. Linux 컨테이너
    2. Windows 컨테이너
  • Windows 진영은 2016년부터 컨테이너를 지원한다
  • 현재는 Win 10 Pro/Ent와 Windows Server 2016 이후 버전을 지원한다
  • Windows 컨테이너 지원 버전은 Docker for Windows 설치가 가능하다
    • Win10 Home이나 Win 7은 지원 안함
  • 이전 버전은 Docker Toolbox를 사용한다
  • Win 10 Pro/Ent, Win Server 2016 버전에서 설치가 가능하다
  • hyper-v를 사용한다
  • 운영 환경에서의 안정성은 아직 검증되지 않았다는 의견이 존재한다
  • 그러나 개발 및 테스트 용도로 사용하는 것은 문제가 없다

 

 

 

Docker Toolbox

  • Win 7/8, 10 Home 버전에서 사용한다
  • 내부적으로 Virtual Box를 사용한다
  • Windows Container를 지원하지 않는다

 

 

 

컨테이너

  • 컨테이너는 격리된 공간에서 프로세스가 동작하는 기술이다
  • 가상화 기술의 하나지만, 기존의 Virtual Box나 VM Ware 등의 방식과는 차이가 있다
  • 기존의 가상화 방식은 주로 OS를 가상화했다
    • 호스트 OS 위에 게스트 OS 전체를 가상화하여 사용하는 방식

 

 

 

컨테이너 vs VM

  • 기존 VM 방식
    • 시스템 위에 Hypervisor를 설치하거나 OS 위에 가상화 레이어를 설치한 후 게스트 OS를 설치한다
    • 그 후 게스트 OS위에 어플리케이션을 설치하는 방식이다
  • Docker
    • 서버 위에 호스트 OS를 설치한다
    • 그 위에 Docker 데몬을 설치하면 게스트 OS 없이 그 위에 바로 어플리케이션을 설치 및 사용이 가능하다
    • 각 어플리케이션이 바로 격리된 프로세스인 컨테이너이다
    • 컨테이너들은 실제로 호스트 OS의 자원을 사용한다

 

 

 

이미지

  • 이미지는 컨테이너 실행에 필요한 파일과 설정값 등을 포함하고 있는 것이다
  • 컨테이너는 이미지를 프로세스화한(실행한) 상태이다
  • 같은 이미지에서 여러 개의 컨테이너를 생성할 수 있다
  • 도커 이미지는 Docker hub에 등록하거나 Docker Registry 저장소를 직접 만들어 관리가 가능하다

 

 

 

이미지와 컨테이너

  • Image : 실행할 애플리케이션 및 미들웨어의 정보를 담고 있는 정적인 상태의 스냅샷
  • Container : Imgae를 기반으로 프로세스화 시킨 인스턴스이다
  • 하나의 Image로 다수의 Container 실행이 가능하다
  • Java로 비유하자면, 이미지가 Class이고 컨테이너가 Object 인 셈이다
  • 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있다
  • 의존성 파일을 컴파일하고 애플리케이션을 설치할 필요가 없다
  • 새로운 서버가 추가되면, 단지 해당 서버에 도커만 설치해두면 미리 만들어 놓은 이미지를 다운받아서 컨테이너를 생성함으로써 서버 구축이 완료된다
  • 한 서버에 여러 개의 컨테이너를 실행할 수 있고, 수많은 서버도 동일하게 생성이 가능하다

 

 

 

도커의 장점

  • 변화하지 않는 실행 환경으로 Idempotency 확보
  • 코드(Dockerfile)를 통한 실행 환경 구축 및 애플리케이션 구성 가능
  • 실행 환경과 애플리케이션의 일체화(패키지)로 이식성이 향상된다
  • 시스템을 구성하는 애플리케이션 및 미들웨어의 관리 용이성이 증가한다

 


< Container Orchestration을 위한 Kubernetes >

 

Container Orchestration

  • 그림으로 보는 예시
    • 컨테이너가 왼쪽처럼 몇 개 없다면 수동으로 관리가 가능하지만, 오른쪽처럼 방대한 양의 컨테이너는 사람이 직접 관리하기가 힘들다
    • 따라서 이렇게 수 많은 컨테이너들을 손쉽게 관리하기 위해 Container Orchestration이 탄생하였다
  • 소수의 컨테이너 관리는 어렵지 않아서 수동으로 가능하다
  • 그러나 서버 자체가 여러 개인 다수의 멀티 호스트로 구성된 대용량 분산 환경에서는 수동 작업이 불가능하다
  • 따라서 대용량 분산 환경에서 다수의 컨테이너를 쉽고 자동으로 관리할 수 있는 역량이 필요해졌다
  • 대용량 분산 환경에서 필요한 서버의 역량
    • 다수의 호스트(서버)를 하나의 클러스터처럼 사용하는 것
    • 여러 개의 호스트(서버)에 컨테이너를 배포하는 것
    • 서비스 디스커버리로 서비스들을 연결하는 것
    • 부하가 생기면 서버를 자동으로 Scale-out 하는 것
    • 장애가 발생하면 기존 컨테이너를 kill 한 후 새로운 컨테이너를 다시 생성하는 것
    • 컨테이너 Health Check를 하는 것
    • 컨테이너 간 Storage 및 Network를 관리하는 것
    • 이 외에도 더 많은 기능이 요구된다

 

  • 그림에서 파란색 박스가 하나의 서버이다
  • 그 안의 회색 박스들이 컨테이너이고, 그 안의 알파벳들이 하나의 서비스라고 생각하자
  • 즉, A와 B라는 서비스는 3개의 서버에 컨테이너가 각각 하나씩 배포되어 있는 상황이다
  • 외부에서 봤을 때는 하나의 단일 대용량 클러스터로 보인다

 

 

 

Kebernetes

  • 컨테이너 오케스트레이션 도구
  • 즉, 분산 환경에서 대규모 컨테이너들에 대한 관리를 한다
  • Kubernetes, Docker Swarm, Apache Mesos/Marathon 등과 같은 도구들이 존재하다
  • 그 중에서 Kubernetes가 표준처럼 자리를 잡았다
  • Google에서 개발하고 현재는 CNCF에 이관되었는데, 이는 영리적으로 사용하지 않겠다는 의지이다
  • Kubernetes에는 Google의 대규모 분산 환경 운영 노하우와 철학이 녹아 있다
  • 사실상 컨테이너 오케스트레이션의 표준이다
  • 대규모 생태계가 만들어지고 있다

 

 

 

Docker Swarm

  • Docker Inc에서 개발
  • 설치와 사용이 K8s(쿠버네티스)에 비해 단순하다는 장점이 있다
  • 대용량 분산 환경에서 사용하기에는 기능이 부족하다
  • 모니터링이나 스토리지 옵션 등의 기능이 부족함

 

 

 

Apache Mesos/Marathon

  • Apache Mesos : A distributes systems kernel
  • 분산된 CPU, memory, storage 등을 추상화하여 하나의 단일 리소스처럼 만든다
  • Marathon은 컨테이너 관리 도구이다
  • Mesos와 Marathon을 통합으로 사용하면 대규모 환경의 컨테이너들을 관리할 수 있다
  • 기능 자체는 뛰어나나, 현재 쿠버네티스가 시장을 장악하면서 많이 사용되지는 않는다

 

 

 

Kubernetes 특징

  • 대규모 분산환경에서 상대적으로 소수의 엔지니어만으로 컨테이너를 관리하는 것이 목적이다
  • 구글 사내에서의 Borg라는 클러스터 관리 시스템의 아키텍처를 베이스로 한다
  • 2014년에 첫 공개되었고, 2015년에 CNCF에 이관되었다
  • Kubernetes의 주요 기능
    • 멀티 호스트에서 컨테이너 관리
    • 컨테이너 배포
    • 컨테이너 간 네트워크 관리
    • 컨테이너 감시
    • 컨테이너 업데이트
    • 장애 발생 시 자동 복구
    • 이 외에도 다양한 기능이 있다

 

 

 

CNCF

  • Cloud Native Computing Foundation
  • 오픈소스 소프트웨어 재단
  • 구글, 아마존, MS, Rad Hat, Docker 등이 참여한다
  • 주요 프로젝트로는 Kubernetes, Fluentd, gPRC, Envoy 등이 있다

 

 

 

Kubernetes 철학

  1. Immutable Infrastructure
  2. Declarative Configuration
  3. Self Healing

 

 

 

1. Immutable Infrastructure

  • 기존에는 서로 다른 시기에 구매한 장비들을 유지 보수하며 상태 관리를 하였다
    • 10년전에 구매한 서버, 5년 전체 구매한 서버 등을 유지보수 하며 상태 관리함
  • 클라우드 환경에서는 자원들을 간단하게 구축하거나 파기하는 것이 가능해졌다
    • 한번 구축한 인프라는 수정하지 않고 파기하면 된다
    • 원하는 상태를 만들어서 새로운 환경을 구축하면 된다
    • 즉, 이전보다 서버가 중요해지지 않아졌다! (쉽게 파기하고 쉽게 재생성 가능!)
  • 기존 방법은 서버의 변경 이력을 관리하는 것이 중요하다
    • 현재 운영되고 있는 인프라의 상태를 관리한다
  • ex) Java Version은 올려야 하는 경우
  • 기존에는 서버에 접속하여 명령어로 버전을 업데이트해야 했다
  • 하지만 Immutable Infra 방식은 기존 서버들은 파기하고, 업데이트된 이미지를 만든 후에 새로운 서버를 구축하여 컨테이너를 배포하면 된다

 

 

 

2. Declarative Configuration (선언적인 설정)

  • 명령 vs 선언
    • 명령형
      • ex) 웍에 기름 뿌리고 야채 볶고 춘장 섞어서 5분 볶은 다음 면을 3분 삶아서 그릇에 담아 소스를 면 위에 뿌려서 가져다 주세요
      • 모든 단계를 하나씩 직접 선언하여 명령을 실행한다
      • 자바나 파이썬 같은 프로그래밍들이 명령형이다
    • 선언형
      • ex) 짜장면 하나요
      • 원하는 상태를 얘기하면 된다
  • K8s는 선언적으로 상태를 명시한다
    • pod 3개로
    • pod 5개
  • 쿠버네티스는 원하는 상태를 만들기 위해 명령어를 하나씩 치는 방식이 아니다
  • 원하는 상태를 기술하여 Kubernetes에 적용한다
  • 원하는 상태 = 시스템이 되어있어야 할 모습
    • 앱을 클러스터 안에서 몇 개 올릴지
    • 네트워크 구성은 어떻게 되어야 할지

 

 

 

*Desired State

클러스터의 상태 변경

  • K8s 클러스터의 원하는 상태를 말한다
    • record of intent
    • Cluster의 desired state
  • Desired State 의 예시
    • 어떤 컨테이너들이 어떤 노드 위에서 동작할지
    • 컨테이너들의 replica set이 몇 개가 되어야 하는지
  • Desired State는 관리자가 최종적으로 바라는 상태이다
  • 현재 상태를 실시간 모니터링한다
  • 관리자가 설정한 원하는 새로운 상태를 주문하거나, 기존 Container의 장애로 클러스터의 상태가 변경되면 원하는 상태로 조정한다
  • Kubernetes가 원하는 상태로 조정한다

 

 

 

3. Self Healing

  • 장애 발생 시 자동으로 복구하여 사람의 개입을 최소화한다
  • 시스템이 되어있어야 하는 상태를 항상 감시한다
  • 만약 원하는 상태와 다를 경우에 자동으로 복구한다

 


< Kubernetes 구조와 Objects >

 

K8s의 구조

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

 

 

 

K8s의 구조 - 마스터

Master Node

  • K8s 클러스터를 관리하는 역할을 한다
  • 노드의 상황을 파악하고 컨테이너를 어떤 노드에서 가동할지 선택한다
  • etcd 분산 저장소를 사용하여 클러스터의 정보를 저장한다
  • 모든 요소들이 API 서버를 기준으로 통신을 한다

 

 

 

K8s의 구조 - API 서버

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

 

 

 

K8s의 구조 - 스케줄러

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

 

 

 

K8s의 구조 - 컨트롤러 매니저

  • K8s 클러스터의 상태를 감시한다
  • 되어있어야 한 시스템을 상태를 감시하고 유지한다
  • 실제 요청된 상태와 현재 시스템의 상태에 차이가 있는지 실시간으로 감시한다
  • 만약 다를 경우 같게 되도록 조치한다
  • 실제 컨트롤러 매니저는 여러 개가 존재할 수 있다

 

 

 

K8s의 구조 - 분산 데이터 저장소 etcd

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

 

 

 

K8s의 구조 - 노드

  • 컨테이너가 가동되는 서버
  • 다수의 노드로 클러스터를 구성한다
  • 클라우드의 경우 가상머신이 노드가 된다 - ec2 등
  • 하나의 노드는 그림과 같이 구성되며, 실제 클러스터는 여러 개의 노드로 구성된다
  • pod는 컨테이너라고 보면 된다
  • 컨테이너가 실제로 기동되는 위치가 노드이며, 어떤 노드에 어떤 컨테이너를 배치할 지는 master에서 결정한다

 

 

 

K8s의 구조 - kubelet

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

 

 

 

K8s의 구조 - kube proxy

  • 각 노드에서 실행되는 네트워크 프록시
  • 노드의 네트워크 규칙을 유지 관리한다
  • 내부 네트워크 세션이나 클러스터 바깥에서 컨테이너로 네트워크 통신을 할 수 있도록 해준다

< Kuberbets Objects >

 

K8s Object

  • 컨테이너 기반의 대규모 분산환경에 필요한 요소들이 추상화 되어 있다
  • 컨테이너, 애플리케이션 배포 및 수행 방식, 네트워크 등을 추상화한다
  • 이렇게 추상화 한 것들을 Object라고 통칭한다
  • 종류
    • Application 및 배포 : Pod, ReplicaSet, Deployment, DaemonSet, StatefulSet ...
    • 네트워크 : Service, Ingress ...
    • 설정 정보 관리 : ConfigMap, Secrets
    • 배치 잡 관리 : Job, CronJob

 

 

Pod

  • K8s에서 배포할 수 있는 가장 작은 단위다
  • 한 개 이상의 컨테이너와 스토리지, 네트워크 속성을 갖는다
  • Pod에 속한 컨테이너는 스토리지와 네트워크를 공유하고 서로 localhost로 접근할 수 있다
  • 컨테이너를 하나만 상요하는 경우도 반드시 Pod 단위로 관리하게 한다

 

 

 

ReplicaSet

  • Pod를 여러 개(한 개 이상) 복제하여 관리한다
  • Pod를 생성하고 개수를 유지하려면 ReplicaSet을 사용해야 한다
  • 특정 서비스를 어플리케이션으로 만들어서 그걸 클러스트 상에 다중화해서 배포하고 싶다면 Replica Set을 사용하면 된다
  • Replica Set에는 아래 정보를 포함한다
    • ReplicaSet : 복제할 개수
    • 생성할 Pod의 설정 정보

 

 

 

Deployment

  • K8s에서 실제 배포를 진행하는 기본 단위
    • Pod나 ReplicaSet 단위로 배포를 진행할 수 있지만, 실제로 배포는 Deployment 단위로 진행된다
    • Deployment가 실제 배포를 진행하기 위한 여러 가지 기능을 제공한다!
  • 배포 전략 선택이 가능하다
    • Rolling Update
    • Recreate
  • 배포 Revision 관리 및 Roll Back
  • 이 외에도 Deployment는 배포와 관련된 다양한 기능 및 옵션을 제공한다

 

 

 

DaemonSet

  • 어플리케이션 수행 방식과 관련된 내용이다
  • 클러스터 전체에 Pod를 띄울 때 사용하는 Controller이다
  • 항상 모든 Node에 특정 Pod가 실행되는 것을 보장한다
  • 새로운 Node가 추가되면 자동으로 Pod가 실행된다
  • 로그 수집기나 모니터링 에이전트 등을 실행하는 용도이다

 

 

 

StatefulSet

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

 

 

 

Sevice

  • 네트워크와 관련된 Object이다
  • Pod 간 연결 및 Pod와 외부에서 Pod를 접속하는데 사용되는 외부 네트워크를 연결한다
  • ReplicaSet을 사용해서 여러 개의 Pod에 대한 내부 로드 밸런서 역할을 수행한다
  • 내부 DNS에 서비스를 등록하여 서비스 디스커버리 역할도 수행한다
  • 기본적으로 Service는 Pod에 대한 L4 로드 밸런싱을 수행한다
  • 서비스의 옵션을 지정할 수 있다
    • Cluster IP - 클러스터 내부에서만 통신을 목적으로 함
    • Node Part - 외부로 IP Address를 노출한다
    • Load Balancer - 클라우드 서비스의 Load Balancer 기능을 사용한다 (AWS ELB)

 

 

 

Ingress

  • 외부 트래픽을 받는 Object로, Service보다 많은 기능을 갖고 있다
  • HTTP / HTTPS 등 L7 레벨을 지원하며 라우팅 규칙, 로드밸런싱 규칙 등도 포함한다
  • Service도 외부로의 노출이 가능하지만, L4레벨만 가능한다
  • 일반적으로 k8s 클러스터를 외부로 노출할 때는 Ingress를 사용한다

 

 

 

기타 Object

  • ConfigMap, Secret
    • 설정 정보를 Key/Value 형태로 저장하고 Pod에서 참조한다
  • Job, CronJob
    • 배치 처리를 위해 특정 조건에 따라 작업이 수행됨을 보장한다
    • 실패함녀 자동 재시작하여 처리한다
  • Label과 Selector
    • K8s 내부 자원 관리를 위해 Label을 붙인다
    • Selector를 이용해서 특정 Label이 붙여진 자원을 Filtering 한다

 

 

 

K8s 구성도

쿠버네티스의 구조
다른 측면에서의 쿠버네티스 구조

 

 

 

Manifest 파일

  • K8s에서 선언전 설정을 위해 Manifest 파일을 사용한다
  • YAML(또는 JSON) 파일로 작성한다
  • 리소스의 종류와 원하는 상태를 입력한다
  • 식당 주문서와 유사하다
  • Master Node로 명세를 제출한다

YAML 형식의 Manifest 파일

  1. apiVersion
    • K8s API 버전 정보 기술
    • 보통 v1 사용
  2. kind
    • 리소스의 종류 기술
    • Pod, Service, Ingress ...
  3. metadata.name
    • Object의 이름을 지정한다
    • 알기 쉽게 지정하는 것이 좋다
  4. spec
    • Object의 상세 정보를 기술한다
    • Object의 종류에 따라 정보가 상이하다
    • 컨테이너 이름
    • 컨테이너 포트 정보
    • 환경 변수 등

 

 

 

Kubernetes 사용

  • 설치형 유/무료의 다양한 배포판이 존재한다
    • Red Hat OpenShift
    • Pivotal PKS
    • Rancher
    • Kubeadm
  • Cloud 서비스의 Managed Kubernetes
    • EKS
    • GKE
    • AKS
    • NCloud K8s Service
728x90

댓글