쿠버네티스 개요

2020-02-09

.

Data_Engineering_TIL_(20200209)

[study program]

  • T아카데미 ‘컨테이너 오케스트레이션 쿠버네티스 살펴보기’

  • URL : https://tacademy.skplanet.com/live/player/onlineLectureDetail.action?seq=162

[학습기록]

1. 쿠버네티스란 무엇인가

  • 2013년에 도커라는 개념이 등장하면서 서버관리 방식을 혁신적으로 바꾸고 있다.

  • 도커의 슬로건 “Build, Ship, and Run Any App, Anywhere” 처럼 빌드하고 쉬핑하고 어디서든지 실행할 수 있다는 것인다 여기서 빠진게 있다.

“그럼 배포는 어떻게해” 라는 부분인데 이 부분까지는 도커가 신경써서 구현되어 있지는 않다.

도커에서 가장 쉽게 배포할 수 있는 방법중에 하나로 아래와 같은 예시를 들 수 있다.

DOCKER_HOST=production.host.ip docker run -d -p 80:80 awesome-app

프로덕션호스트아피에 도커 명령어를 실행하는 것이다.

무슨말이냐면

특정 도커가 설치된 서버에 명령어를 내 로컬pc에서 할 수 있다. 다시말해 도커 호스트자리에 서버 아이피를 넣고 포트를 열어준다음에 런을 하면 원격서버에 있는 도커가 실행이 된다.

“그러면 이런거를 자동화 할 수 있는 방법이 없을까?” 라는 고민이 생겼다.

그래서 나온 것이 뉴렐릭에서 만든 ‘Centurion’이라는 툴이다.

URL : https://github.com/newrelic/centurion

A deployment tool for Docker NewRelic에서 만든 ruby기반의 도커 컨테이너 배포툴이다.

namespace :environment do
   task :common do
     set :image, 'example.com/newrelic/radio-radio'
     host 'docker-server-1.example.com'
     host 'docker-server-2.example.com'
   end

## 위에 호스트를 두번 왔다갔다 하면서 설정에 따라 스테이지나 프로덕션이냐에 따라서 원격으로 접속해서 도커 컨테이너를 실행시켜준다.

   desc 'Staging environment'
   task :staging => :common do
     set_current_environment(:staging)
     env_vars YOUR_ENV: 'staging'
     env_vars MY_DB: 'radio-db.example.com'
     host_port 10234, container_port: 9292
     host_volume '/mnt/volume1', container_volume: '/mnt/volume2'
   end

   desc 'Production environment'
   task :production => :common do
     set_current_environment(:production)
     env_vars YOUR_ENV: 'production'
     env_vars MY_DB: 'radio-db-prod.example.com'
     host_port 22234, container_port: 9292
     command ['/bin/bash', '-c', '/path/to/server -e production']
   end
end

설정법은 대략 위와 같다. 크게 어렵지는 않은 편이고 서버 2~3대까지는 이러한 방식으로 써도 편하고 큰 불편함이 없었다.

그런데 서버가 수십대 단위 이상이 된다면 매우매우 골치아파지게 된다.

중간에 배포중에 실패하는 경우가 생길수도 있고 실패했을때 조치도 취해줘야하는 문제들이 막 발생했다.

그래서 사람들이 이런 불편함을 인식해서 나온 개념이 ‘컨테이너 오케스트레이션’이다.

복잡한 서버를 효과적으로 관리하기 위해서다.

과거에 ‘데이즈’라는 툴이 있는데 요런 툴이 여러대의 서버를 손쉽게 관리해주겠다는 오케스트레이션 툴이었다.

‘렌처’라는 툴도 한참 인기를 끌었었다. 또 ‘메소스’라는 유명한 분산서버 관리툴이 있는데 여기에 ‘마라톤’이라는 툴을 붙여서 컨테이너를 관리할 수 있었다. 또는 ‘노마드’라는 툴도 있었다.

도커에서도 ‘도커스웜’이라는 툴을 내놓기도 했다.

그래서 저마다의 장점을 가진 다양한 오케스트레이션 툴들이 등장하는 컨테이너 관리도구 춘추전국시대가 있었다.

현재는 ‘쿠버네티스’가 싹다 정리했다고해도 무방하다.

