Kubernetes

호호빵·2024년 9월 30일

Kubernetes

용어

  • manifest : deployment.yaml, service.yaml 등의 파일들의 통칭
  • helm : deployment.yaml, service.yaml 등을 하나로 묶어 관리하는 '패키지 매니저'
  • kubectl : K8s 관리소에 명령(Manifest 전달)을 내리는 핵심 도구
    - Master에서만 사용 가능하고, k8s에서 관리하는 자원을 생성, 가져오기 및 삭제하는 작업 수행
  • Cluster : 가장 기본적인 단위, 여러 개의 node로 구성되며 마스터 노드(Control Plane)와 워커 노드(Worker Node)로 나뉨
  • Namespaces : 동일한 물리 클러스터를 기반으로 하는 여러 가상 클러스터를 지원하며, 이런 가상 클러스터를 말함. 논리적인 분리 단위이며, Namespace 별로 클러스터 내에서 논리적으로 리소스를 분리하게 함
    -> 리소스 중 object는 namespaces, service, volume, pod
  • Controller : k8s는 다양한 컨트롤러를 통해 애플리케이션을 자동으로 배포/관리하고 문제 발생 시 복구할 수 있도록 지원
  • Ingress : 클러스터 외부에서 내부 서비스(Pod)로 접근할 수 있도록 트래픽을 제어하는 역할
  • Node : k8s 클러스터를 구성하는 실제 컴퓨터(ec2 등)를 의미
  • Pod : k8s에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위 (컨테이너의 그룹)
    -> 스토리지 및 네트워크를 공유하고, 해당 컨테이너를 구동하는 방식에 대한 명세 또는 정의를 갖게 됨


Cluster

  • cluster = master 노드 + worker 노드
  • master 노드(control plane)
    • k8s 클러스터의 모든 상태를 저장 및 관리
    • 직접 앱을 올리는 곳이 아니라 지시를 내리는 곳
    • component : API server, Etcd, Scheduler, Controller Manager
    • API server : 클러스터의 모든 요청과 응답을 처리하는 중앙통로, REST API를 제공하며 kubectl 명령이나 worker 노드의 보고를 가장 먼저 받음
    • Etcd(상태 저장소) : 클러스터의 모든 상태 정보가 저장되는 중요한 key-value 데이터베이스(pod가 몇 개인지 등)
    • Scheduler(배치 관리자) : 새로 생성된 Pod를 어떤 Worker Node에 배치할지 결정합니다.
    • Controller-Manager(상태 유지) : 현재 상태와 원하는 상태를 끊임없이 비교하며 상태를 일치시킵니다. (예: 파드가 죽으면 새로 생성)
  • worker 노드
    • 마스터 노드의 지시를 받아 컨테이너(Pod)를 실제로 실행하고 유지
    • component : kublet, pod
    • kublet : Kubernetes 노드에서 실행되는 에이전트로, 클러스터의 마스터와 노드 간의 중요한 다리 역할, 지시를 받아 컨테이너 런타임에 전달
    • kube-porxy : 노드 수준애서 Service 네트워크 규칙을 관리하고 트래픽을 전달
    • Container Runtime(엔진) : Docker나 Containerd 같이 실제 컨테이너를 실행하는 소프트웨어
  • kubectl ➔ Master(API server) ➔ Worker(kubelet) ➔ Worker(docker)가 Container 생성
  • Deployment라는 컨트롤러가 ReplicaSet을 만들고, 이 ReplicaSet이 Pod의 개수를 유지
  • Service가 가진 고정 IP를 호출하면, Service가 알아서 현재 살아있는 Pod들 중 하나로 트래픽을 전달해줌


  • 같은 내용을 담은 이미지
  • namespace로 논리적으로 리소스를 구분하고 master, worker로 이루어져있으며 각각의 노드에는 필요한 component들이 있고 Api server, kublet로 통신
  • 개발자가 kubectl로 명령을 내림 -> 마스터의 API Server가 접수 -> 오른쪽 master의 네트워크망을 타고 각 Subnet에 있는 EC2의 Kubelet에게 지시를 내려 Pod를 띄우게 됩니다.


Controller

업로드중..

  • k8s는 다양한 컨트롤러를 통해 애플리케이션을 자동으로 배포/관리하고 문제 발생 시 복구할 수 있도록 지원

Deployment : 지정된 수의 Pod를 항상 유지하며, 애플리케이션을 점진적으로 업데이트하거나 문제가 생겼을 때 이전 버전으로 롤백할 수 있도록 도움
StatefulSet : 각 Pod에 고유한 네트워크 ID와 영구 저장소가 필요한 상태 기반 애플리케이션을 안정적으로 운영할 수 있게 함
DaemonSet
Job & CronJob

