본문 바로가기
클라우드/Kubernetes

쿠버네티스 - 오브젝트

by Cloud_Park 2020. 1. 7.

쿠버네티스 소개

컨테이터 운영환경 중 가장 널리 사용되는 솔루션이 kubernetes(K8s=K와 S사이에 8개의 문자가 있어서) 이다.

구글은 내부 서비스를 클라우드 환경에서 운영하고 있으며  컨테이너 환경을 사용해왔다. 구글의 내부 컨테이너 서비스를 Borg라 하는데 , 이 구조를 오픈소스화한 것이 쿠버네티스이다.

Go언어로 구현되었으며 ,  벤더나 플랫폼에 종속되지 않기 때문에, 대부분의 퍼를릭 클라우드에 사용가능하고 오픈스택과같은 프라이빛 클라우드 구축환경이나 또는 베어메탈에도 배포가능하다.

여러 퍼블릭 클라우드를 섞어서 사용하는  온프레미스/퍼블릭클라우드를 혼용해서 쓰는  하이브리드클라우드으로 많이 각광받고 있다.

 

 

마스터와 노드

쿠버네티스를 이해하기 위해 클러스터 구조를 이해할 필요가 있다.  구조는 매우 간단하다. 클러스터 전체를 관리하는 마스터,  컨테이너가 배포되는 노드가 존재한다.

 

 

오브젝트

쿠버네티스를 이해하기 위해 가장 중요한 부분이 오브젝트이다. 가장 기본적인 단위가 되는  기본 오브젝트와  이를 생성하고 관리하는 컨트롤러로 이루어진다. 그리고  이러한 오브젝트의 스펙(설정) 이외에 추가정보인 메타정보들로 구성된다.

 

오프젝트 스펙 

오프젝트 스펙은  모두 특성을 기술한 오브젝트 스팩으로 정의가 되고  커맨드 라인을 통해서 오브젝트 생성시 인자로 전달되어 정의하거나 Yaml이나 json파일로 정의된다.

 

 

기본 오브젝트

쿠버네티스에 의해서 배포 및 관리되는 가장 기본적인 오프젝트는 컨테이너화 되어 배포되는 애플리케이션의 워크로드를 기술하는 오브젝트로 pod(어플리케이션),service(로드벨런서), volume(디스크),namespace(패치지명) 4가지가 있다.

 

 

Pod

Pod는 쿠버네티스에서 가장 기본적인 배포 단위로 컨테이너를 포함하는 단위이다.

쿠버네티스 특징중 하나는  컨테이너를 개별적으로 하나씩 배포하는 것이 아니라 pod라는 단위로 배포하는데  pod에는 1개 또는 여러개의 컨테이너가 포함될 수 있다.

yaml 예제

apiVersion: v1   //버전설정  참고자료

kind: Pod           //종류 

metadata:         //메타데이터

 name: apache  //리소스에 대한 스펙   

spec:

 containers:

 -name:apache

  image: apache:latest     // 이미지 버전

  ports:

  -containerPort: 8090    //컨테이너 포트 8090을 오픈한다.

 

pod의 특징

1. pod 내의 컨테이너는 IP와 Port를 공유한다.

 파드에 A,B 컨테이너가 있고 A는 1111포트, B는 2222 포트로 배포되어있다.   A에서 B를 호출할때 localhost:2222,B에서 A를 호출할때 localhost:1111로 호출할 수 있다.

2. Pod안에 있는 컨테이너간에 디스크 볼륨을 공유할 수 있다.

 

 

 

 

 

 

 

 

Volume

pod가 기동할때 디폴트로 컨테이너마다 로컬 디스트를 생성해서 기동되는데, 이 로컬 디스크의 경우에는 영구적이지 못하다. 즉 컨테이너가 리스타트 되거나 새로 배포될때 마다 로컬디스크 pod 설정에 따라 새롭게  정의되서 배포되기 때문에 , 디스크에

기록된 내용이 유실된다.

데이터 베이스와 같은 영구적으로 파일을 저장해야하는 경우에는 컨테이너 리스타트에 상관없이 파일을 영구적으로 저장해야하는데 이러한 형태의 스토리지를 볼륨이라고 한다.

볼륨은 컨테이너의 외장 디스크로 생각하면되고 pod가 기동할 때  컨테이너에 마운트 해서 사용한다.

 

 

 

