GDSC SungShin Women's University 23-24/Story

[Winter Blog Challenge] 쿠버네티스 클러스터를 구축하는 방법(Member 장유정)

GDSC SungShin Team 2024. 1. 17. 16:48

GDSC Sungshin Univ 23-24 Member 장유정

 

저는 이번 학기에 ‘클라우드 컴퓨팅’이라는 전공 수업을 수강하면서 쿠버네티스에 대해 공부하고, 직접 클러스터를 구축해 배포하는 프로젝트를 진행했습니다. 처음 해보는 배포에 많이 헤매기도 하고 어려움을 겪기도 했는데요, 그 과정에서 체득한 여러 지식들과 클러스터를 직접 구축해 볼 수 있는 매뉴얼을 우리 GDSC 성신만을 위해 공유하려고 합니다😉

 

1. ‘쿠버네티스’ 란?

여러분이 만약 애플리케이션을 컨테이너를 사용해 배포했을 때 가장 중요한 것이 무엇일까요? 무엇보다 애플리케이션을 실행하는 컨테이너의 가동 중지 시간이 없는지, 즉 갑자기 컨테이너가 다운되더라도 고장 난 컨테이너 대신 다른 컨테이너가 자동 실행돼서 뜻하지 않는 서비스 중단 사태가 벌어지지 않도록 신경 써야 합니다. 그럼 이것을 시스템이 자동으로 관리하고 처리해 준다면 좋겠죠? 그걸 구현한 것이 바로 쿠버네티스입니다.

쿠버네티스는 분산 시스템을 탄력적으로 실행하기 위한 프레임워크를 제공합니다. 예를 들면 애플리케이션 확장이나 장애 조치를 처리하고 배포 패턴 등을 제공합니다. 대규모의 프로덕션 워크로드를 15년 이상 운영해 온 구글이 자신들의 노하우를 담은 쿠버네티스를 전 세계 개발자들을 위해 오픈소스화한 것입니다.

 


2. 오브젝트 구성

쿠버네티스 클러스터를 구성하는 오브젝트는 정말 다양한데요, 다 다룰 순 없으니 이번에 저희가 직접 구현해 볼 SC 통신 프로젝트의 클러스터 구성도를 보며 해당 클러스터를 구성하는 오브젝트들에 대해서 간단히 알아보겠습니다.

 

[1] Pod 파드

파드는 쿠버네티스 애플리케이션의 기본 실행 단위입니다. 한 개 이상의 컨테이너를 담을 수 있는데 저는 하나의 파드 당 하나의 컨테이너를 실행하도록 구성했으므로 편하게 컨테이너 자체라고 생각해도 괜찮습니다.

[2] Deployment 디플로이먼트

디플로이먼트는 파드의 개수를 유지해 주는 역할을 합니다. 아까 위에서 하나의 컨테이너가 장애를 일으키면 그것을 대체할 컨테이너가 신속하게 작동하도록 하는 것이 쿠버네티스의 역할이라고 했었죠? 디플로이먼트가 바로 그 역할을 하는 것입니다. 제 클러스터에서는 백엔드와 프론트엔드의 디플로이먼트가 파드들을 세 개씩 유지 관리 해줍니다.

(실시간 채팅을 구현하는 소켓 통신의 오류로 인해 현재 파드는 하나로 축소한 상태입니다.)

[3] 데이터베이스: Persistent Volume + Statefulset + Secret

데이터베이스를 보시면 백엔드나 프론트엔드와 다르게 디플로이먼트가 아닌 ‘스테이트풀셋’이 데이터베이스 파드 하나를 관리합니다. 파드의 경우 일시적인 존재라서 한번 삭제되면 파드에 저장된 내용이 모두 함께 삭제됩니다. 프론트나 백은 삭제돼도 바로 재부팅 하면 되므로 치명적이지 않지만 데이터베이스 파드는 안에 중요한 정보가 담겨있을 경우 삭제하는 것 자체가 큰 문제가 됩니다.

그래서 ‘퍼시스턴트 볼륨’을 사용해서 데이터를 파드 안에 저장하는 것이 아닌 외부에 저장하여 보존할 수 있습니다. 그리고 이렇게 데이터를 관리하는 파드에 적합한 컨트롤러가 ‘스테이트풀셋’인거죠.

여기서 데이터베이스에 특이점이 한 가지 더 있습니다. 바로 ‘시크릿’입니다. 시크릿은 말 그대로 암호화해야 하는 정보(DB 비밀번호, 토큰, 키 등등)를 base 64로 인코딩해서 저장해 보관하는 오브젝트입니다. 제 클러스터의 경우에 DB 비밀번호를 암호화해 저장해뒀습니다.

 

