자체서버부터 컨테이너까지 쿠버네티스 등장배경

2019-12-25

.

Data_Engineering_TIL_(20191206)

[학습한 Contents]

1) 주제 : 컨테이너 오케스트레이션 쿠버네티스 살펴보기 / SK T아카데미 온라인강의

2) URL : https://tacademy.skplanet.com/live/player/onlineLectureDetail.action?seq=162

[필기노트]

  • 쿠버네티스는 다른 툴들과 마찬가지로 다 이유가 있어서 등장한 것이다. 과거에 서버를 관리하던 사람들이 어떻게하면 서버를 잘 관리할 수 있을까라는 생각으로 만든것이다.

  • 쿠버네티스는 설치하는 방법이 다양하고 다양한 환경에 따라 다 다르기 때문에 복잡한 편이다.

  • 자체서버부터 컨테이너까지 변화과정

1

위의 단계를 보면 결국에는 서버를 어떻게 하면 잘 관리하고, 효율적으로 관리할지에 대한 고민으로 나온 것들이다.

1. 도커가 등장하기 전 서버운영

1) 자체서버 운영단계

클라우드가 없었던 시절. 회사마다 자체 전산실을 운영.

서버를 구축하고 싶으면

서버 주문 > 서버 설치 > CPU, 메모리, 하드디스크 조립 > 네트워크 연결 > OS 설치 > 계정 설정 > 방화벽 설정 > …

위와 같은 복잡한 단계를 거쳐야 했다.

  • 서버를 설정하기 위해 많은 노력과 시간이 필요

  • 성능이 좋은 걸 미리 구매하고 효율적인 사용을 위해 여러 애플리케이션을 설치해야함

  • 예를들어서 Ruby on rails를 설치하는 것을 예를 들어보자.

처음에 os를 설치하고, 유저를 추가한다. 그 다음에 시스템 환경변수도 설정을 하고, 방화벽 설정하고, 루비관련된 패키지 들을 설치를 할 것이다. 그 다음에는 관련 소스를 설치하고 하는 등 아래 그림과 같은 양상이 될 것이다.

여기서 문제가 되는 경우는 아래 그림의 각각의 단계를 거치는데(예를 들어서 상태A → 상태B로 바뀌는데) 명령어(command)를 이용을 한다는 것이다.

2

예를 들어서 위에 그림과 같이 루비 1.8에서 1.9로 버전업을 해야하는 상황이 생겼다. 저 루비만 새로 버전을 올리면 되지만 저 하나의 상태를 바꿈으로써 그 이후에 있는 모든 상태가 다 변경되야 한다는 문제가 발생한다.

마치 카드로 탑을 쌓아올린 것처럼 중간에 어떤게 문제가 발생해버리면 전체가 위태로워지는 것이다.

따라서 상태관리가 참 어려운 부분이었다.

특정 시점의 서버 상태를 누가, 언제, 어떻게 작업했는지 알 수 있을까?

PPT를 만들고 설치 화면을 캡쳐한 메뉴얼이 있는데 믿을 수 있을까?

똑같은 서버를 하나 더 만들 수 있을까?

서버관리자 = GOD = 문제 생기면 다 해결함 = 휴가 못감 = 변화를 싫어함 = 확장이 어려움 = 혁신이 어려움

서버관리자는 위와 같이 조그마한 변화와 변경사항에 대해 두려움이 생길 수 밖에 없고 이는 혁신과 변화라는 것에 큰 장애물이 될 수 밖에 없었다.

그래서 데브와 옵스로 나누어지면서 옵스는 변화를 싫어하고, 데브쪽에서는 계속 변화를 해야하는 악순환이 생기게 된다.

그래서 여러 선구자들은 생각했다. “ 아 이게 사람이 일일히 커맨드를 치고 앉아 있는게 어렵구나. 설정관리도구 같은게 필요하겠다”

2) 설정관리 도구 등장

  • 설정 관리 도구 : Configuration Management

  • 명령어를 통한 서버 관리를 지양 !

  • 상태를 관리하는 코드(또는 설정)를 이용하여 서버 관리

  • 선언적 서버 상태 정의

  • 서버의 상태가 재현 가능해짐 (불완전하지만)

  • 서버 운영의 협업이 가능해짐 (소스관리, 코드리뷰)

