Skip to content

태그: Kubernetes

총 112개의 글이 있습니다.
Session Affinity
개념
Session Affinity(세션 어피니티)는 특정 클라이언트의 요청이 항상 동일한 Pod로 라우팅되도록 하는 Kubernetes Service의 기능이다. “Sticky Session”이라고도 불리며, 상태를 유지하는 애플리케이션에서 세션 일관성을 보장하기 위해 사용한다. 기본 개념 기본적으로 Kubernetes Service는 요청을 모든 엔드포인트에 무작위로 분산한다. 이는 stateless 애플리케이션에는 문제가 없지만, 세션 상태를 메모리에 저장하는 애플리케이션에서는 문제가 된다. ┌──────────┐ ┌─────────────┐ ┌─────────┐│ │ ──▶ │ │ ──▶ │ Pod A │ 요청 1: 로그인 (세션 생성)│
Topology Aware Routing
개념
Topology Aware Routing은 Kubernetes Service의 트래픽을 가능한 한 같은 Zone(가용 영역) 내의 엔드포인트로 라우팅하는 기능이다. 클러스터가 여러 Zone에 걸쳐 배포되어 있을 때, 이 기능을 활성화하면 네트워크 지연 시간을 줄이고 Zone 간 데이터 전송 비용을 절감할 수 있다. 멀티 Zone 클러스터에서 Service로 요청이 들어오면, 기본적으로 kube-proxy는 모든 엔드포인트 중 하나를 무작위로 선택한다. 이 말은 Zone A에 있는 Pod가 Zone B나 Zone C에 있는 엔드포인트로 트래픽을 보낼 수도 있다는 것이다. ┌─────────────────────────────────────────────────────────────┐│
Linkerd와 Istio 비교
service mesh
Service Mesh는 마이크로서비스 간의 통신을 관리하는 인프라 계층이다. Kubernetes 환경에서 가장 많이 사용되는 Service Mesh인 Linkerd와 Istio의 구조와 특징을 비교해보자. Service Mesh가 필요한 이유 마이크로서비스 아키텍처에서는 수십, 수백 개의 서비스가 서로 통신한다. 이때 몇 가지 문제가 발생한다. 서비스 간 통신은 기본적으로 암호화되지 않는다. 어떤 서비스가 어떤 서비스와 통신하는지 파악하기 어렵다. 특정 서비스에 장애가 발생하면 연쇄적으로 다른 서비스에 영향을 미친다. 트래픽을 세밀하게 제어하기 어렵다. 이런 문제를 해결하기 위해 각 서비스에 프록시를 붙여서 모든 트래픽을 가로채고 관리하는 방식이 등장했다. 이것이 Service Mesh다. 그런데 Se
Gateway API
object
Gateway API는 Kubernetes에서 트래픽 라우팅을 관리하기 위한 차세대 API이다. 기존 Ingress의 한계를 극복하고 더 유연하고 표준화된 방식으로 L4/L7 트래픽을 관리할 수 있다. 왜 이런 변화가 필요했고, 어떤 구현체를 선택해야 할지 알아보자. Ingress의 한계 Ingress는 오랫동안 Kubernetes에서 외부 트래픽을 내부 서비스로 라우팅하는 표준이었다. 하지만 사용하다 보면 몇 가지 문제를 마주하게 된다. 프로토콜 제약 Ingress는 HTTP/HTTPS만 지원한다. TCP나 UDP 트래픽을 라우팅하려면 별도의 Service를 NodePort나 LoadBalancer로 노출해야 한다. gRPC도 직접적으로 지원하지 않는다. 어노테이션 지옥 Ingress 스펙 자체는 매우 단
MetalLB
kubernetes
MetalLB는 BareMetal LoadBalancer의 약자로, Kubernetes 클러스터에 연결되어 온프레미스 환경(IDC)에서 로드밸런서 타입 서비스를 구현해주는 툴이다. MetalLB가 제공하는 기능을 크게 나누면 주소를 할당해주는 기능과 외부와 연결하는 기능 두 가지로 나누어 볼 수 있다. 주소 할당 클라우드 제공업체의 Kubernetes 클러스터에서는 로드밸런서를 요청하면 클라우드 플랫폼이 IP 주소를 할당해준다. 베어메탈 클러스터에서는 MetalLB가 이 할당을 담당한다. MetalLB에 사용할 수 있는 IP 주소 풀을 제공하면 해당 풀에서 LB를 생성해준다. 외부 연결 MetalLB가 서비스에 외부 IP 주소를 할당한 후에는 해당 IP가 클러스터에 “존재한다”는 것을 클러스터 외부
K8s Architecture
kubernetes
쿠버네티스는 중앙(Master)에 API 서버와 상태 저장소를 두고 각 서버(Node)의 에이전트(kubelet)와 통신하는구조로 동작한다. 하지만 이 개념을 여러 모듈로 쪼개어 구현하고 다양한 오픈소스를 사용하기 떄문에 설치가 까다롭고 구성이 복잡해보일 수 있다. 마스터-노드 구조 쿠버네티스는 전체 클러스터를 관리하는 마스터와 컨테이너가 배포되는 노드로 구성되어있다. 모든 명령은 마스터의 API 서버를 호출하고 노드는 마스터와 통신하면서 필요한 작업을 수행한다. 특정 노드의 컨테이너에 명령하거나 로그를 조회할 때도 노드에 직접 명령하는게 아니라 마스터에 명령을 내리고 마스터가 노드에 접속하여 대신 결과를 응답한다. Master 마스터 서버는 다양한 모듈이 확장성을 고려하여 기능별로 쪼개져 있는 것이 특징이
Kubernetes
kubernetes
쿠버네티스(Kubernetes)는 컨테이너화 된 애플리케이션의 대규모 배포, 스케일링 및 관리를 간편하게 만들어주는 오픈 소스 기반 컨테이너 오케스트레이션 도구이다. 프로덕션 환경에서는 애플리케이션을 실행하는 여러 컨테이너를 관리하고 다운타임이 없는지 확인해야하는데, Kubernetes는 다중 컨테이너 처리를 자동으로 처리하고, 분산 시스템을 탄력적으로 실행할 수 있는 프레임워크를 제공한다. K8s를 사용하면 애플리케이션의 확장 및 장애 조치를 처리하고 배포 패턴 등을 쉽게 처리할 수 있다. 쿠버네티스의 특징 5가지 1. 선언적 접근 방식 쿠버네티스에서는 동작을 지시하는 개념보다는 상태를 선언하는 개념을 주로 사용한다. 쿠버네티스는 원하는 상태(Desired state)와 현재의 상태(Current sta
ServiceDNS
dns
생성된 서비스의 IP는 어떻게 알 수 있을까? 서비스가 생성된 후 kubectl get svc를 이용하면 생성된 서비스와 IP를 받아올 수 있지만, 이는 서비스가 생성된 후이고, 계속해서 변경되는 임시 IP이다. DNS를 이용하는 방법 가장 쉬운 방법으로는 DNS 이름을 사용하는 방법이 있다. 서비스는 생성되면 [서비스 명].[네임스페이스명].svc.cluster.local 이라는 DNS 명으로 쿠버네티스 내부 DNS에 등록이 된다. 쿠버네티스 클러스터 내부에서는 이 DNS 명으로 서비스에 접근이 가능한데, 이때 DNS에서 리턴해주는 IP는 외부 IP (External IP)가 아니라 Cluster IP (내부 IP)이다. 간단한 테스트를 해보자. hello-node-svc 가 생성이 되었는데, 클러스터내의
Network Troubleshooting
network
각 상황에 맞는 네트워크 트러블슈팅 도구를 정리하면 다음과 같다: 상황도구연결 확인traceroute, ping, telnet, netcat포트 스캔nmapDNS 레코드 확인dig, 연결 확인 도구들HTTP/1 확인cURL, telnet, netcatHTTPS 확인OpenSSL, cURL리스닝 프로그램 확인netstat 보안 본격적으로 도구를 다루기 전에, 보안에 대해 먼저 인지해야 한다. 공격자는 여기 소개된 모든 도구를 이용해 시스템을 탐색하고 침투할 수 있다. 그래서 최선의 방법은 각 머신에 최소한의 네트워킹 도구만 설치하는 것이다. 물론 공격자가 직접 도구를 다운로드하거나 패키지 매니저를 쓸 수도 있다(권한이 있다면). 대부분의 경우 단지 공
eBPF
network
eBPF는 커널에서 샌드박스된 특별한 프로그램을 실행할 수 있게 해주는 프로그래밍 시스템이다. Netfilter나 iptables처럼 커널과 유저 공간을 오가지 않고 커널 내에서 직접 동작한다. eBPF 이전에는 BPF(Berkeley Packet Filter)가 있었다. BPF는 커널에서 네트워크 트래픽을 분석하는 데 사용되는 기술이다. BPF는 패킷 필터링을 지원하는데, 유저 공간 프로세스가 어떤 패킷을 검사할지 지정하는 필터를 제공할 수 있다. BPF의 대표적인 사용 사례가 tcpdump다. tcpdump는 필터를 BPF 프로그램으로 컴파일해서 BPF에 전달한다. BPF의 기법은 이후 다른 프로세스와 커널 작업으로 확장되었다. tcpdump 예제 Terminal window$ sudo tcpdump -
PV & PVC
object
k8s에서 Volume을 사용하는 구조는 PV라고 하는 퍼시스턴트 볼륨(PersistentVolume)과 PVC라고 하는 퍼시스턴트 볼륨 클레임(PersistentVolumeClaim) 2개로 분리되어 있다. PV/PVC PV는 Persistent Volume의 약자이다. pod와는 별개로 관리되며 별도의 생명 주기가 있다. PVC는 사용자가 PV에 하는 요청이다. 사용하고 싶은 용량은 얼마인지, 읽기/쓰기는 어떤 모드로 설정하고 싶은지 등을 정해서 요청한다. k8s 볼륨을 pod에 직접 할당하는 방식이 아니라 중간에 PVC를 두어 pod와 pod가 사용할 스토리지를 분리할 수 있다. 이런 구조는 pod 각각의 상황에 맞게 다양한 스토리지를 사용할 수 있게 한다. 클라우드 서비스를 사용할 때는 본인이 사용
Pod
object
Pod는 동일한 실행환경에서 실행되는 애플리케이션 컨테이너와 볼륨으로 구성된 집합체다. 포드는 쿠버네티스 클러스터에서 배포 가능한 가장 작은 아티팩트(artipact)다. 즉, 포드에 있는 모든 컨테이너가 동일한 머신에 있음을 뜻한다. Pod에 있는 각 컨테이너는 각자의 cgroup을 운영하지만 몇가지 Linux 네임스페이스는 공유한다. Pod의 각 컨테이너는 각자의 cgroup 을 운영하지만 몇가지 리눅스 네임스페이스를 공유하며, 서로 다른 파드는 각 애플리케이션이 격리되어 있고 각기 다른 IP주소와 호스트네임을 갖는다. 또한 System V IPC나 POSIX 메시지 큐(IPC 네임스페이스)를 통해 기본 프로세스 간 통신 채널을 사용해 서로 통신할 수 있다. 동일한 노드에서 동작하는 서로 다른 Pod의
RollingUpdate
object
Rolling Update는 k8s의 업데이트 방법 중 하나로, 새로운 버전의 애플리케이션을 배포하고 기존 버전을 점진적으로 대체하는 과정으로 진행된다. 새로운 버전의 Pod로 트래픽이 전달되기 전까지 기존 버전이 유지되므로 무중단으로 애플리케이션을 업데이트 가능한 장점이 있다. 그러나 새로운 버전의 Pod와 기존 Pod가 함께 유지되는 기간이 존재하기 때문에 업데이트 중에 리소스를 더 사용할 수 있다. 기본적으로 Rolling Update는 다음과 같은 단계로 이뤄진다. 새로운 버전의 애플리케이션을 배포한다. 이때 기존 버전은 유지된 상태로 새로운 버전의 Pod가 함께 생성된다. 새로운 버전의 Pod가 정상적으로 동작하고, 준비 상태가 되면, 이전 버전의 Pod을 하나씩 종료한다. 이때 제거되는 Pod
Service와 port
object
쿠버네티스 환경에서 Service는 Pod들을 통해 실행되고 있는 애플리케이션을 네트워크에 노출(expose)시키는 가상의 컴포넌트다. 쿠버네티스 내부의 다양한 객체들이 애플리케이션과, 그리고 애플리케이션이 다른 외부의 애플리케이션이나 사용자와 연결될 수 있도록 도와주는 역할을 한다. 쿠버네티스에 Service가 있는 이유는, Pod들이 반영속적인 특성을 가지고 있기 때문이다. 쿠버네티스에서의 Pod는 무언가가 구동 중인 상태를 유지하기 위해 동원되는 일회성 자원으로 언제든 다른 노드로 옮겨지거나 삭제될 수 있다. 또한 Pod는 생성될 때마다 새로운 내부 IP를 받게 되므로, 이것만으로 클러스터 내/외부와의 통신을 계속 유지하기 어렵다. 따라서 쿠버네티스는 Pod가 외부와 통신할 수 있도록 클러스터 내부에서
ingress
object
인그레스(ingress)는 클러스터 내의 서비스에 대한 외부 접근을 관리하는 API 오브젝트이며, 일반적으로 HTTP를 관리한다. 인그레스는 부하 분산, SSL 종료, 명칭 기반의 가상 호스팅을 제공할 수 있다. 인그레스는 클러스터 외부에서 클러스터 내부 서비스로 HTTP와 HTTPS 경로를 노출한다. 트래픽 라우팅은 인그레스 리소스에 정의된 규칙에 의해 컨트롤된다. 인그레스는 외부에서 서비스로 접속이 가능한 URL, 로드 밸런스 트래픽, SSL / TLS 종료 그리고 이름-기반의 가상 호스팅을 제공하도록 구성할 수 있다. 인그레스 컨트롤러는 일반적으로 로드 밸런서를 사용해서 인그레스를 수행할 책임이 있으며, 트래픽을 처리하는데 도움이 되도록 에지 라우터 또는 추가 프런트 엔드를 구성할 수도 있다. 인그레
가상 IP와 서비스 프록시
개념
쿠버네티스 클러스터의 모든 노드는 kube-proxy를 실행한다. kube-proxy는 ExternalName 이외의 유형의 서비스에 대한 “가상 IP”의 역할을 한다. service를 조회했을때 나오는 cluster IP가 바로 k8s의 프록시로 만들어진 가상 IP이다. 이 IP는 k8s 내부에서만 접근할 수 있다. 쿠버네티스에서 가상 IP를 사용하는 이유 쿠버네티스가 프록시를 통해 가상 IP를 만드는 이유는, 실제 IP와 DNS를 사용하기 부적절하기 때문이다. k8s의 서비스 객체는 IP를 할당할 수 있는 기기가 아니고 잠시 생겼다가 사라질 수 있는 유한한 존재이다. 하지만 서비스를 식별하고 호출할 수 있는 무언가가 필요하기 때문에 그 방법으로서 프록시로 만든 가상 IP를 사용하는 것이다. ku
사이드카 패턴
개념
사이드카 패턴이란 쿠버네티스와 같이 컨테이너 오케스트레이션 툴에서 구성할 수 있는 컨테이너 배치 패턴으로, 마치 오토바이 옆에 붙어 있는 사이드카와 비슷한 형태이다. 장점 1. 기존 로직의 변경 없이 기능 추가 사이드카 컨테이너를 통해 기존의 로직은 그대로 놔둔체 새로운 기능을 덧붙일 수 있다. 예를 들어 기존 http 프로토콜에 대해서만 서비스를 하는 웹서버에 tls layer를 추가하고 싶은 경우, 메인 컨테이너인 기존의 legacy 웹서버는 그대로 놔둔체 사이드카 컨테이너를 통해 https 서비스를 클라이언트에게 제공할 수 있다. 2. 컨테이너 재사용성 사이드카 컨테이너를 단일한 기능을 하게 모듈화하면 다른 곳에서 재사용하기 수월해진다. 대부분의 app에서는 로깅, 실행 프로세스 정보 확인 등의 작업들
OIDC Authentication with Dex
auth
OIDC (Open ID Connect) 인증 방법은 OAuth2 위에서 동작하는 인증으로, Github이나 Google과 같이 서드 파티에서 부여받은 OAuth 권한을 통해 쿠버네티스의 인증을 수행한다. 기존에 사용하던 OAuth 인증 방법을 쿠버네티스에 그대로 가져온다고 생각하면 이해하기 쉽다. OIDC 인증 방법은 OAuth + JWT 토큰을 사용한다는 점에서 Webhook Token 인증 방법과 차이점을 갖는다. OAuth 토큰을 관리하기 위한 중간 서버를 구현한 Dex를 사용하여 OIDC 인증을 구현해보자. Dex Concept Dex는 서드 파티로부터 OAuth 인증 토큰을 가져와 관리하는 인증 도구이다. OAuth를 사용하기 위해 반드시 Dex를 써야 하는 것은 아니지만, Dex는 OAuth 서
Token Webhook with Guard
auth
Webhook 서버에 인증 데이터를 전달한 뒤, 클라이언트가 유효한지 인증하여 Third party에 권한을 부여하는 Webhook Token 인증 방법에 대해 알아보자. 사용자는 미리 인증 데이터를 발급받아 놓고, 사용자가 인증 데이터를 Bearer 헤더에 담아서 REST API 요청을 보내면 API 서버는 클라이언트가 유효한지를 검증하기 위해 Webhook 서버에 인증 데이터를 전달한다. Webhook 서버는 해당 데이터를 검사한 뒤, 인증 여부를 API 서버에 반환하는 간단한 방식으로 되어 있다 Token Webhook, OIDC 중 어느 방법을 선택하든지에 상관 없이 클라이언트는 HTTP의 Bearer 헤더에 인증 데이터를 담아서 보내기만 하면 된다. 클라이언트는 인증 방법이 무엇인지 알 필요가
k8s 클러스터 root CA를 통한 사용자 인증
auth
k8s는 기본적으로 root CA 인증서를 스스로 발급해 사용한다. 이 인증서를 이용하면 별도의 Third-party 연동 없이도 User와 Group을 사용할 수 있다. 단, 이 방법은 여러모로 한계점이 많기 때문에 가능하면 사용하지 않는 것이 좋다. 인증서가 유출되었을 때 revoke가 힘들기도 하고, 파일 단위로 인증 정보를 관리하는 것은 매우 비효율적이고 보안에 취약하기 때문이다. 따라서 k8s는 인증서 발급을 통한 사용자 인증은 극히 제한된 경우에만 사용하고 있다. 대표적으로는 관리자 권한을 가져야 하는 system:master 그룹의 인증 정보를 생성한다거나 (/etc/kubernetes/admin.conf), k8s의 핵심 컴포넌트에 인증서를 발급한다거나 할 때가 이에 해당한다. 우선, k8s는
spot 인스턴스에서 서버 가용성 개선하기
공부
개요 대덕SW마이스터고 동아리에서 개발한 4개의 교내 서비스(약 250명의 교사와 학생이 사용 중)를 대상으로 서비스 인프라를 통합하는 프로젝트를 진행했다. 이 프로젝트에서 Karpenter를 코드를 커스텀하여, Spot 인스턴스 환경의 Replica 1인 Deployment의 가용성을 96% -99.95%로 개선한 과정을 설명하는 글이다. 문제 상황 해당 인프라에선 각 동아리가 새 프로젝트를 개발할 때마다 배포할 수 있어야 했기 때문에, 자주 변동하는 컨테이너, 컴퓨팅 리소스를 쉽게 관리하기 위해 Kubernetes(EKS)를 사용하였다. 초기에 가용성을 크게 고려하지 않고 각 Deployment의 Replica 수를 1로 유지했음에도, 수십개 컨테이너를 실행하기엔 서버비 예산에 압박이 있었다. 따라서 모