2024. 3. 9. 17:37ㆍStudy/Kubernetes
회사에서 쿠버네티스 스터디를 시작하여, 블로그에 내용들을 정리하고자 한다. 참고 도서는 'Kubernetes in Action'이다.
1.1 쿠버네티스와 같은 시스템이 필요한 이유
거대한 모놀리스 애플리케이션을 작은 마이크로서비스로 세분화함과 동시에 해당 애플리케이션을 실행하는 인프라의 변경으로 인한 것이다. 이런 변화를 이해하면 쿠버네티스와 도커와 같은 컨테이너 기술을 사용하는 것의 이점을 알 수 있다.
1.1.1 모놀리스 애플리케이션에서 마이크로서비스로 전환
모놀리스 애플리케이션은 시간이 지남에 따라 구성 요소간의 경계가 불분명해지고 상호의존성의 제약이 커지면서 전체 시스템의 복잡성이 커지게 된다. 시스템이 복잡해지고, 시스템의 증가하는 부하를 처리하기 위해 수직 확장을 하거나 수평 확장을 해야한다. 이러한 문제들 때문에, 마이크로서비스라는 독립적으로 배포할 수 있는 작은 구성 요소로 분할해야 한다.
마이크로서비스로 애플리케이션 분할

MSA는 RESTful API를 제공하는 http와 같은 동기 프로토콜과 AMQP와 같은 비동기 프로토콜로 통신한다. 이런 프로토콜은 단순하고 특정 개발 언어에 종속적이지 않다.
마이크로서비스 확장
전체 시스템을 함께 확장해야 하는 모놀리스 시스템과 달리 마이크로서비스 확장은 서비스별로 수행되므로 리소스가 더 필요한 서비스만 별도로 확장할 수 있으며, 다른 서비스는 그대로 둬도 된다.
마이크로서비스 배포
MSA의 단점이라고 한다면, 구성 요소가 많아지기 때문에 배포 조합의 수뿐만 아니라 구성 요소 간의 종속성 수가 훨씬 많아지므로 배포 관련 결정이 점점 어려워진다는 것이다.
환경 요구 사항의 다양성