웹서버를  배포하는 pod가 있을 때, 웹서비스를 하는 web server 컨테이너, 그리고 컨텐츠의 내용 /htdocs 를 업데이트하고 관리하는 Content mgmt 컨테이너 그리고 로그 메시지를 관리한느 Logger라는 컨테이너가 있다고 하자

 

  • WebServer 컨테이너는 htdocs 디렉토리의 컨테이너를 서비스하고, /logs 디렉토리에 웹 엑세스 기록을 기록한다.

  • Content 컨테이너는 htdocs 디렉토리의 컨텐트를 업데이트하고 관리한다.

  • Logger 컨테이너는 logs 디렉토리의 로그를 수집한다.

 

이 경우 htcdocs 컨텐츠 디렉토리는 WebServer와 Content 컨테이너가 공유해야하고  logs 디렉토리는 Webserver와  Logger 컨테이너가 공유해야한다.

 

아래와 같이 htdocs와 logs 볼륨을 각각 생성한 후에 htcdocs는 webServer와 Contents management 컨테이너에 마운트해서 공유하고 logs 볼륨은 logger 와  WebServer 컨테이너에서 공유하도록하면된다.

 

 

 

쿠버네티스는 다양한 외장 디스크를 추상화된 형태로 제공한다.  iscsi나 nfs와 같은 온프레미스 기반의 일반적인 외장 스토리지 외에도  클라우드 외장 스토리지인 aws ebs, google pd에서 부터 github,flusterfs와 같은  다양한 오픈소스 기반의 외장 스토리지나 스토리지 서비스를 지원하여 스토리지 아케텍처 설계 다양한 옵션을 제공한다.

 

Service

pod와 볼륨을 이용하여 컨테이너들을 정의한후에 pod를 서비스로 제공할때 일반적으로 분산적인 분산환경에서는 하나의 pod로 서비스하는 경우는 드물고, 여러개의 pod를 서비스하면서, 이를 로드밸런서를 이용해서 하나의 IP와 포트로 묶어서 서비스를 제공한다.

 

Pod의 경우에는 동적으로 생성이 되고 장애가 생기면 자동으로 리스타트 되면서 그 Ip가 바뀌기 때문에 로드밸런서에서 Pod의 목록을 지정할 때는  IP주소를 사용하기 어렵다. 또한 오토 스케일링으로 인하여 Pod가 동적으로 추가 또는 삭제 되기 떄문에 이렇게  추가/삭제된 pod 목록을 로드밸런서가 유연하게 선택해 줘야한다.

그래서 사용하는 것이 라벨과 라벨 설렉터라는 개념이다.

 

서비스를 정의할때, 어떤 Pod를 서비스로 묶을 것인지를 정의하는데 이를 라벨 설렉터라고 한다. 각 pod를 생성할때 메타데이타 정보 부분에 라벨을 정의할 수 있다.  서비스는 라벨 셀렉터에서 특정 라벨을 가지고 있는 pod만 선택하여 서비스에 묶게된다.

아래 그림은 서비스가  라벨이 myapp 인 서비스만골라서 서비스에 넣고 그 pod간에만 로드밸런싱을 통하여 외부로 서비스를 제공하는 형태이다.

service.yaml

 

kind: Service   //리소스 종류 

apiVersion: v1 //스크립트할 버전

metadata:    //메타데이터

 name: my-service

spex:          // 스펙 정리  ( 셀렉터, 프로토콜, 포트 , 타켓 포트)

 selector:

  app:myapp

 ports:

 - protocol: TCP

   port: 80

   targetPort: 9376

 

 

 

 

Namespace

네임 스페이스는  한 쿠버네티스 클러스터내의  논리적인 분리단위라고 보면 된다.

pod,Service 등은  네임스페이스 별로 생성이나 관리가 될 수 있고 사용자의 권한 역시 이 네임스페이스 별로 나눠서 부여할 수 있다.

즉 하나의 클러스터 내에 , 개발/운영/테스트 환경이 있을 때 클러스터를 개발/운영/테스트 3개 네임스페이스로 나눠서 운영할 수 있다.

특징

사용자 별로 네임스페이스별 접근 권한을 다르게 운영할 수있다.

네임스페이스 별로 할당량을 지정할 수 있다.

네임스페이스 별로 리소스를 나눠서 관린할 수 있다.

 

주의할점은 네임스페이스는 논리적인 분리 단위이지 물리적이나 기타 장치를 통해서 환경을 분리한 것이 아니다. 다른 네임 스페이스간의 pod라도 통신은 가능하다.

