이 글에서는 쿠버네티스 네트워킹의 기본 개념을 살펴보고, Service, Ingress, CNI의 핵심 개념과 역할에 대해 알아보겠습니다. 특히 MinIO와 Cilium을 활용하는 환경에서 네트워크 구성 방법을 중심으로 설명하겠습니다.
📌 쿠버네티스 네트워킹 모델 이해하기
✅ 쿠버네티스 네트워킹의 4가지 문제
쿠버네티스는 분산 시스템으로서 네트워킹 문제를 해결하기 위한 명확한 모델을 제시합니다.
▶️ 쿠버네티스가 해결하는 네트워킹 문제:
- 컨테이너-컨테이너 통신: Pod 내 컨테이너 간 통신
- Pod-Pod 통신: 서로 다른 Pod 간 통신
- Pod-Service 통신: Pod에서 서비스로의 접근
- 외부-Service 통신: 외부에서 클러스터 내부 서비스 접근
✅ Pod 네트워킹 기본 원칙
쿠버네티스의 Pod 네트워킹은 몇 가지 중요한 원칙을 따릅니다.
▶️ Pod 네트워킹 특징:
- 모든 Pod는 고유한 IP 주소를 가짐
- 모든 Pod는 NAT 없이 다른 Pod와 통신 가능
- 노드의 에이전트(kubelet)는 Pod의 IP를 할당
- Pod 내 컨테이너는 localhost를 통해 통신
apiVersion: v1 # 쿠버네티스 API 버전
kind: Pod # 리소스 종류
metadata:
name: network-example # Pod 이름
namespace: default # 네임스페이스 지정
spec:
containers:
- name: main-container # 메인 컨테이너 이름
image: nginx:1.21 # 사용할 이미지
ports:
- containerPort: 80 # 컨테이너가 사용하는 포트, 명시적 선언으로 가독성 향상
- name: sidecar # 사이드카 컨테이너 이름
image: busybox # 경량 유틸리티 이미지
command: ["sh", "-c", "while true; do wget -q -O- http://localhost:80; sleep 10; done"] # localhost를 통한 통신 예시
📌 Service의 개념과 유형
✅ Service란 무엇인가?
Service는 Pod 집합에 대한 안정적인 엔드포인트를 제공하는 쿠버네티스 리소스입니다.
▶️ Service의 주요 기능:
- Pod에 대한 단일 DNS 이름 제공
- 로드 밸런싱을 통한 트래픽 분산
- Pod의 생성/삭제에 관계없이 안정적인 IP 주소 유지
- 서비스 디스커버리 메커니즘 제공
apiVersion: v1 # 쿠버네티스 API 버전
kind: Service # 리소스 종류
metadata:
name: minio-service # Service 이름, DNS 이름의 일부가 됨
namespace: minio-system # 네임스페이스 지정
spec:
selector:
app: minio # 이 라벨을 가진 Pod들이 Service의 대상이 됨
ports:
- name: api # 포트 이름, DNS SRV 레코드 및 참조용
port: 9000 # Service가 노출하는 포트
targetPort: 9000 # Pod에서 실제 사용하는 포트
- name: console # 콘솔 UI용 포트 이름
port: 9001 # Service가 노출하는 포트
targetPort: 9001 # Pod에서 실제 사용하는 포트
type: ClusterIP # Service 유형, 클러스터 내부에서만 접근 가능
✅ Service 유형과 특징
쿠버네티스는 다양한 유형의 Service를 제공하여 다양한 네트워킹 요구사항을 충족시킵니다.
- ClusterIP
- 클러스터 내부에서만 접근 가능한 가상 IP 제공
- 기본 Service 유형
- 내부 마이크로서비스 통신에 적합
apiVersion: v1 # 쿠버네티스 API 버전
kind: Service # 리소스 종류
metadata:
name: minio-internal # Service 이름
namespace: minio-system # 네임스페이스
spec:
selector:
app: minio # 대상 Pod 선택자
ports:
- port: 9000 # Service 포트
targetPort: 9000 # 대상 Pod 포트
type: ClusterIP # 클러스터 내부 접근용 타입
- NodePort
- 모든 노드의 특정 포트를 통해 서비스 노출
- 포트 범위: 30000-32767
- 개발 환경이나 임시 외부 액세스에 유용
apiVersion: v1 # 쿠버네티스 API 버전
kind: Service # 리소스 종류
metadata:
name: minio-nodeport # Service 이름
namespace: minio-system # 네임스페이스
spec:
selector:
app: minio # 대상 Pod 선택자
ports:
- port: 9000 # 클러스터 내부 Service 포트
targetPort: 9000 # 대상 Pod 포트
nodePort: 30900 # 모든 노드에서 노출할 포트
type: NodePort # 노드 포트 타입
- LoadBalancer
- 클라우드 제공업체의 로드 밸런서를 프로비저닝
- 외부 IP를 통한 직접 접근 제공
- 프로덕션 환경의 외부 서비스에 적합
apiVersion: v1 # 쿠버네티스 API 버전
kind: Service # 리소스 종류
metadata:
name: minio-lb # Service 이름
namespace: minio-system # 네임스페이스
spec:
selector:
app: minio # 대상 Pod 선택자
ports:
- port: 9000 # Service 포트
targetPort: 9000 # 대상 Pod 포트
type: LoadBalancer # 로드밸런서 타입
- ExternalName
- 외부 서비스에 대한 CNAME 레코드 매핑
- 직접적인 Pod 선택자 없음
- 클러스터 외부 서비스를 내부 DNS로 참조할 때 유용
apiVersion: v1 # 쿠버네티스 API 버전
kind: Service # 리소스 종류
metadata:
name: external-minio # Service 이름
namespace: minio-system # 네임스페이스
spec:
type: ExternalName # 외부 서비스 참조 타입
externalName: minio.example.com # 외부 서비스 도메인
✅ 헤드리스 서비스 (Headless Service)
헤드리스 서비스는 클러스터 IP가 없는 특별한 형태의 서비스로, StatefulSet과 함께 사용할 때 특히 유용합니다.
▶️ 헤드리스 서비스 특징:
- clusterIP: None으로 설정
- 로드 밸런싱이나 프록시 없음
- Pod IP에 직접 연결을 위한 DNS 레코드 제공
- 개별 Pod에 대한 DNS 조회 가능
apiVersion: v1 # 쿠버네티스 API 버전
kind: Service # 리소스 종류
metadata:
name: minio-headless # 헤드리스 서비스 이름
namespace: minio-system # 네임스페이스
spec:
clusterIP: None # 헤드리스 서비스 지정을 위한 None 값
selector:
app: minio # 대상 Pod 선택자
ports:
- port: 9000 # Service 포트
targetPort: 9000 # 대상 Pod 포트
📌 Ingress의 이해
✅ Ingress란 무엇인가?
Ingress는 클러스터 외부에서 내부 서비스로의 HTTP 및 HTTPS 라우팅을 관리하는 API 객체입니다.
▶️ Ingress의 주요 기능:
- URL 기반 라우팅
- SSL/TLS 종료
- 이름 기반 가상 호스팅
- 로드 밸런싱
- 경로 재작성 등
apiVersion: networking.k8s.io/v1 # 네트워킹 API 그룹 버전
kind: Ingress # 리소스 종류
metadata:
name: minio-ingress # Ingress 이름
namespace: minio-system # 네임스페이스
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "0" # 대용량 파일 업로드를 위한 설정
spec:
rules:
- host: minio.example.com # 호스트 이름 기반 라우팅
http:
paths:
- path: / # URL 경로
pathType: Prefix # 경로 매칭 타입(Prefix, Exact 등)
backend:
service:
name: minio-service # 대상 서비스 이름
port:
number: 9000 # 대상 서비스 포트
- host: console.minio.example.com # 콘솔용 별도 호스트
http:
paths:
- path: / # URL 경로
pathType: Prefix # 경로 매칭 타입
backend:
service:
name: minio-service # 대상 서비스 이름
port:
number: 9001 # 콘솔 UI 포트
tls: # TLS 설정
- hosts:
- minio.example.com
- console.minio.example.com
secretName: minio-tls-secret # TLS 인증서를 포함하는 시크릿
✅ Ingress 컨트롤러
Ingress 리소스를 활성화하려면 클러스터에 Ingress 컨트롤러가 필요합니다.
▶️ 주요 Ingress 컨트롤러:
- NGINX Ingress Controller
- Traefik
- Kong
- HAProxy
- AWS ALB Ingress Controller
- Cilium L7 지원
# NGINX Ingress Controller 설치 예시 (Helm 차트 values.yaml)
controller:
service:
type: LoadBalancer
config:
use-proxy-protocol: "false"
use-forwarded-headers: "true"
proxy-body-size: "0" # MinIO의 대용량 파일 업로드를 위한 설정
📌 CNI(Container Network Interface)의 이해
✅ CNI란 무엇인가?
CNI(Container Network Interface)는 컨테이너 네트워킹을 구성하기 위한 표준 인터페이스입니다.
▶️ CNI의 주요 역할:
- Pod IP 할당 및 관리
- Pod 간 네트워크 통신 구현
- 네트워크 정책 시행
- 다양한 네트워크 플러그인 지원
✅ 주요 CNI 플러그인 비교
쿠버네티스는 다양한 CNI 플러그인을 지원하며, 각각 고유한 특징과 장점이 있습니다.
- Calico
- BGP 기반 라우팅
- 뛰어난 성능과 확장성
- 세분화된 네트워크 정책 지원
- Flannel
- 간단한 구성과 설치
- vxlan을 사용한 오버레이 네트워크
- 최소한의 네트워크 기능 제공
- Weave Net
- 멀티 호스트 Docker 네트워킹
- 암호화 통신 지원
- 자동화된 네트워크 설정
- Cilium (다음 장에서 상세 다룸)
- eBPF 기반 네트워킹
- 고성능 데이터 경로
- L3-L7 네트워크 보안 정책
- 애플리케이션 프로토콜 인식
✅ CNI 설정 및 구성
CNI 플러그인은 일반적으로 클러스터 설정 시 구성되며, kubeadm 같은 도구를 사용할 때 지정할 수 있습니다.
▶️ CNI 플러그인 설치 방법:
- kubectl apply로 직접 설치
- Helm 차트 사용
- 클러스터 관리 도구를 통한 설치
# Calico CNI 설치 예시
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
# Flannel CNI 설치 예시
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
📌 네트워크 정책(Network Policy)
✅ 네트워크 정책이란?
네트워크 정책은 Pod 간 통신을 세밀하게 제어하는 쿠버네티스 리소스입니다.
▶️ 네트워크 정책의 특징:
- Pod 간 트래픽 제어
- 네임스페이스 간 트래픽 격리
- 인그레스(수신) 및 이그레스(송신) 규칙 정의
- 라벨 선택자를 통한 타겟팅
apiVersion: networking.k8s.io/v1 # 네트워킹 API 그룹 버전
kind: NetworkPolicy # 리소스 종류
metadata:
name: minio-network-policy # 정책 이름
namespace: minio-system # 네임스페이스
spec:
podSelector: # 정책이 적용될 Pod 선택
matchLabels:
app: minio # MinIO Pod에 적용
policyTypes: # 정책 유형(인그레스/이그레스)
- Ingress # 인그레스(수신) 트래픽 제어
- Egress # 이그레스(송신) 트래픽 제어
ingress: # 인그레스 규칙
- from: # 허용할 소스
- namespaceSelector: # 특정 네임스페이스에서만 접근 허용
matchLabels:
name: frontend # frontend 네임스페이스
- podSelector: # 특정 Pod에서만 접근 허용
matchLabels:
role: api-client # api-client 역할을 가진 Pod
ports: # 허용할 포트
- protocol: TCP # 프로토콜
port: 9000 # MinIO API 포트
egress: # 이그레스 규칙
- to: # 허용할 목적지
- namespaceSelector: # 특정 네임스페이스로만 송신 허용
matchLabels:
name: monitoring # monitoring 네임스페이스
ports: # 허용할 포트
- protocol: TCP # 프로토콜
port: 9090 # Prometheus 포트
✅ MinIO에 최적화된 네트워크 정책
MinIO 서버에 적용할 수 있는 네트워크 정책 예시를 살펴봅시다.
- 기본 접근 제어:
apiVersion: networking.k8s.io/v1 # 네트워킹 API 그룹 버전
kind: NetworkPolicy # 리소스 종류
metadata:
name: minio-default-policy # 정책 이름
namespace: minio-system # 네임스페이스
spec:
podSelector: # 정책 대상 Pod
matchLabels:
app: minio # MinIO Pod
policyTypes:
- Ingress # 인그레스 정책
ingress:
- from: # 소스 제한
- podSelector: {} # 같은 네임스페이스의 모든 Pod
ports:
- protocol: TCP # TCP 프로토콜
port: 9000 # API 포트
- protocol: TCP
port: 9001 # 콘솔 포트
- 애플리케이션별 접근 제어:
apiVersion: networking.k8s.io/v1 # 네트워킹 API 그룹 버전
kind: NetworkPolicy # 리소스 종류
metadata:
name: minio-app-specific # 정책 이름
namespace: minio-system # 네임스페이스
spec:
podSelector: # 정책 대상 Pod
matchLabels:
app: minio # MinIO Pod
policyTypes:
- Ingress # 인그레스 정책
ingress:
- from: # 허용할 소스
- namespaceSelector: # 네임스페이스 선택
matchLabels:
purpose: backend # backend 용도의 네임스페이스
podSelector: # Pod 선택
matchLabels:
app: api-server # API 서버 애플리케이션
ports:
- protocol: TCP # TCP 프로토콜
port: 9000 # MinIO API 포트만 허용
📌 MinIO의 네트워크 구성 설계
✅ 단일 MinIO 인스턴스 네트워크 구성
단일 MinIO 인스턴스의 네트워크 구성을 알아봅시다.
# MinIO Pod
apiVersion: apps/v1 # 앱 API 그룹 버전
kind: Deployment # 리소스 종류
metadata:
name: minio # Deployment 이름
namespace: minio-system # 네임스페이스
spec:
selector:
matchLabels:
app: minio # Pod 선택자
template:
metadata:
labels:
app: minio # Pod 라벨
spec:
containers:
- name: minio # 컨테이너 이름
image: minio/minio:RELEASE.2023-07-21T21-12-44Z # 이미지 버전
args:
- server # 서버 모드
- /data # 데이터 경로
ports:
- containerPort: 9000 # API 포트
name: api # 포트 이름
- containerPort: 9001 # 콘솔 포트
name: console # 포트 이름
# MinIO Service
apiVersion: v1 # 핵심 API 그룹 버전
kind: Service # 리소스 종류
metadata:
name: minio # Service 이름
namespace: minio-system # 네임스페이스
spec:
selector:
app: minio # 대상 Pod 선택자
ports:
- name: api # API 포트 이름
port: 9000 # Service 포트
targetPort: api # 대상 Pod 포트 이름
- name: console # 콘솔 포트 이름
port: 9001 # Service 포트
targetPort: console # 대상 Pod 포트 이름
type: ClusterIP # 클러스터 내부 접근용
# Ingress for external access
apiVersion: networking.k8s.io/v1 # 네트워킹 API 그룹 버전
kind: Ingress # 리소스 종류
metadata:
name: minio-ingress # Ingress 이름
namespace: minio-system # 네임스페이스
spec:
rules:
- host: s3.example.com # API 호스트 이름
http:
paths:
- path: / # 경로
pathType: Prefix # 경로 타입
backend:
service:
name: minio # 대상 Service
port:
name: api # 대상 포트 이름
- host: minio.example.com # 콘솔 호스트 이름
http:
paths:
- path: / # 경로
pathType: Prefix # 경로 타입
backend:
service:
name: minio # 대상 Service
port:
name: console # 대상 포트 이름
✅ 분산 MinIO 인스턴스 네트워크 구성
분산 모드로 운영되는 MinIO의 네트워크 구성을 알아봅시다.
# MinIO StatefulSet
apiVersion: apps/v1 # 앱 API 그룹 버전
kind: StatefulSet # 리소스 종류
metadata:
name: minio # StatefulSet 이름
namespace: minio-system # 네임스페이스
spec:
serviceName: minio-headless # 헤드리스 서비스 이름
replicas: 4 # 복제본 수(4개 이상 권장)
selector:
matchLabels:
app: minio # Pod 선택자
template:
metadata:
labels:
app: minio # Pod 라벨
spec:
containers:
- name: minio # 컨테이너 이름
image: minio/minio:RELEASE.2023-07-21T21-12-44Z # 이미지 버전
args:
- server # 서버 모드
- http://minio-{0...3}.minio-headless.minio-system.svc.cluster.local/data # 분산 모드 구성
ports:
- containerPort: 9000 # API 포트
name: api # 포트 이름
- containerPort: 9001 # 콘솔 포트
name: console # 포트 이름
# Headless Service for StatefulSet
apiVersion: v1 # 핵심 API 그룹 버전
kind: Service # 리소스 종류
metadata:
name: minio-headless # 헤드리스 서비스 이름
namespace: minio-system # 네임스페이스
spec:
clusterIP: None # 헤드리스 서비스 지정
selector:
app: minio # 대상 Pod 선택자
ports:
- name: api # API 포트 이름
port: 9000 # Service 포트
targetPort: api # 대상 Pod 포트 이름
- name: console # 콘솔 포트 이름
port: 9001 # Service 포트
targetPort: console # 대상 Pod 포트 이름
# Regular Service for client access
apiVersion: v1 # 핵심 API 그룹 버전
kind: Service # 리소스 종류
metadata:
name: minio # Service 이름
namespace: minio-system # 네임스페이스
spec:
selector:
app: minio # 대상 Pod 선택자
ports:
- name: api # API 포트 이름
port: 9000 # Service 포트
targetPort: api # 대상 Pod 포트 이름
- name: console # 콘솔 포트 이름
port: 9001 # Service 포트
targetPort: console # 대상 Pod 포트 이름
type: ClusterIP # 클러스터 내부 접근용
📌 Summary
- 쿠버네티스 네트워킹은 컨테이너, Pod, Service, 외부 간의 통신을 해결
- Pod는 고유 IP를 가지며 NAT 없이 다른 Pod와 통신 가능
- Service는 Pod에 안정적인 네트워크 엔드포인트를 제공하며 다양한 유형 존재
- Headless Service는 StatefulSet과 함께 사용하여 Pod 개별 접근 가능
- Ingress는 클러스터 외부에서 내부 서비스로의 HTTP/HTTPS 라우팅 관리
- CNI는 컨테이너 네트워킹 구현을 위한 표준 인터페이스
- 네트워크 정책으로 Pod 간 통신을 세밀하게 제어 가능
- MinIO는 단일 또는 분산 모드에 따라 다른 네트워크 구성 필요
- Cilium은 eBPF 기반의 고성능 CNI 플러그인으로 L3-L7 보안 정책 지원