쿠버네티스의 네트워킹과 서비스 디스커버리 이해하기
쿠버네티스에서 네트워킹과 서비스 디스커버리는 컨테이너 간 통신을 가능하게 하는 핵심 메커니즘이다. 이 기능을 통해 분산된 마이크로서비스들이 서로를 찾고 통신할 수 있으며, 이는 현대적인 클라우드 네이티브 애플리케이션 구축의 필수 요소이다. 이 글에서는 쿠버네티스의 네트워킹 처리 방법과 서비스 디스커버리 작동 원리에 대해 자세히 알아보고 실제 적용 방법까지 다룬다.
쿠버네티스 네트워킹의 기본 원리
쿠버네티스에서 네트워킹은 애플리케이션 컨테이너가 서로 통신할 수 있도록 하는 중요한 기반이다. 이를 이해하기 위해서는 컨테이너 간 통신의 기본 개념을 먼저 알아야 한다.
컨테이너 간 통신의 필요성
애플리케이션을 개발할 때 다양한 서비스를 분리하여 배포하는 것이 일반적이다. 예를 들어, 자바 애플리케이션과 같은 주요 애플리케이션이 데이터베이스에 데이터를 저장해야 하는 경우를 생각해보자. 도커 컨테이너는 단일 서비스를 위해 설계되었으므로, 하나의 컨테이너에 애플리케이션과 데이터베이스를 모두 넣는 것은 바람직하지 않다. 따라서 별도의 컨테이너를 설정하고 데이터베이스용 이미지를 사용하는 것이 권장된다.
이렇게 분리된 컨테이너들은 네트워크로 연결되어야 서로 통신할 수 있다. 여기서 쿠버네티스의 네트워킹 기능이 중요한 역할을 한다.
단일 포드 내 컨테이너 통신
쿠버네티스에서 두 컨테이너를 단일 포드에 배포하면 네트워킹 상황이 단순해진다. 같은 포드 내의 컨테이너들은 localhost를 사용하여 서로를 인식할 수 있다. 예를 들어, 자바 애플리케이션에서 MySQL 데이터베이스에 접근하려면 localhost:3306과 같은 주소를 사용하면 된다.
하지만 하나의 포드에 여러 컨테이너를 추가하는 것은 가능하지만 권장되지 않는다. 그 이유는 다음과 같다:
- 포드 관리가 더 복잡해진다
- 포드에 문제가 발생했을 때 원인 파악이 어려워진다
- 컨테이너별 독립적인 확장이 어렵다
따라서 애플리케이션과 데이터베이스는 일반적으로 별도의 포드에 배포해야 한다.
서비스와 서비스 디스커버리
애플리케이션과 데이터베이스를 별도의 포드에 배포하면 이들이 서로 통신하기 위한 방법이 필요하다. 쿠버네티스는 이 문제를 '서비스'와 '서비스 디스커버리' 메커니즘을 통해 해결한다.
서비스의 역할
쿠버네티스에서 각 서비스는 클러스터 내부에서만 볼 수 있는 고유한 개인 IP 주소를 가진다. 그러나 이러한 IP 주소는 쿠버네티스에 의해 임의로 할당되므로, 미리 알 수 없다. 또한 클러스터를 다시 시작하면 서비스에 다른 IP 주소가 할당될 수 있다.
이 문제를 해결하기 위해 쿠버네티스는 자체적으로 유지 관리되는 프라이빗 DNS 서비스를 제공한다.
kube-dns와 서비스 디스커버리
쿠버네티스에는 kube-dns라는 DNS 서비스가 있다. 이 서비스는 일련의 키-값 쌍을 포함하는 데이터베이스로, 키는 서비스 이름이고 값은 해당 서비스의 IP 주소이다. 이 DNS 시스템의 유지 관리는 쿠버네티스가 전적으로 담당하므로, 사용자가 별도로 구성하거나 관리할 필요가 없다.
kube-dns 서비스는 백그라운드에서 자동으로 실행되며, 애플리케이션이 다른 서비스에 접근할 때 중요한 역할을 한다. 예를 들어, 자바 애플리케이션에서 "database"라는 서비스 이름을 사용하여 데이터베이스를 참조하면, kube-dns는 이 이름을 해당 서비스의 IP 주소로 변환한다.
네임스페이스 개념
쿠버네티스에서 서비스 디스커버리를 이해하기 위해서는 '네임스페이스'라는 개념도 알아야 한다.
네임스페이스의 역할
네임스페이스는 쿠버네티스의 리소스를 별도의 영역으로 분할하는 방법이다. 수천 개의 리소스가 있는 대규모 시스템에서는 이러한 분할이 필수적이다. 네임스페이스를 사용하면 포드, 서비스, 배포 및 레플리카 세트 등을 논리적으로 구분할 수 있다.
예를 들어, 프론트엔드 관련 리소스는 front-end 네임스페이스에, 백엔드 관련 리소스는 back-end 네임스페이스에 배치할 수 있다. 이는 시스템을 분할하고 관리하는 효과적인 방법이다.
기본 네임스페이스와 시스템 네임스페이스
리소스를 생성할 때 별도의 네임스페이스를 지정하지 않으면, 해당 리소스는 기본 네임스페이스(default)에 배치된다. kubectl get all과 같은 명령을 실행할 때 네임스페이스를 지정하지 않으면, 기본 네임스페이스에 있는 리소스만 표시된다.
쿠버네티스에는 자체 네임스페이스인 kube-public과 kube-system도 있다. 특히 kube-system 네임스페이스에는 쿠버네티스 시스템 구성 요소가 포함되어 있다. kube-dns 서비스와 관련 포드도 이 네임스페이스에 위치한다.
kubectl get ns
네임스페이스 작업하기
다른 네임스페이스의 리소스에 접근하려면 명령어에 해당 네임스페이스를 지정해야 한다. 예를 들어:
kubectl get pods -n kube-system
이 명령은 kube-system 네임스페이스에 있는 모든 포드를 표시한다.
또한 특정 서비스에 대한 자세한 정보를 보려면 다음과 같이 입력한다:
kubectl describe svc kube-dns -n kube-system
실습: MySQL 데이터베이스 연결 및 통신
이제 실제로 쿠버네티스에서 네트워킹과 서비스 디스커버리를 활용하는 방법을 살펴보자. 이 실습에서는 웹 애플리케이션에서 MySQL 데이터베이스에 연결하는 방법을 다룬다.
1. MySQL 데이터베이스 배포
먼저 MySQL 데이터베이스를 배포하기 위한 YAML 파일을 작성해야 한다. 다음은 networking-tests.yaml 파일의 예시이다:
apiVersion: v1
kind: Pod
metadata:
name: mysql
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql/mysql-server:8.0.23
env:
# Use secret in real life
- name: MYSQL_ROOT_PASSWORD
value: password
- name: MYSQL_DATABASE
value: fleetman
---
kind: Service
apiVersion: v1
metadata:
name: database
spec:
selector:
app: mysql
ports:
- port: 3306
type: ClusterIP
이 YAML 파일은 다음을 정의한다:
- mysql이라는 이름의 포드
- mysql/mysql-server:8.0.23 이미지를 사용하는 컨테이너
- 환경 변수 MYSQL_ROOT_PASSWORD와 MYSQL_DATABASE
- database라는 이름의 서비스
이제 다음 명령으로 이 리소스를 생성한다:
kubectl apply -f networking-tests.yaml
2. 웹 애플리케이션에서 데이터베이스 접근하기
웹 애플리케이션 컨테이너에서 데이터베이스에 접근하는 방법을 알아보자. 먼저 웹 애플리케이션 포드에 접속한다:
kubectl exec -it webapp -- sh
이 명령은 webapp 포드의 셸에 접속한다.
3. DNS 확인하기
웹 애플리케이션 컨테이너 내에서 DNS 설정을 확인하자:
cat /etc/resolv.conf
이 파일은 DNS 이름 확인 방식을 구성하며, kube-dns 서비스의 IP 주소를 포함한다.
이제 nslookup 명령을 사용하여 데이터베이스 서비스의 IP 주소를 확인할 수 있다:
nslookup database
이 명령은 database 서비스의 IP 주소를 반환한다.
4. MySQL 클라이언트 설치 및 데이터베이스 연결
알파인 리눅스 기반 컨테이너에 MySQL 클라이언트를 설치하고 데이터베이스에 연결해보자:
apk update
apk add mysql-client
mysql -h database -uroot -ppassword fleetman
이 명령은 database라는 서비스 이름을 사용하여 MySQL 데이터베이스에 연결한다. 여기서 database는 서비스 이름이며, kube-dns가 이를 해당 서비스의 IP 주소로 변환한다.
5. 데이터베이스 테스트
연결된 후에는 다음과 같이 테이블을 생성하고 확인할 수 있다:
CREATE TABLE testtable (test VARCHAR(255));
SHOW TABLES;
네트워킹과 서비스 디스커버리의 중요성
쿠버네티스의 네트워킹 메커니즘은 매우 간단하면서도 강력하다. 미리 구성된 DNS 서비스를 통해 서비스 디스커버리가 자동으로 이루어지므로, 개발자는 추가적인 구성 없이도 서비스 간 통신을 쉽게 구현할 수 있다.
이 기능은 특히 마이크로서비스 아키텍처에서 중요하다. 서비스 디스커버리 덕분에 각 서비스는 다른 서비스의 정확한 IP 주소를 알 필요 없이, 서비스 이름만으로 통신할 수 있다. 이는 시스템의 유연성과 확장성을 크게 향상시킨다.
서비스 이름을 통한 통신은 코드가 환경에 독립적이게 만들며, 서비스의 물리적 위치가 변경되더라도 코드 수정 없이 계속 작동할 수 있게 한다. 이는 쿠버네티스가 마이크로서비스 아키텍처 구현에 이상적인 플랫폼인 이유 중 하나이다.
결론
쿠버네티스의 네트워킹과 서비스 디스커버리는 컨테이너화된 애플리케이션 간의 통신을 쉽게 만든다. kube-dns 서비스를 통해 서비스 이름만으로도 다른 서비스를 찾아 통신할 수 있으며, 이는 복잡한 마이크로서비스 아키텍처 구현을 단순화한다.
네임스페이스를 사용하면 리소스를 논리적으로 분리하여 대규모 시스템을 더 쉽게 관리할 수 있다. 이러한 기능들이 결합되어 쿠버네티스는 현대적인 클라우드 네이티브 애플리케이션을 위한 강력한 플랫폼을 제공한다.
실습을 통해 살펴본 것처럼, 서비스 디스커버리 메커니즘은 실제 환경에서도 매우 쉽게 적용할 수 있다. 이는 쿠버네티스가 제공하는 가장 강력하고 유용한 기능 중 하나로, 클라우드 네이티브 애플리케이션 개발에 큰 도움이 된다.
출처
'Server-side 개발 & 트러블 슈팅 > 🚢 Kubernetes (쿠버네티스)' 카테고리의 다른 글
[minikube] 쿠버네티스 디플로이먼트(Deployment)를 이용한 롤링 베포, 롤백 가이드 (rolling, rollout) (1) | 2025.04.30 |
---|---|
[minikube] 쿠버네티스 레플리카셋(replicaset)을 이용한 무중단 베포 가이드 (고가용성 유지) (0) | 2025.04.30 |
[minikube] 쿠버네티스 Queue 파드 및 서비스 배포 가이드 (0) | 2025.04.27 |
[minikube] 쿠버네티스 서비스(Service) 구조와 실행 (0) | 2025.04.08 |
[minikube] 쿠버네티스 포드(pod) 구조와 실행 (0) | 2025.04.08 |
댓글