IMG-LOGO
공지사항 :

Kubernetes 네트워크와 Service 완벽 이해

lmkfox - 2026-08-28 07:35:06 2 Views 0 Comment

Kubernetes 네트워크와 Service 완벽 이해

Kubernetes를 처음 공부할 때 가장 어렵게 느껴지는 부분 중 하나가 네트워크입니다. Docker에서는 컨테이너를 실행하고 포트를 연결하면 비교적 쉽게 서비스를 외부에 노출할 수 있지만, Kubernetes에서는 Pod, Service, Node, Ingress 등 여러 구성 요소가 서로 연결되어 있습니다.

특히 Kubernetes 환경에서는 Pod가 생성될 때마다 IP 주소가 변경될 수 있기 때문에 Pod IP만 이용하여 서비스를 운영하는 것은 적절하지 않습니다. 이를 해결하기 위해 Kubernetes는 Service라는 네트워크 추상화 계층을 제공합니다.

이번 글에서는 Kubernetes 네트워크의 기본 원리부터 Service의 종류, 외부 접속 과정, DNS, Ingress까지 단계적으로 알아보겠습니다.


1. Kubernetes 네트워크의 기본 구조

Kubernetes 네트워크를 이해하기 위해서는 먼저 Pod를 이해해야 합니다.

Kubernetes에서 실제 애플리케이션이 실행되는 기본 단위는 Pod입니다.

예를 들어 Nginx Deployment를 생성하면 Kubernetes는 하나 이상의 Pod를 생성합니다.

Kubernetes Cluster
        │
        ▼
   Deployment
        │
        ▼
   ReplicaSet
        │
   ┌────┼────┐
   ▼    ▼    ▼
 Pod   Pod   Pod

각 Pod는 일반적으로 하나의 고유한 IP 주소를 갖습니다.

예를 들어 다음과 같은 구조가 될 수 있습니다.

Pod 1 → 10.244.1.10
Pod 2 → 10.244.1.11
Pod 3 → 10.244.2.10

하지만 여기에는 중요한 문제가 있습니다.

Pod가 장애로 삭제되고 다시 생성되면 새로운 IP가 할당될 수 있습니다.

기존 Pod
10.244.1.10
    │
    ▼
Pod 장애
    │
    ▼
Pod 삭제
    │
    ▼
새로운 Pod 생성
    │
    ▼
10.244.1.15

따라서 애플리케이션이 특정 Pod의 IP를 직접 사용하도록 구성하면 장애나 배포 과정에서 연결이 끊길 수 있습니다.

이 문제를 해결하는 것이 바로 Service입니다.


2. Kubernetes Service란 무엇인가?

Service는 여러 Pod를 하나의 논리적인 네트워크 주소로 묶어주는 Kubernetes 객체입니다.

예를 들어 Nginx Pod가 3개 있다고 가정하겠습니다.

             Service
          10.96.10.100
                │
       ┌────────┼────────┐
       ▼        ▼        ▼
    Pod 1     Pod 2     Pod 3
10.244.1.10 10.244.1.11 10.244.2.10

사용자는 개별 Pod IP를 알 필요가 없습니다.

Service의 주소만 이용하면 Kubernetes가 적절한 Pod로 트래픽을 전달합니다.

Service의 가장 중요한 역할은 다음과 같습니다.

  • Pod에 안정적인 접근 주소 제공
  • 여러 Pod로 트래픽 분산
  • Pod 변경에 따른 IP 변화 추상화
  • 클러스터 내부 서비스 검색
  • 외부 서비스 노출

즉, Pod는 실제 애플리케이션을 실행하고 Service는 애플리케이션에 접근하기 위한 안정적인 네트워크 접점을 제공한다고 이해하면 됩니다.


3. Service의 동작 원리

Service는 일반적으로 Label Selector를 이용하여 연결할 Pod를 찾습니다.

예를 들어 Pod에 다음과 같은 Label이 있다고 가정하겠습니다.

labels:
  app: nginx

Service에서는 다음과 같이 Selector를 지정할 수 있습니다.

selector:
  app: nginx