2. 왜 그러면 ‘쿠버네티스’가 정리했고, 어떤 툴이길래 사람들이 대중적으로 쓰게 되었는가

  • Made in Google : 구글은 과거부터 1주일에 20억개의 컨테이너를 내렸다 올렸다 하는 작업을 수시로 하고 있었다. 그때 컨테이너 배포 시스템으로 사용하는 ‘보그’라는 툴이 있었는데 이걸 기반으로 만든 것이 쿠버네티스이다.

  • 데이즈나 랜처같은 툴은 본인들의 아키텍처가 있었는데 본인들의 아키텍처를 버리고 쿠버네티스 아키텍처상에서 커스터마이징해서 사용하기 시작한다. 또한 오슨쉬프트 등 쿠버네티스를 기반으로한 플랫폼들이 등장하기 시작했다.

  • 심지어 도커도 도커스웜을 밀어주고 싶었는데 너무 쿠버네티스의 영향력이 커져서 쿠버네티스를 지원할 수 밖에 없었다.

  • 클라우드 3사도 클라우드 네이티브한 쿠버네티스 서비스를 지원한다.

  • 과거에 서비스를 올리려고 하면 리눅스를 알아야하고 리눅스 명령어를 능숙하게 잘 해야했지만 이제는 쿠버네티스가 대신하고 있다.

“쿠버네티스는 컨테이너 응용 프로그램의 배포, 확장 및 관리를 자동화하는 오픈소스 시스템”

3. 쿠버네티스 특징

쿠버네티스는 프로덕션 수준의 컨테이너 오케스트레이션으로 기본기능을 충실하게 제공한다.

1) 상태관리

상태를 선언하고 선언한 상태를 유지 / 노드가 죽거나 컨테이너 응답이 없을 경우 자동으로 복구

2) 스케줄링

클러스터의 여러 노드 중 조건에 맞는 노드를 찾아 컨테이너를 배치

3) 클러스터

가상 네트워크를 통해 하나의 서버에 있는 것처럼 통신

4) 서비스 디스커버리

서로 다른 서비스를 쉽게 찾고 통신할 수 있음

5) 리소스 모니터링

cAdvisor를 통한 리소스 모니터링

6) 스케일링

리소스에 따라 자동으로 서비스를 조정함

7) RollOut/RollBack

배포/롤백 및 버전 관리

8) 빠른 업데이트

쿠버네티스는 현재 가장 빠르게 발전하고 있는 오픈소스

9) 다양한 배포방식

배포는 컨테이너를 클러스터에 올리는 건데 그거를 아래 그림과 같이 상황별로 다르게 적용할 수 있다.

  • DAEMON SET : 모든 노드에 하나씩만 띄우고 싶을때 예를 들어서 모든 서버를 모니터링하고 싶다하면 데몬셋을 사용하면 된다.

  • RELPICASET : 갯수를 제어하고 싶을때 예를들어서 나는 3대를 띄우고 싶다할때

  • STATEFUL SETS : 순서를 지정하고 싶을때 예를들어서 리플리카셋은 세대를 띄우면 알아서 세대가 뜨게 되는데 STATEFUL은 세대를 띄우라고 하면 첫번째가 뜨고 그다음에 두번째가 뜨고 다음에 세번째가 뜨는 이런방식이다. 크론잡같은 기능을 이용해서 하루에 한번씩 어떤 컨테이너를 실행해서 종료하는 그런 것도 만들 수 있다.

  • RELPICATION CONTROLLER는 REPLICASET과 비슷한데 현재는 잘 안쓰는 기능이다.

위와 같이 서버를 운영할때 필요한 배포방식을 다양하게 제공하고 있다.

3

10) ingress 설정

ingress는 쉽게 말해서 엔진엑스라고 보면 되는데 엔진엑스를 사용하려면 도메인 정보를 넣고 어떤 서버를 바라볼지 그 아이피랑 포트를 전부 설정해줘야 하는데 쿠버네티스는 인그레스라는 것이 그 역할을 해준다. 인그레스에 도메인 정보와 패스를 지정해주면 하위에 있는 서비스에 바로 붙일 수 가 있다. 아래 그림과 같이..

과거에는 내가 새로운 도메인을 따서 서비스를 붙이려고 하면 절차가 상당히 복잡한 편이었다. 예를 들어서 서버를 띄우고 엔진엑스 설정파일로 가서 추가해주고 필요하면 도메인 네임서버 설정가서 또 도메인네임 설정도 해줘야하는 번거로움이 있었는데 인그레스를 이용하면 그런 절차들을 다 자동화해줘서 편리하다.