3

앤서블을 예로들면 아래 그림과 같이 서버상태들에 대해 변수들로 관리할 수 있다.

앤서블이라는 어떤 도구를 이용해서 관리를 한다는것이 뭐가 좋아지기는 했지만 절대 쉬워졌다는 얘기가 아니다. 아래 그림과 같이 도구를 이용해서 관리를 하기 위해 그 도구의 작동원리나 그 도구에서 사용하는 변수를 공부해야 한다는 것이 쉽지는 않다.

예를 들어서 아래그림에서는 어떤 호스트에 대한 설정을 부여하는 변수가 있고, 인벤토리나, 플레이북 등 configuration 툴마다 갖고 있는 개념을 다 이해하고 개념에 따라 올바르게 설정을 해줘야 잘 운영을 할 수 있다.

4

위에 그림과 같이 앤서블 설정파일을 만들어서 실행을 하면 뒷단에서 무슨일이 일어나는지는 자세히 알 수는 없지만 앤서블이 알아서 서버에 접속해서 내가 설정파일에 선언한 상태를 만들기위해서 알아서 명령어를 수행하는 것을 알 수 있다.

그래서 커맨드라인으로 한땀한담 작업을 하는 것이 아니라 설정관리도구를 이용해서 서버의 환경을 관리할 수 있게 되었다. 그리고 이런무렵에 가상머신이 등장하게 된다.

3) 가상 머신의 등장

가상머신이 등장하면서 서버관리자 입장에서 굉장히 편해졌다. 왜냐하면 기존에는 하나의 서버에 여러 복잡한 서비스를 띄우는 것이 매우 어려웠다. 예를 들어서 하나의 서버안에 여러버전의 자바를 운영하려면 디렉토리를 정말 잘 관리해야하는 복잡성이 있었다. 또는 여러개의 mysql을 하나의 서버에 띄우려고해도 그 mysql의 실제 데이터를 저장할 디렉토리나 설정디텍토리를 정말 잘 관리해줘야 했는데 가상머신이라는 것이 등장하면서 하나의 물리서버에 여러개의 독립적인 서버를 띄울 수 있게 되어 굉장히 편해졌다. 또한 서버의 상태를 이미지로 관리가 가능해졌다. 어떤 가상머신의 현재상태를 스냅샷을 찍어서 이미지 파일을 만들어 동일한 가상머신을 여러개 생성할 수 있다.

  • 하나의 서버에 여러개의 가상 서버를 설치할 수 있음

  • 다양한 버전의 Java, 여러개의 데이터베이스를 쉽게 사용

  • 서버의 상태를 이미지로 저장할 수 있음

  • 새로운 서버를 만들고 기존 서버의 내용을 복사할 수 있음

4) mutable과 immutable(변하지 않은)

  • 서버에 설치된 애플리케이션을 새로운 버전으로 업데이트 하면 mutable

  • 새로운 버전이 설치된 서버의 상태를 이미지로 만들고 교체하면 immutable

개념이 단순해짐

  • 기존 상태를 고려할 필요 없이 통째로 서버를 교체

생각보다 어렵고 느리고 특정 회사의 제품을 써야함

5) 클라우드 서비스의 등장

아래 그림과 같이 각 스테이지별로 이미지를 구워서 재활용이 매우 용이해졌다.

5

6) Platform as a service 등장

서버관리자 입장에서 서버를 관리하는 것 조차 이제는 귀찮은 것이다. 나는 그냥 node 언어가 잘 설치되어 있는 웹서버에 소스만 배포하겠다. 라는 아이디어에서 등장한 개념이다. 그래서 이제는 서버에 대해 잘 몰라도 원하는 서비스를 배포할 수 있게된다.

  • Heroku, Netlify, AWS Elastic Beanstalk, Google Cloud App Engine, …

  • 서버를 운영하는 것은 복잡하고 어렵다

  • 소스 코드만으로 배포가 가능함

  • 일반화된 프로비저닝 방법을 제공 프로비저닝 과정에 개입할 수 없음 예시) Heroku의 buildpacks

7) PaaS 단점

  • 애플리케이션을 PaaS 방식에 맞게 작성해야함

  • 서버에 대한 원격 접속 시스템을 제공하지 않음

  • 서버에 파일 시스템을 사용할 수 없음

  • Site 패키지를 설치할 수 없음

  • 로그 수집을 제한적인 방식으로 허용 (STDOUT)

  • 애플리케이션 배포에 대한 새로운 패러다임