그러면 Kubernetes는 app=nginx라는 Label을 가지고 있는 Pod를 Service의 대상으로 연결합니다.

구조는 다음과 같습니다.

             Nginx Service
                   │
          selector: app=nginx
                   │
        ┌──────────┼──────────┐
        ▼          ▼          ▼
   nginx Pod   nginx Pod   nginx Pod

따라서 Pod가 삭제되고 새로운 Pod가 생성되더라도 동일한 Label을 가지고 있다면 Service가 새로운 Pod를 자동으로 대상으로 사용할 수 있습니다.

이것이 Kubernetes Service가 중요한 이유입니다.


4. ClusterIP

가장 기본적인 Service 유형이 ClusterIP입니다.

ClusterIP는 Kubernetes 클러스터 내부에서만 접근할 수 있습니다.

예를 들어 다음과 같은 Service가 있다고 가정하겠습니다.

Service
ClusterIP: 10.96.10.100
Port: 80

클러스터 내부의 다른 Pod에서는 이 Service를 통해 Nginx에 접근할 수 있습니다.

Pod A
 │
 │ HTTP Request
 ▼
10.96.10.100:80
 │
 ▼
Nginx Service
 │
 ├── Pod 1
 ├── Pod 2
 └── Pod 3

Service를 생성할 때 별도의 타입을 지정하지 않으면 기본적으로 ClusterIP가 사용됩니다.

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80

적용합니다.

kubectl apply -f nginx-service.yaml

확인합니다.

kubectl get service

예를 들어 다음과 같이 나타날 수 있습니다.

NAME            TYPE        CLUSTER-IP      PORT(S)
nginx-service   ClusterIP   10.96.10.100    80/TCP

ClusterIP는 데이터베이스, Redis, 내부 API 서버처럼 외부에 직접 노출할 필요가 없는 서비스에서 특히 유용합니다.


5. NodePort

외부에서 Kubernetes 서비스를 접근해야 한다면 NodePort를 사용할 수 있습니다.

NodePort는 Kubernetes Node의 특정 포트를 열어 Service에 연결합니다.

구조는 다음과 같습니다.

인터넷
   │
   ▼
Node IP:30080
   │
   ▼
NodePort Service
   │
   ▼
ClusterIP
   │
   ▼
Nginx Pod

예를 들어 NodePort를 30080으로 지정하면 다음과 같이 접근할 수 있습니다.

http://192.168.10.11:30080

Service 설정 예시는 다음과 같습니다.

apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080

적용합니다.

kubectl apply -f nginx-nodeport.yaml

확인합니다.

kubectl get service

결과는 다음과 비슷합니다.

NAME             TYPE       CLUSTER-IP      PORT(S)
nginx-nodeport   NodePort   10.96.20.100    80:30080/TCP

NodePort의 포트 번호는 일반적으로 Kubernetes에서 지정한 범위 내에서 사용합니다.

NodePort는 테스트나 간단한 환경에서는 편리하지만 운영 환경에서 모든 서비스를 NodePort로 직접 노출하는 방식은 관리하기 어렵습니다.


6. LoadBalancer

클라우드 환경에서는 LoadBalancer Service를 많이 사용합니다.

예를 들어 AWS, Azure, Google Cloud와 같은 환경에서는 Kubernetes Service를 LoadBalancer 유형으로 생성하면 클라우드 환경의 로드밸런서와 연결할 수 있습니다.

구조는 다음과 같습니다.

Internet
    │
    ▼
Cloud Load Balancer
    │
    ▼
Kubernetes Service
    │
 ┌──┼──┐
 ▼  ▼  ▼
Pod Pod Pod

예를 들어 다음과 같이 설정합니다.

apiVersion: v1
kind: Service
metadata:
  name: nginx-lb
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80

확인합니다.

kubectl get service

클라우드 환경에서는 EXTERNAL-IP가 할당될 수 있습니다.

NAME       TYPE           CLUSTER-IP      EXTERNAL-IP
nginx-lb   LoadBalancer   10.96.30.100    203.0.113.10

이제 외부 사용자는 Load Balancer의 IP를 통해 서비스에 접근할 수 있습니다.


