쿠버네티스는 왜 쓰는건가?

쓰여진 날: by Creative Commons Licence

쿠버네티스는 단지 클라우드에 대한 관심으로 처음 접하게 되었고 공부하게 되었다. 개인적으로는 쿠버네티스는 진입장벽이 꽤 높다. 특히 나처럼 클라우드와 관련없는 분야에 있고, cs에 지식이 없다면 매우 높을 것이다. 쿠버네티스를 익히면서도 이걸 왜 써야하는지 한참 나중에 이해했고, 관련 용어, 개념도 일단 받아들이고 공부하다 나중에야 이해하기 시작했다. 쿠버네티스는 그 양이 너무나 방대해서 다 알기는 어렵다. 기초만 잘 이해하고 나에게 필요한 부분을 검색해서 쓰는 것이 중요한 듯 하다. 이번 구글 스터디잼 통합반을 참여하면서 배우게 된 것을 정리하고자 포스트를 남긴다. 이번 포스트는 다음의 순서로 쓸 에정.

  1. 쿠버네티스의 목적, 구조, 구성
  2. 기본적인 튜토리얼

쿠버네티스란?

컨테이너는 10년이 넘게 발전해오면서 현재는 거의 모든 개발자들이 알아야할 필수 기술이 되었다. 개발, 테스트, 배포에서 모두 동일하게 동작하고 어떤 머신을 쓰던 동일한 환경을 구성할 수 있기 때문이다. 그것도 단 하나의 파일로. 컨테이너가 보편화되면서 마이크로서비스가 가능해지기도 했다. 또 컨테이너가 보편화되고 클라우드 기술마저 이를 지원하니 일반 개발자도 운영을 관리하게 되면서 데브옵스라는 용어도 나오기 시작했다. 구글에서는 하루에 약 10억개 정도의 컨테이너가 생성된다고 한다. 나만해도 하루에 수십개의 컨테이너를 생성한다. 개인이 수많은 컨테이너를 생성하면서 이 컨테이너를 어떻게 관리할지에 대한 문제가 생겼고 컨테이너 오케스트레이션이라는 기술이 나오기 시작했다. 간단하게 많은 컨테이너를 관리하는건데 쿠버네티스가 대표적인 예이다. 구글은 내부적으로 개발해 온 Borg 를 쿠버네티스란 이름으로 공개했다. 현재는 CNCF에서 관리하고 있다. 만약 도커에 대해 잘 모른다면 서비큐라님의 블로그를 보자. 여기에 쿠버네티스 글도 있으니 같이 보자.

Kubernetes는 조타기라는 의미로 컨테이너를 다룬다는 의미인 듯 하다. 쿠버네티스가 할 수 있는 것, 사용한느 이유 몇가지를 나열해본다.

  1. 하나의 서버(마스터 노드)에서 어떻게 여러개의 다른 서버들(워커 노드)에 컨테이너를 만들고 실행시키고 또 다른 동작을 시킬 것인가?
  2. 컨테이너를 몇개의 노드(서버)에 배포하여 실행시킬 것인가?
  3. 다른 서버에 있는 컨테이너가 실행중 에러로 실패하면 어떻게 처리할 것이가?
  4. 컨테이너끼리의 연결, 스토리지 연결은 어떻게 할 것인가?

한대나 두대의 컴퓨터에서 위의 문제를 처리하려면 사실 도커의 기능들과 간단한 서버를 만들면 해결할 수 있다고 생각되기도 한다. 그런데 실제로 훨씬 더 많은 요구사항들이 있고 훨씬 더 많은 서버들이 있다고 생각하면 복잡해지는데 쿠버네티스가 이런 머리 아픈 상황을 위해 만들어진 것이다. 쿠버네티스는 간단하게 내 명령을 수행해주는 프로그램이다. 내 노트북에서 kubectl 명령어를 치면 마스터 서버의 API 서버를 통해 다른 서버들로 요청이 가는데 이 때 어떤 서버로, 어떻게 배치할지는 쿠버네티스가 알아서 한다. 명령을 받은 서버는 받은 명령을 수행하게 되는데 kubelet이라는 프로그램이 각 서버에서 명령이 잘 이행되고 있는지 감시하게 된다. 이 상황에서 내 컴퓨터를 유저, 유저의 명령을 실제 명령이 수행될 서버로 전달하는 서버를 마스터 노드라고 하고 명령을 받는 서버들을 워커 노드라 부르며, 마스터와 워커 노드를 합쳐 하나의 클러스터라고 부른다. 일반적으로는 안전을 위해 한 클러스터를 여러개의 마스터 노드와 수많은 워커 노드로 구성한다.

