CNI(Container Network Interface) & Cluster Networking

2025. 4. 15. 17:27Kubernetes

CNI(Container Network Interface)

CNI는 Container를 위한 Network Interface를 제공하는 Standard Interface 이다.

Kubernetes와 같은 Orchestration System이 Container 마다 Network setting( ip, routing table etc)을 자동화할 수 있게 해준다.

주요 역할

- IP 주소 할당

각 Pod에 고유한 IP를 할당하여 Pod 간 직접 통신이 가능하게 한다.

- 네트워크 구성

각 Node 또는 Cluster 내에서 Pod Network를 구성하는 Bridge, Tunnel Overlay Network 등을 자동화한다.

- Plugin 방식

다양한 CNI Plugin을 사용할 수 있어, Cluster 운영 환경에 맞춰 네트워크 정책, 보안, 성능 최적화를 진행할 수 있다.

 

CNI Plugin

아래와 같이 다양한 플러그인을 통해 환경에 맞는 유연한 네트워크 구성이 가능하며, Overlay Network 혹은 Native Routing 방식을 선택할 수 있다.

- Flannel: 간단하고 설정이 쉬운 오버레이 네트워크 솔루션으로, 대부분의 소규모 클러스터에 적합하다. 주로 VXLAN 방식을 통해 Pod 간 통신을 가능하게 한다.

- Calico: 고성능 네트워크와 네트워크 보안을 제공하며, 네트워크 정책 기반의 트래픽 제어를 지원한다. 오버레이 방식과 라우팅 모드를 모두 지원해 대규모 클러스터에서도 많이 사용된다.

- Weave Net: 분산 네트워크 구축에 중점을 두며, 클러스터 간의 네트워크 연결과 손쉬운 설정을 제공하는 플러그인이다.

 

Cluster Networking

1. Pod Network Model

- Pod 마다 고유한 IP

Kubernetes Network Model에서는 모든 Pod가 Cluster 내에서 고유한 IP 주소를 가지며 서로 직접 통신할 수 있어야한다.

Network 추상화

CNI Plugin은 모델을 구현하기위해 각 Pod에 IP를 할당하고 Node 간, Pod 간 통신을 위한 라우팅 및 Bridge 설정을 자동으로 처리한다.l

Overlay Network vs Native Routing 두 가지 방식이 가능하

Overlay Network : 기존 네트워크 위에 논리적으로 구축된 또 하나의 네트워크를 의미한다. 물리적 네트워크와는 독립적으로 동작하며 Node 간에 가상 링크를 만들어 데이터를 전달한다. 대표적으로 VPN이 있다.

Navtive Routing : IP Routing 같은 전통적인 방식으로 물리 네트워크에서 각 라우터가 목적지까지의 경로를 직접 계산해서 데이터를 전송하는 방식이다.

Overlay 방식(VXLAN 등)은 물리 네트워크 위에 논리적인 네트워크 레이어를 추가해 pod 네트워크를 구성한다.

Native Ratvie 방식은 Node 간의 직접 연결을 기반으로 구성되어 Overlay Layer 가 없기 때문에 성능점으로는 이점이 있다.

 

2. Service

Kubernetes Cluster 내에서 Pod 집합에 대해 안정적이고 지속적인 Network Endpoint 를 제공하는 추상화된 Object 이다.

Service는 기본적으로 OSI 7계층에서 Network Layer에 속한다 (TCP/UDP Level) 

1) Pod의 동적인 특성을 해결하기 위한 지속가능한 Endpoint 제공

Kubernetes 에서 Pod 는 Cluster 내에서 Auto Scaling 이나 Rolling Update 등의 이유로 단기간 존재할 수 있다. 이로 인해 Pod IP는 자주 변경되고 Pod가동적으로 늘어나거나 줄어들 수 있어서 직접 Pod의 IP를 대상으로 통신하기 보다는 Service를통해 고정된 접근점을 통해 통신하는 것이 안전하다 .

이를 위해 Service는 Pod 집합에 대해 일정한 DNS 이름과 IP를 제공하여 Client가 언제나 동일한 Endpoint로 접속할 수 있게 해준다.

 

  2) Load Balancing 역할

Service는 내부 로드 밸런싱 기능이다. 각 Node에 분산되어 실행되는 kube-proxy가 iptables / ipvs 를 통해 TCP / UDP Packet 을 해당 Pod로 전달하는 방식이기 때문에 별도의 추가 구성 없이 Pod 의 변화가 자동으로 업데이트 된다. 다른 말로는

