쿠버네티스 이론
들어가기전, 쿠버네티스 이론을 다루려고 하는 이유는 내가 사용하고있는 쿠버네티스 의 기본적인 이론도 모르면서 사용하는 내 자신이 부끄러웠습니다. 구성할 줄 은 알지만, 누군가가 물어본다면, 아무 답을 하지 못하는… 그래서 다시 공부해보기로 했습니다. 다시 배우지만, 새롭게 느껴지는 느낌은 제가 잘못 배웠다는 증거겠죠 ^^
쿠버네티스란 ?
쿠버네티스는 컨테이너를 쉽고 빠르게 배포 / 확장할 수 있는 자동화 관리 오픈소스 플랫폼 입니다.
단순한 컨테이너 플랫폼이 아닌 microservice, cloudplatform 을 지향하고 컨테이너로 이루어진 것들을 손쉽게 담고 관리할 수 있는 그릇 역할을 합니다. 서버리스, Ci/CD 머신러닝 등 다양한 기능이 쿠버네티스 플랫폼위에서 동작할 수 있습니다.
쿠버네티스 특징
-
다양한 배포 방식
쿠버네티스는 Deployment, StatefulSet, Daemonset, Job, CronJob 등 다양한 배포 방식을 지원합니다. - Deployment 는 새로운 버전의 애플리케이션을 다양한 전략으로 무중단 배포 할 수 있습니다.
- StatefulSets 은 실행 순서를 보장하고 호스트 이름과 볼륨을 일정하게 사용할 수 있어 순서나 데이터가 중요한 경우에 사용할 수 있습니다.
- DaemonSet 은 로그나 모니터링 등 모든 노드에 설치가필요한 경우에 사용할수 있습니다.
- Job 과 CronJob 은 배치성 작업을 진행할때 이용하면 됩니다.
-
Ingress 설정
다양한 웹 어플리케이션을 하나의 로드밸런서로 서비스하기 위해
Ingress
기능을 제공합니다. 웹 어플리케이션을 관리 하는 과정을 보면 외부에서 직접 접근할 수 없도록 어플리케이션을 내부망에 설치하고 외부에서 접근이 가능한ALB
나Nginx
,Apache
를 프록시 서버로 활용합니다. 프록시 서버는 도메인과 Path 조건에 따라 등록된 서버로 요청 을 전달하는데 서버가 바뀌거나 IP 가 변경되면 매번 설정을 수정해줘야 합니다. 쿠버네티스의 Ingress 는 이를 자동화 하면서 기존 프록시 서버에서 사용하는 설정을 거의 그대로 사용할 수 있습니다. 새로운 도메인을 추가하거나 업로드 용량을 제한하기 위해 일일이 프록시 서버에 접속하여 설정할 필요가 없습니다.
하나의 클러스터에 여러개의 Ingress 설정을 할 수 있어 관리자 접속용 Ingress와 일반 접속용 Ingress를 따로 관리할 수 있습니다.
-
Namespace & Label
하나의 클러스터 를 논리저긍로 구분하여 사용할 수 있습니다. 하나의 클러스터에 다양한 프레임워크와 애플리케이션을 설치하기 때문에 기본 (
system
&default
)외 여러개의 네임스페이스를 사용하는 것이 일반적입니다. 더 세부적인 설정으로 라벨기능을 적극적으로 사용하여 유연하면서 확장성 있게 리소스를 관리할 수 있습니다. - RBAC(role-based access control) 접근 권한 시스템입니다. 각각의 리소스에 대해 유저별로 CRUD스런 권한을 손쉽게 지정할 수 있습니다. 클러스터 전체에 적용하거나 특정 네임스페이스에 적용할 수 있습니다. AWS의 경우 IAM 을 연동해서 사용할 수도 있습니다.
-
CRD (Custom Resource Definition) 쿠버네티스가 제공하지 않는 기능을 기본 기능과 동일한 방식으로 적용하고 사용할 수 있습니다. 예를 들어 쿠버네티스는 기본적으로 SSL 인증서 관리 기능을 제공하지 않지만, cert-manager를 설치하고 Certificate 리소스를 이용하면 익숙한 쿠버네티스 명령어로 인증서를 관리 할 수 있습니다. 또 다른 도구, 방식을 익힐 필요 없이 다양한 기능을 손쉽게 확장할 수 있습니다.
-
Auto Scailing CPU, memory 사용량에 따른 확장은 기본이고 현재 접속자 수와 같은 값을 사용할 수도 있습니다. 컨테이너의 개수를 조정하는 Horizonal Pod AutoScaler(HPA), 컨테이너의 리소스 할당량을 조정하는 Vertical Pod Autoscaler(VPA), 서버 개수를 조정하는 Cluster Autoscaler(CA) 방식이 있습니다.
-
Federation, MultiCluster
클라우드에 설치한 쿠버네티스 클러스터와 자체 서버에 설치한 쿠버네티스를 묶어서 하나로 사용할 수 있습니다. 구글에서 발표한 Anthos 를 이용하면 한 곳에서 여러 클라우드의 여러 클러스터를 관리할 수 있습니다.
쿠버네티스 단점
쿠버네티스는 확실히 복잡하고 초반에 개념을 이해하기 어렵습니다. Yaml 설정 파일은 너무 많고 클러스터를 만드는 것도 쉽지 않습니다. 하지만 여러 클라우드에서 관리형 서비스를 제공하고 Cloud Code 같은 플러그인 을 이요하거나 helm 같은 패키지 매니저를 사용하면 비교적 편리하게 설정파일을 관리할 수 있습니다.
쿠버네티스 기본 개념
-
Desired state
쿠버네티스에서 가장 중요한 것은 desired state - 원하는상태 라는 개념입니다. 원하는 상태라 함은 관리자가 바라는 환경은 의미하고 좀 더 구체적으로는 얼마나 많은 웹서버가 떠 있으면 좋은지, 몇번 포트로 서비스하기를 원하는지 등을 말합니다.
쿠버네티스는 복잡하고 다양한 작업을 하지만 자세히 들여다보면 current state - 현재상태 를 모니터링 하면서 관리자가 설정한 원하는 상태를 유지하려고 내부적으로 이런저런 작업을 하는 단순한 로직을 가지고 있습니다.
이러한 개념 때문에 관리자가 서버를 배포할때 직접적인 동작을 명령하지 않고 상태를 선언 하는 방식을 사용합니다. 예를들어 “nginx 컨테이너 실행해줘, 그리고 80포트로 오픈해줘” 는 현재상태를 원하는 상태로 바꾸기 위한 명령이고 “80포트를 오픈한 nginx 컨테이너를 유지해줘” 는 원하는 상태를 선언 한것입니다.
언뜻 똑같은 요청을 단어만 살짝 바꿔 말장난 하는게 아닌가 싶은데 CLI 명령을 보면 다릅니다.
$ docker run # 명령 $ kubectl create # 상태 생성 (kubectl run 도 있지만 잘 사용하지 않는다.)
쿠버네티스의 핵심은 상태이며 쿠버네티스를 사용하려면 어떤 상태가 있고 어떻게 상태를 선언하는지를 알아야합니다.
-
Kubernetes Object
쿠버네티스는 상태를 관리하기 위한 대상을 오브젝트로 정의합니다. 기본으로 수십 가지 오브젝트를 제공하고 새로운 오브젝트를 추가하기가 매우 쉽기 때문에 확장성이 좋습니다. 여러 오브젝트 중 주요 오브젝트는 다음과 같습니다.
-
POD
쿠버네티스 에서 배포할 수 있는 가장 작은 단위로 한개 이상의 컨테이너와 스토리지, 네트워크 속성을 가집니다. Pod에 속한 컨테이너는 스토리지와 네트워크를 공유하고 서로 localhost로 접근할 수 있습니다. 컨테이너를 하나만 사용하는 경우도 반드시 Pod으로 감싸서 관리합니다.
-
ReplicaSet
Pod을 여러 개(한개 이상) 복제하여 관리하는 오브젝트 입니다. Pod을 생성하고 개수를 유지하려면 반드시 ReplicaSet 을 사용해야 합니다. Replicaset은 복제할 개수, 개수를 체크할 라벨 선택자, 생성할 Pod의 설정값(템플릿) 등을 가지고 있습니다. 직접적으로 Replicaset을 사용하기보다는 Deployment등 다른 오브젝트에 의해서 사용되는 경우가 많습니다.
-
Service
네트워크와 관련된 오브젝트 입니다. Pod을 외부 네트워크와 연결해주고 여러 개의 Pod을 바라보도록 내부 로드밸런서 를 생성할때 사용합니다. 내부 DNS 에 서비스 이름을 도메인으로 등록하기 떄문에 서비스 디스커벌 역할도 합니다.
-
Volume
저장소와 관련된 오브젝트입니다. 호스트 디렉토리를 그대로 사용할 수도 있고 EBS 같인 스토리지를 동적으로 생성하여 사용할 수도 있습니다.
-
쿠버네티스 배포방식
쿠버네티스는 애플리케이션을 배포하기 위해 원하는 상태(Dersired state)를 다양한 오브젝트에 라벨을 붙혀 저으이 하고 API 서버에 전달하는 방식을 사용합니다.
"컨테이너 2개를 배포하고 80포트로 오픈해줘"와 같은 간단한 작업을 위해 다음과 같은 구체적인 명령을 전달해야합니다.
> "컨테이너를 Pod 으로 감싸고 type=app,app=web이라는 라벨을 달아줘. type=app app=web이라는 라벨이 달린 Pod이 2개 있는지 체크하고 없으면 Deployment Spec에 정의된 템플릿을 참고해서 Pod을 생성해줘. 그리고 해당 라벨을 가진 Pod 을 바라보는 가상의 서비스 IP 를 만들고 외부의 80포트를 방금 만든 서비스IP 랑 연결해줘."