pod

포드(pod)는 쿠버네티스의 가장 작은 작업 단위로 하나 이상의 컨테이너가 들어있는 것이 포드라고 보면 된다. 하나의 컨테이너 이미지만 실행하고 싶어도 포드 안에서 실행된다. 한 포드안에 컨네이너들은 네트워크, 스토리지를 공유하게 된다. 여러대의 포드는 기본적으로 서로 연결되있지는 않으며 설정을 통해 연결 가능하다. 또 포드들은 외부와 직접적으로 연결되어 있지는 않다. 외부세계와 연결된 것은 노드 뿐이고 노드 안에 여러 포드들은 노드를 통해 외부와 접촉하게 된다. 물론 노드들도 마스터 노드와 연결되어 있을뿐 서로의 연관은 없다. 실제 쿠버네티스를 사용하게 된다면 deployments 객체를 통해 사용하게 될 것이다. Deployments는 pod을 관리하는 객체이다. 그리고 그 전에 pod은 replicaset을 통해 관리된다. replicaset을 몇 개의 복제 포드를 배포할지에 대한 객체이다. deployments > replicasets > pod 과 같은 관계로 이해된다. Deployments는 포드들의 생성, 업데이트, 롤백, 스케일링을 하고 이 과정에서 Replicaset을 사용하게 된다. 아주 간략하게 예를 들어 한 엡을 배포할 때 이런식으로 결정하게 된다. hello-world 라는 이름의 배포를 helloworld-app을 세개를 생성하고 hello라는 라벨을 붙여 유지해서 배포하는 것이다.

Deployment
  - name: hello-world
ReplicaSet
  - replicas: 3
  - selector:
    - app: hello
Pod
  - containers:
    - image: helloworld-app

연속적인 상태의 포드를 사용해야한다면 StatefulSet을 사용해야 한다. Deployments를 통해 생성된 포드들은 스펙은 같지만 완전히 동일한 것은 아니다. 이런 경우 완전히 같은 아이덴티티를 가진 포드를 만드는 것이 statefulset이다. Statefulset 이외에도 여러가지 종류가 있다.

service

기본적으로 쿠버네티스로 생성된 작업은 어느것과도 연결되어 있지 않다. (한 포드안의 컨테이너들 제외) 포드와 포드, 노드와 노드 혹은 외부세계로의 연결을 책임지는 것이 service이다. 모든 연결은 service를 통해 정의한다. Service의 몇가지 주요 대표기능에는 ClusterIP, NodePort, LoadBalancer가 있는데 각각의 쓰임새를 한번 보자.

  • ClusterIP: 클러스터 안에서만 접근가능한 IP를 노출시킨다. 즉, 클러스터 내부 자원끼리만 연결이 가능하다.
  • NodePort: 각 노드의 IP를 특정 포트에 노출시킨다.
  • LoadBalancer: 클러스터를 외부세계에 노출시킨다. 이 때 로드밸런싱은 클라우드 제공자의 기능을 쓰게된다. Global http 로드밸런싱의 경우 인그레스 객체를 사용해야 한다.

etc

이외에도 단순히 어떤 작업을 수행하는 Job 이라는 객체등 여러가지 개념들이 존재한다. 쿠버네티스를 볼수록 이걸 다 안다는 건 불가능할 거라는 생각이 든다. 이런 것들이 있다는 것만 알아두고 나중에 검색해서 사용해야겠다. 내용이 이렇게 방대하니 udacity, udemy, coursera와 같은 온라인 강의 사이트에서도 많은 것을 다루지 않는다. 가장 기본적인 개념들을 소개하고 쿠버네티스가 무얼할 수 있는 것인지와 간단한 튜토리얼을 해보는 정도이다. 기능이 너무 많으니 한가지 태스크를 하는데도 여러 방법을 통해서 할 수 있다. 필자는 udemy와 udacity에서 강의를 제일 처음 들어봤는데 이때까지는 명렁어는 따라쳐보고 대충이런걸 하는구나만 알았고 그 내부가 어떻게 돌아가는지는 사실 제대로 모르고 듣기만 했다. 그도 그럴 것이 대부분의 강의가 겉핥기식으로 진행되기 때문이다. 이런에 스터디잼 강의를 통해 코세라 강의를 들었는데 구글이 만든거라 그런지 설명을 자세하게 해주고 가장 기본적인 개념을 설명해주니 응용되는 것은 자연스레 이해가 쉽게 되는 거 같다. 쿠버네티스를 공부하려면 가장 기본 개념부터 하는걸 추천한다.

참고

  • 구글 클라우드 스터디잼 가이드 - 박찬성