7. NodePort와 LoadBalancer의 차이

두 가지를 혼동하는 경우가 많습니다.

구분 ClusterIP NodePort LoadBalancer
클러스터 내부 가능 가능 가능
외부 접근 기본적으로 불가 가능 가능
Node 포트 사용 아니오 내부적으로 활용 가능
클라우드 LB 아니오 아니오
주요 용도 내부 서비스 테스트/간단한 외부 공개 운영 외부 서비스

실무에서는 일반적으로 다음과 같은 구조를 많이 사용합니다.

외부 사용자
     │
     ▼
Load Balancer
     │
     ▼
Ingress
     │
     ▼
Service
     │
     ▼
Pod

8. Kubernetes DNS

Kubernetes에는 클러스터 내부 서비스 검색을 위한 DNS 기능이 제공됩니다.

예를 들어 다음과 같은 Service가 있다고 가정하겠습니다.

postgres-service

다른 Pod에서는 Service의 이름을 이용해 접근할 수 있습니다.

postgres-service

같은 Namespace라면 간단한 Service 이름으로 접근할 수 있습니다.

다른 Namespace라면 다음과 같은 형태를 사용할 수 있습니다.

postgres-service.database.svc.cluster.local

일반적인 DNS 구조는 다음과 같습니다.

서비스 이름
    │
    ▼
postgres-service
    │
    ▼
Kubernetes DNS
    │
    ▼
ClusterIP
    │
    ▼
PostgreSQL Pod

따라서 애플리케이션 설정에서 Pod의 IP 주소를 직접 입력하는 것보다 Service 이름을 사용하는 것이 훨씬 안정적입니다.

예를 들어 FastAPI 애플리케이션에서 PostgreSQL에 접속한다고 가정하면 다음과 같이 구성할 수 있습니다.

DB_HOST=postgres-service
DB_PORT=5432

PostgreSQL Pod가 변경되더라도 애플리케이션은 Service 이름을 계속 사용할 수 있습니다.


9. Endpoint와 EndpointSlice

Service가 실제로 어떤 Pod에 연결되어 있는지 확인하려면 Endpoint 정보를 확인하는 것이 좋습니다.

kubectl get endpoints

최근 Kubernetes 환경에서는 EndpointSlice도 중요한 개념입니다.

kubectl get endpointslice

Service와 Pod 연결에 문제가 발생했을 때 시스템 엔지니어가 반드시 확인해야 하는 부분입니다.

예를 들어 Service는 존재하지만 연결할 Pod가 없다면 다음과 같은 상황이 발생할 수 있습니다.

Client
  │
  ▼
Service
  │
  X
Endpoint 없음

이 경우 Service 자체의 문제가 아니라 Selector와 Pod Label이 일치하지 않는 문제일 가능성이 있습니다.


10. Ingress란 무엇인가?

운영 환경에서 웹 서비스를 여러 개 운영한다면 NodePort나 LoadBalancer를 서비스마다 사용하는 것은 비효율적입니다.

예를 들어 다음과 같은 서비스가 있다고 가정하겠습니다.

www.example.com
api.example.com
admin.example.com

각각을 별도의 LoadBalancer로 구성한다면 관리 비용이 증가합니다.

이때 사용할 수 있는 것이 Ingress입니다.

                    Internet
                       │
                       ▼
                    Ingress
                       │
          ┌────────────┼────────────┐
          ▼            ▼            ▼
        Service       Service      Service
          │            │            │
        Web Pod       API Pod     Admin Pod

Ingress는 HTTP/HTTPS 요청을 Host나 URL 경로에 따라 적절한 Service로 전달할 수 있습니다.

예를 들어 다음과 같이 구성할 수 있습니다.

www.example.com
        │
        ▼
   web-service

api.example.com
        │
        ▼
   api-service

admin.example.com
        │
        ▼
  admin-service

따라서 Kubernetes 기반 웹 서비스 운영에서는 Ingress가 매우 중요한 역할을 합니다.


11. 실제 서버 요청의 전체 흐름

