[Cloud] Kubernetes(k8s)
현업에서는 Docker Image Container 를 하나만 띄우지 않는다. 서비스나 제품 별로 많은 Container 들을 띄우게 되며, 이러한 Container 들을 관리할 수 있는 도구인 kubernetes(이하 k8s) 를 많이 쓰게 된다. 자세한 사용법에 대해서 알아보기 전에, 먼저 k8s 란 무엇인지 알아보자.
Kubernetes 등장배경
- 과거에는 배포하고자 하는 애플리케이션의 개수가 늘어날수록 구매해야 하는 서버도 늘어났다. 이에 한 대의 서버를 잘 이용해서 여러 개의 애플리케이션을 배포할 수 없을까 하는 고민이 있었다. 그럼에도 서버를 매번 추가할 때마다 세팅해줘야 하는 것이 번거로웠다.
- VM(Virtual Machine)
-
하나의 컴퓨터에 여러 OS 환경을 두고, 각 환경의 리소스를 조정해서 하나의 컴퓨터로 안정감 있게 여러 애플리케이션을 배포할 수 있게 해준 기술이다.
-
아래 그림과 같은 Vurtual Box tool 을 이용해서, OS 환경 셋팅을 Image 라는 하나의 파일로 만들고 이를 Virtual box 로 실행했다.
-
- 그러나 VM 은 OS 전체를 다운받아 기동하는 방식이었기 때문에 굉장히 무거웠다. 즉 환경끼리 충돌은 안나더라도 리소스적으로 너무 무거웠다.
- 이에 가벼움에 대한 니즈가 있었고 Linux 에서 Container 기술이 발전했다. 이를 대중적으로 만든 것이 바로 Docker 다.
- 이제 Docker 를 이용해서 사람들이 VM 을 더 가볍고 빠르게 개별 환경을 셋팅할 수 있었고, 애플리케이션을 배포할 수 있게 되었다.
- 특히 Docker Compose 를 위해 yaml 을 작성하고 이를 입력으로 주면, 작성된 Image 로 Container 여러 개를 한번에 띄울 수 있다. 이에 대해서는 해당 포스트에서 정리했다.
- 그래도 여전히 문제가 있었다. 애플리케이션이 많아지고 트래픽 규모가 커지고 더 많은 컴퓨터를 쓸 때는 어떻게 해야할까?
- Docker 만 사용하면 서버를 증설할 때마다 서버마다 Docker 를 설치하고 서버에 필요한 것을 설치해줘야 한다. 또 여러 컴퓨터가 같은 네트워크에 묶이도록 설정해줘야 한다.
- 여러 개의 컴퓨터를 같은 목적 범위 내에서 사용하는 것을 분산환경이라고 한다.
- 이에 따라 배포하고자 하는 Docker Image 와 이 Image 가 사용할 리소스만 알면, 서버 증설, 네트워크 묶기, 분산환경 등을 알아서 설정하여 배포해주는 기술이 등장했다. 이것이 바로 kubernetes(k8s)다.
- 즉 VM $\rightarrow$ Docker $\rightarrow$ Docker Compose $\rightarrow$ kubernetes 순으로 발전하게 된 것이다.
Kubernetes (k8s)
- k8s 란 분산 노드 환경에서의 Container 오케스트레이션 도구다. 여러 노드가 필요하며 Container 기반으로 배포하고 싶을 때 사용한다.
- k8s 는 여러 개의 컴퓨터 위에서 활용된다. 각 컴퓨터는 ‘노드’이며, 이 노드의 묶음을 ‘클러스터’라고 표현한다.
- 사용자가 k8s 클러스터에 Docker Image 를 가지고 배포 요청을 하면, k8s 가 클러스터 내 노드 중 하나에 적절하게 배포하는 흐름을 가진다.
- Docker 처럼 특정 Container 를 실행하지만 이를 여러 개의 노드(컴퓨터) 환경에서 동작하게 하는 것으로, 하나의 컴퓨팅에 구속받지 않고 필요에 따라 쉽게 늘릴 수 있다.
- GCP(GKE), AWS(EKS), Azure(AKS) 와 같은 클라우드 서비스에서 제공하는 managed 서비스를 가지고 k8s 클러스터를 사용해볼 수 있다.
- GCP 를 대표적으로 예를 들어보자.
- 클러스터를 만든다는 것은 컴퓨터 모음을 배포한다는 것을 의미한다. Region 과 k8s 버전을 설정해줘야 한다.
- 사용할 노드(컴퓨터)의 수를 정한다. managed 서비스에서는 최소 3개.
- 노드의 집합을 ‘노드풀‘이라 한다. 여러 개의 노드풀을 둘 수 있고, gpu 를 사용한 풀도 만들 수 있다.
- 쉽게 말해 클러스터 운영은 내가 사용할 인프라의 모음을 만드는 것이라 이해할 수 있다.
- k8s 클러스터와 통신하기 위해
kubectl
(k8s 클라이언트)를 설치한다.kubectl
로 CLI 도구를 쓸 수 있다. - 클러스터는 클라우드에 떠 있기 때문에, 클러스터가 통신할 수 있도록
kubeconfig
세팅을 해줘야 한다. managed 서비스를 쓰면 클라우드 벤더에서 스크립트 형태로 제공해준다. kubectl get nodes
명령어를 통해 클러스터 내 노드들을 확인할 수 있다.
- k8s 클러스터에 애플리케이션을 띄우는 방법은 아래와 같다.
- yaml 파일을 작성해야 한다. 이 yaml 파일은
docker-compose.yml
과 비슷한 역할을 한다. - nginx Docker Image 를 배포하려면 nginx 애플리케이션을 배포하는 yaml 을 만들어야 한다.
- yaml 파일을 작성해야 한다. 이 yaml 파일은
- k8s 를 사용하게 되면 아래와 같은 이점을 얻을 수 있다.
- 먼저 k8s 를 사용하는 전제는, 여러 노드가 필요한 상황이다. 애플리케이션을 한 개만 배포하고 굳이 여러 컴퓨터가 필요 없으면 사용하지 않는다.
- 복잡한 인프라(노드, 네트워크 등)를 통합적으로 관리할 수 있다.
- 분산 노드 환경에서 쉽고 빠르게 애플리케이션 배포가 가능하다.
- k8s 클러스터에 yaml 파일을 제출하기만 하면 알아서 적절한 노드에 띄워준다.
- yaml 파일을 통해 선언적으로 배포를 관리하고 상황을 가시화할 수 있다.
-
아래 그림과 같이 ArgoCD 같은 도구를 쓰면 yaml 을 parsing 하여 클러스터에 뭐가 떠있는지를 GUI 형태로 볼 수 있다. 의도한대로 되지 않으면
sync fail
이 뜬다.
- 그 외 다양한 기능을 사용할 수 있다.
- 배포할 애플리케이션의 리소스(cpu, mem)를 설정할 수 있다.
nodeSelector
를 활용하여 애플리케이션이 배포될 노드풀 설정할 수 있다.- 애플리케이션이 죽었을 시 자동으로 재실행된다.
- 애플리케이션 무중단 배포가 가능하다.
k8s 아키텍처
- k8s 클러스터는 크게 마스터 노드와 워커 노드로 구분된다. 위 섹션에서의 노드는 모두 워커 노드에 해당한다. 즉 대부분의 배포 애플리케이션들은 워커 노드 중 하나에 배포된다.
-
마스터 노드는 일반적으로 숨겨져있고, 클라우드를 쓴다면 접근하고 배포할 수 있는 부분이 아니다. k8s 시스템의 컴포넌트들이 마스터 노드 위에 배포됨.
- 마스터 노드의 k8s 컴포넌트는 아래와 같다.
- API Server
- REST API 서버를 제공해준다.
kubectl get nodes
는GET /api/vi/nodes
로 접근하는 것과 같다.
- Controller
- 상태를 계속 모니터링 한다.
- yaml 파일에 명시된 것과 같은 상태가 되도록 모니터링하고 조정한다.
- Etcd
- key-value 형태의 DB 로, 클러스터의 모든 상태들을 저장한다.
- Scheduler
- Pod 를 배포할 때 최종적으로 이 Container Image 를 어느 노드에 배치 시킬지 결정한다.
- API Server
- 워커 노드에는 kubelet, kubeproxy 가 있다.
- kubelet
- 마스터 노드의 스케쥴러의 명령을 받아 실제로 해당 노드에 애플리케이션을 배포한다.
- kube-proxy
- k8s 를 사용할 때는 일반적으로 분산 환경이기 때문에 여러 노드, 네트워크를 하나로 묶어줘야 한다. Pod 에 네트워크 정보(IP, DNS 등)를 기록하고 클러스터에 전달하는 역할을 한다.
- kubelet
k8s usecase
- 일반적인 앱 배포
- 회사에서 서비스 하는 앱들을 배포하는데 사용한다. 즉 서버 배포를 k8s 기반으로 한다.
- Airflow on kubernetes
- Airflow task 는 컴퓨터에서 하나의 프로세스다.
- k8s 를 쓰면 Pod 라는 리소스로 task 를 만들어 리소스를 효율적으로 사용 가능하다.
- 많이 사용할 때는 자동으로 infra 를 추가하고, 사용하지 않을 때는 리소스를 다 죽일 수 있다.
- MLflow 의 train 프로세스를 kubernetes job 으로 실행할 수 있다.
- node pool 을 골라서 train job 을 실행시킬 수 있고, 스케줄링을 할 수 있다.
댓글 남기기