- 출처: Kubernetes in action
- 앱 실행
일반적으로 쿠버네티스에 앱을 배포할때는 구성 요소를 기술한 JSON이나 YAML 매니페스트를 준비해야 하지만 첫번째 앱 배포 예제이므로 간단한 방법으로 배포해본다.
책에서는 "kubectl run" 명령어를 통해 레플리케이션 컨트롤러를 생성하여 파드 생성을 제어한다. 그러기 위해 명령어 옵션에 "--generator=run/v1"을 추가하고 있는데 현재 kubectl 버전에서는 사장되었다. (레플리케이션 컨트롤러 vs 레플리카셋 vs 디플로이먼트 비교: https://preiner.medium.com/kubernetes%EC%9D%98-%EC%9D%B4%ED%95%B4-%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC-17245a0d5f4d)
대신 권고되는 방법은 디플로이먼트 를 사용하여 배포하는것인데 쿠버네티스 튜토리얼 공식 문서를 확인하면 어떻게 디플로이먼트를 생성하는지 알 수 있다. "kubectl create deployment kubia --image=ocwokocw/kubia --port=8080" 명령어를 실행한다.
이전 포스트에서 kubectl을 k로 alias 설정했기 때문에 k로 실행했다. --image로 실행하고자 하는 컨테이너 이미지를 명시하였고 --port로 앱이 8080 포트를 수신대기 해야한다는것을 쿠버네티스에 알려주었다.
- 파드
kubernetes를 실행했으므로 컨테이너를 조회해보자. 쿠버네티스는 컨테이너를 직접 다루지 않으므로 직접 조회하는 방법은 제공하지 않는다. 대신 함께 배치된 다수의 컨테이너 그룹이라는 개념을 제공하는데 이것이 바로 파드이다.
파드는 같은 워커노드 내에서 같은 리눅스 네임스페이드로 함께 실행된다. 각 파드는 자체 IP, 호스트 이름, 프로세스 등이 있는 논리적으로 분리된 머신이다. 워커노드 하나에 파드가 여러개이며 (워커노드 : 파드 = 1 : N), 파드 내에는 여러 개의 컨테이너가 존재한다. (파드 : 컨테이너 = 1 : N) "kubectl get pods"로 파드를 조회해보자.
STATUS가 Running 상태이지만 쿠버네티스에 앱을 배포한 직후 조회하면 Running 이 아닌 다른 상태이다. 이는 워커노드가 컨테이너를 실행하기전 이미지를 다운로드중이기 때문이다.
- 쿠버네티스 앱 배포과정
쿠버네티스에 앱을 배포하고 파드까지 조회해보았다. 쿠버네티스 내부적으로 어떤 과정을 통해 배포되는지 알아보자.
쿠버네티스의 컴포넌트 구조에 대한 그림을 가져왔다. 로컬에서 디플로이먼트를 생성하는 명령어를 실행하면 kubectl 이 Control Plane (마스터 노드) 내의 api 컴포넌트로 REST 요청을 보낸다. 그 후 디플로이먼트가 클러스터에 새로운 레플리카셋을 생성하고, 레플리카셋은 파드를 생성하도록 오케스트레이션 한다. 파드는 스케줄러에 의해 워커 노드 중 하나에 스케줄링된다.
워커 노드의 kubelet은 파드가 스케줄링 됐다는 것을 보고 도커(컨테이너 런타임)에게 이미지가 로컬에 없다면 레지스트리에서 이미지를 가져오도록(pull) 지시한다. 이미지를 다운로드하면 도커는 컨테이너를 생성하고 실행한다.
- 서비스(앱 노출)
파드가 생성되긴 했지만 접근은 할 수 없다. 파드가 자체 IP 주소를 갖고 있긴 하지만 클러스터 내부에 있어서 외부에서 접근이 불가하기 때문이다. 외부에서 접근 가능하게 하려면 서비스라는 오브젝트를 통해 노출해야 한다.
일반적인 서비스(Cluster IP 유형)을 생성하면 이 역시 클러스터 내부에서만 접근 가능하기 때문에 LoadBalancer(이하 LB) 유형의 서비스를 생성해야 한다. 하지만 LoadBalancer는 클라우드에서 지원하는 경우에만 지정가능한 타입이며 현재 minikube 환경에서는 type을 NodePort로 지정해준다.
서비스 오브젝트를 생성해주자. 책에서는 레플리케이션컨트롤러를 노출하도록 명령한다고 했지만 쿠버네티스에 앱 배포시 디플로이먼트를 배포했기 때문에 디플로이먼트를 노출한다. "kubectl expose deployment kubia --type=NodePort --name kubia-http" 명령어를 실행해보자. 그 후 서비스 오브젝트가 제대로 생성되었는지 확인하려면 "kubectl get service"를 실행하면 된다.
만약 LoadBalancer Type으로 지정했다면 시간이 지나면서 EXTERNAL-IP가 생기게 되고 "curl [생성된 IP]:8080"으로 접속하면 앱이 동작하게 된다. 하지만 minikube 환경에서는 "minikube service kubia-http"를 실행해 서비스에 접근 가능한 IP와 포트를 얻어야 한다.
자동으로 브라우저 창이 열리면서 접속이 될것이다.
- 컴포넌트들의 이해
책에서는 레플리케이션 컨트롤러, 파드, 서비스가 서로 어떤 관계로 동작하는지 설명하고 있지만 앱 배포시 디플로이먼트를 사용했으므로 디플로이먼트를 기반으로 설명한다.
디플로이먼트는 파드와 레플리카셋에 대한 선언적 업데이트를 제공한다. 디플로이먼트를 생성하면 디플로이먼트는 레플리카셋을 생성한다. 위의 내용에서는 조회해보지 않았었지만 "kubectl get rs"로 조회하면 생성된 레플리카셋을 조회할 수 있다. 레플리카셋의 이름은 항상 "[디플로이먼트 이름]-[Random 문자열]" 형식으로 생성된다.
레플리카셋은 파드 집합의 실행을 안정적으로 유지해주며 보통 명시된 동일 파드 개수에 대한 가용성을 보증하는데 사용된다. 즉 레플리카셋은 지정된 수의 파드 레플리카가 항상 실행되도록 보장해준다. 그렇다고 해서 파드 변경시 레플리카셋을 직접 제어하는것은 권장되는 방법은 아니다. 디플로이먼트는 레플리카셋의 상위개념이므로 레플리카셋을 직접 제어하기 보다는 디플로이먼트를 변경하는것이 권장된다.
클러스터 외부에서는 곧바로 파드에 접근할 수 없다. 따라서 디플로이먼트에 의해 관리되는 파드들을 단일 서비스로 노출하기 위해서 디플로이먼트를 노출하는 서비스를 생성한다.
서비스를 통해서 노출해야 하는 이유는 파드가 일시적이기 때문이다. 누군가 삭제하거나 노드가 비 정상적이라면 파드는 언제든지 새 파드로 교체되고 이때 IP도 달라진다. 서비스는 항상 달라지는 IP 문제를 해결해주며, 여러 파드들을 단일 IP, 포트 쌍으로 노출시켜준다. 파드의 쌍들이 단일 서비스를 통해 노출되므로 어떤 요청이 서비스의 IP, 포트로 전달되면 서비스에 속한 파드들 중 하나로 전달된다.
- 쿠버네티스 대시보드
지금까지 앱을 배포할 때 kubectl 을 이용했지만 쿠버네티스는 UI를 통해서도 이런 작업을 할 수 있도록 대시보드를 제공한다. "minikube dashboard" 명령어를 수행하면 브라우저 창이 열린다. 아직 나머지 요소들에 대해 알지 못하므로 우선 이런 기능이 있다는것만 알아두도록 하자.
'Framework and Tool > Kubernetes' 카테고리의 다른 글
Kubernetes - Label 및 Annotation (0) | 2022.10.09 |
---|---|
Kubernetes - Pod (0) | 2022.10.09 |
Kubernetes - cluster 생성 (0) | 2022.10.06 |
Kubernetes - Docker basic (0) | 2022.10.06 |
Kubernetes - 개요 (0) | 2022.10.02 |
댓글