위 그림을 보고 쿠버네티스를 한 번에 이해하기 어렵다.....
개념부터 잡고 이해하자..!
쿠버네티스에서 실행되는 최소 단위이다. 독립적인 공간과 IP를 가진다.
- 쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위이다. 이는 쿠버네티스 애플리케이션의 최소 단위, 즉, 웹 서비스를 구동하는 데 필요한 최소 단위이다. 하나 이상의 컨테이너를 감싸고 있는데, 쿠버네티스의 가장 작은 배포 단위이다.
- 같은 Pod 안에 있는 컨테이너들은 아래 2가지를 공유한다.
- 네트워크: Pod 내 모든 컨테이너는 동일한 IP 주소와 네트워크 네임스페이스를 공유합니다.
- 스토리지: Pod 내 컨테이너는 볼륨(Volume)을 공유할 수 있습니다.
- Pod는 클러스터 내에서 단일 IP 주소를 가지고, 외부에서 접근 시에는 Pod IP를 사용한다. Pod는 생성될 때 유동적으로 IP를 부여받고, 장애가 발생했을 때 다시 생성되는데, 이 때도 유동적으로 IP를 붙여받게 된다.
- Pod 자체를 직접 관리하기 보다는 상위 객체인 Depolyment 같은 애들이 Pod의 생애 주기를 관리한다.
- 대부분 1개 Container를 1개 Pod로 감싸서 사용하지만, 여러 개 컨테이너를 1개의 파드로 감싸는 경우가 있다. 예를 들어서 메인 애플리케이션 컨테이너 + 로깅 컨테이너를 같이 감싸는 경우이다. --> "사이드카 패턴"
처음에는 Pod를 Container라고 이해해도 괜찮다.
위 사진은 Nginx Pod 실행한 모습이다. Port 30730으로 할당됐는데, 이게 매번 Pod를 실행할 때마다 바뀐다.
쿠버네티스 클러스터에서 사용되는 리소소들을 논리적으로 분리하기 위한 가상의 클러스터이다.
- pod와 service 등은 네임스페이스별로 생성 및 관리될 수 있으며, 네임스페이스별로 사용자 접근 권한을 다르게 설정할 수도 있다. 그룹을 나누기 위해 도입되었으며, 각 네임스페이스는 서로 독립적이다. 예를 들어서, 네임스페이스에 dev, prod 가 둘 다 있다면, dev/pod1 과 prod/pod1은 충돌하지 않는다. 이처럼 다른 네임스페이스끼리는 동일한 이름의 pod를 생성할 수 있다.
- 네임스페이스 기반으로 접근 제어(Role-Based Access Control)를 설정할 수 있다. 이 때 역할 기반 접근 제어를 제공하는데, 역할별로 특정 네임스페이스에만 접근 권한을 부여할 수 있다.
- 네임스페이스별로 리소스를 부여할 수 있다. 이를 ‘리소스 쿼터’라고 부른다.
- 기본적으로 쿠버네티스는 몇 가지 기본 네임스페이스를 제공한다.
- default: 모든 리소스가 별도로 지정하지 않을 경우 생성되는 기본 네임스페이스.
- kube-system: 쿠버네티스의 시스템 구성 요소(Pod, Service 등)가 실행되는 네임스페이스.
- kube-public: 모든 사용자가 읽을 수 있는 공개 리소스가 저장되는 네임스페이스.
- kube-node-lease: 노드의 상태 정보를 관리하는 데 사용.
쿠버네티스에서 파드(Pod) 내의 컨테이너들이 데이터를 저장하고 공유할 수 있는 디렉터리를 제공한다.
- Pod는 일시적인 특성을 가진다. 따라서 Pod 내 디렉터리는 ‘임시 저장소’ 취급한다. Pod가 생성되고, 삭제되면 Pod 내 데이터는 사라진다. 이 문제를 해결하기 위해 Volume을 사용하여 데이터의 지속성을 제공한다. 외부 저장소와 연결한다면 Pod가 사라지더라도 데이터를 계속 유지할 수 있다.
- 또한 Pod 내 여러 컨테이너가 있다면, 공유 스토리지 형태로 Volume을 사용하여 데이터를 공유한다.
- Volume 종류
- EmptyDir
- Pod 내 컨테이너끼리 공유, Pod 삭제 시 같이 삭제
- HostPath
- 노드 수준에서 관리
- PersistentVolume (PV) & PersistentVolumeClaim (PVC)
- 클러스터 수준에서 관리
- Volume 설정 시 주의할 점은 해당 볼륨의 목적이다. 중요한 정보라서 데이터를 유지할 생각이라면 클라우드 기반 스토리지에 연결하여 PV방식을 사용하거나, 아니라면 EmptyDir 방식을 사용하면 된다.
Pod의 집합에 대한 네트워크 추상화 객체이다.
- Pod는 일시적이어서 IP 주소가 동적으로 변경되기 때문에, 특정 Pod에 고정적으로 접근하기 어렵다. Service는 Pod의 집합을 묶어서 고정된 네트워크 엔드포인트를 제공하여 이 문제를 해결한다. 예를 들어 Dcoekr-compose로 container를 띄울 때 port를 지정해줄 수 있는데, 이와 비슷하다.
- 로드밸런싱 기능을 제공한다. 트래픽이 몰리면 pod를 여러 개로 늘릴 수 있는데, 이 때 service에서 이를 제공한다.
- service 주요 개념
- Label Selector
- service는 label 기반으로 Pod를 식별한다.
- nginx 라벨을 가진 모든 pod를 대상으로 식별한다.
- ClusterIP:
- 서비스의 default 유형으로, 클러스터 내부에서만 접근 가능합니다.
- service 종류
- ClusterIP (default)
- 클러스터 내부에서만 Pod에 접근 가능하도록 설정
- NodePort
- 클러스터 외부에서 Node의 IP와 특정 포트를 통해 Pod에 접근 가능.
- 기본적으로 30000~32767 범위의 포트가 할당됩니다. http://:30001 외부 접근 가능
- LoadBalancer
- 클라우드 환경(AWS, Azure…)에서 외부 로드 밸런서를 자동으로 생성하여 서비스에 연결.
- 클러스터 외부에서 서비스에 쉽게 접근 가능.
- 클러스터 내부 Pod로 분할하는 것은 service에서 자동 제공, 이 유형은 클라우드 제공자가 해주는 로드밸런싱을 의미함.
- ExternalName
- 클러스터 외부의 DNS 이름을 참조하는 서비스.
- 트래픽을 외부 리소스로 리디렉션.
애플리케이션 워크로드를 실행하기 위한 물리적 또는 가상 머신이다.
- 노드는 클러스터에서 실행 가능한 리소스(cpu, memory….)를 제공한다. 또한 컨트롤 플레인에 자신의 상태와 리소스를 보고한다.
- Kubernetes 노드 구성 요소
- Kubelet
- 쿠버네티스 에이전트로, Pod를 실행하고 상태를 관리한다.
- 컨트롤 플레인의 명령을 받고 실행 결과를 보고한다.
- Kube Proxy
- 네트워크 프록시로, Pod 간의 네트워크 통신을 관리한다.
- 컨테이너 런타임
- 컨테이너를 실행하는 소프트웨어로, Docker, containerd, CRI-O 등을 지원한다.
- 노드 위에서 Pod가 실행된다. 노드가 없다면 Pod는 실행할 수 없다. 쿠버네티스는 각 노드의 사용 가능한 리소스를 바탕으로 Pod를 스케줄링한다. 우리는 각 노드의 memory, cpu 등등을 제한할 수 있다.
- 노드 종류
- 마스터 노드 (Control Plane Node)
- 클러스터의 관리 및 제어를 담당하는 노드.
- API 서버: 쿠버네티스 클러스터의 진입점으로, 모든 요청을 처리합니다.
- 컨트롤러 매니저: 클러스터 상태를 관리합니다.
- 스케줄러: Pod를 적절한 워커 노드에 배치합니다.
- ETCD: 클러스터 상태를 저장하는 분산 키-값 저장소.
- 컨트롤 플레인 ≠ 컨트롤 플레인 노드
- 컨트롤 플레인은 위에서 말한 API 서버, 컨트롤러 매니저, 스케줄러, ECTD를 관리하는 집합을 말하는 것이고, 이게 실행되는 곳이 컨트롤 플레인 노드인 마스터 노드이다.
- 워커 노드 (Worker Node)
- 실제로 애플리케이션(Pod)을 실행하는 노드.
- Pod는 워커 노드에서 컨트롤 플레인 노드의 명령에 따라 실행하고, 관리한다.
- 주요 컴포넌트
- Kubelet: pod와 container 관리
- Kube Proxy: proxy 수행
- 컨테이너 런타임: docker를 쓰는 게 일반적이지만 다른 것도 가능.
쿠버네티스에서 애플리케이션 배포 및 관리를 위한 고수준 추상화 객체이다.
- 쿠버네티스 컨트롤러 유형 중 하나이다. 컨트롤러는 파드의 설정과 배포를 조금 더 편리하게 관리하기 위해 사용하는 개념이다. 컨트롤러 종류에는 Replication Controller(RC), Replica Set, DaemonSet, Job, StatefulSet, Deployment가 있다. 이 중 Deployment가 일반적이고, 각 컨트롤러마다 목적이 다 다르다.
- Replication Controller(RC)
- 초기부터 있던 가장 기본적인 컨트롤러
- Pod Selector : 라벨 기반, Pod를 가져오는 데 사용
- Replica 수 : 관리되는 파드의 수인데, 그 숫자만큼 파드의 수를 유지
- Pod Template : 파드를 새로 만들 때 어떤 파드를 만들지에 대한 정보가 필요한데 (도커 이미지, 포트, 라벨 등) 이에 대한 정보를 정의한 템플릿
- Replica Set
- Replication Controller 상위 버전
- 같은 동작을 하지만, 사용할 수 있는 연산자가 몇 개 추가되었다.
- Deployment
- Replication Controller, Replica Set를 좀 더 추상화한 개념.
- 실제 많이 사용
- pod 갯수 유지 + 롤링 업데이트, 롤백 가능
- DaemonSet
- 특정 노드에만 Pod가 1개씩 지정되도록 설정이 가능
- Job
- 실행되고, 유지할 필요 없는 배치 작업 같은 애들에 적합. 실행 후 종료까지 보장
- Stateful Set
- 기존에는 모두 상태가 없는 파드를 관리하는 용도였다. 상태가 없다는 건 컨테이너나 노드에 문제가 생겼을 때 다른 노드로 옮길 수 있다는 의미인데, 이건 컨테이너의 장점이자 단점이 된다.
- DB 컨테이너 같은 경우 에러가 발생해도 데이터를 지울 수 없다. 따라서 컨테이너를 삭제하고 다른 노드로 옮기면 안된다. 그래서 볼륨을 이용해 컨테이너를 삭제하더라도 볼륨에 데이터를 저장하여 컨테이너를 재시작해도 데이터를 유지할 수 있다.
- Pod 생성 및 관리한다. 이 때 직접 생성하는 것이 아니라 ReplicaSet을 통해 Pod를 통해 관리한다. Deployment는 ReplicaSet 관리 및 생성하고, 이를 통해 Replica를 유지한다.
- 애플리케이션 업데이트 및 복구, 롤백이 가능하다. 서비스가 중지되는 시간 없이 롤링 업데이트가 가능하며, 삭제되는 경우 자동으로 새 Pod 생성한다. 롤백도 이와 같다.
- Deployment → ReplicaSet → Pod 구조를 유지한다. Replica 갯수를 지정하면 Deployment는 Pod를 해당 갯수만큼 유지한다.
- 만약 Pod를 생성했는데, 에러가 계속 발생하면 어떻게 될까
- CrashLoopBackOff 상태
- Pod가 반복적으로 시작되었다가 실패하는 상태
- ReplicaSet은 Pod 갯수를 유지하기 위해 계속 새로운 Pod를 생성한다. 하지만 에러가 발생하여 Pod가 계속 다운되게 되면, 이는 클러스터 리소스 낭비로 이어진다.
- 이를 방지하기 위해 노드의 리소스를 지정해놓으면 Pod가 특정 수치만큼 리소스를 쓰지 못한다.
- 개별 컨테이너를 실행해보거나 로그 분석을 통해 해결할 수 있다.