8) 서비스를 제공하는 사람 입장에서 PaaS를 사용하는것이 적절한지 신중하게 검토해야 하는 경우

  • 크론잡 (문자 발송, 예약, 정산 등)

  • 데이터 분석 (BigQuery, S3 등 연동)

  • 로그 분석 (엘라스틱 서치, 스택드라이버, 클라우드와치 등)

  • 애플리케이션 성능 모니터링

  • A/B 테스트, Canary 배포

  • 네트워크, 스토리지 설정

이런 와중에 도거카 등장하게 된다.

2. 도커의 등장

1) 도커란

  • 2013년에 DotCloud(현 Docker)에서 첫 공개

  • 컨테이너를 아주 쉽게 사용할 수 있는 툴

컨테이너: 격리된 환경에서 작동하는 프로세스

  • 리눅스 커널의 여러 기술을 활용

  • 하드웨어 가상화 기술보다 가벼움

  • 이미지 단위로 프로세스 실행 환경을 구성

2) 가상머신 vs 도커

가상머신 같은 경우는 os 위에 또 다른 os를 올려서 돌리는 반면에 도커는 os위에 os를 올리는게 아니라 격리만 시켜서 불필요한 오버헤드를 줄임

6

3) 도커의 특징 - 확장성

  • 도커가 설치되어 있다면 어디서든 컨테이너를 실행할 수 있음

  • 특정 회사나 서비스에 종속적이지 않음

  • 쉽게 개발서버를 만들 수 있고 테스트서버 생성도 간편함

4) 도커의 특징 - 표준성

  • 도커를 사용하지 않는 경우 ruby, nodejs, go, php로 만든 서비스들의 배포 방식은 제각각 다름

도커는 docker run이라는 명령어로 배포 방식이 통일되어 있음

  • 컨테이너라는 표준으로 서버를 배포하므로 모든 서비스들의 배포과정이 동일해짐

  • capistrano? fabric? ftp? 바이바이~

5) 도커의 특징 - 이미지

  • 이미지에서 컨테이너를 생성하기 때문에 반드시 이미지를 만드는 과정이 필요

  • Dockerfile을 이용하여 이미지를 만들고 처음부터 재현 가능

  • 빌드 서버에서 이미지를 만들면 해당 이미지를 이미지 저장소에 저장하고 운영서버에서 이미지를 불러옴

6) 도커의 특징 - 설정

  • 설정은 보통 환경변수로 제어함

  • MYSQL_PASS=password와 같이 컨테이너를 띄울때 환경변수를 같이 지정

  • 하나의 이미지가 환경변수에 따라 동적으로 설정파일을 생성하도록 만들어져야함

7) 도커의 특징 - 자원

  • 컨테이너는 삭제 후 새로 만들면 모든 데이터가 초기화됨

  • 업로드 파일을 외부 스토리지와 링크하여 사용하거나 S3같은 별도의 저장소가 필요

  • 세션이나 캐시를 파일로 사용하고 있다면 memcached나 redis와 같은 외부로 분리

8) 도커가 가져온 변화

  • PaaS와 같은 제한 없음

  • 클라우드 이미지보다 관리하기 쉬움

  • 다른 프로세스와 격리되어 가상머신처럼 사용하지만 성능저하 (거의) 없음

  • 복잡한 기술(namespace, cgroups, network, …)을 몰라도 사용할 수 있음

  • 이미지 빌드 기록이 남음

  • 코드와 설정으로 관리 > 재현 및 수정 가능

  • 오픈소스 > 특정 회사 기술에 종속적이지 않음

9) 도커를 배우면 모든 서비스를 컨테이너로 만들고 싶게 된다.

7

10) 블루-그린 배포

서비스를 업데이트 하려면 기존에 있는 컨테이너를 죽이고 새로운 컨테이너를 띄워야 한다. 그러기 위해 앞단에 엔진엑스 같은 프록시를 둬서 컨테이너를 교체해줘야 한다.

8

11) Service Discovery

