[Kubernetes] Kubernetes의 구조 - Master/Worker, 기본 오브젝트
쿠버네티스는 매번 할때마다 새롭기때문에, 간단하게라도 정리해두고자 함.
매우 간단하게 정리할 예정임!
Kubernetest의 구조
- 크게 Master node와 Worker node로 구성되어있음
Master
- API 서버 : KUBE의 기능을 API 형태로 제공하는 서버
- etcd : Key-Value 구조의 DB로, 설정값, 클러스터의 정보 등을 저장하는 DB
- Scheduler : Pod, 서비스 등을 워커노드에 적절하게 할당하는 역할을 담당
- Controller Manager : Replica, Service, Volume, Node Controller 등 다양한 컨트롤러를 생성하고 관리하는 역할
- DNS : KUBE는 리소스의 endpoint를 DNS로 관리함. 각 리소스의 IP는 동적으로 배정되므로 이를 위한 DNS가 필요함.
--> Service Discovery 패턴!!
Worker
- kubelet : 각 노드에 배포되는 에이전트로, 노드가 할 일을 받고 결과 및 상태를 마스터에 전송.
: Pod의 lifecycle을 관리하는 주체.
- kube-proxy : 노드로 들어오는 트래픽을 라우팅하여 컨테이너에게 전송
- cAdvisor : 모니터링 에이전트로, 컨테이너의 상태를 수집해서 마스터에 전송
- Container Runtime : Pod를 통해 배포된 컨테이너들을 실제로 실행하는 역할.
Kubernetes의 Object?
- KUBE는 크게 기본 오브젝트와 컨트롤러라는 두 종류의 오브젝트로 구성된다.
- 기본 오브젝트는 각종 리소스들(Pod, NameSpace, Volume, Service, Ingress 등)을 일컬으며, 컨트롤러는 이러한 기본 오브젝트를 생성하고 관리한다!
: 기본 오브젝트 - Pod, Namespace, Volume, Service
: 컨트롤러 - Replication Controller(ReplicaSet), Deployment, StatefulSet, DaemonSet, Job Controller
우선은 기본 오브젝트에 대해 설명하고 넘어가자.
1) Pod - Kubernetes의 가장 작은 배포 단위
- 여러개의 Container로 구성될 수 있음
- Pod 내의 컨테이너들은 IP와 port 정보를 공유함. 즉 Pod 내의 컨테이너끼리는 자유로이 통신이 가능함.
- Pod 내의 컨테이너끼리는 단일 volume을 공유할 수 있음. 즉, 데이터의 공유가 가능함.
2) Service
- Kubernetes의 Pod에 대한 네임서비스로, L4 레이어에서 로드밸런싱과 포워딩을 담당함.
(그럼 이 Service를 라우팅해주는건??? Ingress)
- Pod들은 생성될 때마다 IP가 새로이 부여되므로, 고정된 IP로 호출하는 것이 어렵다.
- 서비스는 이러한 Pod들을 Label Selector를 이용해서 묶음으로 관리함.
- 이러한 상황에서 네임서비스의 역할을 해주는 것.
- 이 서비스는 타입이 가장 중요한데, 크게 ClusterIP, NodePort, LoadBalancer, ExternalName이 있음
: ClusterIP - 디폴트값이며, 해당 서비스에 내부 IP를 할당하게 됨. 즉, 클러스터 외부에서는 접근이 불가능함!
: NodePort - 해당 노드의 IP를 통해 접근이 가능하도록 Node의 IP와 port를 사용함!
: LoadBalancer - 고정 IP를 지닌 로드밸런서를 할당함. 외부 IP를 지니게 됨!
: ExternalName - 클러스터 내부에서 "외부의 서비스"를 호출하고자 할 때 사용함. 예로, AAA라는 서비스로 들어온 요청을 externalname:nairns.tistory.com으로 보내는 식으로 사용이 가능함
- 마지막으로 Headless service라는 것이 있음
: 서비스는 기본적으로 "엔드포인트 관리"를 목적으로 두고 있음.
: 이로 인해, 일반적인 서비스는 clusterIP와 domain name을 기본적으로 할당받게 됨
: 그러나 이 headless service는 IP 없이 domain name만 가지게 됨.
- 이 headless service는 DNS 조회를 할 시에 서비스의 IP가 아닌, 연결된 Pod의 IP를 리턴함!!!!!
- 이러한 점을 이용하여 lstio라는 다른 서비스 디스커버리 방식을 사용하거나, 특정 Pod들을 servicename.namespace.svc.cluster.local과 같은 DNS이름으로 접근하는데 사용할 수 있음!
3) Ingress
- URL 기반의 라우팅이 가능한 L7 로드밸런서로, service를 라우팅해주는 친구.
- 반드시 Ingress controller가 필요함에 주의!!!
- Ingress를 사용하고자 할 때, 만약 사용하는 ingress 리소스가 GKE(Google Cloud의 로드밸런서)라면 반드시 서비스는 NodePort로 구성되어야 함
: WHY?? - '구글 클라우드 로드밸런서'는 서비스의 heartbeat체크를 NodePort 기반으로 동작하기 때문.
- 다른 리소스를 사용하면 아니어도 됨!
- Ingress는 TLS 설정도 가능함! SSL 인증서를 생성하고 kube의 secret에 private key와 crt 파일을 등록.
- 이후, ingress를 생성할 때 spec부분에 해당 secret을 전달(spec.tls 에다가 전달)
4) Volume
- Pod에 종속되는 disk로, Pod 내의 컨테이너간 공유가 가능함.
- 컨테이너는 주로 마운트 방식으로 해당 디스크를 사용할 수 있음
- emptyDir, cephfs 등의 다양한 종류의 볼륨이 있음
- 이를 관리하기 쉽도록 추상화된 개념이 존재하는데, 그것이 바로 PersistentVolume, PersistentVolumeClame (PV, PVC)
- 사용 방법은 다음과 같음.
1. 시스템 관리자가 물리 디스크를 PV로 등록
2. 개발자는 PVC를 생성하고, 앞서 등록된 PV와 연결
- 이렇게 되면 PVC가 삭제되더라도 PV에 파일이 남을 수 있음. (PV의 Reclaim policy에 따라 다름)
- 이 때의 access 모드는 RWOnce, ROMany, RWMany 등.
4-1) PVC?
- Pod의 Volume과 PV를 바인딩하는 역할로, selector를 기반으로 PV를 선택할 수 있음.
- Dynamic Provisioning 이라는 기능을 제공함. 이 기능을 사용하면 PV도 안만들어도 됨. PVC를 정의하면 PV는 자동으로 생성됨.
- storage class를 지정해주어야 하는데, 이는 PV가 자동으로 생성할 disk의 정보.
- 이 외에도, 볼륨 바인딩 모드라는게 있는데, PVC 생성 시에 볼륨 바인딩과 dynamic provisioning을 언제 시작될지 시기를 지정하는 것.
- 어렵지만 정리하자면 다음과 같음
: Pod <-> PVC <-> Storage Class <-> PV 와 같은 구조로 생성됨
: 이 때 PV를 생성하는 것이 Provisioning이며 PVC와 PV를 묶는 과정을 바인딩 이라고 일컬음.
: 사용자가 PVC를 정의하면, 사전에 정의된 Storage Class의 정보에 의해 PV가 자동으로 생성되는 것!!!!
5) Namespace
- 클러스터 내의 논리적인 단위.
- 작업공간을 분리한다고 생각하면 될 듯. 각 네임스페이스는 별도의 접근권한, 리소스 할당량 등을 지니게 됨!
- 즉, 각 네임스페이스별로 리소스를 나누고 관리할 수 있음