티스토리 뷰

여러 블로그 및 사이트에 있는 개념들을 제가 보기 좋게 정리하였습니다.

출처는 모두 아래에 밝혀져 있으며 혹시 문제가 되면 삭제 또는 비공개 처리하겠습니다. :)

1. 쿠버네티스란?

  • 쿠버네티스는 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식성이 있고, 확장가능한 오픈소스 플랫폼
  • 쿠버네티스란 명칭은 키잡이(helmsman)이나 파일럿을 뜻하는 그리스어에서 유래
  • 글이 2014년에 쿠버네티스 프로젝트를 오픈소스화

출현 배경

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

2.1. 전통적인 배포 시대

초기 앱을 배포시에는 물리서버에서 실행하였다.

한 물리서버에서 앱 리소스 한계를 정의할 방법이 없어 리소스 할당에 문제가 발생함.

2.2. 가상화된 배포 시대

위의 해결책으로 가상화가 도입됨.

단일 물리서버에서 여러 가상시스템을 실행 할 수 있어 서버에서 보다 효율적으로 사용할 수 있다.

각 가상서버는 자체 운영체제를 포함한 모든 구성요소를 실행하는 전체 시스템이다.

2.3. 컨테이너 시대

컨테이너는 가상서버와 유사하지만 격리 속성을 완화하여 하이퍼바이져를 사용하지 않고 앱간에 운영체제를 공유한다.

  • 컨테이너는 효율성이 높다.
    • 운영체제의 자원을 공유하기 때문에 애플리케이션을 실행하는데 필요한 만큼의 자원만 할당받을 수 있다.
  • 컨테이너는 신속성이 높다.
    • 컨테이너의 경우 구조적으로 운영체제가 없기 때문에 용량이 가상 서버에 비해 작아 배포하는데 걸리는 시간이 적다.
  • 클라우드 및 OS 배포판에 관계없이 어디든 배포가 가능하다.

2.4. 쿠버네티스

오케스트레이션 플랫폼 중 하나로 많은 컨테이너들의 관리와 운영을 제공한다.

애플리케이션의 확장과 장애 조치를 처리하고, 배포 패턴 등을 제공한다.

  • 서비스 디스커버리와 로드 밸런싱
    • DNS나 직접 IP로 서비스 노출이 가능하며 k8s를 로드밸런싱하고 배포가 안정적으로 이뤄질 수 있다.
  • 자동화된 롤아웃과 롤백
    • k8s를 사용하여 원하는 상태를 설정할 수 있으며 자동화하여 컨테이너를 삭제 또는 추가할 수 있다.
  • 자동화된 공간 활용
    • 각 컨테이너가 필요로하는 자원을 k8s에 지시하면 각 컨테이너 리소스를 잘 사용 할수 있도록 해준다.
  • 자동화된 복구
    • k8s는 실패한 컨테이너를 재시작시키고 교체하며 응답하지 않는 컨테이너를 죽이기고 서비스 준비를 자동화한다.

3. 아키텍쳐

https://awskrug.github.io/eks-workshop/introduction/architecture/architecture_control_and_data_overview/

3.1. 클러스터

클러스터란 여러대의 컴퓨터를 하나의 묶음으로 취급하는걸 의미하며 쿠버네티스 클러스터는 크게 마스터 노드 워커 노드로 구성된다.

마스터노드는 쿠버네티스의 설정 환경을 저장하고 전체 클러스터를 관리하는 역할을 담당한다.

워커 노드는 컨테이너 애플리케이션이 작동하는 서버로서 Api Server 에 의하여 명령을 받고 실제 워크로드를 생성하여 서비스가 실행된다.

3.2. 마스터 노드

마스터 노드는 전체 클러스터에 관한 전반적인 결정을 수행하고 디플로이먼트의 replicas 필드가 요구조건을 충족되지 않을 경우 새로운 파드를 구동시키는 것과 같은 이벤트를 감지하고 반응한다.

마스터 컴포넌트는 클러스터 내 어떠한 머신에서든지 동작 될 수 있다.

그러나 간결성을 위하여, 구성 스크립트는 보통 동일 머신 상에 모든 마스터 컴포넌트를 구동시키고, 사용자 컨테이너는 해당 머신 상에 동작시키지 않는다.

마스터 노드는 고가용성을 위해서 보통 3대 정도를 실행해서 운영한다.

