Post
KO

컨테이너를 다루는 표준 아키텍처, 쿠버네티스

쿠버네티스 기본 사용법 배우기

파드를 생성하는 방법

kublctl run nginx-pod –image=nginx

파드가 잘 생성되었는지 확인

kubectl get pod

kubectl run과 동일하게 kubectl create로 파드를 생성

kubectl create deployment dry-nginx –image=nginx

직접 생성시에는 이름이 무작위로 생성될 수 있다.

파드의 ip까지 확인하려면 아래 명령어를 입력하면 된다.

kubectl get pods -o wide

run으로 파드를 생성하면 단일 파드 1개만 생성되고 관리됩니다. 그리고 create deployment 로 파드를 생성하면 디플로이먼트(deployment)라는 관리 그룹 내에서 파드가 생성됩니다.

이유로 표현하면, run으로 생성한 파드는 초코파이 1개이고, create deployment로 생성한 파드는 초코파이 상자에 들어 있는 초코파이 1개 입니다.

오브젝트

쿠버네티스를 사용하는 관점에서 파드와 디플로이먼트는 스펙(spec)과 상태(status)등의 값을 가지고 있다.

이러한 값을 가지고 있는 파드와 디플로이먼트를 개별 속성을 포함해 부르는 단위를 오브젝트(object)라고 한다.

기본 오브젝트

파드(pod)

쿠버네티스에서 실행되는 최소 단위. 독립적인 공간과 사용 가능한 IP를 가지고 있다. 하나의 파드는 1개 이상의 컨테이너를 갖고 있기 때문에 여러 기능을 묶어 하나의 목적으로 사용할 수도 있다.

네임스페이스(namespace)

쿠버네티스 클러스터에서 사용되는 리소스들을 구분해 관리하는 그룹이다. 특별히 지정하지 않으면 기본으로 할당되는 default, 쿠버네티스 시스템에서 사용되는 kube-system, 온프레미스에서 쿠버네티스를 사용할 경우 외부에서 쿠버네티스 클러스터 내부로 접속하게 도와주는 컨테이너들이 속해 있는 metalib-system이 있다.

**볼륨(volume) **

파드가 생성될 때 파드에서 사용할 수 있는 디렉터리를 제공한다. 기본적으로 파드는 영속되는 개념이 아니라 제공되는 디렉터리도 임시로 사용한다. 하지만 영구적으로 사용할 수 있도록 설정도 가능하다.

서비스(service)

파드는 클러스터 내에서 유동적이기 때문에 접속 정보가 고정일 수 없다. 따라서 파드가 접속을 안정적으로 유지하도록 서비스를 통해 내/외부로 연결된다, 그래서 서비스는 새로 파드가 생성될 때 부여되는 새로운 IP를 기존에 제공하던 기능과 연결해준다. 쉽게 설명하면 쿠버네티스 외부에서 쿠버네티스 내부로 접속할 때 내부가 어떤 구조로 돼 있는지, 파드가 살았는지 죽었는지 신경 쓰지 않아도 이를 논리적으로 연결하는 것이 서비스이다.

-> 로드밸런서라고 생각하면 좋다.

디플로이먼트(deployment)

기본 오브젝트만으로도 쿠버네티스를 사용할 수 있다. 하지만 한계가 있어서 이를 좀 더 효율적으로 작동하도록 기능들을 조합하고 추가해 구현한 것이 디플로이먼트(Deployment)이다.

그 외에도 데몬셋(DaemonSet), 컨피그맵(ConfigMap), 레플리카셋(ReplicaSet), PV(Persistent Volume), PVC(PersistentVolumeClaim), 스테이트풀셋(StatefulSet)등이 있다.

쿠버네티스에서 가장 많이 쓰이는 디플로이먼트 오브젝트는 파드에 기반으로 두고 있으며, 레플리카셋 오브젝트를 합쳐 놓은 형태이다.


레플리카셋으로 파드 수 관리하기

kubectl scale pod nginx-pod –replicas=3

디플로이먼트로 생성된 파드에는 아래와 같이 실행한다.

kubectl scale deployment dpy-nginx –replicas=3

삭제할 때는 delete 명령어를 사용한다.


스펙을 지정해 오브젝트 생성하기

디플로이먼트를 생성하면서 한꺼번에 여러 개의 파드를 만들 수 있는 방법은 없을까?

이런 설정을 적용하려면 필요한 내용을 파일로 작성해야 한다. 이 파일을 **오브젝트 스펙(spec) **이라고 한다.

오브젝트 스펙은 일반적으로 야믈(YAML) 문법으로 작성해야 한다.

apiVersion: apps/v1 # API 버전 kind: Deployment # 오브젝트 종류 metadata: name: echo-hname labels: app: nginx spec: replicas: 3 #몇 개의 파드를 생성할지 결정 selector: matchLabels: app:nginx template: metadata: labels: app: nginx spec: containers: - name: echo-hname image: sysnet4admin/echo-hname #사용되는 이미지