동일한 라이브러리를 필요로 하는 경우 애플리케이션 구성 요소 간의 종속성의 차이는 불가피하다.
1.1.2 애플리케이션에 일관된 환경 제공
개발과 프로덕션 환경 사이에 큰 차이가 있을 뿐만 아니라 각 프로덕션 머신 간에도 차이가 있어서는 안된다는 내용...
1.1.3 지속적인 배포로 전환: 데브옵스와 노옵스
데브옵스란 개발자, QA, 운영 팀이 전체 프로세스에서 협업해야 한다는 것을 말한다.
데브옵스의 장점
개발자는 이제 애플리케이션을 신속하게 제공할 수 있으므로 사용자의 피드백을 추가적인 개발에 반영할 수 있다.
개발자와 시스템 관리자 각자가 최고로 잘하는 것을 하게 하는 것
개발자와 시스템 관리자는 각자 원하는 목표가 있고, 알고 싶지 않은 것도 존재한다. 예를 들어, 개발자는 os나 보안 패치 같은 것들에 신경쓰지 않고 싶으며 운영 팀은 애플리케이션 구성 요소의 암묵적인 상호 종속성을 다루기를 원하지 않는다.
이와 같은 문제를 쿠버네티스를 사용하면 해결 할 수 있다.
1.2 컨테이너 기술 소개
앞서 언급한 문제들은 여러 방법으로 해결할 수 있지만, 이 책에서는 쿠버네티스로 해결하는 방법에 중점을 둔다. 이를 위해, 컨테이너 기술에 대해 알아야 한다.
1.2.1 컨테이너 이해
애플리케이션이 더 작은 수의 커다란 구성 요소로만 이뤄진 경우, 각 구성 요소에 전용 가상머신을 제공하여 환경을 격리시키는 것은 하드웨어 리소스 낭비하는 것이다. 또한, 각각의 가상머신을 개별적으로 구성하고 관리해야 해 시스템 관리자의 작업량이 증가한다.
리눅스 컨테이너 기술로 구성 요소 격리
컨테이너는 동일한 호스트 시스템에서 여러 개의 서비스를 실행할 수 있으며 동시에 서로 다른 환경을 만들어줄 뿐만 아니라 가상머신과 유사하게 서로 격리하지만 오버헤드가 훨씬 적다. 컨테이너에서 실행되는 프로세스는 다른 모든 프로세스와 마찬가지로 호스트 운영체제 내에서 실행된다. 그러나 컨테이너의 프로세스는 여전히 다른 프로세스와 격리돼 있다.
컨테이너와 가상 머신 비교
컨테이너 | 가상머신 | |
리소스 | 적음 | 많이듬 why? 구성 요소 프로세스뿐만 아니라, 시스템 프로세스도 실행 시켜야함. |
격리수준 | 낮음 | 높음 why? 완전히 독립된 하드웨어 스택을 가지고 있음 |
시작 시간 | 빠름 | 느림 why? OS를 부팅하기 때문에 시간이 오래 걸림 |
보안 수준 | 낮음 why? 동일한 커널을 호출함으로 보안 위험이 발생할 수 있음 |
높음 |
컨테이너 격리를 가능하게 하는 메커니즘 소개
1) 리눅스 네임스페이스로 각 프로세스가 시스템(파일, 프로세스, 네트워크 인터페이스, 호스트 이름 등)에 대한 독립된 뷰만 볼 수 있도록 한다.
2) 리눅스 컨트롤 그룹으로, 프로세스가 사용할 수 있는 리소스(cpu, 메모리, 네트워크 대역폭 등)의 양을 제한한다.
리눅스 네임스페이스로 프로세스 격리
기본적으로 각 리눅스 시스템은 초기 구동 시 하나의 네임스페이스가 있다. 그러나 추가 네임스페이스를 생성하고 리소스를 구성할 수 있다. 프로세스를 실행할 때 해당 네임스페이스 중 하나에서 프로세스를 실행한다. 프로세스는 동일한 네임스페이스 내에 있는 리소스만 볼 수 있다.
➡️ 네임스페이스의 종류
- 마운트(mnt)
- 프로세스 ID(pid)
- 네트워크(net)
- 프로세스 간 통신(ipc)
- 호스트와 도메인 이름(uts)
- 사용자 id(user)
프로세스의 가용 리소스 제한
프로세스의 리소스 사용을 제한하는 리눅스 커널 기능인 cgroups로 이뤄진다. 프로세스는 설정된 양 이상의 cpu, 메모리, 네트워크 대역폭 등을 사용할 수 없다.
1.2.2 도커 컨테이너 플랫폼 소개
도커는 컨테이너를 여러 시스템에 쉽게 이식 가능하게 하는 최초의 컨테이너 시스템이다.
도커 개념 이해
도커는 애플리케이션을 패키징, 배포, 실행하기 위한 플랫폼이다. 도커의 세 가지 주요 개념은 다음과 같다.
1️⃣ 이미지 : 애플리케이션과 해당 환경을 패키지화한 것이다. 여기에는 애플리케이션에서 사용할 수 있는 파일시스템과 이미지가 실행될 때 실행되야 하는 실행파일 경로와 같은 메타데이터가 포함돼 있다.
2️⃣ 레지스트리 : 도커 이미지를 저장하고 다른 사람이나 컴퓨터 간에 해당 이미지를 쉽게 공유할 수 있는 저장소이다. docker-hub 생각하면 될 것 같다.
3️⃣ 컨테이너 : 도커 기반 컨테이너 이미지에서 생성된 일반적인 리눅스 컨테이너다. 할당된 리소스의 양만 액세스하고 사용할 수 있다.
💁♂️참고로, 도커는 build, ship and run any app, anywhere라는 슬로건을 제시하면서 등장했다.
도커 이미지의 빌드, 배포, 실행