사실 이게 굉장히 복잡한 개념인데 쿠버네티스에서는 하나의 기능으로 매우 편리하게 쓸 수 있다. 이전에는 서비스관리자가 한땀한땀 전부 작업을 해줘야 했던 부분이다.

  • 서버들의 정보(IP, Port등등)를 포함한 다양한 정보를 저장하고 가져오고 값의 변화가 일어날때 이벤트를 받아 자동으로 서비스의 설정 정보를 수정하고 재시작하는 개념

1 새로운 서버가 추가되면 서버 정보를 key/value store에 추가함

2 key/value store는 directory 형태로 값을 저장함. /services/web 하위를 읽으면 전체 web 서버 정보를 읽을 수 있음

3 key/value store를 watch하고 있던 configuration manager가 값이 추가되었다는 이벤트를 받음

4 이벤트를 받으면 템플릿 파일을 기반으로 새로운 설정파일을 생성

5 새로운 설정파일을 만들어 기존파일을 대체하고 서비스를 재시작함

아래 그림으로 이해해보자.

원래는 서버가 컨테이너 두대로 이루어져 있었는데 한대가 추가가 되면 중간에 있는 키벨류 스토어에 저 세대의 컨테이너 서버에 대한 정보가 저장된다. 그러면 configuration manager는 키벨류 스토어가 변경될때마다 알아챌 수 있다. 그래서 기존에는 컨테이너 두대에 대한 정보밖에 없었는데 추가로 한대에 대한 정보가 업데이터 되는 것을 알아채고 configuration manager가 config file(설정파일)을 최신으로 바꾸게 된다. 기존에는 프록시에 두대만 바라보고 있었다면 세대가 바라볼 수 있게 바꾸고 그 다음에 엔진엑스를 재시작 해준다.

기존에는 내가 서버를 추가하게 되면 엔진엑스 서버에 접속해서 설정파일을 수작업으로 수정해서 추가된 서버정보를 추가하고, 엔진엑스 리로드 명령어를 또 실행해줘야 하는 번거로움이 있었으나 이런 작업을 자동으로 해준다는 것이다.

9

12) docker-gen

위와 같이 자동화를 할 수 있는 기술로 도커-젠이라는 것이 있다.

도커에 변화가 발생하면 이벤트라는 것을 발생시킨다. 예를 들어서 도커 컨테이너가 하나 생성되면 어떤 컨테이너가 생성되었다는 이벤트를 발생시키는데 그 이벤트를 보고 그때마다 원하는 작업을 할 수 있게 해주는 기술이다.

docker의 기본 기능을 적극 활용한 service discovery 도구

  • 도커 데몬이 가지고 있는 컨테이너의 정보를 그대로 이용

  • 컨테이너를 실행할때 입력한 환경변수를 읽음

  • VIRTUAL_HOST=www.subicura.com과 같이 환경변수를 지정하면 이를 보고 nginx의 virtual host 설정파일들을 구성함

3. 컨테이너 오케스트레이션의 등장

그래서 이런 여러개의 도커서비스를 편리하게 관리할 수 없을까해서 나온 개념이다.

“여러 대의 서버와 여러 개의 서비스를 편리하게 관리해주는 작업”

도커는 이런 여러대의 서버와 서비스를 관리할 수 있는 기능을 잘 제공하지는 않았다.

컨테이너 오케스트레이션의 특징은 아래와 같다.

1) 스케줄링

  • 컨테이너를 적당한 서버에 배포해 주는 작업

  • 여러 대의 서버 중 가장 할일 없는 서버에 배포하거나 그냥 차례대로 배포 또는 아예 랜덤하게 배포

  • 컨테이너 개수를 여러 개로 늘리면 적당히 나눠서 배포하고 서버가 죽으면 실행 중이던 컨테이너를 다른 서버에 띄워줌

2) 클러스터링

  • 여러 개의 서버를 하나의 서버처럼 사용

한곳에 명령어를 내리면 클러스터 전체에 내려질 수 있는 편리성

  • 작게는 몇 개 안 되는 서버부터 많게는 수천 대의 서버를 하나의 클러스터로

  • 여기저기 흩어져 있는 컨테이너도 가상 네트워크를 이용하여 마치 같은 서버에 있는 것처럼 쉽게 통신