평소 마스터는 1대이고 나머지 2대는 대기중으로 있다가 리더 마스터에 장애가 발생하면 자연스럽게 나머지 2대중 1대로 리더역할이 넘어가게 된다.

특정 노드의 컨테이너에 명령하거나 로그를 조회할 때도 특정 노드에 직접 명령하는 게 아니라 마스터에 명령을 내리고 마스터가 노드에 접속하여 대신 결과를 응답한다.

보통 마스터 노드는 API Server,  Controller Manager,  Scheduler,  etcd로 구성된다.

3.2.1. API Server

쿠버네티스의 구성요소들은 서로 직접 연결되어 있지않고 API를 통해 통신하는데 그 중심이되는 서버이다.

kubectl의 요청뿐만 아니라 내부 모듈의 요청도 처리하며 권한을 체크하여 요청을 거부할 수도 있다.

API Server는 각 컴포넌트로 부터 정보를 받아서 etcd (key-value 저장소)에 저장하고 상태를 조회하는 작업을 한다.

이외의 각 컴포넌트들은 API Server를 바라보고 있다가 변경사항이 생기면 업데이트하는 구조이다.

3.2.2. ETCD (Key - Value 저장소)

쿠버네티스에서 필요한 모든 정보를 저장하는 Key-Value 저장소이다.

데이터의 안정성을 위해서는 여러개의 장비에 분산해서 etcd를 클러스터링을 구성해서 띄우는게 일반적인 방법이다.

etcd가 안정적이기는 하지만 보다 안정적으로 쿠버네티스를 운영하려면 주기적으로 etcd에 있는 데이터를 백업해 둬야한다.

3.2.3. 스케쥴러 (Scheduler)

위에서 설명한것처럼 API Server는 외부로 부터 요청을 받으면 etcd저장소에 저장할 뿐 실제 상태를 바꾸는 것은 스케쥴러와 컨트롤러이다.

스케쥴러는 노드가 배정되지 않은 새로 생성된 pod를 감지하고 클러스터내 자원할당이 가능한 노드중 알맞은 노드를 선택하여 해당 노드에 pod를 띄우는 역할을 한다.

이때 스케쥴러는 노드를 선택할때 여러가지 조건(필요 자원, 라벨)을 고려하여 할당하며 설정이 가능하다.

3.3. 워커노드

컨테이너가 동작하는 서버로써 마스터와 통신하면서 필요한 pod를 생성하고 네트워크와 볼륨을 설정한다.

워커 노드에는 Kubelet, Kube-proxy 그리고 컨테이너(Docker) 런타임이 배포된다.

Node 를 여러대 구성하여 하나의 클러스터로 구성하며, 여러대로 구성하게 되면 그 개수에 따라 서비스 가용성이 향상 된다. 

3.3.1. 큐블릿 (kubelet)

클러스터의 각 노드에서 실행되는 에이전트 pod내부의 컨테이너가 동작하도록 관리한다.

마스터 API 서버와 동신하면서 노드가 수행해야할 명령을 수행하고 반대로 노드의 상태를 전달하는 역할도 한다.

3.3.2. 큐브 프록시 (kube-proxy)

kube-proxy는 각 워커 노드에서 실행되는 네트워크 프록시이다.

노드로 들어오는 네트워크 트래픽을 적절한 컨테이너로 라우팅시켜 내부 네트워크나 클러스터 바깥에서 pod로 네트워크 통신을 할 수 있도록 해준다.

3.3.3. 컨테이너 런타임(Container Runtime)

컨테이너 런타임은 실제로 컨테이너를 실행시키는 역할을 한다. 가장 많이 알려진 런타임으로는 도커(Docner)가 있고, 그외 rkt, runc같은 런타임도 지원한다.


4. 오브젝트

쿠버네티스에서 가장 기본적인 구성단위인 기본 오브젝트, 기본 오브젝트를 생성, 관리, 추가하는 컨트롤러(Controller), 이러한 오브젝트를 설정하는 스펙으로 나눌 수 있다.

4.1. 오브젝트 스펙 (Object Spec)

오브젝트들은 모두 오브젝트 스펙 (Object Spec)으로 정의가 되고, 커맨드 라인을 통해서 인자로 전달하여 정의를 하거나 또는 yaml이나 json 파일로 스펙을 정의할 수 있다. (주로 yaml을 많이 쓴다.)

4.2. 기본 오브젝트 (Basic Object)