4

11) Namespace & Label

사용자들이 적극적으로 사용하는 기능중에 하나이다.

5

12) RBAC

Role 관리 기능으로 도커스웜과 쿠버네티스와 차별되는 기능이다. 누가 어떤기능을 갖고 있는지에 대한 기능을 쿠버네티스에서는 상당히 쉽게 할 수 있다. 총 세가지로 나누어진다.

1) 누가

2) Pod(어떻게)

3) list, get create

조회할 수 있고, 배포할 수 있고 이런것들에 대한 권한을 줄 수 있다.

6

13) 다양한 지원

쿠버네티스는 다양한 환경을 지원한다.

예를 들어서 외부저장소를 연결한다 그러면 AWS 같은 경우에는 EBS를 붙일 수 있고 이런 기능들을 연결 할 수 있다.

  • Cluster Networking

ACI, Cilium, Contiv, Contrail, Flannel, Google Compute Engine (GCE), Kube-router, L2 networks and linux bridging, Multus (a Multi Network plugin), NSX-T, Nuage Networks VCS (Virtualized Cloud Services), OpenVSwitch, OVN (Open Virtual Networking), Project Calico, Romana, Weave Net from Weaveworks, CNI-Genie from Huawei

  • Volume Type

awsElasticBlockStore, azureDisk, azureFile, cephfs, configMap, csi, downwardAPI, emptyDir, fc (fibre channel), flocker, gcePersistentDisk, gitRepo, glusterfs, hostPath, iscsi, local, nfs, persistentVolumeClaim, projected, portworxVolume, quobyte, rbd, scaleIO, secret, storageos, vsphereVolume Ingress Service ingress-nginx, ingress-gce

위와 같이 다양하게 지원하며, 다양한 기능을 쉽게 커스터마이징 할 수 있어 여러 클라우드 서비스에 적절하게 적용할 수 있고 쿠버네티스 기반의 플랫폼이 나오기 쉬운 구조

4. 쿠버네티스 기본개념

1) Desired State

이 개념으로 쿠버네티스의 모든걸 구성했다고해도 과언이 아니다.

Current state가 현재상태이고, Desired state는 서버관리자가 뭔가 액션을 취해서 의도하고자 하는걸 구현한 상태이다.

쿠버네티스는 반복적으로 Current state에서 Desired state로 바꾸는 플랫폼이라고 할 수 있다.

예를 들어서 3개의 서비스를 띄우고 싶다라는 서버관리자의 의도가 있다면 그게 Desired state이고 Desired state로 갈 수 있도록 서비스, 네트워크, 스토리지 등 전반적인 조건을 매니징해준다.

즉 쿠버네티스는 Current state를 Desired state로 바꿔주는 툴이다.

7

2) Kubernetes Object

쿠버네티스는 위에서 state라는 개념을 object로 나누어서 관리하게 된다.

https://www.youtube.com/watch?v=4ht22ReBjno

8분동안 쿠버네티스 개념을 쉽게 소개한다.

요약 : PHP라는 앱이 있었고, 이걸 컨테이너로 만들었는데 컨테이너를 만들어준 고래에게 여러가지 요청을 했는데 자기는 그걸 할 수 없다면서 떠나고 캡틴 쿠버네티스가 나타나서 도와주는 내용이다.

3) Kubernetes Object - Pod

쿠버네티스는 컨테이너로 관리하는 것이 아니라 pod이라고해서 컨테이너를 하나 더 감싸서 관리를 하고 있고, 보통은 컨테이너 하나에 팟하나이지만 아래 그림과 같이 팟하나에 컨테이너 두대이상 들어가는 경우도 있다. 팟하나에 컨테이너가 두대이상 들어가게 되면 그 안에서 로컬호스트로 서로 통신도 할 수 있다.

8

4) Kubernetes Object - ReplicaSet

ReplicaSet은 replicas라는 옵션을 주게되면 동일한 팟을 여러개로 확장시킬 수 있다.

9

5) Kubernetes Object - etc

  • Service

  • Volume

  • Namespace

6) Object Spec - YAML

