쿠버네티스란 컨테이너화된 워크로드와 서비스를 관리하는 오픈 소스 플랫폼이다. 선언적인 구성이 가능하며 자동화를 지원한다. 많은 IT 회사들이 서비스를 배포하는데 쿠버네티스를 사용하고 있고, 표준화에 가장 가까운 플랫폼이라고 생각하여 조금씩 공부해보려고 한다.
쿠버네티스를 배포하면 클러스터를 얻게 된다. 이 클러스터는 컨트롤 플레인, 노드로 구성된다.
대략 이러한 그림이다.
컨트롤 플레인은 클러스터에 관한 전반적인 결정을 수행하고, 노드는 컨트롤 플레인의 지시에 따라 컨테이너화된 애플리케이션을 배포하고 실행하는 워커머신의 집합, 작업 단위를 의미한다.
크게 쿠버네티스 클러스터를 나누어 보았으니 각각 조금 더 자세히 알아보자.
컨트롤 플레인은 클러스터에 관한 전반적인 결정을 하게 된다. 스케줄링, 클러스터의 전체적인 상태, 동작을 관리하는데.
예를 들면 Deployment(쿠버네티스의 배포를 담당하는 서비스)에서 각 파드(도커의 컨테이너에 해당하는 쿠버네티스 구성요소)의 replicas(몇 개의 컨테이너를 실행하는지)에 대한 요구 조건이 충족되지 않을 경우 새로운 파드를 실행시키는 등의 관리를 하게 된다.
도식의 오른쪽을 보면 컨트롤 플레인의 구성 요소가 나열되어 있따.
쿠버네티스의 API를 노출한다. 쿠버네티스 컨트롤 플레인의 프론트엔드 단이며 외부 혹은 클러스터 내부에서 이 쿠버네티스 API 서버를 통해 명령을 수행하거나 정보를 조회한다.
자주 사용하게 되는 Kubectl 명령어를 통해 명령을 수행하면 Kube-apiserver를 통해 적절한 컴포넌트로 요청을 전달한다.
키-밸류 저장소로 클러스터 동작에 필요한 리소스의 구성정보, 상태 정보, 명세정보를 영구적으로 저장한다. 고가용성을 가지고 있으며 중요한 데이터 저장소로 백업이 필요한 계층이다.
안정적인 동작을 위해 분산형으로 구현되어 있다.
노드가 배정되지 않은 새로 생성된 파드를 감지하고 실행될 적절한 노드를 찾아준다.
리소스의 요구사항, 노드의 가용성, 제약 조건들을 고려하여 스케쥴링 한다.
다양한 컨트롤러들이 모여있는 곳으로 클러스터의 상태가 사용자가 원하는 상태와 일치하도록 지속적으로 확인하고 조정한다. 다운된 노드가 없는지 복제본을 정해준 숫자대로 유지하고 있는지 서비스와 파드가 연결되어 있는지 등을 확인하고 잘못되어 있다면 조치하는 역할을 한다.
다양한 컨트롤러에는
가 포함된다.
이러한 컨트롤러들은 각각 프로세스가 분리되어 작업하지만 복잡성을 낮추기 위해 단일 바이너리로 컴파일되어 단일 프로세스에서 실행된다.
클라우드별 컨트롤 로직을 포함한다. 클라우드 컨트롤러 매니저를 통해 클러스터를 클라우드 공급자(AWS, GCP 등)에 연결해준다.
만약 사내, 로컬로 쿠버네티스를 실행중이라면 그 쿠버네티스 클러스터 내에는 클라우드 컨트롤러 매니저가 없다.
노드는 동작중인 파드를 유지시키고 쿠버네티스 런타임 환경을 제공한다. 컨트롤 플레인의 지시를 따르며 실제 어플리케이션의 컨테이너가 배포되고 실행되는 작업 단위이다.
파드는 위에서도 몇 번 언급했지만 쿠버네티스의 작은 배포 단위로 하나 이상의 컨테이너를 그룹화하여 실행하는 논리적인 호스트이다.
도커의 컨테이너와 유사하지만 이 파드내에는 다른 종류의 컨테이너들을 포함시켜서 배포할 수 있다. 예를 들면 웹 서버 컨테이너와 nginx 컨테이너를 하나의 파드로 묶어서 실행할 수 있다. 이런 경우 네트워크, 볼륨 스토리지, 라이프 사이클 등을 공유하게 된다.
그림에서 볼 수 있듯 각 노드에서 실행되며 컨트롤 플레인의 지시를 받아 파드와 컨테이너의 생명 주기를 관리한다. 쿠버네티스를 통해 생성된 컨테이너가 파드내에서 동작할 수 있도록 관리해주는 역할이다.
쿠버네티스 파드 관리를 위해 설정 yml 파일을 작성해서 적용하면 이 설정파일이 kube-apiserver로 전송된 후 Kubelet으로 전달된다. 그리고 kubelet이 전달받은 파드를 생성하거나 변경된 설정에 맞게 변경해준다.
클러스터 내 각 노드에서 실행되는 네트워크 프록시를 의미한다. 이 후에 나올 Service라는 개념이 있는데, 이 Service는 어떤 Deployment의 네트워크를 구현하게 되는데, 이 Service의 구현부이며 노드의 네트워크 규칙을 관리한다.
이를 통해 내부 네트워크 세션이나 클러스터 바깥에서 파드로 네트워크 통신을 하게 해준다. 또 어떤 네트워크 요청이 클러스터 내에 파드로 적절히 라우팅 되도록 해준다.
컨테이너 런타임은 실제로 컨테이너를 실행시키는 소프트웨어이다. 이 글 가장 처음에 설명했던 쿠버네티스는 컨테이너화된 어플리케이션을 실행하는 워크로드라고 했는데, 이 컨테이너는 꼭 도커가 아니어도 된다.
워크로드는 쿠버네티스에서 작동되는 어플리케이션을 의미한다. 위에서 설명한 파드와 비슷한데, 사실 파드가 이 워크로드에 포함된다. 그리고 이 파드의 실행에 도움이 되는 고수준의 추상화도 포함한다.
워크로드 = 파드 + 워크로드 리소스(파드를 실행해주는 추상화)
파드를 간단히 다시 설명하자면 파드는 쿠버네티스 클러스터에서 생성하고 관리할 수 있는 배포가능한 가장 작은 컴퓨팅 유닛이다.
이 파드는 하나의 컨테이너가 아니라 서로 다른 종류의 컨테이너의 집합일 수도 있다. 도커가 가장 잘 알려진 컨테이너 런타임이지만 이외에 다른 컨테이너들도 지원한다. 파드는 직접 만들 필요가 없이 Deployment 혹은 Job과 같은 워크로드 리소스를 사용하여 생성할 수 있다.
일반적으로 파드는 직접 만들일이 없는데 왜냐하면 파드는 일시적이고 언제든 삭제될 수 있음을 생각하고 만들기 때문이다. 실제로 이런 컨테이너 집합을 직접 만들 것이라면 도커만을 사용해도 된다.
쿠버네티스를 사용하는 이유는 이러한 컨테이너들을 관리해주는 오케스트레이션이 주이기 때문에 파드보다는 디플로이먼트를 사용한다.
디플로이먼트는 파드은 파드를 업데이트하기 위한 선언적인 명세를 의미한다. 레플리카셋을 이용하여 원하는 개수만큼 파드를 실행시키고 컨트롤 플레인을 이용하여 파드를 업데이트하거나 롤백할 수도 있다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
이렇게 디플로이먼트를 명세하면 Nginx 컨테이너를 파드내에 3개를 생성하게 된다.
파드를 원하는 개수만큼 안정적으로 유지하고 가용성을 보증하는데 사용된다.
서비스는 공식문서에 따르면 워크로드라기보단 네트워킹 및 로드밸런싱에 해당하지만 디플로이먼트와 같은 레벨에서 작성되며 자주 만날 수 있는 계층이다.
디플로이먼트를 통해서 배포된 파드는 각각 고유한 IP를 가지지만 바로 직접 접속할 수는 없다. 이러한 파드 집합에 접근할 수 있도록 돕는게 서비스이다.
서비스를 사용하면 파드에서 실행중인 어플리케이션을 클러슽어 외부에서 접근할 수 있다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
이렇게 서비스 설정 파일을 작성하면 외부 수신 포트를 80번으로 지정하게 되고, Port가 클러스터 Ip나 로드밸런서에 노출되는 포트이며, 타겟 포트가 수신된 트래픽을 전달한 pod의 포트이다.
인그레스는 http, https를 이용하여 쿠버네티스 API를 통해 트래픽을 다른 백엔드에 매핑시켜준다. 이를 통해 더 복잡한 트래픽을 관리할 수 있다.
서비스는 특정 파드 그룹과 네트워크 트래픽을 연결해주고 클러스터 내부, 외부에서 접근할 수 있는 엔드포인트를 제공하는 반면 인그레스는 여러 서비스에 걸쳐서 http, https 트래픽을 외부에서 클러스터로 라우딩할 수 있도록 조금 더 복잡한 설정, 라우팅 규칙을 지원한다.
Configuration(이하 설정)은 쿠버네티스에서 파드를 위해 설정 정보를 제공하는 리소스이다.
키-밸류 형태의 기밀이 아닌 데이터를 저장하는 오브젝트이다. 환경별로 configmap으로 이미지에서 구성을 분리하여 쉽게 어플리케이션을 이식하게 도와준다.
configmap은 보안, 암호화를 지원하지 않으므로 데이터가 기밀일 경우에는 Secret을 사용해야 한다.
시크릿은 기밀 형태의 암호, 토큰과 같은 소량의 중요한 데이터를 저장하는 오브젝트이다. Configmap과 유사하지만 기밀 데이터를 보관하는 용도로 사용된다.
이외에도 정말 많은 쿠버네티스의 구성요소가 있지만 공부하면서 자주 만나게 되는 구성요소들에 대해서 역할을 간단히 정리해보았다. 실제로 부딫쳐보면서 공부하는 중인데, 모든 요소에 딥다이브가 필요해보이지만 기본 역할들을 알고 가는게 좋은 것 같아 먼저 정리해볼 필요가 있었다.
출처