무지를 아는 것이 곧 앎의 시작

인프라/도커 & 쿠버네티스

[욕망의 인프라 : 도커 & 쿠버네티스] - 컨테이너와 배포

Alex96 2022. 11. 19. 19:51

본 스터디(이하 욕망의 인프라)는 열음(https://github.com/Juhyung990122)과 함께합니다.

용어 정리

컨테이너가 뭐야

앱이 구동되는 환경까지 감싸서 실행할 수 있도록 하는 격리 기술임

PC에 프로그램을 설치할 때 특정 경로에 맞춰서 설치를 해야 하거나, 그 PC에 맞는 옵션을 맞춰야 하거나 하는 번거로운 작업들이 필요할 때가 있는데, 컨테이너는 이런 환경까지 모두 포함하여 독립적으로 프로그램을 실행할 수 있도록 도와주는 기술.

컨테이너 환경을 묶어서 배포한 컨테이너 이미지라는 프로그램을 내려받아 구동하면 된다.

컨테이너 런타임

컨테이너를 다루는 도구이다. 대표적으로 가장 유명한게 도커

컨테이너를 쉽게 내려받거나 공유하고 구동할 수 있도록 해준다. 도커가 사용하는 컨테이너 규격은 표준화되어 있기 때문에 도커가 아닌 다른 컨테이너 런타임들도 도커로 만든 컨테이너를 사용할 수 있다.

쿠버네티스?

컨테이너 런타임을 통해 컨테이너를 오케스트레이션 하는 도구이다. 여러 서버에 컨테이너를 분산해서 배치하거나, 문제가 생긴 컨테이너를 교체하거나, 컨테이너가 사용할 환경 설정을 관리하고 주입하는 역할 등을 할 수 있고 이걸 오케스트레이션이라고 한다.

배포의 변화

출처 https://kubernetes.io/ko/docs/concepts/overview/what-is-kubernetes/

전통적 배포(Traditional Deployment)

전통적인 배포는 컴퓨터 한 대에 하나의 OS를 깔고 필요한 어플리케이션들을 올려서 사용하는 방식. 가장 원시저이고 단순한 방식이며 단일 목적 시스템이라면 이것으로 충분….

가상화 배포(Virtualized Deployment)

만약 서버에 어플리케이션을 여러 개 돌려야 하고, 이 어플리케이션이 서로가 서로에게 영향을 준다면 어떨까? A어플리케이션의 부하가 B어플리케이션의 부하로 이어진다면? 단순하게 생각해보면 아 A어플리케이션과 B어플리케이션의 컴퓨터를 각각 두면 되겠다고 생각할 수 있지만, 그러기엔 so expensive…

그래서 등장한 방식이 위 그림의 2번 째 방법인 가상화 배포. VM을 기반으로 배포하는 것인데, 하나의 컴퓨터에서 여러 가상 컴퓨터를 구동할 수 있도록 해주는 하이퍼바이저라는 어플리케이션을 두고 여러 VM을 올린다. 각 VM에 각 어플리케이션을 올려두면 VM은 CPU, 하드, 메모리 등 자원을 개별적으로 할당하기 때문에 어플리케이션끼리 서로 간섭하지 않는다.

이 방식은 전통적 배포보단 효율적일 수 있지만, VM에 일일이 운영체제를 설치해야 하고 VM을 관리하는 하이퍼바이저도 관리해야 하기 때문에 컨테이너 중심의 배포보단 번거롭고 무거운 편이다.

AWS EC2 인스턴스는 가상머신일까?

가상화와 클라우드 모두 추상적인 리소스에서 환경을 생성하므로 헷갈릴 수 있다.

그러나 가상화는 단일한 물리 하드웨어 시스템에서 여러 시뮬레이션 환경이나 전용 리소스를 생성할 수 있는 기술이고, 클라우드는 네트워크 전체에서 확장 가능한 리소스를 추상화하고 풀링하는 IT 환경이다. 즉 가상화는 기술이고 클라우드는 환경이다.

클라우드라는 환경에서 EC2라는 VM을 제공해주는 것이라고 볼 수 있다.

컨테이너 중심의 배포(Container Deployment)

가상화 배포와 비교하면 하이퍼바이저가 컨테이너 런타임으로 대체되었고, VM이 컨테이너로 대체되었다.

컨테이너는 VM과 달리 매번 OS를 설치하지 않아도 된다. OS는 모든 컨테이너가 공유하지만, 각 컨테이너에 올라간 어플리케이션들은 서로 독립된 환경에서 실행되며 서로 간섭하지 않는다.

컨테이너는 OS하단이 어떻게 동작하는 지 관심을 두지 않는다(가상머신 OS 위에서도 컨테이너 기반 배포를 할 수 있다). 이와 같은 컨테이너 동작 방식을 OS 커널을 공유하는 가상화라고 표현하기도 한다.

컨테이너는 다음과 같은 추가적인 혜택을 제공하기 때문에 인기가 있다.

  • 기민한 애플리케이션 생성과 배포: VM 이미지를 사용하는 것에 비해 컨테이너 이미지 생성이 보다 쉽고 효율적임.
  • 지속적인 개발, 통합 및 배포: 안정적이고 주기적으로 컨테이너 이미지를 빌드해서 배포할 수 있고 (이미지의 불변성 덕에) 빠르고 효율적으로 롤백할 수 있다.
  • 개발과 운영의 관심사 분리: 배포 시점이 아닌 빌드/릴리스 시점에 애플리케이션 컨테이너 이미지를 만들기 때문에, 애플리케이션이 인프라스트럭처에서 분리된다.
  • 가시성(observability): OS 수준의 정보와 메트릭에 머무르지 않고, 애플리케이션의 헬스와 그 밖의 시그널을 볼 수 있다.
  • 개발, 테스팅 및 운영 환경에 걸친 일관성: 랩탑에서도 클라우드에서와 동일하게 구동된다.
  • 클라우드 및 OS 배포판 간 이식성: Ubuntu, RHEL, CoreOS, 온-프레미스, 주요 퍼블릭 클라우드와 어디에서든 구동된다.
  • 애플리케이션 중심 관리: 가상 하드웨어 상에서 OS를 실행하는 수준에서 논리적인 리소스를 사용하는 OS 상에서 애플리케이션을 실행하는 수준으로 추상화 수준이 높아진다.
  • 느슨하게 커플되고, 분산되고, 유연하며, 자유로운 마이크로서비스: 애플리케이션은 단일 목적의 머신에서 모놀리식 스택으로 구동되지 않고 보다 작고 독립적인 단위로 쪼개져서 동적으로 배포되고 관리될 수 있다.
  • 리소스 격리: 애플리케이션 성능을 예측할 수 있다.
  • 자원 사용량: 리소스 사용량: 고효율 고집적.

출처 https://www.samsungsds.com/kr/insights/220222_kubernetes1.html

 

주의할 점은 OS를 공유하기 때문에 OS단의 문제가 일어난 경우엔 OS에서 구동 중인 전체 컨테이너의 문제가 될 가능성이 있다. 이 점에 신경을 써야 한다.

리눅스를 기준으로 내가 실행한 프로그램이 독립된 환경에서 실행되는 것처럼 격리시켜주고, CPU, 메모리 및 저장 장치와 같은 자원도 실행한 프로그램이 독립적으로 쓸 수 있도록 해주는 namespace 및 cgroup이라는 기술이 있다.

  • namespace: 프로세스를 실행할 때 시스템의 리소스를 분리해서 실행할 수 있도록 도와주는 기능
  • cgroup: 프로세스들의 자원 사용을 제한하고 격리시키는 리눅스 커널 기능

namespace 실습

namespace 확인

namespace는 파일시스템에 남는다.

ls -al /proc/{PID}/ns

1번 프로세스는 init 프로세스이다. 1번 프로세스의 namespace를 확인해보자. 뒤에 오는 숫자들은 namespace의 주소다

init 프로세스의 네임스페이스 정보

따로 설정하지 않으면 이 시스템에서 실행되는 프로세스들은 전부 이 네임스페이스를 사용한다. 다른 pid의 네임스페이스도 확인해보자

완전히 같은 namespace를 가진다. 그럼 다른 네임스페이스를 생성하면 네임스페이스 주소값이 달라질까?

새로운 namespace를 생성해보겠다. unshare 명령어를 사용하면 간단하게 네임스페이스를 격리하는 기능을 사용할 수 있다. uts네임스페이스를 생성한다.

sudo unshare -u /bin/bash

678번 pid로 새 배쉬가 생성되었다.

네임스페이스 확인

uts네임스페이스가 처음과 다른걸 볼 수 있다.

새로운 uts 네임스페이스 주소값

Ref

https://kubernetes.io/ko/docs/concepts/overview/what-is-kubernetes/

https://www.samsungsds.com/kr/insights/220222_kubernetes1.html

https://go-coding.tistory.com/92

https://www.redhat.com/ko/topics/cloud-computing/cloud-vs-virtualization