25. Kubernetes 자동 확장 메커니즘
Kubernetes는 Horizontal Pod Autoscaler(HPA) 컨트롤러를 사용하여 CPU 사용률을 기반으로 한 Pod의 자동 확장 및 축소 기능을 구현합니다.
- HPA 컨트롤러는 주기적으로 대상 Pod의 리소스 성능 지표를 모니터링하고, HPA 리소스 객체에 정의된 확장/축소 조건과 비교합니다.
- 조건이 충족되면 Pod의 복제본 수를 조정합니다.
26. Kubernetes Service 타입
Service를 생성하면 동일한 기능을 수행하는 컨테이너 애플리케이션 그룹에 대해 통합된 진입 주소를 제공할 수 있습니다. 또한, 요청 부하를 백엔드의 각 컨테이너 애플리케이션으로 분산시킵니다. 주요 Service 타입은 다음과 같습니다:
ClusterIP:
- 가상 서비스 IP 주소로, Kubernetes 클러스터 내부의 Pod 간 통신에 사용됩니다.
- 각 Node에서 kube-proxy가 설정한 iptables 규칙을 통해 트래픽을 포드로 전달합니다.
- 목적: 클러스터 내부에서만 접근 가능한 Service를 생성합니다.
- 사용 시나리오: 백엔드 애플리케이션이 클러스터 내부 다른 Pod에 의해 호출될 때.
apiVersion: v1
kind: Service
metadata:
name: backend-service
namespace: default
spec:
selector:
app: backend
ports:
- protocol: TCP
port: 80 # Service의 포트
targetPort: 8080 # Pod에서 노출된 포트
type: ClusterIP
예시 사용법:
- 클러스터 내부의 다른 Pod에서 backend-service로 요청.
- 예: curl http://backend-service:80.
NodePort:
- 호스트 머신(Node)의 포트를 사용하여 외부 클라이언트가 Node의 IP 주소와 포트 번호를 통해 서비스에 접근할 수 있도록 합니다.
- 목적: 클러스터 외부에서도 Node의 IP와 포트를 통해 서비스에 접근할 수 있도록 설정합니다.
- 사용 시나리오: 간단한 테스트나 로컬 환경에서 외부 접근이 필요할 때.
apiVersion: v1
kind: Service
metadata:
name: nodeport-service
namespace: default
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80 # Service의 포트
targetPort: 8080 # Pod에서 노출된 포트
nodePort: 30007 # Node에서 사용할 고정 포트 (선택 사항, 생략 시 자동 할당)
type: NodePort
예시 사용법:
- 클러스터 외부에서 http://<Node_IP>:30007로 서비스 접근.
- 예: curl http://192.168.1.10:30007.
LoadBalancer:
- 외부 로드 밸런서를 사용하여 서비스로의 부하 분산을 수행합니다.
- spec.status.loadBalancer 필드에서 외부 로드 밸런서의 IP 주소를 지정해야 합니다.
- 주로 퍼블릭 클라우드 환경에서 사용됩니다.
- 목적: 퍼블릭 클라우드의 로드 밸런서를 통해 외부 트래픽을 서비스로 연결.
- 사용 시나리오: AWS, GCP, Azure 같은 클라우드 환경에서 애플리케이션을 외부 사용자에게 노출할 때.
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service
namespace: default
spec:
selector:
app: web-app
ports:
- protocol: TCP
port: 80 # Service의 포트
targetPort: 8080 # Pod에서 노출된 포트
type: LoadBalancer
예시 사용법:
- 클라우드 공급자가 로드 밸런서를 생성하고, 외부 IP를 자동으로 할당.
- spec.status.loadBalancer.ingress에 할당된 외부 IP를 통해 서비스에 접근.
- 예: curl http://<External_IP>.\
27. Kubernetes Service의 백엔드 분배 전략
Kubernetes Service는 요청을 백엔드 Pod에 분배하기 위해 다음과 같은 두 가지 전략을 제공합니다:
- RoundRobin (라운드 로빈):
- 기본 분배 방식으로, 요청을 순차적으로 각 Pod에 분배합니다.
- 모든 Pod에 공평하게 트래픽을 나누어 부하를 고르게 분산합니다.
- SessionAffinity (세션 고정):
- 클라이언트의 IP 주소 기반 세션 유지 방식입니다.
- 첫 번째 요청을 특정 Pod로 전달한 후, 같은 클라이언트로부터 오는 요청은 동일한 Pod로 전달됩니다.
- 세션 유지가 필요한 애플리케이션에서 사용됩니다.
apiVersion: v1
kind: Service
metadata:
name: sessionaffinity-service
namespace: default
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80 # Service 포트
targetPort: 8080 # Pod의 포트
type: ClusterIP
sessionAffinity: ClientIP # 세션 고정 설정 , 기본 설정은 RoundRobin
28. Kubernetes Headless Service 란?
Headless Service는 클러스터 IP를 생성하지 않고, Pod의 DNS 정보를 직접 클라이언트에 반환합니다. 아래는 예제를 통해 이를 설명합니다.
Headless Service 정의
- 목적: ClusterIP를 사용하지 않고, 같은 Label을 가진 Pod 목록을 반환.
- YAML 정의:
apiVersion: v1
kind: Service
metadata:
name: headless-service
namespace: default
spec:
clusterIP: None # Headless Service를 정의하는 핵심 설정
selector:
app: my-app
ports:
- protocol: TCP
port: 80 # Service 포트
targetPort: 8080 # Pod의 컨테이너 포트
Deployment 정의
- 목적: 여러 Pod를 생성하여 Headless Service의 동작 확인.
- YAML 정의:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app-container
image: nginx
ports:
- containerPort: 8080
동작 테스트
DNS 확인:
- Headless Service는 clusterIP가 없으므로 DNS 요청 시 Pod의 IP 목록을 반환.
- 클러스터 내부의 다른 Pod에서 DNS 확인:
nslookup headless-service.default.svc.cluster.local
반환 결과:
Name: headless-service.default.svc.cluster.local
Address: 192.168.1.101
Address: 192.168.1.102
Address: 192.168.1.103
클라이언트 요청:
- Headless Service를 통해 직접 각 Pod로 요청 가능.
curl http://192.168.1.101:8080
curl http://192.168.1.102:8080
29. Kubernetes Ingress 란?
- Ingress 규칙:
- Ingress는 정의된 규칙에 따라 URL 또는 도메인 기반으로 요청을 라우팅합니다.
- Ingress Controller:
- Ingress Controller는 Ingress 규칙을 기반으로 클라이언트 요청을 Service에 연결하는 역할을 합니다.
- Ingress Controller는 요청을 **Service의 백엔드 Endpoint(Pod)**로 직접 전달합니다.
- 이 과정에서 kube-proxy를 우회하므로 kube-proxy는 작동하지 않습니다.
- 트래픽 흐름:
- Ingress Controller + Ingress 규칙 → Service → Pod (Endpoint) 형태로 요청이 전달됩니다.
Kubernetes Ingress 예제:
아래는 Ingress와 Ingress Controller를 설정하고 사용하는 예제입니다. 이 예제는 URL 기반 트래픽 라우팅을 구현합니다.
Deployment와 Service 생성
두 개의 애플리케이션(Pod)을 실행하고, 각각 Service로 노출합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: app1
labels:
app: app1
spec:
replicas: 1
selector:
matchLabels:
app: app1
template:
metadata:
labels:
app: app1
spec:
containers:
- name: app1
image: nginx
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app2
labels:
app: app2
spec:
replicas: 1
selector:
matchLabels:
app: app2
template:
metadata:
labels:
app: app2
spec:
containers:
- name: app2
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: app1-service
spec:
selector:
app: app1
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: app2-service
spec:
selector:
app: app2
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
Ingress 설정
Ingress를 생성하여 URL 경로를 기반으로 Service로 트래픽을 라우팅합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: "example.com" # 클라이언트 요청 시 사용되는 도메인
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- path: /app2
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
참고로 Ingress Controller는 Kubernetes 클러스터에 기본적으로 설치되어 있지 않습니다.
Ingress 리소스는 Kubernetes의 기본 기능으로 지원되지만, 실제로 이를 처리하는 Ingress Controller는 사용자가 직접 설치해야 합니다.
29. Kubernetes 이미지 다운로드 전략
Kubernetes의 이미지 다운로드(풀링) 전략에는 Always, Never, IfNotPresent 세 가지가 있습니다.
- Always:
- 이미지 태그가 latest인 경우, 항상 지정된 레지스트리에서 이미지를 가져옵니다.
- Never:
- 레지스트리에서 이미지를 다운로드하지 않습니다.
- 즉, 로컬에 이미 있는 이미지만 사용할 수 있습니다.
- IfNotPresent:
- 로컬에 해당 이미지가 없을 때만 대상 레지스트리에서 이미지를 다운로드합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: ifnotpresent-example
labels:
app: example
spec:
replicas: 1
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example
spec:
containers:
- name: app-container
image: nginx:1.20
imagePullPolicy: IfNotPresent # 기본값
Always # 항상 레지스트리에서 이미지를 가져옵니다.
Never # 레지스트리에서 이미지를 다운로드하지 않습니다.
IfNotPresent # 기본값 -> 로컬에 이미지가 없으면 레지스트리에서 다운로드.
30. Kubernetes의 로드 밸런서
로드 밸런서는 서비스를 외부로 노출하는 가장 일반적이고 표준적인 방법 중 하나입니다.
로드 밸런서의 종류
작업 환경에 따라 내부 로드 밸런서와 외부 로드 밸런서 두 가지 유형이 사용됩니다:
- 내부 로드 밸런서 (Internal Load Balancer):
- 클러스터 내부에서 트래픽을 자동으로 분산합니다.
- 필요한 설정에 따라 컨테이너에 트래픽을 할당합니다.
- 외부 로드 밸런서 (External Load Balancer):
- 클러스터 외부에서 들어오는 트래픽을 백엔드 컨테이너로 라우팅합니다.
- 클라이언트가 외부에서 서비스에 접근할 수 있도록 합니다.
이러한 로드 밸런서는 Kubernetes에서 서비스와 컨테이너 간의 트래픽을 효율적으로 관리하는 데 사용됩니다.
31. Kubernetes 각 모듈이 API Server와 통신하는 방식
Kubernetes의 API Server는 클러스터의 핵심으로, 클러스터 내 모든 기능 모듈 간의 통신을 담당합니다.
- 각 모듈은 API Server를 통해 정보를 etcd에 저장하거나 데이터를 가져옵니다.
- 데이터 요청 및 처리에는 REST 인터페이스(GET, LIST, WATCH 등)가 사용됩니다.
이를 통해 Kubernetes의 각 모듈은 서로 정보를 교환하고 동작을 조율합니다.
1. kubelet과 API Server의 통신
- 동작 방식:
- 각 Node에서 실행되는 kubelet은 주기적으로 API Server의 REST 인터페이스를 호출하여 자신의 상태를 보고합니다.
- API Server는 이 정보를 수신한 후 etcd에 노드 상태를 업데이트합니다.
- 예시:
- Node의 CPU, 메모리 사용량, Pod 상태 등의 정보가 포함됩니다.
2. kube-controller-manager와 API Server의 통신
- Node Controller와의 상호작용:
- kube-controller-manager의 Node Controller 모듈은 API Server의 WATCH 인터페이스를 사용하여 Node 상태 정보를 실시간으로 모니터링합니다.
- Node에 이상이 발생하면 적절한 조치를 실행합니다(예: Pod 재배치).
- Pod 관리:
- ReplicaSet Controller와 같은 다른 컨트롤러는 API Server를 통해 Pod 상태를 확인하고 복제본 수를 조정합니다
3. kube-scheduler와 API Server의 통신
- Pod 스케줄링:
- kube-scheduler는 API Server의 WATCH 인터페이스를 통해 새로 생성된 Pod의 정보를 수신합니다.
- 수신 후, Pod 요구사항에 부합하는 Node 목록을 생성하고, 최적의 Node를 선택하여 Pod을 배치합니다.
- 스케줄링이 완료되면 API Server를 통해 Pod을 대상 Node에 바인딩합니다.
통신 흐름 요약
- 데이터 저장:
- 모든 Kubernetes 모듈은 API Server를 통해 데이터를 etcd에 저장합니다.
- 데이터 조회:
- 모듈이 데이터를 요청할 때 API Server의 REST 인터페이스를 사용하여 데이터를 조회하거나 모니터링합니다.
- 데이터 동기화:
- API Server는 etcd와 지속적으로 데이터를 동기화하여 클러스터의 최신 상태를 유지합니다.
31. Kubernetes Scheduler의 역할 및 구현 원리
Kubernetes Scheduler는 Pod 스케줄링을 담당하는 핵심 기능 모듈로, 시스템에서 "위로는 상위 기능과 연결하고, 아래로는 하위 작업을 시작하는 중요한 역할" 을 수행합니다.
역할
- "위로 연결":
- Controller Manager가 생성한 새 Pod을 받아, 적절한 Node로 스케줄링합니다.
- "아래로 시작":
- 스케줄링이 완료된 후, 해당 Node의 kubelet 프로세스가 후속 작업을 이어받아 Pod의 생명 주기를 관리합니다.
동작 원리
- Kubernetes Scheduler는 API Server에서 대기 중인 새 Pod(예: 새로 생성되었거나, Controller Manager가 복제를 위해 생성한 Pod)을 감지합니다.
- 특정 스케줄링 알고리즘과 스케줄링 정책을 기반으로, 클러스터 내에서 가장 적합한 Node를 선택합니다.
- 선택된 Node에 Pod을 바인딩(Binding) 하고, 이 정보를 etcd에 저장합니다.
Scheduler의 핵심 기능
- 적합한 Node 선택: Pod 요구 사항(예: CPU, 메모리 등)과 Node 리소스 상태를 비교하여 최적의 Node를 결정.
- Pod 바인딩: 선택된 Node에 Pod을 할당하고 이 정보를 클러스터에 기록.
- 정책 기반 스케줄링: 사용자 정의 규칙 및 우선 순위에 따라 스케줄링 전략을 설정 가능.
32. Kubernetes kubelet의 역할
Kubernetes 클러스터에서 각 Node(Worker Node)에는 kubelet 서비스 프로세스가 실행됩니다.
kubelet은 마스터 노드에서 해당 노드로 전달된 작업을 처리하고, Pod 및 Pod 내부의 컨테이너를 관리하는 역할을 합니다.
주요 역할
- Node 정보 등록:
- 각 kubelet 프로세스는 API Server에 자신의 Node 정보를 등록합니다.
- Node 상태 보고:
- 주기적으로 마스터 노드에 Node 리소스 사용량(CPU, 메모리 등)을 보고합니다.
- Pod 및 컨테이너 관리:
- 마스터에서 전달된 Pod 생성 요청을 처리하며, Pod 내부의 컨테이너를 생성하고 실행 상태를 관리합니다.
- 리소스 모니터링:
- cAdvisor를 사용하여 컨테이너와 Node 리소스를 실시간으로 모니터링합니다.
'K8S' 카테고리의 다른 글
Kubernetes 기술 개념 정리 6 (2) | 2024.12.12 |
---|---|
Kubernetes 기술 개념 정리 5 (0) | 2024.12.11 |
Kubernetes 기술 개념 정리 3 (9) | 2024.12.05 |
Kubernetes 기술 개념 정리 2 (2) | 2024.12.05 |
Kubernetes 기술 개념 정리 1 (1) | 2024.12.03 |
댓글