쿠버네티스가 어떤 종류의 상태를 관리하냐. pod이나 replicaset이나 service나 network라는 상태를 관리하게 된다. 그러면 그 상태를 어떻게 관리하냐인데 아래와 같이 YAML파일로 관리하게 된다.

야믈파일은 아래와 같이 키벨류 형태로 쓸 수 있고, 데쉬라는 짝대기를 이용해서 배열형식으로 쓸 수도 있다.

아래 야믈파일의 의미는 다음과 같다. “나는 팟을 하나 갖고 싶은데 팟의 이름은 ‘example’이고, ‘example’이라는 팟 안에는 하나의 컨테이너가 들어가 있는데 그 컨테이너의 이름은 ‘busybox’라는 이름이고 이미지는 busybox의 1.25버전의 컨테이너다.” 이 의미가 서버관리자가 의도하는 Desired state가 되는 것이다. 이 state를 야믈파일로 정의하고, 쿠버네티스에게 명령을하면 쿠버네티스는 이 정의된 내용을 만들기 위해 내부적으로 Desired state로 가기위해 current state를 바꿔주는 작업을 수행한다.

apiVersion: v1
kind: Pod
metadata:
       name: example
spec:
      containers:
      - name: busybox
           image: busybox:1.25

7) Kubernetes 사용하기

위에서 언급한 내용을 한줄로 요약하면

“원하는 상태(desired state)를 다양한 오브젝트(object)에 라벨Label을 붙여 정의(yaml)하고 API 서버에 전달” 한다는 것이다.

5. 쿠버네티스 아키텍처

1) Server - Agent

처음에 쿠버네티스를 어떻게 만들었을까 상상해보면 서버관리자가 어떤의도하는 액션을 요청하면 모든서버에 요청하지는 않을 것이고, 아래 그림과 같이 마스터서버에 먼저 요청할 것이다. 마스터서버에 요청하면 마스터서버가 각각의 노드서버에 명령을 전달하는 구조가 될것이다.

11

2) Master - Node

위에서 언급했던 구조가 더 발전한 개념이 아래 그림과 같을 것이다.

관리자가 명령을 하기 위해서 클라이언트를 하나 만들었는데 클라이언트 이름이 Kubectl이라는 이름이고, 클라이언트를 이용해서 야믈파일로 작성한 설정을 마스터에 전송을 하게되면 마스터 안에는 API서버가 돌고 있는데 API서버가 그거를 받고나서 각각의 노드에 전송을 해야하는데 직접적으로 도커를 실행하는 것이 아니라 도커를 실행해주는 kubelet이라는 것을 하나 만들어서 실행시키게 된다. 이 kubelet을 왜 만들었냐면 쿠버네티스는 무조건 도커를 쓰지는 않는다. 가상화와 관련된 기술을 다 쓸 수 있는데 예를들어서 구글에서 만든 클라이오라는 것도 쓸 수 있다. 어쨌든 이런 가상화 머신을 큐블릿에서 관리한다고 보면 되고 API서버에서 pod을 만들라는 명령어를 보내면 큐블릿이 받아서 팟을 대신생성해주고 팟의 현재상태가 어떤지를 다시 API서버에 전달해준다. 그러면 current state를 계속 알 수 있을테고, Desired state 요청이 오면 현재상태와 비교를 해서 조치를 취할 수 있을것이다.

12

  • Master

마스터 서버는 다양한 모듈이 확장성을 고려하여 기능별로 쪼개져 있는 것이 특징. 관리자만 접속할 수 있도록 보안 설정을 해야 하고 마스터 서버가 죽으면 클러스터를 관리할 수 없기 때문에 보통 3대를 구성하여 안정성을 높임

만약에 세대의 마스터서버를 운영하게 되면 각각의 서버마다 current state를 갖고 있을텐데 이게 서로 다르면 안되기 때문에 항상 세대가 전부 같은 current state가 되야하기 때문에 ‘etcd’라는 저장소를 갖고 있는데 이 저장소의 특징은 분산된 데이터를 항상 동일하게 맞춰주는 기능을 갖고 있다.

  • Node

노드 서버는 마스터 서버와 통신하면서 필요한 Pod을 생성하고 네트워크와 볼륨을 설정

  • kubectl : 명령도구로 실제 API서버에 명령을 내리는 커맨드라인 툴이다.

3) Master

