K8S 개요

반영환·2023년 7월 17일
0

k8s

목록 보기
1/14
post-thumbnail

K8S 개요

K8S 공식사이트

쿠버네티스는 컨테이너 기반 환경에서 서비스의 고가용성, 운영, 스케일아웃, 네트워크, 로드밸런싱을 쉽게 할 수 있도록 나온 오픈소스이다.

기업에서 쿠버네티스만을 쓰는 곳은 없고, 관리형 쿠버네티스인 EKS와 같은 서비스를 이용한다고 한다.

1.24v 이후부터 컨테이너엔진을 골라서 사용할 수 있는데, 그 이전 버전은 도커엔진을 사용하도록 하드코딩 돼있다.

따라서 실습 환경은 1.23v 을 사용할 것이다.

K8S 구성

VM 기반으로 클러스터를 구성할 것이며 Control Plane 1대, Worker Node 2대로 이루어져있다.
클러스터의 각 노드들은 각자의 사설IP로 통신하며, TCP/IP 기반의 네트워크 통신을 한다.

배포 단위

K8S는 컨테이너 오케스트레이터로 배포의 단위가 컨테이너가 아닌 상위 개념의 POD 이다.
pod 내부에서는 localhost로 통신이 가능하다.

어플리케이션을 독립적으로 배포하기 위해서 만든 것이 쿠버네티스인데, 의존도가 있는 어플리케이션들을 묶어서 배포하기 위해 pod라는 상위 개념으로 여러 컨테이너와 DB를 묶어 배포한다.

하지만 MSA 환경에서 배포를 진행할 때에는 1 POD , 1 Container로 약속을 해야 적절한 로드벨런싱과 섬세한 스케일아웃이 가능하다.

모든 POD 생성 요청은 Control Plane에서 진행된다.

Control Plane

모든 POD의 요청은 C/P로 전달되기 때문에 이 부분이 부하가 가장 크다.

따라서 API Server 를 부하분산을 시켜주어야 하는데 2개로 해버리면 Data replica 과정에서 오류가 났을 때 무엇이 실패한 명령인지 확인할 수 없다.

따라서 3중화를 통해 과반수가 넘는 설정 파일을 성공한 명령어로 믿고 작업을 진행한다.

내부 요소

Automatic Bin Packing

POD를 어떤 노드에 배치하는게 최적의 배치인가? 를 처리해주는 K8S의 역할이다.

이와 같은 기능을 위해서는 각 파드끼리 통신하기 위한 CNI ( Container Network Interface ) 를 구축해주어야 한다.

API Server

kubernetes API를 노출하는 컴포넌트로, kubectl 등으로 부터 리소스를 조작하라는 지시를 받는다.

API 서버는 최종 사용자, 클러스터의 다른 부분 그리고 외부 컴포넌트가 서로 통신할 수 있도록 HTTP API를 제공한다

Scheduler

pod를 어떠한 워커노드에 배치하는게 최적인가를 Scheduler 가 처리해준다.
개발자는 C/P에 pod를 배포해달라는 명령만 내리면 된다.

최적 노드를 선정하는 방식은 etcd 라는 C/P의 DB에 저장돼있는 정보를 통해 확인한다.

이 저장소에는 워커노드의 kubelet의 정보등과 함께 클러스터에서 발생하는 모든 이벤트들을 저장한다.

각각의 이벤트들을 확인하면서 동일한 파드가 노드에 있는지와 리소스 사용률이 적은 곳을 우선적으로 스케쥴러가 판단해서 파드를 배포한다.

kubelet

kubelet은 항상 C/P의 etcd를 확인하며 본인의 노드에 주어진 일이 있는지를 확인한다.

배포 요청을 확인하면 docker0 에 요청하고 이미지를 내려 받아서 pod를 띄워준다.

Controller Manager

워커노드에서 kubelet이 파드를 배치했을 때 C/P에 요청된 replicas의 수와 같은지 Controller Manager가 지속적으로 확인한다.

Service Discovery & Load Balancing

Spring Cloud의 Eureka Server의 기능을 해준다.

k8s는 service 라는 네트워크 요소를 구성할 수 있게 해준다.

서비스를 생성하고 replicas = n 으로 pod들을 배포하면, 각 pod들의 사설IP ( end point ) 들이 서비스의 가상IP와 1:N 맵핑된다.

미리 알고 있는 가상 IP로 서비스를 호출하면 서비스의 EndPoint인 사설IP들 중 하나로 트래픽을 부하분산시켜준다.

