개요
Google Cloud Skills Boost의 설명에 따르면, 쿠버네티스 클러스터는 다음과 같다.
Google Kubernetes Engine (이하 GKE)에서는 Google 인프라를 사용하여 컨테이너화된 애플리케이션을 배포, 관리 및 확장할 수 있는 관리형 환경을 제공한다. Kubernetes Engine 환경은 컨테이너 클러스터를 형성하도록 그룹화된 여러 머신(구체적으로 Compute Engine 인스턴스)으로 구성되어 있다.
쿠버네티스를 더욱 공부하다보면 알게 되겠지만, 쿠버네티스에는 컴퓨팅 리소스인 Node가 있고, 그 노드 안에 컨테이너를 실행시킬 수 있는 Pod가 존재하며, Pod 안에는 실제로 실행되어야 하는 어플리케이션 컨테이너가 존재한다. 그리고 이러한 Node를 관리하는 API 서버, Scheduler, Storage 등이 또 따로 존재하는데, 이러한 모든 것을 총칭하는 단어를 "쿠버네티스 클러스터"라고 생각하면 편리하다. 구글에서 공식으로 제공하는 다음 사진을 보고 간략하게 이해해보자.
각 요소들이 무엇을 의미하는 지는 아직 모를 수 있지만, 아키텍쳐를 보면 모든 것을 통틀어 말하는 개념이 쿠버네티스 클러스터라는 것을 알 수 있다. 이번 시간에는 이러한 클러스터를 생성하고, 클러스터에 배포하고, 삭제하는 방법을 배우게 된다.
작업 1. 기본 컴퓨팅 영역 설정
컴퓨팅 영역이란 클러스터와 리소스가 존재하는 리전 내 대략적인 위치를 의미한다. 예를 들어 us-central1-a는 us-central1 리전에 속한 영역이다. Google Cloud Platform(이하 GCP)에서는 먼저 리전(region)이 존재하고, 그 안에 컴퓨팅 영역(compute zone)이 존재한다. 컴퓨팅 영역은 1개 이상의 물리적인 데이터 센터를 엮은 논리적인 데이터 센터, 그리고 리전은 이러한 컴퓨팅 영역을 묶은 지리적인 영역이라고 생각하면 된다. AWS에서는 리전(region)과 가용영역(availability zone)에 각각 일치하는 개념이다.
정말 쉽게 말하자면 리전은 전 세계에서 어느 지역에 데이터 센터를 만들 것인지 결정하는 것이고, 컴퓨팅 영역은 그 지역의 어떤 데이터 센터를 선택할지를 결정하는 것이다. 아래는 GCP가 소개하는 전 세계의 리전들이다.
그럼 왜 이렇게 리전/컴퓨팅 영역을 나누어 놓았는지 궁금할 수 있다.
리전을 나누어 놓은 이유는 전 세계에 서비스를 제공하기 위해서이다. 이때 리전을 잘 선택하는 것이 중요한 이유는 GCP가 실제로 가지고 있는 물리적인 데이터 센터와 내가 서비스를 호스팅하고 있는 지역이 가까울수록 네트워크 지연 등이 적어지면서 원활하게 이루어질 수 있기 때문이다. 내가 한국에서 서비스를 제공하고 있는데, 내 GCP 리전이 북미에 있다면 당연히 네트워크 지연이 생길 것이다. 반면 Seoul 리전에 인프라를 구성해 놓았다면 비교적 네트워크 지연이 적어지게 된다.
컴퓨팅 영역을 나누어 놓은 이유는 가용성을 위해서이다. 내가 만든 서비스를 여러 컴퓨팅 영역에 걸처 구성해 놓았다면, 하나의 컴퓨팅 영역에 문제가 생겨도 서비스는 여전히 원활하게 제공되게 만들 수 있다. 이러한 의미를 가지고 있기 때문에 똑같은 개념을 AWS에서는 컴퓨팅 영역이 아니라 가용영역(availability zone)이라고 부른다.
리전과 컴퓨팅 영역에 대해 알았으니, 이제 Cloud Shell에서 구성을 변경해보자.
# 사용할 region과 zone 설정
gcloud config set compute/region [lab에서 설정된 region]
gcloud config set compute/zone [lab에서 설정된 zone]
사용할 리전과 영역을 설정해주었으니, 이 안에서 이제 쿠버네티스 클러스터를 만들어보자.
작업 2. GKE 클러스터 만들기
클러스터는 1개 이상의 클러스터 Master 머신과 여러 Worker 머신으로 구성됩니다. 위에서 컴퓨팅 리소스=Node라고 했으므로, 이 머신들은 노드라고 부를 수도 있다. 노드는 Compute Engine 가상 머신(VM) 인스턴스로 구현된다. 쉽게 말하자면 각 노드를 만들어 주기 위해 컴퓨팅 리소스가 필요한데, GCP에서는 이 컴퓨팅 리소스를 가상 머신으로 만들어서 구현한다는 뜻이다.
쿠버네티스를 직접 구축한다면 가상 머신을 하나하나 만들고, 이 가상 머신 중 Master node로 쓸 것과 Worker node로 쓸 것을 각각 설정해주어야 한다. 하지만 다행스럽게도 GKE를 통해 쿠버네티스 클러스터를 만들면 이 모든 일을 알아서 해준다(관리형 리소스 만세!) 다음 명령어를 통해 쿠버네티스 클러스터를 만들어주자.
gcloud container clusters create --machine-type=e2-medium --zone=[lab에서 설정된 zone] lab-cluster
만드는 데에는 약 5분 정도가 소요된다. 그리고 위에서 말한 대로, zone은 결국 리전보다 작은 개념이기 때문에 zone만 지정해주면 자동으로 리전이 어디인지 알 수 있다. 따라서 리전은 지정해주지 않아도 된다. 클러스터가 생성되면 다음과 같은 메세지가 출력된다.
작업 3. 클러스터의 사용자 인증 정보 얻기
클러스터를 만든 후 클러스터와 상호작용하려면 사용자 인증 정보가 필요하다. 다음 명령어로 간단하게 인증할 수 있다.
gcloud container clusters get-credentials lab-cluster
📌의문점
그런데 인증하는 과정에서 의문점이 2가지 정도 생겼다.
- 왜 내가 만든 클러스터에 인증을 해야 하는 걸까? 내가 만들었으니 당연히 나는 접근 가능해야 하는 것 아닌가?
- 무엇으로 인증하는 걸까? 인증서나 pem 키도 만들어준 적이 없는데 어떻게 인증하는 것인지 궁금해졌다.
왜 인증이 필요한지는 구글링해도 이유가 잘 나오지 않아서 GKE에 대해서 잘 아시는 분에게 여쭈어보았더니, Cloud Shell은 쿠버네티스 클러스터가 아니라고 한다. 나는 당연히 클라우드 쉘에서 클러스터를 생성하는 명령어를 쳐주었으니 클러스터에 접속이 되어 있을 줄 알았다. 그러나 클라우드 쉘은 그저 온라인 개발 및 운영 환경을 제공해주는 도구이기 때문에 클러스터에 접속하기 위해서는 따로 인증을 거쳐야 한다. 인증을 했을 때 출력되는 메세지 중 Fetching cluster endpoint
를 통해 클라우드 쉘과 클러스터는 다른 것이며 따라서 클러스터의 엔드포인트와 연결되어야 클러스터를 사용 할 수 있다는 힌트를 얻을 수 있다.
또한 무엇으로 인증하는지 찾아본 결과, 구글에서는 사용자 인증 키(credential key)를 통해서 인증을 관리한다고 한다. 사용자 인증 키는 서비스 계정에 할당된 키로, AWS의 Access Key 개념과 비슷하다고 이해하면 될 것 같다.
😲반전
여기까지 공부해본 결과, "그럼 인증 과정을 거치지 않고 바로 kubectl
명령어를 사용하면 에러가 발생하겠지?"라는 생각이 들었다. 그래서 다른 실습을 하나 더 시작해서 이번에는 인증 과정 없이 바로 kubectl
명령어를 실행해보았더니 결과는 다음과 같았다.
놀랍게도 인증 정보 없이도 노드를 조회하고 컨테이너를 배포하는 과정이 모두 정상적으로 작동했다. 이건 또 왜 그런 것인가...하면서 클러스터를 생성할 때 출력되는 메세지를 읽어보았더니 다음과 같은 문구가 있었다: kubeconfig entry generated for lab-cluster.
위에서 사용자 인증 정보 가져오기를 할 때 출력되었던 것과 같은 메세지였다. 그러니까 결론적으로는 1) 클라우드 쉘과 쿠버네티스 클러스터는 다른 것이기 때문에 클러스터에 접근하려면 인증이 필요하지만, 2) 클라우드 쉘에서 클러스터를 만들어주면 자동으로 인증을 하기 때문에 인증 과정이 필요하지 않다.
왜 인증하는 과정을 굳이 넣었는지 궁금했는데, 아마 이런 것들을 공부해 보라고 실습 중에 인증하는 작업을 넣은 것 같다.
작업 4. 클러스터에 애플리케이션 배포
클러스터가 만들어졌고 인증도 완료되었으니 이제 클러스터에 접근하여 컨테이너화된 애플리케이션을 배포할 수 있다. 구글에서 제공해주는 hello-app
이미지를 활용해서 배포를 생성하고, 이를 로드 밸런서를 통해 서비스를 노출해보자.
# 배포 생성
kubectl create deployment hello-server --image=gcr.io/google-samples/hello-app:1.0
# 서비스 노출
kubectl expose deployment hello-server --type=LoadBalancer --port 8080
위 명령어의 뜻은 다음과 같다.
--image
: 배포할 이미지를 지정한다.
kubectl create
: 지정된 이미지를 기반으로 배포를 생성한다.
--type=LoadBalancer
: 컨테이너의 Compute Engine 로드 밸런서를 생성한다.
--port
: 컨테이너가 노출될 포트를 지정한다.
kubectl expose
: 지정된 타입과 포트를 기반으로, 애플리케이션을 외부 트래픽에 노출할 수 있는 kubernetes service를 만든다.
이렇게 외부로 서비스를 노출한 후에는 로드 밸런서의 외부 아이피:8080
으로 접근할 수 있다.
작업 5. 클러스터 삭제
이제 모든 작업을 완료했으니 클러스터를 삭제해보자.
gcloud container clusters delete lab-cluster
5분쯤 기다리면 삭제가 완료된다.