etcd의 특징은 여러대의 서버를 분산해서 관리할 수 있는 데이터베이스이다. 그래서 etcd는 API서버와 끊임없이 통신한다. 만약에 pod을 하나 만드는 것이 Desired state라고 하면 저 etcd와 API서버는 끊임없이 정보를 교환한다. kube-controller가 현재 pod이 하나 있는지 물어보고 API서버가 etcd에 다시 물어봐서 결과를 알려준다. 이때 현재상태와 desired state가 다르면 팟을 하나 생성하라고 API서버에 알려준다. 그러면 API서버는 새로운 pod을 생성하라는 명령을 etcd에 쓰게되고 좌측상단에 스케쥴러가 새로운 팟이 생성되었는지 계속감시한다. 그런데 가운데 있는 컨트롤러가 새로운 팟을 생성하라고 했으니까 그것을 스케쥴러가 인식하고 여거개의 노드중에 어디에다 배치할까라는 것을 스케쥴러가 확인하고 처리를 해준다.

이런식으로 현재상태를 계속 확인하고 desired state로 갈 수 있게 각각의 역할을 수행하게 된다.

13

  • API Server

운영자 및 내부 노드와 통신하기 위한 인터페이스 / HTTP(S) RestAPI로 노출되어있고 모든 명령은 여기를 통함

  • Controller Manager

다양한 컨트롤러 (복제/배포/상태/크론/..)를 관리하고 API Server와 통신하여 작업을 수행

  • Scheduler

서비스를 리소스 상황에 맞게 적절한 노드에 배치하는 역할 / predicates와 priorities (LeastRequestedPriority, BalancedResourceAllocation,ServiceSpreadingPriority, EqualPriority) 설정

  • etcd

가볍고 빠른 분산형 key-value 저장소 / 설정 및 상태를 저장

4) Node

14

실제 서비스(컨테이너)가 실행되는 서버입니다. 마스터의 API Server와 통신하며 서비스를 생성하고 상태를 관리

  • kubelet

서비스(컨테이너)를 실행/중지하고 상태를 체크하여 계속해서 살아있는 상태로 관리

  • Proxy

네트워크 프록시와 로드 발란서 역할 (creates a iptable rule/…)

  • Docker(containerd 또는 rkt 또는 Hyper)

도커 뿐만 아니라 다양한 컨테이너 엔진을 지원

15

6. 쿠버네티스 단점

1) 복잡한 개념

공부할게 너무 많다. 쿠버네티스를 구성하고 관리하려면 알아야 할 내용이 많기 때문에 복잡한 클러스터를 구성하는게 아니라면 배보다 배꼽이 더 큰 상황은 아닌지 고민해봐야 한다.

2) 복잡한 설치

설치가 너무 어렵다. 클라우드를 이용하는 것을 권장한다.

한땀한땀 설치해보고 싶을때 참고URL : https://github.com/kelseyhightower/kubernetes-the-hard-way

3) 헤비한 환경

기본적으로 실행되는 프로그램이 많고 그에 따라 기본 리소스 사용이 많은 편이다.

4) 복잡한 설정파일

모든 설정이 마이크로서비스 스럽게 나뉘어져 있기 때문에 길고 복잡하다. swarm 설정과 비교해보자.

  • docker swarm
version: "3"
services:
   api:
      image: vfarcic/go-demo-2
      environment:
        - DB=db
      ports:
        - 8080
     deploy:
        replicas: 3
   db:
      image: mongo:3.3
  • kubernetes config file(뒤에 짤림..)

17

7. 질문사항

1) Pod을 IP로 설정관리 한다면, 이때 IP는 고정 IP인가요?

고정 IP를 쓸 수 있다. 중요한 점은 컨테이너는 언제 죽었다 살아날지 모르는 존재이기 때문에 이럴때마다 아이피는 항상 바뀔 수 밖에없고 그런 가정하에 쿠버네티스를 사용하는 것이 쿠버네티스의 철학이라고 보면된다. 또한 쿠버네티스 내부에 도메인을 관리하는 툴이 들어가 있기 때문에 아이피보다는 서버스의 이름으로 접근하는 것이 일반적이다.

2) 맺음맨트

야믈파일이 복잡해서 관리가 필요한 경우 헬름 등과 같이 패키지 매니저를 사용하는 경우가 많다.