물론 네트워크 정책을 이용하여 네임스페이스간의 통신을 막을 수 있지만 높은 수준의 분리 정책을 원하는 경우에는 쿠버네시스 클러스터 자체를 분리하는 것을 권장한다.

 

 

 

 

 

라벨

앞에서 잠깐 언급햇던 것 중의 하나가 Labe인데 , 라벨은 쿠버네티스의 리소스를 선택하는데 사용이 된다. 각 리소스는 라벨을 가질수 있고 , 라벨 검색 조건에 따라서 특정 라벨을 가지고 있는 리소스만을 선택할 수 있다.

이렇게 라벨을 선책하여 특정 리소스만 배포하거나 업데이트할 수 있고 또는 라벨로 선택된 리소스만 Service에 연결하거나 특정 라벨로 선택된 리소스에만 네트워크 접근 권한을 부여하는 등의 행위를 할 수 있다.

라벨은 metadata 섹션에서  key/value의 쌍으로 가능하며 하나의 리소스에는 하나의  라벨이아니라 여러 라벨을 동시에 적용할 수 있다.

 

"metadata": {

 "labels": {

   "key": "value",

   "key1": "value"

 }

}

 

 

셀럭터를 사용하는 방법은 오브젝트 스펙에서 selector라고 정의하고 라벨 조건을 적어 놓으면 된다.

쿠버네티스에서는 두 가지 셀렉터를 제공한느데 기본적으로 equalilty baseed selector와 Set based selector가 있다.

조건을 사용하여 리소스를 선택하는 방법으로

environment= dev

tier != frontend

식으로  등가조건에 따라 리소스를 선택한다.

이보다 향상된 셀렉터는 집합개념을 사용한다

environment in (a,b,c)는 a,b,c인 경우이고

tier not in(a,b)  a,b 둘다 아닌 리소스를 선택하는 방법이다.

 

다음 예제는 my-server라는 이름의 서비스를 정의한 것으로 셀렉터에서 app:myapp정의해서 pod의 라벨 app이 myapp것만 골라서 이서비스에 바인딩해서 9763포트로 서비스하는 예제이다.

 

service.yaml

 

 

kind: Service

apiVersion: v1

metadata:

 name: my-service

spex:

 selector:

  app: myapp

ports:

 - portocol: TCP

   port: 80

   targetPort: 9376

 

 

 

 

 

 

컨트롤러

기본오브젝트로 애플리케이션을 설졍하고 배포하는 것이 가능한데 이를 조금 더 편리하게 관리하기 위해서 쿠버네티스는 컨트롤러라는 개념을 사용한다.

컨트롤러는 기본 오브젝트들을 생성하고 이를 관리하는 역할을 해준다 . 컨트롤러는 Relication Controller,Replication set, DaemonSet , Job, StatefulSet, Deployment들이 있다. 각자의 개념에서 알아보면

 

Replication Controller

pod를 관리해주는 역활을 한다 . Pod를  지정된 수만큼 기동시키고 관리한다. Replica의 수(수만큼 pod를 유지 시켜줌), pod Selector(라벨을 기반으로 pod를 가지고 옴), Pod Template(도커이미지, 포트, 라벨등 정보) 3가지로 구성된다.

주의할점은 이미 돌고 있는 pod가 있는 상태에서  RC 리소스를 생성하면 그 Pod의 라벨이 RC의 라벨과 일치하면 새롭게 생성된 RC컨트롤을 받는다. 만약 해당 Pod 들이  RC에서 정의한 replica 수 보다 많으면  replica 수에 맞게 추가분의

pod를 삭제하고  모자르면 template에 정의된 pod정보에 따라서 새로운 pod를 생성하는데 기존에 생성되어 잇는 pod가  template에 정의된 스펙과 다를지라도 그 pod를 삭제하지 않는다 .예를들어 기존에  아파치  웹서버로 기동중인 pod가 있고

Pc의 template은 neginx로 pod를 실행하게 되어 있다고하더라고  기존에 둘고잇는 아파치 웹서버기반의 pod 를 삭제하지 않는다

 

 

예제

 

apiVersion: v1

kind: ReplicationController

metadata:

 name: nginx

spex:

 repilcas: 3

 selector:

  app: nginx

