[kubernetes] 쿠버네티스 아키텍처

2해승·2024년 7월 24일

쿠버네티스?!

목록 보기
5/16
post-thumbnail

이번 글에서는 쿠버네티스 아키텍처에 대한 이해와 함께 컨테이너들의 동작 과정과 중요한 개념 중 하나인 네임스페이스를 설명하고 실습까지 진행해보겠다.

쿠버네티스 아키텍처

쿠버네티스 아키텍처는 컨테이너화된 워크로드를 안정적이고 적응 가능한 환경을 제공하기 위해 여러 서버와 클러스터에 분산된 컴포넌트들이 함께 동작하는 집합이다. 크게 컨트롤 플레인(Control plane)과 워커 노드(Worker node)로 구성된다.

컨트롤 플레인에 해당하는 master는 워커 노드들을 관리하며 Pod들로 캡슐화된 컨테이너들을 워커 노드들 내에 배포되어 실행된다.

동작 과정을 알아보기 전에 쿠버네티스 컴포넌트들에 대해 간단하게 이해하고 넘어가보자.

쿠버네티스 컴포넌트

Control Plane

컨트롤 플레인 컴포넌트는 컨테이너 오케스트레이션을 담당하며 클러스터의 상태를 유지하는 역할을 한다. 네가지 요소로 구성되며 각각 담당하는 작업이 정해져있다.

  • kube-apiserver: K8S API를 사용하도록 요청 받고 요청이 유효한지 검사
  • etcd: key-value 타입의 저장소, 쿠버네티스 마스터 및 노드들의 상태 정보 저장
  • kube-scheduler: pod를 실행할 노드 선택
  • kube-controller-manager: pod를 관찰하며 개수를 보장

Worker node

노드 컴포넌트는 동작 중인 파드를 유지시키고 쿠버네티스 런타임 환경을 제공하며, 모든 노드 상에서 동작한다.

  • kubelet: 모든 노드에서 실행되는 K8S 에이전트이며 데몬 형태로 동작
  • kube-proxy: K8S network 동작관리 및 iptables rule을 구성
  • 컨테이너 런타임: 컨테이너 실행을 담당하는 소프트웨어(docker, containerd, runc ...)

쿠버네티스에서 컨테이너의 동작 과정

1. docker push hub.exmaple.com/nginx

  • docker build를 통해 컨테이너를 생성하고 이를 로컬 환경의 쿠버네티스에서 가동

2. Image nginx is pushed to Docker Hub

  • 생성한 컨테이너 이미지를 컨테이너 저장소(Docker Hub)에 업로드

3. kubectl create deploy web --image=hub.example.com/nginx

  • 쿠버네티스 명령어를 통해 컨테이너 이미지를 바탕으로 컨테이너가 실행되도록 요청

4. kubectl issues REST call

  • kubectl 명령이 마스터 노드로 전달되고 마스터 노드의 API server가 Kubectl 명령어를 받음

5. Pod created and scheduled to a worker node

  • 어느 노드에서 pod를 실행하는 것이 좋을지 Scheduler에게 확인을 요청하고 Scheduler는 현재 노드들의 상태를 보고 어느쪽에 배치할지 결정 후 API server에 응답

6. kubelet is notified

  • pod를 생성하기 적당한 노드를 찾아 해당 노드의 kubelet에 파드 생성 요청

7. kubelet instructs Docker to run the image

  • pod 생성 요청을 받은 kublet이 Docker 데몬에게 실제 컨테이너의 생성을 요청

8. Docker pulls and runs nginx

  • 컨테이너 생성 요청을 받은 Docker 데몬이 Docker Hub에 이미지가 존재하는지 확인하고 컨테이너를 실행

이렇게 생성된 컨테이너를 쿠버네티스에서는 pod라는 단위로 관리하게 된다!

쿠버네티스 네임스페이스

쿠버네티스에서는 네임스페이스를 통해서 단일 클러스터 내에 리소스들을 그룹화하여 격리할 수 있다. API를 기준으로해서 클러스터 하나를 여러 개의 논리적인 단위로 나눠서 사용하는 것이다.

이처럼 클러스터가 하나여도 그 안에서는 용도에 따라 실행해야 하는 앱을 구분할 때 네임스페이스를 사용한다.

네임스페이스는 물리적으로 분리하는 것이 아니기 때문에 클러스터 전체에 장애가 나면 네임스페이스와 관계 없이 문제가 발생한다. 또한 특정 노드에 문제가 생기면 네임스페이스와 관련 없이 노드에서 실행되고 있는 pod들에게 문제가 생긴다.