3) 서비스 디스커버리

  • 서비스를 찾아주는 기능

  • 클러스터 환경에서 컨테이너는 어느 서버에 생성될지 알 수 없고 다른 서버로 이동할 수도 있음. 따라서 컨테이너와 통신을 하기 위해서 어느 서버에서 실행중인지 알아야 하고 컨테이너가 생성되고 중지될 때 어딘가에 IP와 Port같은 정보를 업데이트해줘야 함

  • 키-벨류 스토리지에 정보를 저장할 수도 있고 내부 DNS 서버를 이용

4) 로깅, 모니터링

  • 여러 대의 서버를 관리하는 경우 로그와 서버 상태를 한곳에서 관리

  • ELK와 prometheus등 다양한 도구 사용

5) 대표적인 컨테이너 오케스트레이션 툴 : 도커 스웜, 쿠버네티스

6) docker swarm

  • docker에서 만든 컨테이너 오케스트레이션 도구

  • 호스트 OS에 Agent만 설치하면 간단하게 작동하고 빠름

  • 단순한 구조에서 효과적

7) kubernetes

  • 구글에서 개발한 컨테이너 배포, 확장, 운영 도구

  • 사실상 컨테이너 오케스트레이션 표준

  • 대규모에 적합

  • 다양한 생태계 구축되어 있음

8) Service Mesh

10

2019년 말 현재 가장 트랜디한 기술중에 하나로 마이크로 서비스 아키텍처에서 특정서비스에서 또다른 특정서비스로 통신을 할때 안정적으로 하기 위해서 여러가지 라이브러리를 쓴다. 대표적으로 넷플릭스에서 제공하는 라이브러리를 쓴다. 예를 들어서 통신을 요청했는데 실패할 경우 retry를 한다더지 하는 경우가 있다. 그리고 여러개의 서버를 로드밸런싱을 하는 것을 클라이언트 단에서 한다던가가 있다. 또한 히스트릭스라고 해서 여러가지 기술을 쓸 수 있는데 이것을 프록시로 대체할 수 있다. 이게 무슨말이냐면 아래의 그림을 보면서 이해해보자.

12

위의 그림과 같이 원래는 서비스가 하나밖에 없었는데 서비스마다 옆에 프록시를 하나씩 붙이고, 저 프록시가 대신 관리를 해준다. 예를들어서 1번서비스에서 2번서비스로 통신을 할때 기존에는 통신을 실패하면 실패로 끝이었는데 이제는 프록시가 대신 요청하고 프록시가 또 대신받아서 다시 서비스에 전달하기 때문에 retry를 할 수 있는 구조가 된다. 기존에는 이런 구조를 만들기가 굉장히 어려웠는데 쿠버네티스 같은 경우에는 특정 컨테이너에 어떤 프로그램을 심는것이 굉장히 쉬워져서 이런 구조가 나올 수 있게 되었다.

  • Service Mesh 기능

Service Discovery (서비스 발견)

Load Balancing (부하 분산)

Routing Management (경로 관리)

Traffic Management (트래픽 관리)

Resilient (운영 탄력성)

Fault Injection (오류 주입) : 일부러 오류상황을 부여하여 테스트를 해볼 수 있음

Logging / Monitoring (로깅/모니터링)

Distributed Tracing (분산 추적)

Security (보안)

Authentication, Authorization (인증, 인가)

  • 왜 서비스 메시인가, 특정사례로 보는 서비스 메시의 장점

마이크로서비스는 서비스간에 통신하는 경우가 매우 많이 때문에 이런 과정에서 실패하는 수많은 가정에 대한 대비를 해야 한다.

서비스메시는 아래 그림처럼 라이브러리를 쓰는게 아니라 프록시를 쓰겠다는 것이다.

13

4. 자체서버부터 컨테이너까지

11

  • 자체서버부터 컨테이너까지 서버 상태를 관리하기 위한 노력

1) 서버 생성을 쉽고 편리하게

2) 명령어가 아닌 코드와 설정을 사용

3) 격리된 환경을 이용하여 독립적인 실행환경 구성

4) Immutable하게 애플리케이션을 관리하고 스토리지 또는 로그를 분리하여 관리

5) 이미지를 쉽게 만들고 편리하게 사용

6) 로드 밸런서와 프록시 서버등 자주 사용하는 기술을 쉽게 사용

7) 확장 가능한 설계