이제 실제 사용자가 웹 브라우저에서 Kubernetes의 웹 애플리케이션에 접속하는 과정을 살펴보겠습니다.

사용자가 다음 주소를 입력한다고 가정합니다.

https://api.example.com

전체 흐름은 다음과 같습니다.

사용자 브라우저
       │
       ▼
DNS
       │
       ▼
공인 IP
       │
       ▼
Load Balancer
       │
       ▼
Ingress
       │
       ▼
API Service
       │
       ▼
Pod
       │
       ▼
FastAPI Application

여기에서 HTTPS 인증서 처리, DNS, Load Balancer, Ingress, Service, Pod가 서로 연결되어 있습니다.

시스템 엔지니어가 Kubernetes를 운영하려면 단순히 kubectl get pods만 사용할 것이 아니라 이 전체 흐름을 이해해야 합니다.


12. Kubernetes 네트워크 장애 분석

실무에서 중요한 것은 정상적인 상황보다 장애 상황입니다.

예를 들어 사용자가 웹사이트에 접속할 수 없다고 가정하겠습니다.

먼저 Pod 상태를 확인합니다.

kubectl get pods -o wide

다음으로 Service를 확인합니다.

kubectl get service

Endpoint를 확인합니다.

kubectl get endpoints

Ingress를 사용하고 있다면 다음도 확인합니다.

kubectl get ingress

Pod 로그를 확인합니다.

kubectl logs <pod-name>

Pod 내부에서 네트워크 테스트를 수행하는 것도 중요합니다.

kubectl exec -it <pod-name> -- /bin/sh

그 후 다른 Service로 통신을 테스트할 수 있습니다.

curl http://api-service:8000

이 과정을 통해 장애 지점을 단계적으로 좁혀갈 수 있습니다.

외부 접속
   │
   ▼
DNS
   │
   ▼
Load Balancer
   │
   ▼
Ingress
   │
   ▼
Service
   │
   ▼
Endpoint
   │
   ▼
Pod
   │
   ▼
Application

어느 단계에서 문제가 발생하는지를 찾는 것이 Kubernetes 네트워크 장애 분석의 핵심입니다.


13. 시스템 엔지니어가 반드시 기억해야 할 Kubernetes 네트워크

Kubernetes 네트워크를 처음 배울 때는 많은 개념이 등장하지만 다음 구조만 먼저 확실하게 이해하면 됩니다.

Pod
│
├── 실제 애플리케이션 실행
│
└── Pod IP 사용

Service
│
├── 안정적인 접근 지점
│
├── Pod 연결
│
└── 트래픽 분산

ClusterIP
│
└── 클러스터 내부 통신

NodePort
│
└── Node의 포트를 이용한 외부 접근

LoadBalancer
│
└── 외부 로드밸런서를 통한 접근

Ingress
│
└── HTTP/HTTPS 기반 외부 요청 라우팅

DNS
│
└── Service 이름을 이용한 서비스 검색

마무리

Kubernetes 네트워크를 제대로 이해하기 위해서는 단순히 Service 명령어를 외우는 것보다 Pod → Service → Ingress → Load Balancer → Internet으로 이어지는 전체 데이터 흐름을 이해하는 것이 중요합니다.

특히 시스템 엔지니어라면 장애가 발생했을 때 다음 순서로 문제를 확인하는 습관을 들이는 것이 좋습니다.

1. Pod가 정상인가?
       ↓
2. Pod IP가 존재하는가?
       ↓
3. Service가 정상인가?
       ↓
4. Selector가 Pod Label과 일치하는가?
       ↓
5. Endpoint가 정상적으로 생성되었는가?
       ↓
6. Service Port와 targetPort가 맞는가?
       ↓
7. Ingress 설정은 정상인가?
       ↓
8. Load Balancer가 정상인가?
       ↓
9. DNS가 올바른 IP를 반환하는가?
       ↓
10. 애플리케이션 자체에 문제가 없는가?

이러한 순서로 접근하면 Kubernetes 네트워크 장애를 무작정 추측하는 것이 아니라 계층별로 원인을 좁혀가는 방식으로 분석할 수 있습니다.


댓글