네임스페이스 실습을 해보자!

CLI를 이용한 namespace 생성 및 조회하기

$ kubectl create namespace dev
$ kubectl get namespace
NAME                 STATUS   AGE
default              Active   15h
dev                  Active   3s
kube-node-lease      Active   15h
kube-public          Active   15h
kube-system          Active   15h
local-path-storage   Active   15h

yaml을 이용한 namespace 생성하기

$ kubectl create namespace staging --dry-run -o yaml
$ kubectl create namespace staging --dry-run -o yaml > stagin-ns.yaml

apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: null
  name: staging
spec: {}
status: {}

yaml 파일을 통해 네임스페이스를 생성하기 위해서는 위처럼 명령어를 실행해주면 되는데 여기서 옵션은 다음과 같이 의미한다.

  • --dry-on: 실제로 실행하지 않고 실행 가능 여부만 보여주도록 함
  • -o yaml: 결과를 yaml 형태로 출력
$ kubectl create -f stagin-ns.yaml
$ kubectl get namespace
NAME                 STATUS   AGE
default              Active   15h
dev                  Active   3s
...
staging              Active   10s

따라서 해당 명령어의 결과를 stagin-ns.yaml 파일로 저장하고 kubectl create 명령어를 통해 새로운 네임스페이스를 생성한다.

※ 쿠버네티스의 기본 네임스페이스는 default ※

쿠버네티스는 별도의 설정을 하지 않는 이상 default 네임스페이스를 사용하는데 이는 pod를 조회할 때부터 알 수 있다.

$ kubectl get pods
NAME           READY   STATUS    RESTARTS         AGE
liveness-pod   1/1     Running   99 (5m53s ago)   14h
nginx-pod      1/1     Running   0                14h

$ kubectl get pods -n default
NAME           READY   STATUS    RESTARTS        AGE
liveness-pod   1/1     Running   100 (53s ago)   14h
nginx-pod      1/1     Running   0               14h

옵션을 지정하지 않고 명령을 사용했을 때 확인 할 수 있는 pod들이다. 이는 -n default를 부여해도 동일하게 나올 것이다. 이는 기본 네임스페이스가 default로 설정되어있음을 의미한다.

$ kubectl get pods -n dev
No resources found in dev namespace.

또한 새롭게 생성한 dev 네임스페이스에서는 pod가 존재하지 않아 위와같은 메시지를 확인할 수 있다. 그렇다면 매번 이렇게 '-n <네임스페이스명>' 옵션을 지정해줘야 할까?

아니다. 귀찮음을 줄이기 위해 기본으로 사용하는 네임스페이스를 default가 아닌 다른 네임스페이스로 변경할 수 있는 방법을 알아보도록하자.

기본 네임스페이스를 다른 이름의 네임스페이스로 변경하기

다른 이름의 네임스페이스로 변경하기 위해서는 쿠버네티스의 config에 네임스페이스 등록을 해야한다.

$ kubectl config set-context dev@kind-test-cluster --cluster=kind-test-cluster --user=kind-test-cluster --namespace=dev

나는 dev 네임스페이스를 context에 등록해주었다. kubectl config view 명령어를 통해 새롭게 추가된 부분을 아래처럼 확인할 수 있을 것이다.

$ kubectl config view
- context:
    cluster: kind-test-cluster
    namespace: dev
    user: kind-test-cluster
  name: dev@kind-test-cluster

use-context 명령어는 기본 네임스페이스를 변경해주는 명령어이다. 앞서 생성했던 dev 네임스페이스를 사용하기위해 context를 스위치 해주도록하자.

$ kubectl config use-context dev@kind-test-cluster

$ kubectl config current-context
dev

이제 pod를 조회할 때 별다른 옵션을 지정하지 않고서도 dev에 존재하는 pod를 확인할 수 있을 것이다.

$ kubectl get pods
No resources found in dev namespace.

터미널의 기본 네임스페이스가 dev로 변경되어 입력하는 명령어는 기본적으로 dev 네임스페이스에서 동작하는 리소스에만 적용될 것이다.

추가: 네임스페이스 삭제하기

$ kubectl delete namespace dev
namespace "dev" deleted

네임스페이스를 삭제하면 해당 네임스페이스 안에 있는 모든 리소스가 삭제되니 유의하도록 하자!



[참고]

쿠버네티스 공식 문서
Kubernetes Architecture, 제대로 이해하기 - Control Plane
따배쿠4강 쿠버네티스 아키텍처

profile
주니어 데브옵스 엔지니어

0개의 댓글