이미지 레이어의 이해
도커 이미지는 레이어로 구성돼 있다. 모든 도커 이미지는 다른 이미지 위에 빌드되며 두 개의 다른 이미지는 기본 이미지로 동일한 부모 이미지를 사용할 수 있으므로 다른 이미지에는 정확히 동일한 레이어가 포함될 수 있다.
컨테이너 이미지의 제한적인 이식성 이해
호스트에서 실행되는 모든 컨테이너가 호스트의 리눅스 커널을 사용한다는 사실과 관련해 주의할 것이 하나 있다. 컨테이너화된 애플리케이션이 특정 커널 버전이 필요하다면 모든 시스템에서 작동하지 않을 수 있다. 예를 들어, x86 아키텍처용으로 만들어진 애플리케이션을 ARM 기반 컴퓨터에서 도커가 실행된다고 해서 컨테이너화할 수 없다. 여전히 가상머신이 필요하다.
❗️한 번 짚고 넘어가자!
- 도커 자체가 프로세스 격리를 제공하지 않는다. 컨테이너의 격리는 리눅스 네임스페이스와 cgroup과 같은 커널 기능으로 리눅스 커널 수준에서 수행된다.
- 쿠버네티스가 도커 기반 컨테이너만을 위해 특별히 만들어진 컨테이너 오케스트레이션 시스템이 아니다.
1.3 쿠버네티스 소개
시스템이 배포 가능한 애플리케이션 구성 요소의 수가 많아짐에 따라 모든 구성 요소의 관리가 더 어려워졌다. 이에 소프트웨어 구성 요소와 인프라를 훨씬 더 잘 배치하고 관리하는 방법이 필요해졌다.
1.3.1 쿠버네티스의 기원
구글은 보그라는 내부 시스템을 개발해 애플리케이션 개발자와 시스템 관리자가 수천 개의 애플리케이션과 서비스를 관리하는 데 도움을 줬다. 10년 동안 보그와 오메가를 비밀로 유지하다가 2014년 보그, 오메가, 기타 내부 구글 시스템으로 얻은 경험을 기반으로 하는 오픈소스 시스템인 쿠버네티스를 출시했다.
1.3.2 넓은 시각으로 쿠버네티스 바라보기
쿠버네티스는 컨테이너화된 애플리케이션을 쉽게 배포하고 관리할 수 있게 해주는 소프트웨어 시스템이다. 쿠버네티스를 사용하면 모든 노드가 하나의 거대한 컴퓨터인 것처럼 수천 대의 컴퓨터 노드에서 소프트웨어 애플리케이션을 실행할 수 있다. 기본 인프라를 추상화하고 개발과 운영 팀 모두의 개발, 배포, 관리를 단순화한다.
쿠버네티스 핵심 이해
개발자가 애플리케이션 매니페스트를 마스터에쿠버네티스 시스템은 마스터 노드와 여러 워커 노드로 구성된다. 게시하면 쿠버네티스는 해당 애플리케이션을 워커 노드 클러스터에 배포한다.
개발자가 애플리케이션 핵심 기능에 집중할 수 있도록 지원
개발자가 특정 인프라 관련 서비스를 애플리케이션에 구현하지 않아도 된다. 대신 쿠버네티스에 의존하여 서비스 디스커버리, 스케일링, 로드밸런싱, 자가 치유, 리더 선출 같은 것들이 포함된다.
따라서, 애플리케이션 개발자는 애플리케이션의 실제 기능을 구현하는 데 집중할 수 있으며 애플리케잇녀을 인프라와 통합하는 방법을 찾는 데 시간을 낭비하지 않아도 된다.
운영 팀이 효과적으로 리소스를 활용할 수 있도록 지원
애플리케이션은 어떤 노드에서 실행되든 상관이 없기 때문에 쿠버네티스는 언제든지 애플리케이션을 재배치하고 애플리케이션을 조합함으로써 리소스를 수동 스케주링보다 훨씬 더 잘 활용할 수 있다.
1.3.3 쿠버네티스 클러스터 아키텍처 이해
하드웨어 수준에서 쿠버네티스 클러스터는 여러 노드로 구성되며, 두 가지 유형으로 나눌 수 있다.
- 마스터 노드 : 전체 쿠버네티스 시스템을 제어하고 관리하는 쿠버네티스 컨트롤 플레인을 실행
- 워커 노드 : 실제 배포되는 컨테이너 애플리케이션을 싱행
컨트롤 플레인
컨트롤 플레인은 클러스터를 제어하고 작동시킨다. 하나의 마스터 노드에서 실행하거나 여러 노드로 분할되고 복제돼 고가용성을 보장할 수 있는 여러 구성 요소로 구성된다.
- API 서버 : 사용자, 컨트롤 플레인 구성 요소와 통신
- 스케줄러 : 애플리케이션의 배포를 담당
- 컨트롤 매니저 : 구성 요소 복제본, 워커 노드 추적, 노드 장애 처리 등과 같은 클러스터단의 기능을 수행
- Etcd : 클러스터 구성을 지속적으로 저장하는 신뢰할 수 있는 분산 데이터 저장소
노드
워커 노드는 컨테이너화된 애플리케이션을 실행하는 시스템이다. 애플리케이션을 실행하고 모니터링하며 애플리케이션에 서비스를 제공하는 작업은 다음 구성 요소에 의해 수행된다.
- 컨테이너를 실행하는 도커, rkt 또는 다른 컨테이너 런타임
- API 서버와 통신하고 노드의 컨테이너를 관리하는 Kubelet
- 애플리케이션 구성 요소 간에 네트워크 트래픽을 로드밸런싱하는 쿠버네티스 서비스 프록시(kube-proxy)
1.3.4 쿠버네티스에서 애플리케이션 실행
쿠버네티스에서 애플리케이션을 실행하려면 먼저 애플리케이션을 하나 이상의 컨테이너 이미지로 패키징하고 해당 이미지를 이미지 레지스트리로 푸시한 다음 쿠버네티스 API 서버에 애플리케이션 디스크립션을 게시해야 한다.
디스크립션으로 컨테이너를 실행하는 방법 이해
API 서버가 애플리케이션 디스크립션을 처리할 때 스케줄러는 각 컨테이너에 필요한 리소스를 계산하고 해당 시점에 각 노드에 할당되지 않은 리소스를 기반으로 사용 가능한 워커노드에 지정된 컨테이너를 할당한다.
실행된 컨테이너 유지
애플리케이션이 실행되면 쿠버네티스는 애플리케이션의 배포 상태가 사용자가 제공한 디스크립션과 일치하는지 지속적으로 확인한다.
복제본 수 스케일링
애플리케이션이 실행되는 동안 복제본 수를 늘릴지 줄일지 결정할 수 있으며, 쿠버네티스는 추가 복제본을 기동하거나 초과 복제본을 정지시킬 수 있다. CPU 부하, 메모리 사용량, 초당 요청 수 등등 노출하는 다른 메트릭과 같은 실시간 메트릭을 기반으로 복제본 수를 자동으로 조정할 수 있다.
이동한 애플리케이션에 접근하기
쿠버네티스에게 동일한 서비스를 제공하는 컨테이너를 알려주면 쿠버네티스는 하나의 고정 IP 주소로 모든 컨테이너를 노출하고 핻아 주소를 클러스터에서 실행 중인 모든 애플리케이션에 노출한다. kube-proxy는 서비스를 제공하는 모든 컨테이너에서 서비스 연결이 로드밸런싱되도록 한다. 서비스 IP는 일정하게 유지되므로,
클라이언트는 컨테이너가 클러스터 내에서 이동하더라도 컨테이너에 항상 연결할 수 있다.
1.3.5 쿠버네티스 사용의 장점
- 애플리케이션 배포의 단순화
- 모든 워커 노드를 하나의 배포 플랫폼으로 제공하기 때문에 개발자는 배포를 시작할 수 있으며 클러스터를 구성하는 서버에 관해 알 필요가 없다.
- 하드웨어 활용도를 높임
- 애플리케이션의 리소스 요구 사항에 대한 디스크립션과 각 노드에서 사용 가능한 리소스에 따라 애플리케이션을 실행할 가장 적합한노드를 선택할 수 있음
- 상태 확인과 자가 치유
- 오토스케일링
- 애플리케이션 개발 단순화
- 클러스터된 애플리케이션에서 서비스나 피어를 검색하는 기능을 개발하지 않아도 된다.
Q&A
- containerd란?
containerd는 도커(Docker) 같은 컨테이너 기반의 가상화 환경에서 컨테이너의 생명 주기를 관리하는 오픈 소스 컨테이너 런타임입니다. 컨테이너를 생성, 실행, 정지, 삭제와 같은 기본적인 작업을 수행하며, 이미지 관리 및 스토리지, 네트워킹 기능도 제공합니다.
CNCF에 의해 관리되며, 도커 엔진의 핵심 컴포넌트로도 사용되어 왔다. 도커와 같은 상위 레벨의 컨테이너 플랫폼이 사용자 친화적인 인터페이스를 제공하는 반면, containerd는 좀 더 낮은 수준에서 컨테이너를 직접 관리하는데 초점을 맞춥니다.
'Study > Kubernetes' 카테고리의 다른 글
2. 도커와 쿠버네티스 첫걸음 (0) | 2024.03.15 |
---|