쿠버네티스에 의해서 배포 및 관리되는 가장 기본적인 오브젝트로 컨테이너화 되어 배포되는 애플리케이션의 워크로드를 기술하는 오브젝트로 Pod, Service, Volume, Namespace 4가지로 구분된다.

4.2.1. pod (파드)

  • 쿠버네티스는 하나의 컨테이너를 개별적으로 배포하는 것이 아닌 Pod 단위로 배포하여 하나의 pod안에는 하나 이상의 컨테이너가 포함될 수 있다.
    (보통 하나의 파드에 하나의 컨테이너만 포함한다.)
  • pod내 컨테이너들은 ip, port를 공유한다. (localhost로 port를 다르게하여 통신이 가능하다.)
  • pod가 재시작되면 ip변경 및 디스크 내용이 삭제된다.
  • pod내의 서로다른 컨테이너는 Volume(디스크)를 공유 할 수 있다.

https://bcho.tistory.com/1256?category=731548

4.2.2. 볼륨 (Volume)

  • Pod가 기동할때 컨테이너마다 로컬 디스크를 생성해서 기동되는데, 이 로컬 디스크의 경우에는 영구적이지 않아 pod 재시작시 데이터가 소멸된다.
  • 영구적인 자료를 저장하기 위해서는 PersistentVolume(볼륨)을 사용해야 한다

4.2.3. 서비스 (Service)

pod를 서비스로 제공할때, 일반적인 분산환경에서는 여러개의 Pod를 서비스하면서, 이를 로드밸런서를 이용해서 하나의 IP와 포트로 묶어서 서비스를 제공하는 것이 서비스이다. (내부 LB느낌)

pod의 경우에는 오토스케일링과 같은 동적으로 생성/삭제 및 재시작 되면서 그 IP가 바뀌기 때문에, 로드밸런서에서 Pod의 목록을 지정할 때는 IP주소를 이용하는 것은 어렵다. 

그래서 사용하는 것이 라벨(label)과 라벨 셀렉터(label selector) 라는 개념이다.

서비스를 정의할 때 어떤 pod들을 Service로 묶을 것인지를 정의하는데 이를 Label Selector라고 한다,

각 Pod를 생성할 때 Object Spec의 metadata 부분에 Pod에서 사용할 라벨(Label)을 정의할 수 있다.

Service는 Label Selector(라벨 셀렉터)에서 특정 라벨을 가진 Pod만을 선택하여 Service에 묶는다.

https://bcho.tistory.com/1256?category=731548

4.2.4. 네임스페이스 (Name space)

네임스페이스는 하나의 쿠버네티스 클러스터내 논리적인 분리단위라고 보면 된다.

Pod,Service 등은 네임 스페이스 별로 생성이나 관리가 될 수 있고, 사용자의 권한 역시 이 네임 스페이스 별로 나눠서 부여할 수 있다.

  • 사용자별로 네임스페이스별 접근 권한을 다르게 운영할 수 있다.

  • 네임스페이스별로 리소스 할당량을 지정할 수 있다. 개발계에는 CPU 100, 운영계에는 CPU 400과 GPU 100개 식으로, 사용 가능한 리소스의 수를 지정할 수 있다.

  • 네임 스페이스별로 리소스를 나눠서 관리할 수 있다. (Pod, Service 등)

주의할점은 네임 스페이스는 논리적인 분리 단위이지 물리적이나 기타 장치를 통해서 환경을 분리(Isolation)한것이 아니다. 다른 네임 스페이스간의 pod 라도 통신은 가능하다.

물론 네트워크 정책을 이용하여, 네임 스페이스간의 통신을 막을 수 있지만 높은 수준의 분리 정책을 원하는 경우에는 쿠버네티스 클러스터 자체를 분리하는 것을 권장한다.

4.2.5. 라벨 (Label)

라벨은 쿠버네티스의 리소스를 선택하는데 사용이 된다.

각 리소스는 라벨을 가질 수 있고, 라벨 검색 조건에 따라서 특정 라벨을 가지고 있는 리소스만을 선택할 수 있다.

특정 리소스만 배포하거나 업데이트할 수 있고 또는 라벨로 선택된 리소스만 Service에 연결하거나 특정 라벨로 선택된 리소스에만 네트워크 접근 권한을 부여하는 등의 행위를 할 수 있다.