[4] Service 서비스

그럼 저 세 가지 종류의 파드들은 서로 어떻게 통신하고, 또 외부와는 어떻게 통신하는 걸까요? 그 역할을 해주는 것이 서비스입니다. 보시면 프론트엔드, 백엔드, 데이터베이스 모두에게 서비스가 존재하는 것을 볼 수 있습니다. 서비스의 종류는 다양한데, 제 클러스터의 경우는 디폴트인 클러스터 IP로 설정해 클러스터 내부에서는 서로의 서비스 이름으로, 외부에서는 인그레스를 통해서 통신하도록 구성했습니다.

[5] Ingress 인그레스

인그레스는 외부 클라이언트와 클러스터 내부를 이어주는 역할을 합니다. 외부와 통신이 필요한 프론트엔드와 백엔드의 서비스가 인그레스를 통하지 않고 외부와 바로 통신하도록 각 포트를 외부로 노출시키는 노드 포트 서비스나 로드 밸런서를 사용하는 방법도 있지만, 저는 하나의 엔드포인트로 모든 요청이 들어오는 것을 원했고, 서비스를 외부로 노출시키는 것이 상대적으로 보안성이 떨어진다고 판단했기 때문에 두 개의 서비스는 클러스터 내부에 두고 대신 인그레스를 최상단에 위치시켰습니다 .

그럼 인그레스가 각 요청에 대해 어떻게 작동하는지 아래 통신 원리를 통해 자세히 알아보겠습니다.

 

우선 외부에서 요청이 들어오면 url 경로에 따라 각 서비스 포트로 포워딩해 줍니다. ‘/’경로의 경우에는 80번 포트의 프론트엔드 서비스로, ‘/api’ 혹은 ‘socket.io’의 경우에는 5000번 포트의 백엔드 서비스로 포워딩해 줍니다.

이후에는 각 서비스가 알아서 각 파드 포트로 요청을 전달해줍니다.

3. 쿠버네티스 클러스터 직접 구축하기

이제 복잡한 설명은 그만하고 클러스터를 직접 구축해 봅시다!

1) 쿠버네티스 클러스터 환경 구축하기

ㄱ. 구글 클라우드 플랫폼(GCP)에서 Kubernetes 클러스터를 생성한다

ㄴ. 클러스터 기본 사항: 리전(동북아시아), 제어 영역 버전(정적)

 

ㄷ. 노드 설정 최소 스펙: 이미지 유형(Ubuntu), 시리즈(N1), 머신 유형(커스텀),코어1, 메모리1, 부팅 디스크 크기(10)

 

ㄹ. Google Cloud SDK 설치 – 공식 문서 매뉴얼 확인

 

ㅁ. 생성된 클러스터의 연결 버튼을 눌러 연결 명령어를 복사한다.

 

ㅂ. 터미널 혹은 WSL에서 명령어를 실행하고 클러스터에 연결한다


2) 오브젝트 매니페스트 파일 가져오기

깃허브 소스: https://github.com/JangYouJung/Kubernetes

위의 깃허브 링크에서 ‘직접 구축용’ 디렉토리에 있는 매니페스트 파일을 클론해온다.

  • sc-backend.yml
  • sc-frontend.yml
  • sc-database.yml
  • sc-ingress.yml
  • sc-db-secret.yml

3) 클러스터에서 오브젝트 생성하기: 아래 순서대로 각 파일을 apply 명령어를 사용해 적용한다.

명령어: $kubectl apply –f [파일 명]

sc-db-secret.yml sc-database.yml

sc-backend.yml sc-frontend.yml sc-ingress.yml

 

4) 호스트 파일을 수정해서 로컬 도메인 네임 등록하기

⟾ Hosts 파일 경로 ⟽ Windows: C:\Windows\System32\drivers\etc\hosts MacOS: /etc/hosts

호스트 파일에 아래 내용을 입력해 저장한다.

[인그레스의 External IP]	sc-chatting.com

아래 명령어를 사용하면 내 인그레스의 External IP를 확인할 수 있다.

⟾ 명령어: $kubectl get ingress

명령어 입력 후 출력되는 ‘ADDRESS’ 항목을 확인하면 된다.

 

5) Chrome에서 ‘sc-chatting.com’ 접속하기

완료!

클러스터 구축 과정 중 발생하는 오류나 질문은 아래로 문의해주세요

https://github.com/JangYouJung/Kubernetes/discussions

 

 

참고 문헌

  1. 쿠버네티스 정의: https://kubernetes.io/ko/docs/concepts/overview/