Service

  • 동일한 서비스를 제공하는 여러 개의 Pod에 접근할 수 있는 하나의 IP를 제공하는 네트워크 노출을 위한 특정 리소스(객체) (Pod에 연결시켜주는 Network)
    • Service의 IP로 접속할 때 Pod으로 연결시켜주는 원리는 Service는 자신이 가지고 있는 Selector 값과 Cluster에서 운영중인 Pod의 Label 값이 동일한 Pod으로 연결시켜줌
  • Controller를 사용하여 Pod를 실행하고 관리하지만, 실행된 Pod에 접근할 때는 Service를 이용
  • Pod는 기본적으로 한 Node에서만 실행되지 않고 상황에 따라 Cluster 내에 속한 여러 Node로 옮겨 다님
    -> 그러므로 Pod의 IP로 접속하는데는 한계가 있고 동일한 서비스의 대표 IP인 Service의 IP로 접근하는 것이 편리함
  • 종류 : ClusterIP, NodePort, LoadBalancer, ExternalName

ClusterIP

  • Default Service로서 Pod 그룹의 단일 진입점(Virtual IP) 생성

NodePort

  • ClusterIP가 동시에 만들어진다
  • Cluster내의 아무 Worker Node의 IP에 대한 Port 번호로 접속하도록 함(기본적으로 30,000 ~ 32,767까지 포트 번호가 동적으로 할당됨)

LoadBalancer

  • Layer 2 ~ Layer 4를 지원하는 부하조정 장비
  • Public Cloud 업체 및 OpenStack에서 이용 가능(OnPremises Cluster에서는 metallb 사용 가능)
  • load Balancer를 만들면 ClusterIP와 NodePort가 동시에 만들어짐
    (외부에서 접속 시 Load Balancer ➔ NodePort ➔ ClusterIP로 거쳐서 결국 Pod에 접속하게 됨)

ExternalName

  • Cluster 안에서 외부에 접속시 사용할 도메인을 등록해서 사용
  • Cluster domain이 실제 외부 도메인으로 치환되어 동작

pod 접속

  • 클러스터 내에서 Pod 접속 → Cluster IP
  • 클러스터 밖에서 Pod 접속 → Node Port
  • 클러스터 밖에서 Pod 접속 → Load Balancer
    -> 최종적으로 밖에서 Pod에 접속 할 때 Load Balancer → Node Port→ Cluster IP로 접속

정리

1. 컨트롤러(Controller)를 통한 Pod 관리 방식
- 명령 전달: 개발자가 kubectl을 통해 YAML 파일(선언적 명세)을 API Server에 전달합니다.
- 상태 기록: API Server는 이 명세를 etcd에 기록합니다.
- 컨트롤러 작동: Controller Manager는 etcd에 기록된 '원하는 상태(예: Pod 3개)'와 '현재 상태'를 지속적으로 비교합니다.
- 스케줄링: 개수가 부족하면 Scheduler가 어느 워커 노드에 Pod를 띄울지 결정합니다.
- 실행 지시: API Server가 해당 노드의 kubelet에게 Pod 생성을 요청합니다.
- 현지 관리: kubelet은 컨테이너 런타임(Docker 등)을 호출해 컨테이너를 실행하고, 그 상태를 다시 API Server에 보고합니다.

2. 서비스(Service)를 통한 Pod 접근 방식
- 객체 생성: 사용자가 Service 리소스를 생성하면 고정된 ClusterIP가 할당됩니다.
- 엔드포인트(Endpoint) 관리: Service는 레이블 셀렉터(Label Selector)를 사용하여 대응하는 Pod들의 IP 목록을 자동으로 관리합니다.
- kube-proxy의 역할: 모든 워커 노드에는 kube-proxy라는 네트워크 관리자가 상주합니다.
- 트래픽 라우팅: 사용자가 Service IP로 접속하면, 각 노드의 kube-proxy가 설정한 네트워크 규칙(iptables/IPVS)에 따라 실제 살아있는 Pod 중 하나로 트래픽을 전달(Load Balancing)합니다.
- 추상화: 사용자는 Pod가 삭제되고 새로 생성되어 IP가 바뀌어도, 고정된 Service IP만 바라보면 되므로 통신이 단절되지 않습니다.



배포 과정

  1. Containerize (Dockerize): 내 Spring Boot 프로젝트를 Docker 이미지로 만듦 (JAR 파일을 포함한 실행 파일)
  2. Image Push: 빌드한 이미지를 이미지 저장소(Docker Hub, AWS ECR, Azure ACR)에 업로드
  3. Manifest 작성 (YAML): "어떤 이미지를 사용할지", "파드를 몇 개 띄울지" 등을 담은 설정 파일(YAML)을 작성
  4. Deployment 실행: kubectl apply -f deployment.yaml 명령어로 K8s에게 배포를 명령
  5. Scheduling: K8s가 클러스터 내의 여러 노드 중 여유가 있는 노드에 Pod를 생성
  6. Expose (Service): 외부 사용자가 접속할 수 있도록 Service와 Ingress(Gateway 역할)를 설정


테스트



reference

profile
하루에 한 개념씩

0개의 댓글