쿠버네티스 아키텍처

Monday·2024년 6월 6일
post-thumbnail

Desired State

현재 상태가 원하는 상태인지 체크하고 그렇지 않다면 원하는 상태가 되기 위한 조치를 취한다.

컨테이너가 n개 동작하고 있어야 하는데 n-1 개가 동작하고 있다면
1개를 더 동작시키는 것이다.

이러한 동작을 계속 반복하며 원하는 상태를 유지한다.

아키텍처

Master

Desired State를 체크하는 것 처럼, 어떠한 것을 체크하고 실행하는 영역

Controller

어떠한 리소스가 Desired State인지 체크하고 유지

논리적으로 다양한 컨트롤러가 존재

  • Replication Controller, Endpoint Controller, Namespace Controller 등 여러 종류가 있고 Custom Controller도 만들 수 있다.

복잡성을 낮추기 위해 하나의 프로세스로 실행

Etcd

모든 상태와 데이터를 저장하는 스토리지

분산 시스템으로 구성하여 안정성과 고가용성 확보

  • 현재 상태가 어떤지, 어떤 상태를 원하는지 정보들이 다 담겨있기에
    정보가 손실되면 안된다
  • 여러대가 떠있어서 하나가 죽어도 계속 동작 가능함

가볍고 빠르며 정확하게 설계

  • 저장된 정보를 바탕으로 해당 상태로 유지할려고 할 것이므로
    정확한 정보가 저장되어야 한다

Key-Value 형태로 데이터 저장

TTL, Watch 같은 부가 기능 제공

중요한 데이터이므로 백업은 필수

API Server

상태를 바꾸거나 조회를 하는 역할

Etcd와 유일하게 통신하는 모듈

  • 다른 컴포넌트가 Etcd에 있는 정보를 원하면
    API Server를 통해 접근해야 한다

REST API 형태로 제공

권한을 체크하여 권한이 있는 영역의 정보만 제공

관리자 요청 뿐만 아니라 다양한 내부 모듈과 통신

수많은 요청을 받기에 수평 확장 가능하도록 디자인

Scheduler

새로 생성된 Pod을 감지하고 어떤 노드에 실행할지 선택

노드의 현재 상태와 Pod의 요구사항을 체크

  • 노드에 라벨을 부여하고
    특정 라벨이 있는 노드에 Pod을 띄우도록 요청 가능

Node

실제로 컨테이너가 실행되는 영역

Kubelet

pod랑 직접 통신

각 노드에 다 떠있어야 함

  • Pod을 실행, 중지, 상태체크 하기 때문

CRI (Container Runtime Interface)

  • 컨테이너를 직접 쓰지 않고 Pod이라는걸로 감싸서 컨테이너를 사용할 수 있게함

Proxy

네트워크 프록시와 부하 분산 역할

성능상의 이유로 별도의 프록시 애플리케이션을 띄우지는 않고
커널 레벨에서 iptables, ipvs 방식 사용 (설정만 관리)

그 외

CNI (네트워크)
DNS (도메인, 서비스 디스커버리)
대시보드 (시각화)


오브젝트

Pod

가장 작은 배포 단위

컨테이너를 배포하는게 아니라 Pod을 배포한다

전체 클러스터에서 고유한 IP를 할당받아 내부적으로 통신 가능

여러개의 컨테이너가 하나의 Pod에 속할 수 있음

  • 같은 Pod에 속한 컨테이너들은 localhost 공유 가능

ReplicaSet

여러개의 Pod을 관리

Template을 참고하여 새로운 Pod을 생성한다.

신규 Pod을 생성하거나 기존 Pod을 제거하여 원하는 수 (Replicas)를 유지

Deployment

배포 버전을 관리

ReplicaSet을 활용하여 버전 관리를 한다

배포 버전을 올릴려는 경우 (v1 -> v2)

  • 순간적으로 ReplicaSet을 2개로 만든다.
    (Pod 3개가 있던 ReplicaSet를 Pod 2개짜리, Pod 1개짜리로 나눈다)
  • ReplicaSet 하나는 v1 으로 두고, 나머지 ReplicaSet은 v2로 만든다.
  • v2인 ReplicaSet의 replicas를 3으로 만들고 v1인 ReplicaSet의 replicas를 0으로 만든다

Service - Cluster IP

클러스터 내부에서 사용하는 프록시

Pod을 로드밸런싱 하는 별도의 서비스다

  • Cluster IP로 요청을 보내면 연결된 Pod중 하나로 요청이 간다

이러한 방식으로 되어있는 이유

  • Pod은 언제든지 생겼다 사라졌다 하기때문에 ip가 계속 바뀐다
  • Cluster IP는 고정되어 있고 여기로만 요청을 보낸다면 Pod은 계속 ip가 바뀌어도 상관이 없다

클러스터 내부에서 서비스 연결은 DNS를 이용

Service - NodePort

노드에 노출되어 외부에서 접근 가능한 서비스

Cluster IP는 내부에서만 통신 가능하지만, NodePort는 외부에서 접근 가능

Web browser -> Node Port -> Cluseter IP -> Pod 로 요청이 전달되는 형식

Service - LoadBalancer

하나의 IP 주소를 외부에 노출

연결된 Node가 갑자기 죽을 수 있다. 이렇게 되면 순간적으로 접속이 안 될 것이다.

이러한 것을 방지하기 위해 앞에 LoadBalancer를 둔다

Web browser -> LoadBalancer -> Node Port -> Cluseter IP -> Pod 로 요청이 전달되는 형식

Ingress

도메인 또는 Path에 따라서 내부에 있는 Cluster IP에 연결

기존에 있는 Nginx, HAProxy, ALB 같은걸 k8s에 맞게 포장해서 사용

그외 기본 오브젝트

Volume - Storage(EBS, NFS ...)
NameSpace - 논리적인 리소스
ConfigMap/Secret - 설정
ServiceAccount - 권한 계정
Role/ClusterRole - 권한 설정 (get, list, watch, create ...)
....

일반적인 구성

Pod을 띄우는 경우는 잘 없음, Deployment를 생성하면 Deployment가 ReplicaSet을 자동으로 생성, ReplicaSet이 Pod을 자동으로 생성

이것들을 외부에 노출하기 위한 Service(Cluster IP) 생성하고 이것을 Ingress 와 붙인다.
Ingress를 붙이면 LoadBalancer 와 NodePort가 자동으로 따라온다.

API 호출

원하는 상태(Desired State)를 다양한 오브젝트(Object)로 정의(Spec)하고 API 서버에 yaml형식으로 전달


참조

초보를 위한 쿠버네티스 안내서

profile
차근차근 꾸준히

0개의 댓글