내부적으로 kube-proxy가 iptables 또는 ipvs를 사용해 라우팅 규칙을 설정함으로써 수행된다는 것이다.

하지만 기존의 ALB와 NLB 같은 클라우드 서비스 로드 밸런서는 클러스터 외부에서 트래픽을 처리하기 때문에 복잡한 라우팅 정책을 지원한다.

3) Service Discovery

내부 DNS와 연동이 된다.

Kubernetes Cluster 내에서는 CoreDNS 같은 DNS Service가 Service 이름을 IP로 해석하여 애플리케이션들이 동적으로 서비스 주소를 찾을 수 있게 해준다.

- CoreDNS

Cluster 내의 모든 DNS Query 를 처리하는 DNS 서버로 Service 이름, Pod 이름 그리고 기타 DNS 기반의 이름을 ClusterIP 등으로 해석해준다.

CoreDNS는 Kubernetes Cluster 내부에 Pod 형태로 배포된다. 보통 kube-system NameSpace 에 배포되어 Cluster 내 모든 Node와 Pod들이 DNS Service 를 이용할 수 있게 구성되어있다.

애플리케이션이나 Cluster 내의 다른 Resource 들은 CoreDNS를 통해 동적으로 Service Name을 IP address 로 변환하여 통신할 수 있기 때문에 Pod의 IP가 바뀌더라도 Service 이름을 통해 안정적으로 연결된다.

이를 통해 Cluster 환경에서의 Network 관리와 애플리케이션 간 통신이 크게 단순화된다.

 

2.1 Servie 주요 타입

Kubernetes Service는 사용 목적에 따라 여러 가지 타입으로 정의할 수 있다.

1) ClusterIP (기본적인 타입)

Cluster 내부에서만 접근 가능한 가상의 IP 주소이다. 내부 마이크로서비스 간 통신이나 Cluster 내 다른 Compoenet 끼리 통신할 때 사용된다. 

동작 방식은 kube-proxy가 iptables / ipvs role을 통해 ClusterIP에 도착한 패킷을 해당 Endpoint (Pod IP)로 전달한다

 

2) NodePort

각 Cluster Node 의 고정된 Port 를 열어서 외부 네트워크 요청을 해당 포트로 전달하는 방식이다. Cluster 외부에서 직접 서비스에 접근해야하는 경우에 사용하며 동작방식은 ClusterIP 기능을 바탕으로 각 Node에 지정된 Port를 통해 외부 요청을 내부 서비스로 포워딩하는 방식이다.

 

3) LoadBalancer

Cloud 환경에서 Cloud Provider의 LoadBalancer를 자동으로 프로비저닝하여 외부의 요청을 처리하는 방식이다. AWS, GCP, Azure 등 외부 트래픽을 받아 서비스를 전달해야하는 경우에 사용하며 클라우드 공급자가 할당한 외부 IP와 로드 밸런싱 기능을 통해 트래픽을 NodePort와 연계하여 내부의 ClusterIP 서비스로 전달하는 방식으로 동작한다.

 

4) ExternalName

Cluster 내부에서 DNS CNAME Record를 만들어 외부 DNS NAME으로 요청을 전달하는 방식이다. 외부의 기존 서비스나 Database 같은 것을 Cluster 내부에서 마치 로컬 Service 인 것처럼 사용하고자 할 때 사용한다. DNS Record만 관리하며 프록시 역할은 하지 않는다.

Label

Kubernetes Object 에 추가할 수 있는 Key - Value 의 Pair 이다. Label을 사용하는 목적은 분류 및 식별 그리고 선택 및 필터링이 있다

분류 및 식별

Label을 통해 Object를 카테고리별로 묶을 수 있고 이를 통해 관리 및 모니터링이 용이해준다.

- 선택 및 필터링

나중에 특정 Label을 가진 객체들을 선택하거나 업데이트할 때 기준으로 삼을 수 있다 

apiVersion: v1
kind: Pod
metadata:
  name: my-web-pod
  labels:
    app: web
    env: production
spec:
  containers:
    - name: web
      image: nginx

 

Label Selector

어떤 Pod들이 Service 대상(트래픽을 받아야할 Backend)인지 지정하는 기준이다.

Label Selector 는 Object 에 부여된 Label을 기반으로 특정 Object들을 선택하는 조건을 정의한다. 이를 통해 Service, ReplicaSet, Deployment 등은 Label Selector를 사용해서 필요한 Pod들을 동적으로 선택하는 것이다.

#Service
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web   # ← Label Selector
  ports:
  - port: 80
    targetPort: 80