라벨은 metadata 섹션에 키/값 쌍으로 정의가 가능하며, 하나의 리소스에는 하나의 라벨이 아니라 여러 라벨을 동시에 적용할 수 있다.


5. 컨트롤러 (Controller)

기본 오브젝트로 애플리케이션을 설정하고 배포하는 것이 가능한데 이를 편리하게 관리하기 위해서 컨트롤러라는 개념을 사용한다.

컨트롤러는 기본 오브젝트들을 생성하고 이를 관리하는 역할을 해준다.

컨트롤러는 Replication Controller (aka RC), Replication Set, DaemonSet, Job, StatefulSet, Deployment 들이 있다.

5.1. Replication Controller (이하 RC)

Pod를 관리해주는 역할을 하는데, 지정된 숫자로 Pod를 기동 시키고, 관리하는 역할을 한다.

RC는 크게 세가지로 구성된다.

  • Selector : selector 라벨을 기반으로 하여,  RC가 관리할 Pod를 지정하는데 사용한다.

  • Replica 수 :  RC에 의해서 관리되는 Pod의 수인데, 그 숫자만큼 Pod 의 수를 유지하도록 한다.

  • template: Pod를 생성할 때 어떻게 Pod를 만들지 Pod에 대한 정보가 필요한데 이를 template 부분에 정의 한다.

5.2. Deployment

Deployment (이하 디플로이먼트) Replication controller와 Replica Set의 좀더 상위 추상화 개념이다.

실제 운영에서는 ReplicaSet 이나 Replication Controller를 바로 사용하는 것보다, 좀 더 추상화된 Deployment를 사용하게 된다.

더 자세한 내용은 아래에서 참고한다.

https://arisu1000.tistory.com/27833
https://bcho.tistory.com/1256?category=731548

5.3. 나머지

5.3.1. DaemonSet

DaemonSet (이하 DS) 은 Pod가 각각의 노드에서 하나씩만 돌게 하는 형태로 Pod를 관리하는 컨트롤러이다.

서버의 모니터링이나 로그 수집 용도로 많이 사용된다.

https://bcho.tistory.com/1257?category=731548

5.3.2. Job

워크로드 모델중에서 배치나 한번 실행되고 끝나는 형태의 작업시 사용한다.

Job에 의해서 관리되는 Pod는 Job이 종료되면, Pod 를 같이 종료한다.

5.3.3. Cron jobs

주기적으로 정해진 스케쥴에 따라 Job 컨트롤러에 의해 작업을 실행해주는 컨트롤러로 cron jobs 컨트롤러를 사용한다.


6. Ingress

쿠버네티스의 Ingress는 외부에서 쿠버네티스 클러스터 내부로 들어오는 네트워크 요청을 어떻게 처리할지 정의한다.

외부에서 쿠버네티스에서 실행 중인 Deployment와 Service에 접근하기 위한, 일종의 관문 (Gateway) 같은 역할을 담당한다.

외부로부터 들어오는 요청에 대한 로드 밸런싱, TLS/SSL 인증서 처리, 특정 HTTP 경로의 라우팅 등을 Ingress를 통해 자세하게 정의할 수 있다. 

이러한 기능들은 위에서 언급한 NodePort 등의 방법으로도 절대로 불가능한 것은 아니지만, 이러한 세부적인 로직을 모든 애플리케이션 개발 레벨에서 각각 구현하게 되면 서비스 운영 측면에서 추가적인 복잡성이 발생한다.
그 대신에, 외부 요청을 어떻게 처리할 것인지를 정의하는 집합인 Ingress를 정의한 뒤, 이를 Ingress Controller라고 부르는 특별한 웹 서버에 적용함으로써 추상화된 단계에서 서비스 처리 로직을 정의할 수 있다. 

Ingress는 yaml파일로 설정할 수 있으며 Ingress Controller를 설치하여 yaml의 규칙에 의해 외부 요청을 어떻게 처리할지 결정 할 수 있다.

https://blog.naver.com/PostView.nhn?blogId=alice_k106&logNo=221502890249


출처

https://bcho.tistory.com/1255?category=731548 (조대협의 블로그, 정리가 굉장히 잘되어있음.)

https://galid1.tistory.com/413 (배움이 즐거운 개발자)

https://kubernetes.io/ko/docs/concepts/ (k8s 공식 페이지)

https://arisu1000.tistory.com/27833 (아리수, 여기도 잘되있음)

https://subicura.com/2019/05/19/kubernetes-basic-1.html

댓글