Core-dns

이를 도메인 기준으로 설정하게 도와주는 역할을 Core-dns 가 해준다.

가상 IP또한 동적으로 바뀔 수 있기 때문에 DNS가 필요하다.

POD 배포부터 다시 돌아가보자.

C/P에 nginx 컨테이너 배포 요청이 spec.selector.matchLabels.app = myApp 과 함께 왔다고 해보자. replicas = 2 이다.

그러면 C/P는 Core-dns에 myApp : <<가상 IP>> 로 맵핑을 한다.

kube-proxy

다음으로 W/N에서는 kubelet이 etcd를 살펴보며 배포요청을 확인하고 이미지를 당겨와 pod를 배포한다.
이때 pod의 end-point를 생성한다.

end-point를 생성할 때 C/P의 Core-dns에도 기입해 가상 IP와 POD End Point가 맵핑되게 한다.

이후 kube-proxyiptables 에 서비스로 이동하는 Rule 을 적용시킨다.

서비스로 요청이 들어왔을 때 iptable이 서비스 가상IP를 보고 직접 부하분산을 진행한다.

kube-proxy가 부하분산을 진행한다는 말도 있는데 직접 부하분산을 진행하는 것은 iptables이지만 룰을 설정해주는 컴포넌트가 kube-proxy 이기 때문에 나온 말이다.

Self-Healing

쿠버네티스는 파드의 헬스체크를 할 수 있다.

C/P에 파드 요청을 할 때 파드가 정상인지 체크한다. 사용자가 요청했을 때 파드가 정상이 아니라면, 연결을 해주지 않고 다른 곳으로 부하분산을 해준다.

만일 파드가 문제가 있다면 파드를 내리고 다시 띄워준다.

K8S는 절대로 migration을 하지 않는다. 단순히 새로 배포하는 것이 컨테이너 환경의 주요 메커니즘이며 컨테이너를 stateless 하게 빌드해야 하는 이유이다.

만일 실수로 ec2를 지워버리면 controller manager가 pod의 개수의 이상함을 감지하고, 스케쥴러가 워커노드의 상태를 보고 다른 곳에 배포하는 이벤트를 etcd에 남긴다. 그래서 항상 Contrller manager를 살펴보고 pod를 지워주어야 한다.

Automated rollouts and rollbacks

롤링 업데이트

  • 새로 만들고 삭제한다.
  • 배포를 위해서 추가 비용이 안든다.
  • 배포중에 장애가 발생하면 롤백을 자동으로 해준다.

블루 그린 배포

  • 인프라를 그대로 복사해 새로운 버전을 배포하고, 사용자의 엔드포인트만 변경시킨다.
  • 기업에서 선호한다.
  • 고가용성을 확보할 수 있지만 비용이 많이 든다.
  • V1, V2를 배포후 로드밸런서로 사용자들이 다른 서비스를 이용하게 한다. ( A/B test )

카나리아 배포

  • 서비스의 변경이 너무 커서 제품을 올리기에는 걱정이 될 때 사용한다(장애발생 유무)
  • 기존 파드의 트래픽 흐름을 90% 로 설정하고 새로운 파드를 10%로 설정한다. 그리고 점차 트래픽을 올려가며 모니터링한다.
  • 장애가 절때 나면 안되는 상황에서 사용한다.

Secret and configuration management

Spring Cloud의 Config server 역할을 해준다.

  • 어플리케이션내의 파일 정보를 쿠버네티스의 configMap 에 객체로 만들 수 있다.

  • 즉 어플리케이션내의 환경 설정을 어플리케이션과 분리시켜주는 기능

  • 민감한 정보는 configMap에서 secret 객체가 있는데, Base64로 인코딩해준다. 암호화는 아니다.

  • etcd에는 시크릿 객체가 암호화돼서 저장돼있다.

Storage orchestration

  • 실무에서는 네트워크 스토리지는 개발자가 구성해서 사용하는 것은 불가능하다.

  • 어떤 파드를 요청하면 자동으로 스토리지가 생성되고 붙여준다.

  • 파드가 죽거나 삭제되면 파드가 사용하던 스토리지를 죽일지, 살릴지, 보관할지 설정 가능하다.

  • Cloud와 같이 사용하면 powerful하다.

profile
최고의 오늘을 꿈꾸는 개발자

1개의 댓글

comment-user-thumbnail
2023년 7월 17일

저도 개발자인데 같이 교류 많이 해봐요 ㅎㅎ! 서로 화이팅합시다!

답글 달기