설정된대로 Pod 이 생성될때 app = web 이라는 Label 이 붙고 Service는 app=web 이라는 Label 이 붙은 Pod을 자동으로 찾아서 연결한다. Cluster 내 모든 Node에서 실행 중인 kube-proxy 가 이 정보를 감지한다. 

예를 들어 Client 가 Service Name으로 요청을 보내게 되면 CoreDNS가 이를 받아서 DNS Name 을 ClusterIP로 변환해준다. 변환된 ClusterIP는 실제 요청으로 전송이 되고 이때 kube-proxy가 Local Cache 에 있는 Endpoint 목록을 기반으로 라운드 로빈 방식 등으로 Pod를 포워딩해준다. 결과적으로 실제 Pod의 IP / Port 로 요청이 분산된다.

 

Deployment / Replicaset : 특정 label을 가진 Pod 들을 모니터링하며 필요시 새로운 Pod을 생성하거나 기존 Pod를 업데이트한다.

 

Label Selector Type

1) Equality based Selector

지정한 Key의 값이 특정 값과 같은 지 아닌지를 기준으로 객체를 선택한다. 

selector:
  matchLabels:
    app: web
    env: production

위 설정은 app label이 web 이고 env label 이 production 인 객체들을 선택한다

 

2) Set based Selector

Label 값이 특정 집합 내에 포함되거나 포함되지 않는 지를 기준으로 객체를 선택한다.

연산자:

  • in: 지정한 값 집합 내에 있는지 여부
    예: env in (production, staging)
  • notin: 지정한 값 집합 내에 없는지 여부
    예: tier notin (frontend, backend)
  • exists: 특정 키의 레이블이 존재하는지 여부
    예: metadata.name이 존재하면 선택
  • doesNotExist: 특정 키의 레이블이 존재하지 않는지 여부
selector:
  matchExpressions:
    - key: env
      operator: In
      values:
        - production
        - staging

이는 env 레이블의 값이 production 또는 staging인 객체들을 선택한

2.2 Service & kube-proxy 동작원리

Kubernetes 에서는 Pod가 동적으로 생성되고 종료되기 대문에 외부 혹은 Cluster 내 다른 Pod들이 이를 발견하고 통신할 수 있도록하는 Service의 역할이 매우 중요하다

Kubernetes에서  Service는 Pod 집합에 대해 안정적인 Network Endpoint를 제공하는 Object 이다.

Service는 Pod 의 IP가 동적으로 변해도 항상 일정한 Endpoint(Cluster IP, NodePort, LoadBalancer)를 통해 접근할 수 있도록 한다.

kube-proxy는 각 Node에서 실행되며 Service와 관련된 네트워크 트래픽을 관리하는 중요한 컴포넌트이다.

 

동작원리

- iptables /ipvs 사용: 내부적으로 iptables 또는 ipvs를 사용하여 Service의 가상 IP와 실제 Pod의 IP 간 연결을 설정한다.

 

  • iptables 방식: 커널의 Netfilter 프레임워크를 이용해 패킷을 받아 Service에서 지정한 포트로 라우팅한다.
  • ipvs 방식: Linux IP Virtual Server(IPVS)를 사용해, 더 고성능의 로드밸런싱을 구현다.

- Load Balancing : Service에 도착한 트래픽을 여러 Pod로 분산시켜서 부하 분산과 장애 조치 기능을 제공한다.

- 동적 업데이트 : kube-proxy는 Kubernetes API 서버와 통신해서 Cluster 내 Pod 의 IP 변화나 Service 추가 및 삭제 상황을 실시간을 반영하여 iptables / ipvs 설정을 업데이트한다.

 

Cluster Network 의 흐름을 예로 들면 Pod가 생성하면 CNI Plugin이 작동하여 각 Pod에 고유한 IP를 할당하고 필요한 네트워크 경로(bridge, tunnel)를 설정한다 그리고 Service Object를 생성하고 kube-proxy가 API 서버에서 Service와 연관된 Endpoint (Pod list)를 받아 해당 정보를 기반으로 iptables / ipvs role을 생성한다. 그리고 Cluster 내부에서 Service ClusterIP와 같은 요청이 들어오면 kube-proxy가 해당 요청을 적적한 Pod IP로 전달한다. (로드 밸런싱)  Pod의 추가, 삭제 및 상태 변화 등이 발생하면 kube-proxy가 이를 감지해 네트워크 규칙을 업데이트하고 항상 최신 라우팅 정보가 적용되도록한다.