레플리카셋은 몇 개의 파드를 생성할지 replicas로 결정한다.

위 yaml 파일 구조를 정리하면 아래와 같다

![](/assets/images/posts/222691254206/1e28d147cd01.png?type=w580)

apply로 오브젝트 생성하고 관리하기

쿠버네티스에서는 파일의 변경사항을 바로 적용할 수 있도록 apply 명령어를 제공한다.

kubectl apply -f ~/파일이름.yml

파드의 컨테이너 자동 복구 방법

쿠버네티스는 거의 모든 부분이 자동 복구되도록 설계되었다. 특히 파드의 자동 복구 기술을 셀프 힐링(Self-Healing)이라고 하는데, 제대로 작동하지 않는 컨테이너를 다시 시작하거나 교체해 파드가 정상적으로 작동하게 합니다.

컨테이너에 접속 하는 방법

kubectl exec -it nginx-pod – /bin/bash

exec = execute (실행)

i = stdin(표준 입력)

t = tty(teletypewriter)

노드** **자원 보호하기

노드는 쿠버네티스 스케줄러에서 파드를 할당받고 처리하는 역할을 한다.

하지만, 최근에 몇 차례 문제가 생긴 노드에 파드를 할당하면 문제가 생길 가능성이 높다.

쿠버네티스는 모든 노드에 균등하게 파드를 할당하려고 한다.

그러면 어떻게 문제가 생길 가능성이 있는 노드라는 것을 쿠버네티스에 알려줄 수 있는가?

이럴 경우 cordon 기능을 사용한다.

노드 유지보수하기

쿠버네티스를 사용하다 보면 정기 또는 비정기적인 유지보수를 위해 노드를 꺼야 하는 상황이 발생한다.

이런 경우 쿠버네티스는 drain 기능을 제공한다.

명령어 예시

kubectl drain w3-k8s

drain은 실제로 파드를 옮기는 것이 아니라 노드에서 파드를 삭제하고 다른 곳에서 다시 생성합니다.

drain 명령과 ignore-daemonsets

이 옵션을 사용하면 DaemonSet을 무시하고 진행한다.

푸는 방법은 undrain 을 입력하면 된다.

kubectl undrain w3-k8s

위에서 apply 명령어를 사용할 때, –record 옵션을 주게 되면 배포한 정보의 히스토리를 기록할 수 있다.

kubectl apply -f ~/파일명.yaml –record

record 옵션으로 기록된 히스토리는 rollout history 명령을 실행해 확인할 수 있다.

kubectl rollout history deployment 디플로이먼트명

구동 중 상태를 확인하는 방법은 status 옵션을 이용한다.

구동 중 문제가 발생되는 경우 describe 옵션을 이용해서 확인할 수 있다.

kubectl describe deployment 디플로이먼트명

상태를 확인하고 복구를 하는 방법은 undo 명령어를 이용하면 된다.

kubectl rollout undo deployment 디플로이먼트명

특정시점으로 파드를 복구 하고 싶다면 –to-revision 옵션을 사용한다

kubectl rollout undo deploymet 디플로이먼트명 –to-revision=1

쿠버네티스 연결을 담당하는 서비스

쿠버네티스에서는 외부에서 쿠버네티스 클러스터에 접속하는 방법을 서비스(Service)라고 한다.

노드포트(NodePort)

외부에서 쿠버네티스 클러스터의 내부에 접속하는 가장 쉬운 방법은 노드포트(NodePort) 서비스를 이용하는 것 입니다. 노드포트 서비스를 설정하면 모든 워커 노드의 특정 포트(노드포트)를 열고 여기로 오는 모든 요청을 노드포트 서비스로 전달합니다.

노드포트 설명

노드포트 서비스는 포트를 중복으로 사용할 수 없어서 1개의 노드포트에 1개의 디플로이먼트만 적용된다. 여러 개의 디플로이먼트가 있을 때 그 수만큼 노드포트 서비스를 구동해야 할까? 쿠버네티스에서는 이런 경우에 인그레스를 사용한다. 인그레스(Ingress)는 고유한 주소를 제공해 사용목적에 따라 다른 응답을 제공할 수 있고, 트래픽에 대한 L4/L7 로드밸런서와 보안 인증서를 처리하는 기능을 제공한다.

인그레스 컨트롤러는 파드와 직접 통신할 수 없어서 노드포트 또는 로드밸런서 서비스와 연동되어야 한다.

인그레스 컨트롤러의 궁극적인 목적은 사용자가 접속하는 경로에 따라 다른 결괏값을 제공하는 것이다.

L4 레이어

