쿠버네티스 소개
서비스 개발 및 운용 방식
마이크로서비스 아키텍처(microservice architecture; MSA)
🔸응용 시스템 개발 및 구성을 위한 아키텍처 스타일의 하나
🔸이에 비교하여 전통적인 방식의 아키텍처를 모놀리식(monolithic) 아키텍처라고 부르기도 함
🔸애플리케이션이 서비스 모음으로 개발되어
각 마이크로서비스는 특정한 기능을 수용하고 개별 작업을 처리,
이 서비스 들이 서로 연결되어 전체 응용을 구성
컨테이너 인프라 환경의 적용
컨테이너 모델은 마이크로서비스를 구현하기에 적합
쿠버네티스(Kubernetes)란
줄여서 k8s 라고 표기
- k와 s사이 글자가 8개라 k8s라고
컨테이너 오케스트레이션 솔루션
- 다수의 컨테이너들을 관리하면서
- 자동배포, 배포된 컨테이너의 동작 보증, 부하에 따른 동적 확장 등의 기능을 담당
도커와 잘 어울리는 실행 환경 구성 도구
- 도커 컨테이너들을 클러스터 내에 실행하고 관리하는데 적합
- 지속적 통합과 인도(CI/CD)에 유효하게 적용할 수 있음
- 컨테이너는 포드(pod)라고 불리는 k8s 오브젝트와 연관하여 실행
- (포드 위에서 실행한다고 대강 표현)
k8s 클러스터 구성요소
클러스터는 하나의 컨트롤 플레인과 하나 이상의 노드들로 구성됨
마스터 노드 (컨트롤 플레인)
- kubectl (반드시 마스터 노드에 있어야 하는건 아님)
- API 서버, etcd - 클러스터의 중심 역할을 하는 구성 요소들
- 컨트롤러 매니저, 스케줄러
워커노드
- 컨테이너 런타임(CRI; Container Runtime Interface) - 포드를 이루는 컨테이너의 실행을 담당
- kubelet - 포드의 구성 내용을 받아 CRI에 전달하고 컨테이너들의 동작 상태를 모니터링
k8s가 제공하는 기능
컨테이너 밸런싱(container balancing)
포드의 부하 균등화를 수행 - 몇 개의 응용을 복제할 것인지를 알려주면
나머지는 k8s가 처리
트래픽 로드 밸런싱(traffic load balancing)
응용의 복제본이 둘 이상 있다면 k8s가 트래픽 부하 균등화를 수행하여
클러스터 내부에 적절히 분배
동적 수평 스케일링(HPA; horizontal pod autoscaling)
인스턴스 수를 동적으로 확장하거나 감축하여 동적 요구사항에 대응하면서
시스템 자원을 효율적으로 활용
오류 복구(error recovery)
포드와 노드를 지속적으로 모니터링하고 장애가 발생하면
새 포드를 실행하여 지정된 복제본의 수를 유지
롤링 업데이트(rolling update)
지연 시간을 적용하고 순차적으로 업데이트 배포함으로써
문제가 발생하더라도 서비스를 정상 유지할 수 있음
스토리지 오케스트레이션(storage orchestration)
원하는 응용에 다양한 스토리지 시스템
(Amazon EBS, Google CGE, Persistent Disk 등)을 마운트 할 수 있음
서비스 디스커버리(service discovery)
태생적으로 수명이 짧은 포드의 동적 성질을 관리하기 위하여
자체 DNS 기반으로 서비스를 동적 바인딩할 수 있는 기능을 제공
k8s의 생명주기 (Life Cycle)
🔸kubectl을 통해서 API 서버에 포드의 생성을 요청
- (업데이트가 있을때마다) API 서버는 etcd에 기록하고 클러스터의 상태를 최신으로 유지(하려고 함)
🔸컨트롤러 매니저는 포드를 생성하고, 이 상태를 API 서버에 전달
- 아직 어떤 워커 노드에 포드를 적용할지는 결정하지 않은 상태
🔸스케줄러는 포드가 생성되었다는 정보를 인지하고,
이 포드를 어떤 워커 노드에 적용할지를 결정해서 해당 노드에 포드의 실행을 요청
🔸해당 노드의 kubelet이 CRI에 요청하여 포드가 만들어지고 사용가능한 상태가 됨
🔸k8s는 절차적인 구조가 아닌 선언적인 구조를 가지고 있음
- 각 요소가 추구하는 상태(desired state)를 선언하면
- 현재 상태(current state)와 비교하고 지속적으로 맞추어가려고 노력하는 구조
k8s 오브젝트들
기본오브젝트
- Pod - 한 개 이상의 컨테이너로 단일 목적의 일을 하기 위해서 모인 단위
- 독립적인 공간과 사용 가능한 IP를 가지고 있음, 언제든지 죽을 수 있음
- Namespace - k8s 클러스터에서 사용되는 리소스들을 구분해 관리하는 그룹
- Volume - 포드가 생성될 때 포드에서 사용할 수 있느 디렉토리를 제공
- Service - 유동적인 포드들에 대한 접속을 안정적으로 유지하도록 클러스터 내/외부에 연결하는 역할
디플로이먼드 (Deployment)
- 기본 오브젝트들을 보다 효율적으로 작동할 수 있도록 조합하고 추가로 구현한 것
- 레플리카셋(replicaset) 오브젝트를 합쳐 놓은 형태로 단숙하게 생각 할 수 있음
k8s 인프라 구축
로컬환경
- kubeadm, docker desktop 등을 설치, 운용함으로써 로컬 환경에 간단한 클러스터 구성 가능
- 개발 단계에서늬 테스트 등에 이용
Public clouds
- Amazon의 AWS EKS(Elastic Kubernetes Sevices)
- GCP(Google Cloud Platform)의 GKE(Google Kubernetes Engine)
- Microsoft의 AKS(Azuer Kubernetes Service)
On-prem 설치
- SUSE의 Rancher
- RedHat의 OpenShift
쿠버네티스 기본 사용법
노드(Node)와 포드(Pod) 정보를 조회하는 방법
명령어
🔸kubectl get nodes
🔸kubectl get pods
어떤 정보를 파악할 수 있는지 알아보자
옵션 '-o wide'를 적용하여 무엇이 더 축력되는지 살펴보자
컨테이너 이미지를 이용한 포드의 생성
명령어
🔸kubectl run <포드 이름> --image=<이미지 지정>
쿠버네티스 디플로이먼트
Deployment
- 응용의 배포를 위하여 많이 이용되는 k8s의 오브젝트 형태
- 동일한 모습의 포드들의 복제본 모임인 레플리카셋(replicaset)을 이용하는 것이 일반적
- 단순한 레플리카셋에 비하여 동적 업데이트 및 롤백(rollback),
- 배포 버전의 관리 등이 유연하여 응용의 배포에 널리 이용됨
- 보통은 상태가 없는 (stateless) 응용의 배포에 이용
- 포드는 언제라도 사멸할 수 있음
동작방식
- 디플로이먼트의 상태를 선언하면 k8s가 동적으로 의도된 상태(desired state)가 되도록 레플리카셋을 관리
pods에 레플리카셋을 실행했더니 error가 남
dpy-nginx를 deployment하고 describe명령어를 사용
pods를 확인하고 nginx pod의 describe
deployment된 dpy-nginx의 레플리카셋을 3으로 하니
3개로 늘어난 것을 볼 수 있다.
클러스터 바깥으로 응용을 노출해보자
k8s 서비스(service)
- 클러스터 내부의 포드에 의하여 실행되는 응용을 외부에 접근 가능하도록 노출하는 기능을 하는 오브젝트
노출하는 대상
- 특적 포드(또는 포드들의 집합)에서 실행하는 컨테이너의 특정 포드
서비스의 서로 다른 형태들
- ClusterIP
- NodePort
- LoadBalancer
- EternalName
NodePort 타입으로 port는 80으로 설정하고 클러스터를 바깥으로 노출했다.
get svc(service)를 해서 port번호를 받아서 확인하니
다음의 html을 가져왔다.
deployment로 생성한 dpy-nginx를 클러스터 바깥으로 노출했다.
port를 보여받고 curl시 html과 브라우저 화면이다.
deployment로 생성한 dpy-nginx는 레플리카셋을 3을 했는데
이 중에 어떤 것이 노출된것인지는 나중에 강의에 나온다고 한다.
오브젝트의 삭제
노출한 클러스터 삭제하기
명령어
🔸kubectl delete <오브젝트 형태> <오브젝트 이름>
먼저 생성한 pod-svc를 삭제하고 curl로 확인하여 접근실패를 확인
마찬가지로 dpy-nginx 디플로이먼트를 노출하고 있던 dpy-svc도 삭제했다
포드의 삭제
포드 삭제
- 처음에 생성한 nginx-pod도 삭제
디플로이먼트의 생성에 의하여 만들어진 포드의 삭제
디플로이먼트로 생성한 dpy-nginx의 name을 가지고 와서 삭제를 했더니
삭제가 됐지만, 새로운 컨테이너가 또 생겼다.
이는 아까 우리가 설정한 레플리카셋이 3이므로
쿠버네티스가 이 상태를 유지하려고하는 성질을 가지고 있어서 그렇다.
디플로이먼트를 확인하고 디플로이먼트로 생성된 dpy-nginx를 삭제하자
디플로이먼트와 포드에서 사라진 것을 확인할 수 있다.
매니페스트(Manifest)
k8s 오브젝트에 대한 명세를 파일로 기록한 것
- YAML(Yet Another Markup Language || YAML Ain't Markup Language) 형태를 이용
파일에 각 오브젝트에 의도하는 상태(desired state)를 기술
- 이것을 오브젝트 스펙(obejct spec.)이라고 부름
이 파일을 이용하여
- 오브젝트를 생성할 수 있고
- (파일의 내용을 변경하여) 오브젝트의 상태를 변경할 수 있음
- 물론, 파일의 내용을 변경하지 않고 다른 파일을 이용하여 오브젝트 상태를 변경하는 것도 가능
자동화가 필요한 환경에서 명령어 라인에 일일이 입력하는 것보다 많이 이용됨
디플로이먼트의 오브젝트 스펙
앞서 kubectl create deployment 명령을 이용한 것과 동일한
(다만, 옵션 --replicas=3 적용)
형태의 디플로이먼트를 생성하는데 이용할 수 있는 파일 (예시)
앞서 kubectl create deployment 명령을 이용한 것과
동일한 서비스를 생성하는데 이용할 수 있는 파일(예시)
🔸단 NodePort 설정을 통해 노드의 어느 포트를 통해 노출할 것인지를 설정
매니패스트를 이용한 오브젝트 생성
명령어
- kubectl apply -f <매니페스트 파일>
- kubectl create -f 를 이용할 수도 있으나 위의 명령을 더 널리 이용함
- 왜 그런지 실습 후 생각해보기
쿠버네티스를 이용한 서비스 운용
포드의 업데이트와 복구
배포된 소프트웨어의 업데이트와 복구
소프트웨어의 업데이트가 발생함에 따라 (매번 새로 배포하는 것이 아니라) 동적 업데이트 필요
- 여기에서는 수동(kubectl)으로 업데이틑 적용하는 실습을 통해 k8s가 어떻게 업데이트를 수행하는지 관찰
소프트웨어의 업데이트는 실패할 수 있으므로, 빠르고 유연한 복구는 필수 기능
- 업데이트 자체가 실패하는 경우
- 이번 강의의 실습에서 복구(rollback)하는 내용 포함
- 새 버전의 소프트웨어가 오동작 하는 경우
- 가능한 한 발생하지 않도록 해야하지만, 만약 발생하는경우 민첩한 복구 조치가 필요
롤아웃 정보의 열람
새로 배우는 명령을 이용하여 롤아웃 정보와 이력을 조회
- kubectl rollout status deployment <디플로이먼트>
- kubectl rollout history deployment <디플로이먼트>
특정 시점으로 디플로이먼트 복구하기
명령어
- kubectl rollout undo deployment <디플로이먼트> --to-revision=<리비전 번호>
쿠버네티스 서비스와 볼륨
서비스(Service)
클러스터로 외부에서 클러스터에 접속하는 방법
- 클러스터 내부에서 동작하는 기능을 외부로 "노출"하는 것을 서비스(service)라고 부름
서로다른 서비스의 종류
- 클로스터 IP (ClusterIP)
- 노드포트 (NodePort)
- 로드밸런서 (LoadBalancer)
- 인그레스 (Ingress)
클러스터 IP
- 클러스터 내부에서만 접근할 수 있는 IP를 할당
- 포트 포워딩(port forwarding) 또는 프록시(proxy)를 통해 클러스터 외부로부터 접근 가능
- 테스트, 디버깅 등의 목적에 제한적으로 이용
노드포트
동작방식
- 모든 워커 노드의 특정포트(NodePort)를 열고 여기로 오는 모든 요청을 노드포트 서비스에 전달
- 노트포트 서비스는 해당 요청을 처리할 수 있는 포드로 요청을 전달
로드밸런서
- 클러스터 외부의 로드밸런서(public cloud 들은 공히 제공) 를 이용하여 부하 균등하 수행
- 노트포트와 달리 특정 노드가 접근 불가한 경우에도 서비스 제공 가능
인그레스
- 엄밀히 말하자면 k8s 서비스의 한 종류는 아니고,
- 복수의 서비스에 대해 목정에 따라 트래픽을 연결하는 도구
동적 수평 오토스케일링
HPA (Horizontal Pod Autoscaler)
- 부하량에 따라 디플로이먼트의 포드 수를 유동적으로 관리하는 k8s의 기능
- (보통) 고려되는 부하량: CPU 및 메모리 사용량
- 메트릭스 서버(metrics server)로부터 부하 계측 값을 전달받아 동일한 기능을 제공하는 포드의 수를 동적으로 조절
스케일링 기준이 되는 값과 최소/최대 포드의 수를 지정
메트릭스 서버의 설치 (배포)
설치(배포)
- kubectl apply -f metrics.yaml
메트릭스 서버
php-apache
부하주기
부하 확인
볼륨 (Volumes)
k8s는 클러스터 내에서 이용할 수 있는 저장장치(storage)의 추상화된 객체로 볼륨을 정의
PV(PersistentVolume)
- 클러스터 내에 존재하는 스토리지를 추상화한 것
- 클러스터 내의 노드에 존재하는 물리적 저장장치를 이용할 수도 있으며,
- 다양한 원격 저장소 및 크랄우드 서비스들도 이용할 수 있음
PVC(PersistentVoumeClaim)
- (사용자에 의한) PV를 이용하기 위한 요청
- Pod : Node = PVC : PV
- 저장 공간의 크기와 접근 코드 (읽기/쓰기,...)를 지정
요약
k8s서비스
- 클러스터 내부에서 실행되고 있는 기능을 클러스터 외부에 노출
HPA(Horizontal Pod Autoscaler)
- 부하 상황에 따라 동적으로 디플로이먼트의 레플리카셋 크기를 조정
PV(Persistent Volume)
- 포드에서 바인드 마운트(bind mount)로 이용할 수 있는 저장장치
- 변화하는 데이터를 기록, 저장하기 위해서 반드시 필요
'공부 > 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js)' 카테고리의 다른 글
웹 개발 파이프라인 구축(4) (1) | 2024.12.05 |
---|---|
웹 개발 파이프라인 구축(3) (1) | 2024.12.04 |
웹 개발 파이프라인 구축(1) (1) | 2024.12.02 |
Code contributor: 오픈소스 프로젝트 활용(5) (4) | 2024.11.29 |
Code contributor: 오픈소스 프로젝트 활용(4) (1) | 2024.11.28 |