template:

 matadata:

  name: nginx

  label:

   app: nginx

 spex:

   conatiners:

   - name: nginx

     image: nginx

     ports:

     - containerPort: 80

 

 

 이 예제는 nginx라는  이름의 RC를 저정의한것이고 label이 app: nginx인 pod들을 관리하고 3개의 pod가 항상 운영되도록 설정한다. Pod는 app: nginx라는 라벨을 가지면서 이름이 nginx이고 이미지도 nginx를 사용하여 생성하고 컨테이너의

포트번호는 80을 제공한다.

 

ReplicaSet

replicaset은 ReplicationController의 새번전이라 생각하면 된다.

큰 차이는 없고 Replication Controller는 Equality기반 selector를 사용하는데반해 replicaset은  set기반 selector를 이용한다.

 

Deployment

deployment는 Replication Controller와 ReplicaSet의 좀더 추상화 계념이다  실제 운영에서는  조금더 추상화된 Deployment를 사용하게된다.

 

 

 

쿠버네티스의 이해

 

쿠버네티스의 Deployment 리소스를 이해하기 위해서  쿠버네티스에서 Deployment 없이 어떻게 배포하는지에 대해 이해하면  deployment를 이해하기 쉽다.

다음과 같이  Pod와 RC가 있다고 가정하자

애플리케이션이 업데이트되서 새로운 버전으로  컨테이너를 굽고 이 컨테이너를 배포하는 시나리오에 대해 알아보자.

여러가지 배포전략이 있겟지만. 많이 사용하는 블루/그린 과 롤링업데이트 방식 두가지 방법에 대해서 설명한다.

 

블루그린 배포

 

이전 서비스하고 있던 시스템을  새로운 버전을 배포후 , 트레픽을 블루에서 그린으로 한번에 돌리는 방식이다.

여러가지 방법이 있지만  가장 쉬운 방법으로 RC를 만들어 새로운  템플릿으로 Pod를 생성한 후에 pod생성이 끝나면  서비스를 새로운 pod로 옮기는 방식이다.

 

 

 

https://bcho.tistory.com/1256?category=731548

후에 , 배포가 완료되고 문제가 없으면 예전버전의 RC와 pod를 지워준다.

 

 

 

 

롤링업그레이드

롤링업그레이드 방식은 pod를 하나씩 업그레이드 해가는 방식이다.

이렇게 배포를 하려면 먼전 새로운 RC를 만든 후에 기존 RC에서 Replica 수를 줄이고 ,  새로운 RC에 replica 수를 하나만준다.

다음 라벨을 같은 이름으로 해주면 서비스는 자연히 새로운 RC에 의해 생성된 Pod를 서비스에 포함시킨다.

다음으로 기존 RC의 Replica를 하나  저 줄이고 , 새로운 RC의 replica를 수를 늘린다.

 

https://bcho.tistory.com/1256?category=731548

반복을 하게 되면 새로운 RC에서 Pod가 서비스하게된다.

 

만약 배포가 잘못되었을 경우에는 기존 RC에 replica의 수를 원래 대로 올리고 새버전 replica수를 0으로 해서 예전 버전으로 롤백이 가능하다.

https://bcho.tistory.com/1256?category=731548

이 과정은

kubectl rolling-updage라는  명령으로 RC단위로 컨트롤이 가능하지만 그래도 여전히 작업이 필요하고, 배포 과정을 모니터링해야한다.  그리고 가장 문제는  rolling-update 명령은  클라이언트에서 실행하는 명령으로

명령어 실행중 클라이언트의 연결이 끊어지면 배포작업이 비정상적으로 끊어질수있다.

그리고 롤백 과정은 역시 수동컨트롤이 필요할 수 있다.

 

이러한 과정을 자동화하고 추상화한 개념을 Deployment라고 보면된다.

deployment는 pod 배포를 위해서 rc를 생성하고 관리하는 역할을 하며, 롤백을 위한 기존 버전의 RC 관리등 여러가지 기능을 포괄적으로 포함하고 있다.

 

 

https://bcho.tistory.com/1256?category=731548

 

 

 

위 자료는 https://bcho.tistory.com/1256?category=731548에서 참고하였습니다.

 

 

 

 

 

 

'클라우드 > Kubernetes' 카테고리의 다른 글

쿠버네티스 Ingress  (0) 2020.01.13
쿠버네티스 서비스  (0) 2020.01.10
쿠버네티스 불륨설명  (0) 2020.01.10
쿠버네티스 구조  (0) 2020.01.08
컨트롤러  (0) 2020.01.07