전송 계층은 특정 프로토콜로 연결하여 데이터 전송 서비스를 제공하고, 두 사용자 사이의 데이터 전송을 위한 종단간(end to end) 제어를 담당한다.

흐름제어, 에러제어, 에러복구, sliding window, connetion oriented communication 지원

L7 레이어

URL 스위칭 지원

URL에서 특정 String을 검사하고, 검색된 문자열 기준으로 부하분산 시키는 방식.

Cookie 스위칭, Content 스위칭(Header 모든 필드)

기존 L4/L7 대안으로는 HAPoxy가 있다.

클라우드에서 쉽게 구성 가능한 로드밸런서

앞에서 배운 방식은 요청을 모두 워커 노드의 노드포트를 통해 노드포트 서비스로 이동하고 이를 다시 쿠버네티스의 파드로 보내는 구조였다. 이 방식은 매우 비효율적이다. 그래서 쿠버네티스에서는 로드밸런서(LoadBalancer)라는 서비스 타입을 제공해 다음 그림과 같은 간단한 구조로 파드를 외부에 노출하고 부하를 분산시킨다. 그런데 왜 지금까지 로드밸런서를 사용하지 않았을까? 로드밸런서를 사용하려면 로드밸런서를 이미 구현해 둔 서비스업체의 도움을 받아 쿠버네티스 클러스터 외부에 구현해야 하기 때문이다. 클라우드에서 제공하는 쿠버네티스를 사용하고 있다면 다음과 같이 선언하면 된다.

kubectl expose deployment ex-lb –type=LoadBalancer –name=디플로이명 exposed

kubectl get service ex-svc

온프레미스에서 로드밸런서를 제공하는 MetalLB

온프레미스에서 로드밸런서를 사용하려면 내부에 로드밸런서 서비스를 받아주는 구성이 필요한데, 이를 지원하는 것이 MetalLB 이다.

MetalLB는 특별한 네트워크 설정이나 구성이 있는 것이 아니라 기존의 L2 네트워크(ARP/NDP)와 L3 네트워크(BGP)로 로드밸런서를 구현합니다.

L2 스위치

Mac Address 기반으로 부하분산을 지원해준다.

(IP 대역으로 분배)

MetalLB 설정

부하에 따라 자동으로 파드 수를 조절하는 HPA

쿠버네티스는 이런 경우를 대비해 부하량에 따라 디플로이먼트의 파드 수를 유동적으로 관리하는 기능을 제공한다.

이를 HPA(Horizontal Pod Autoscaler)라고 한다.

디플로이먼트를 hpa-hname-pods 라는 이름으로 생성한다.

kubectl create deployent hpa-hname-pods –image=sysnet4admin.echo-hname

MetalLB를 구성했으므로 expose를 실행해 hpa-hname-pods를 로드밸런서 서비스로 설정한다.

kubectl expose deployment hpa-hname-pods –type=LoadBalancer –name=hpa-hname-svc –port=80

부하를 확인하는 명령은 리눅스 top(table of processes)과 비슷한 kubectl top pods 이다.

HPA가 자원을 요청할 때 메트릭 서버(Metrics-Server)를 통해 계측값을 전달받는다.

scale에는 기준 값을 설정할 수 있다.

사용단위 m은 milliunits의 약어로 1000m은 1개의 CPU가 된다. 따라서 10m은 파드의 CPU 0.01 사용을 기준으로 파드를 증설하게 설정될 것이다. 순간적으로 파드로 부하가 몰릴 경우를 대비해 CPU 사용 제한을 0,05로 주었다.

yaml 파일 내 명시

resource:

request:

cpu: “10m”

limits:

cpu: “50m”


데몬셋(DaemonSet)

데몬셋은 디플로이먼트의 replicas가 노드 수 만큼 정해져 있는 형태라고 할 수 있는데, 노드 하나당 파드 한 개만을 생성한다. 노드의 단일 접속 지점으로 노드 외부와 통신하는 것이다.

컨피그맵(ConfigMap)

컨피그맵(ConfigMap)은 이름 그대로 설정(config)을 목적으로 사용하는 오브젝트이다.

PV와 PVC

쿠버네티스는 필요할 때 PVC(PersistentVolumeClaim, 지속적으로 사용 가능한 볼륨 요청)를 요청해 사용합니다. PVC를 사용하려면 PV(PersistentVolume, 지속적으로 사용 가능한 볼룸)로 볼륨을 선언해야 합니다. PV는 볼륨을 사용할 수 있게 준비하는 단계이고, PVC는 준비된 볼륨에서 일정공간을 할당 받는 것입니다. 비유하면 PV는 요리사(관리자)가 피자를 굽는 것이고, PVC는 손님(사용자)가 원하는 만큼의 피자를 담아 가져오는 것입니다.

존재하지 않는 이미지입니다.

출처 : PV와PVC

This article is licensed under CC BY 4.0 by the author.