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 특징
- 높은 확장성
- Docker만 설치되어 있으면 컨테이너 사용이 가능하다
- OS 환경, 클라우드 벤더 등에 종속적이지 않다
- 쉽고 빠르게 서버 환경 구축이 가능하다
- 도커를 사용하게 되면 인스턴스를 provisioning 한 후 해야할 일이 도커 설치 뿐이다!
- OS 위에 도커만 설치되어 있다면 도커 위에 어떤 프로그랭이든 설치가 가능하다
- 또한 도커를 사용하면 동일한 인스턴스를 수없이 만들 수 있다
- 표준화 가능
- 이전 기술들을 동일한 인터페이스로 배포하고 관리가 가능해진다
- Java, Python, Nodejs 등 서로 다른 App 들을 동일한 방식으로 실행이 가능하다
- 이종 기술이라도 배포 및 운영 과정이 동일하다
- 재현 가능한 이미지
- 기존의 가상 머신 이미지는 재현이 어렵다
- 이미지를 그대로 만들 수 없다
- 이미지라는 결과만 존재하다
- 이미지를 만드는 절차가 없다
- Docker 이미지는 Dockerfile이라는 파일에 이미지가 어떻게 만들어지는지 기술한다
- 따라서 100% 재현이 가능하다!
- 기존의 가상 머신 이미지는 재현이 어렵다
Matrix from Hell
- 기존 서비스에선 환경 별로 배포를 따로 해야하는 어려움이 있었다
- 그러나 도커를 사용하게 되면 이러한 어려움들이 해결 가능하다
- 모든 이종 기술들을 도커 컨테이너 단위로 패키징해서 배포하면 동일한 인터페이스로 배포/실행/관리가 가능해진다
- CI/CD 과정 또한 단순해진다
- 뿐만 아니라 미들웨어도 동일한 인터페이스로 실행이 가능해진다
Docker on Windows
- 2가지 유형의 컨테이너가 존재한다
- Linux 컨테이너
- 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 철학
- Immutable Infrastructure
- Declarative Configuration
- 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의 구조 - 마스터
- 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로 명세를 제출한다
- apiVersion
- K8s API 버전 정보 기술
- 보통 v1 사용
- kind
- 리소스의 종류 기술
- Pod, Service, Ingress ...
- metadata.name
- Object의 이름을 지정한다
- 알기 쉽게 지정하는 것이 좋다
- spec
- Object의 상세 정보를 기술한다
- Object의 종류에 따라 정보가 상이하다
- 컨테이너 이름
- 컨테이너 포트 정보
- 환경 변수 등
Kubernetes 사용
- 설치형 유/무료의 다양한 배포판이 존재한다
- Red Hat OpenShift
- Pivotal PKS
- Rancher
- Kubeadm
- Cloud 서비스의 Managed Kubernetes
- EKS
- GKE
- AKS
- NCloud K8s Service
728x90
'코드프레소 체험단 > MSA' 카테고리의 다른 글
[마이크로서비스 아키텍처 : 패턴과 핵심 기술] MSA를 위한 아키텍처 패턴 - 서비스 디스커버리 패턴 (0) | 2022.05.30 |
---|---|
[마이크로서비스 아키텍처 : 패턴과 핵심 기술] MSA를 위한 기술 - Service Mesh와 Istio (0) | 2022.05.30 |
[마이크로서비스 아키텍처 : 패턴과 핵심 기술] MSA를 위한 기술 - Spring Boot와 Spring Cloud (0) | 2022.05.28 |
[마이크로서비스 아키텍처 : 패턴과 핵심 기술] MSA 분리 전략 - Microservice 분리 프로세스 (0) | 2022.05.27 |
[마이크로서비스 아키텍처 : 패턴과 핵심 기술] MSA 분리 전략 - 도메인 주도 설계 (0) | 2022.05.27 |
댓글