이 페이지에서는 Google Kubernetes Engine(GKE) 네트워킹의 주요 특징에 대한 가이드를 제공합니다. 여기에서는 Kubernetes를 처음 시작하는 사용자는 물론 애플리케이션을 더 효과적으로 설계하거나 Kubernetes 워크로드를 더 효과적으로 구성하기 위해 Kubernetes 네트워킹에 대해 자세히 알고 싶어하는 숙련된 클러스터 운영자 또는 애플리케이션 개발자를 위해서도 유용한 정보를 제공합니다.
Kubernetes를 사용하면 애플리케이션 배포 방식, 애플리케이션이 서로 간에 그리고 Kubernetes 제어 영역과 통신하는 방식, 클라이언트가 애플리케이션에 연결하는 방식을 선언적으로 정의할 수 있습니다. 또한 이 페이지에서는 GKE가 네트워킹과 관련하여 Google Cloud 서비스를 구성하는 방식에 대한 정보도 제공합니다.
Kubernetes를 사용해서 애플리케이션을 조정할 때는 애플리케이션 및 해당 호스트의 네트워크 설계에 대한 생각을 바꾸는 것이 중요합니다. Kubernetes에서는 호스트 또는 가상 머신(VM)이 연결되는 방식보다는 포드, 서비스, 외부 클라이언트가 통신하는 방식이 더 중요합니다.
Kubernetes의 고급 소프트웨어 정의 네트워킹(SDN)을 사용하면 동일한 리전 클러스터의 여러 영역에서 포드, 서비스 및 노드의 패킷 라우팅 및 전달이 가능합니다. Kubernetes는 Google Cloud와 함께 Kubernetes 배포의 선언적 모델과 Google Cloud에서의 클러스터 구성에 따라 각 노드에서 IP 필터링 규칙, 라우팅 테이블, 방화벽 규칙을 동적으로 구성합니다.
기본 요건
이 페이지에서는 HTTP 및 DNS를 포함하여 인터넷 프로토콜의 전송, 인터넷, DNS 레이어와 관련된 용어가 사용되지만 이러한 개념에 대한 전문적인 지식이 필요하지는 않습니다.
또한 Linux 네트워크 관리 개념과 iptables
규칙 및 라우팅과 같은 유틸리티를 기본적으로 알고 있으면 이 페이지 내용을 더 쉽게 이해할 수 있을 것입니다.
Kubernetes의 IP 주소 관련 용어
Kubernetes 네트워킹 모델은 IP 주소에 크게 의존합니다. 서비스, 포드, 컨테이너, 노드는 IP 주소와 포트를 사용하여 통신합니다. Kubernetes는 트래픽을 올바른 포드로 전달하기 위해 다양한 유형의 부하 분산을 제공합니다. 이러한 메커니즘은 모두 뒷부분에서 자세히 설명합니다. 이 페이지를 읽는 동안 다음과 같은 용어에 유의하세요.
- ClusterIP: 서비스에 할당된 IP 주소입니다. 다른 문서에서는 '클러스터 IP'로 표시될 수도 있습니다. 이 주소는 서비스의 설명대로 서비스 수명 기간 동안 안정적으로 유지됩니다.
- 포드 IP 주소: 특정 포드에 할당된 IP 주소입니다. 포드에 설명된 대로 일시적입니다.
- 노드 IP 주소: 특정 노드에 할당된 IP 주소입니다.
클러스터 네트워킹 요구사항
공개 및 비공개 클러스터 모두 *.googleapis.com
, *.gcr.io
, 제어 영역 IP 주소 연결이 필요합니다. 이 요구사항은 암시적 허용 이그레스 규칙 및 GKE에서 생성되는 자동 생성된 방화벽 규칙에 의해 충족됩니다.
공개 클러스터에서 우선순위가 더 높은 이그레스를 거부하는 방화벽 규칙을 추가하는 경우 *.googleapis.com
, *.gcr.io
, 제어 영역 IP 주소를 허용하는 방화벽 규칙을 만들어야 합니다.
비공개 클러스터 요구사항에 대한 자세한 내용은 요구사항 및 제한사항을 참조하세요.
클러스터 내부 네트워킹
이 섹션에서는 IP 할당, 포드, 서비스, DNS, 제어 영역과 관련된 Kubernetes 클러스터 내부의 네트워킹을 설명합니다.
IP 할당
Kubernetes는 다양한 IP 범위를 사용하여 노드, 포드, 서비스에 IP 주소를 할당합니다.
- 각 노드에는 클러스터의 VPC(Virtual Private Cloud) 네트워크에서 할당되는 IP 주소가 포함됩니다. 이 노드 IP는
kube-proxy
및kubelet
과 같은 제어 구성요소에서 Kubernetes API 서버로의 연결을 제공합니다. 이 IP 주소는 나머지 클러스터에 대한 노드의 연결입니다. - 각 노드는 GKE가 해당 노드에서 실행 중인 포드를 할당하는 IP 주소 풀을 가지고 있습니다(기본값 /24 CIDR 블록). 필요에 따라 클러스터를 만들 때 IP 범위를 지정할 수 있습니다. 가변형 포드 CIDR 범위 기능을 사용하면 노드 풀의 노드에 대한 포드 IP 주소 범위의 크기를 줄일 수 있습니다.
- 각 포드에는 해당 노드의 포드 CIDR 범위에서 할당된 단일 IP 주소가 있습니다. 이 IP 주소는 포드 내에서 실행되는 모든 컨테이너가 공유하며 클러스터에서 실행 중인 다른 포드에 해당 컨테이너를 연결합니다.
- 각 서비스에는 클러스터의 VPC 네트워크에서 할당된 ClusterIP라는 IP 주소가 있습니다. 원한다면 클러스터를 만들 때 VPC 네트워크를 맞춤설정할 수 있습니다.
- 각 제어 영역에는 클러스터 유형, 버전, 생성 날짜를 기준으로 공개 또는 내부 IP 주소가 있습니다. 자세한 내용은 제어 영역 설명을 참조하세요.
GKE 네트워킹 모델에서는 네트워크 간에 IP 주소를 재사용할 수 없습니다. GKE로 마이그레이션할 때 IP 주소 할당을 GKE에서 내부 IP 주소 사용 감소로 계획해야 합니다.
MTU
포드 인터페이스로 선택된 MTU는 클러스터 노드 및 기본 VPC MTU 설정에 사용되는 컨테이너 네트워크 인터페이스(CNI)에 따라 달라집니다. 자세한 내용은 포드를 참조하세요.
포드 인터페이스 MTU 값은 1460
이거나 노드의 기본 인터페이스에서 상속됩니다.
CNI | MTU | GKE Standard |
---|---|---|
kubenet | 1460 | 기본값 |
kubenet (GKE 버전 1.26.1 이상) |
상속됨 | 기본값 |
Calico | 1460 |
자세한 내용은 네트워크 정책을 사용한 포드 및 서비스 간 통신 제어를 참조하세요. |
netd | 상속됨 | 다음 중 하나를 사용하여 사용 설정됩니다. |
GKE Dataplane V2 | 상속됨 |
자세한 내용은 GKE Dataplane V2 사용을 참조하세요. |
자세한 내용은 VPC 기반 클러스터를 참조하세요.
지원되는 네트워크 플러그인
- 네트워크 플러그인을 사용하려면 직접 설치해야 합니다. GKE는 다음과 같이 기본적으로 지원되는 네트워크 플러그인을 제공합니다.
- Calico(Dataplane V1)
- Cilium(Dataplane V2)
- Istio-CNI(GKE Enterprise용 관리형 데이터 영역 컨트롤러)
포드
Kubernetes에서 포드는 Kubernetes 클러스터 내에서 가장 기본적인 배포 가능한 단위입니다. 포드는 하나 이상의 컨테이너를 실행합니다. 한 노드에서는 0개 이상의 포드가 실행됩니다. 클러스터에 있는 각 노드는 노드 풀에 속합니다.
GKE에서 이러한 노드는 Compute Engine에서 하나의 인스턴스로 실행되는 가상 머신입니다.
포드는 또한 외부 저장소 볼륨 및 다른 커스텀 리소스에 연결될 수 있습니다. 아래 다이어그램은 각각 2개의 볼륨에 연결된 2개의 포드를 실행하는 단일 노드를 보여줍니다.
Kubernetes는 노드에서 실행할 포드를 예약할 때 노드의 Linux 커널에 있는 포드의 네트워크 네임스페이스를 만듭니다. 이 네트워크 네임스페이스는 가상 네트워크 인터페이스를 사용하여 노드의 물리적 네트워크 인터페이스(예: eth0
)를 포드와 연결하므로 패킷이 포드를 오고 갈 수 있습니다. 노드의 루트 네트워크 네임스페이스에 있는 연결된 가상 네트워크 인터페이스가 Linux 브리지에 연결되어, 동일 노드에서 포드 간 통신을 허용합니다. 또한 포드는 동일한 가상 인터페이스를 사용해서 노드 외부로 패킷을 전송할 수 있습니다.
Kubernetes는 노드의 포드에 대해 예약된 주소 범위에서 포드의 네트워크 네임스페이스에 있는 가상 네트워크 인터페이스에 IP 주소(포드 IP 주소)를 할당합니다. 이 주소 범위는 포드의 클러스터에 할당된 IP 주소 범위의 하위 집합으로, 클러스터를 만들 때 구성할 수 있습니다.
포드에서 실행되는 컨테이너는 포드의 네트워크 네임스페이스를 사용합니다. 컨테이너의 관점에서 포드는 하나의 네트워크 인터페이스를 포함하는 물리적 머신으로 표시됩니다. 포드의 모든 컨테이너에는 이러한 동일한 네트워크 인터페이스가 표시됩니다.
각 컨테이너의 localhost
는 포드를 통해 노드의 물리적 네트워크 인터페이스(예: eth0
)에 연결됩니다.
이러한 연결은 GKE의 컨테이너 네트워크 인터페이스(CNI)를 사용할지 여부 또는 클러스터 생성 시 네트워크 정책을 사용 설정하여 Calico 구현을 사용할지 여부에 따라 크게 달라집니다.
GKE의 CNI를 사용하는 경우 가상 이더넷 기기(veth) 쌍의 한쪽 끝은 네임스페이스의 포드에 연결되고 다른 한쪽 끝은 Linux 브리지 기기
cbr0
에 연결됩니다.1 이 경우 다음 명령어를 실행하면cbr0
에 연결된 다양한 포드의 MAC 주소가 표시됩니다.arp -n
도구 상자 컨테이너에서 다음 명령어를 실행하면
cbr0
에 연결된 각 veth 쌍의 루트 네임스페이스 끝이 표시됩니다.brctl show cbr0
네트워크 정책이 사용 설정되면 veth 쌍의 한쪽 끝은 포드에 연결되고 다른 한쪽 끝은
eth0
에 연결됩니다. 이 경우 다음 명령어를 실행하면 서로 다른 veth 기기에 연결된 다양한 포드의 MAC 주소가 표시됩니다.arp -n
도구 상자 컨테이너에서 다음 명령어를 실행하면
cbr0
이라는 Linux 브리지 기기 없음이 표시됩니다.brctl show
클러스터 내에서 전달을 용이하게 하는 iptables 규칙은 시나리오마다 다릅니다. 연결 문제를 세부적으로 해결할 때는 이러한 구분을 고려하는 것이 중요합니다.
기본적으로 각 포드에서는 클러스터의 모든 노드에서 실행되는 다른 모든 포드에 대한 액세스가 제한되지 않지만 개발자가 포드 간 액세스를 제한할 수 있습니다. Kubernetes는 포드를 정기적으로 분해하고 다시 만듭니다. 이러한 작업은 노드 풀이 업그레이드될 때, 포드의 선언적 구성을 변경하거나 컨테이너의 이미지를 변경할 때 또는 노드가 사용 불가능하게 될 때 발생합니다. 따라서 포드의 IP 주소는 구현 세부정보이며, 여기에 의존해서는 안 됩니다. Kubernetes는 서비스를 사용해서 안정적인 IP 주소를 제공합니다.
-
가상 네트워크 브리지
cbr0
는hostNetwork: false
를 설정하는 포드가 있을 때만 생성됩니다.↩
서비스
Kubernetes에서는 라벨이라고 부르는 임의의 키-값 쌍을 모든 Kubernetes 리소스에 할당할 수 있습니다. Kubernetes는 라벨을 사용하여 여러 관련된 포드를 서비스라는 논리 단위로 그룹화합니다. 서비스는 안정적인 IP 주소 및 포트를 포함하며, 개발자가 서비스를 만들 때 라벨 선택기에서 정의하는 모든 라벨과 라벨이 일치하는 포드 집합 간에 부하 분산을 제공합니다.
다음 다이어그램은 2개의 개별 서비스를 보여줍니다. 이러한 각 서비스는 여러 포드로 구성됩니다. 다이어그램에 있는 각 포드에는 app=demo
라벨이 있지만 다른 라벨은 서로 다릅니다. 'frontend' 서비스는 모든 포드를 app=demo
및 component=frontend
에 일치시키고, 'user' 서비스는 모든 포드를 app=demo
및 component=users
에 일치시킵니다. 클라이언트 포드는 서비스 선택기와 정확하게 일치하지 않으므로 서비스의 일부가 아닙니다. 하지만 클라이언트 포드는 동일한 클러스터에서 실행되기 때문에 서비스 중 하나와 통신할 수 있습니다.
Kubernetes는 ClusterIP의 클러스터 풀에서 새로 생성된 각 서비스(ClusterIP)에 안정적이고 신뢰할 수 있는 IP 주소를 할당합니다. Kubernetes는 또한 DNS 항목을 추가하여 ClusterIP에 호스트 이름을 할당합니다. ClusterIP 및 호스트 이름은 클러스터 내에서 고유하며 서비스 수명 주기 동안 변경되지 않습니다. Kubernetes는 클러스터 구성에서 서비스가 삭제될 경우에만 ClusterIP 및 호스트 이름을 해제합니다. ClusterIP 또는 서비스의 호스트 이름을 사용하여 애플리케이션을 실행하는 정상 상태의 포드에 연결할 수 있습니다.
처음에는 서비스가 애플리케이션의 단일 장애점인 것으로 보일 수 있습니다. 하지만 Kubernetes는 여러 노드에서 실행되는 전체 포드 집합 간에 가능한 한 고르게 트래픽을 분산하므로 모두가 아닌 하나 이상의 노드에 영향을 주는 중단이 발생해도 클러스터가 이를 견딜 수 있습니다.
Kube-Proxy
Kubernetes는 일반적으로 각 노드에서 정적 포드로 실행되는 kube-proxy
구성요소를 사용하여 포드와 서비스 간 연결을 관리합니다.
인라인 프록시가 아니지만 이그레스 기반 부하 분산 컨트롤러인 kube-proxy
는 Kubernetes API 서버를 감시하고, 노드의 iptables
하위 시스템에 대상 NAT(DNAT) 규칙을 추가 및 삭제하여 ClusterIP를 정상 상태의 포드에 계속 매핑합니다. 포드에서 실행되는 컨테이너가 서비스의 ClusterIP에 트래픽을 전송할 때 노드는 포드를 무작위로 선택하고 이 포드로 트래픽을 라우팅합니다.
서비스를 구성할 때 port
및 targetPort
값을 정의하여 수신 포트를 선택적으로 다시 매핑할 수 있습니다.
port
는 클라이언트가 애플리케이션에 연결하는 지점입니다.targetPort
는 애플리케이션이 포드 내에서 트래픽을 실제로 리스닝하는 포트입니다.
kube-proxy
는 노드에서 iptables
규칙을 추가 및 삭제하여 이러한 포트 다시 매핑을 관리합니다.
이 다이어그램은 클라이언트 포드에서 다른 노드의 서버 포드로의 트래픽 흐름을 보여줍니다. 클라이언트는 172.16.12.100:80
에서 서비스에 연결합니다.
Kubernetes API 서버는 애플리케이션을 실행하는 포드 목록을 유지 관리합니다. 각 노드의 kube-proxy
프로세스는 이 목록을 사용해서 적절한 포드(예: 10.255.255.202:8080
)로 트래픽을 보내기 위한 iptables
규칙을 만듭니다. 클라이언트 포드는 클러스터의 토폴로지 또는 내부의 개별 포드 또는 컨테이너에 대한 세부정보를 알 필요가 없습니다.
kube-proxy
를 배포하는 방법은 클러스터의 GKE 버전에 따라 다릅니다.
- GKE 버전 1.16.0 및 1.16.8-gke.13의 경우
kube-proxy
가 DaemonSet로 배포됩니다. - 1.16.8-gke.13 이상의 GKE 버전에서
kube-proxy
는 노드의 정적 포드로 배포됩니다.
DNS
GKE는 서비스 이름 및 외부 이름을 확인할 수 있도록 다음과 같은 관리형 클러스터 DNS 옵션을 제공합니다.
kube-dns: 기본적으로 모든 GKE 클러스터에 배포되는 클러스터 부가기능입니다. 자세한 내용은 kube-dns 사용을 참조하세요.
Cloud DNS: 클러스터에서 kube-dns를 대체하는 클라우드 관리형 클러스터 DNS 인프라입니다. 자세한 내용은 GKE용 Cloud DNS 사용을 참조하세요.
또한 GKE는 클러스터 DNS 성능을 개선하기 위해 kube-dns 또는 Cloud DNS와 함께 선택적 부가기능으로 NodeLocal DNSCache를 제공합니다.
GKE가 DNS를 제공하는 방법에 대한 자세한 내용은 서비스 검색 및 DNS를 참조하세요.
제어 영역
Kubernetes에서 제어 영역은 Kubernetes API 서버를 포함한 제어 영역 프로세스를 관리합니다. 컨트롤 플레인에 액세스하는 방법은 GKE Autopilot 또는 Standard 클러스터의 버전에 따라 다릅니다.
Private Service Connect를 사용하는 클러스터
다음 조건을 충족하는 비공개 또는 공개 클러스터는 Private Service Connect를 사용하여 노드와 컨트롤 플레인을 비공개로 연결합니다.
- 2022년 3월 15일 이후 버전 1.23의 새 공개 클러스터
- 2024년 1월 28일 이후 버전 1.29의 새 비공개 클러스터
앞의 조건을 충족하지 않는 기존 공개 클러스터는 Private Service Connect로 마이그레이션됩니다. 따라서 이러한 클러스터는 이미 Private Service Connect를 사용하고 있을 수 있습니다. 클러스터가 Private Service Connect를 사용하는지 확인하려면 gcloud container clusters describe 명령어를 실행합니다. 공개 클러스터에서 Private Service Connect를 사용하는 경우 privateClusterConfig
리소스에 다음 값이 포함됩니다.
peeringName
필드가 비어 있거나 존재하지 않습니다.privateEndpoint
필드에 할당된 값이 있습니다.
하지만 위의 조건을 충족하지 않는 기존 비공개 클러스터는 아직 마이그레이션되지 않습니다.
Private Service Connect를 사용하는 클러스터를 만들고 클러스터 격리를 변경할 수 있습니다.
승인된 네트워크를 통해 제어 영역에 도달할 수 있는 출처를 정의하여 클러스터의 제어 영역에 대한 액세스를 제한합니다.
GKE 클러스터에 사용되는 Private Service Connect 리소스가 숨겨져 있습니다.
클러스터 외부 네트워킹
이 섹션에서는 클러스터 외부의 트래픽이 Kubernetes 클러스터 내부에서 실행되는 애플리케이션에 연결되는 방법을 설명합니다. 이 정보는 클러스터의 애플리케이션 및 워크로드를 디자인할 때 중요합니다.
Kubernetes가 서비스를 사용하여 포드 내에서 실행되는 애플리케이션에 안정적인 IP 주소를 제공하는 방법은 이미 살펴봤습니다. kube-proxy
가 각 노드에서 모든 트래픽을 관리하기 때문에 기본적으로 포드는 외부 IP 주소를 노출하지 않습니다. 포드 및 해당 컨테이너는 자유롭게 통신할 수 있지만 클러스터 외부의 연결은 서비스에 액세스할 수 없습니다. 예를 들어 이전 그림에서 클러스터 외부의 클라이언트는 해당 ClusterIP를 사용하여 프런트엔드 서비스에 액세스할 수 없습니다.
GKE는 액세스를 제어하고 들어오는 트래픽을 클러스터 간에 가능한 한 고르게 분산하기 위해 세 가지 유형의 부하 분산기를 제공합니다. 여러 유형의 부하 분산기를 동시에 사용하도록 서비스 하나를 구성할 수 있습니다.
- 외부 부하 분산기는 클러스터 및 Google Cloud VPC 네트워크 외부에서 들어오는 트래픽을 관리하며, Google Cloud 네트워크와 연결된 전달 규칙을 사용하여 트래픽을 Kubernetes 노드로 라우팅합니다.
- 내부 부하 분산기는 동일한 VPC 네트워크 내에서 들어오는 트래픽을 관리합니다. 외부 부하 분산기처럼 내부 부하 분산기도 Google Cloud 네트워크와 연결된 전달 규칙을 사용하여 트래픽을 Kubernetes 노드로 라우팅합니다.
- 애플리케이션 부하 분산기는 HTTP(S) 트래픽에 사용되는 특수한 외부 부하 분산기입니다. 이 부하 분산기는 전달 규칙 대신 인그레스 리소스를 사용해서 트래픽을 Kubernetes 노드로 라우팅합니다.
트래픽이 Kubernetes 노드에 연결되면 부하 분산기 유형에 관계없이 동일한 방식으로 처리됩니다. 부하 분산기는 클러스터의 어떤 노드가 해당 서비스에 대해 포드를 실행 중인지 알 수 없습니다. 대신 관련 포드를 실행하지 않는 노드까지 포함해 클러스터의 모든 노드에 트래픽을 분산합니다. 리전 클러스터에서는 클러스터 리전의 모든 영역에 있는 모든 노드에 부하가 분산됩니다. 트래픽이 노드로 라우팅되면 노드는 동일 노드나 다른 노드에서 실행 중인 포드로 트래픽을 라우팅합니다. 노드는 kube-proxy
가 노드에서 관리하는 iptables
규칙을 사용하여 무작위로 선택된 포드에 트래픽을 전달합니다.
다음 다이어그램에서 외부 패스 스루 네트워크 부하 분산기는 중간 노드로 트래픽을 전달하고, 트래픽은 첫 번째 노드에 있는 포드로 리디렉션됩니다.
부하 분산기가 노드로 보내는 트래픽은 다른 노드에 있는 포드로 전달될 수 있습니다. 그러려면 추가 네트워크 홉이 필요합니다. 추가 홉을 피하려면 트래픽을 처음 수신하는 동일 노드에 있는 포드로 트래픽이 가야 한다고 지정할 수 있습니다.
동일 노드에 있는 포드로 트래픽이 가야 한다고 지정하려면 서비스 매니페스트에서 externalTrafficPolicy
를 Local
로 설정하세요.
apiVersion: v1
kind: Service
metadata:
name: my-lb-service
spec:
type: LoadBalancer
externalTrafficPolicy: Local
selector:
app: demo
component: users
ports:
- protocol: TCP
port: 80
targetPort: 8080
externalTrafficPolicy
를 Local
로 설정하면 부하 분산기는 서비스에 속한 정상적 포드가 있는 노드에만 트래픽을 보냅니다.
부하 분산기는 상태 확인을 사용하여 적절한 포드가 있는 노드를 확인합니다.
외부 부하 분산기
클러스터 외부와 VPC 네트워크 외부에서 서비스에 연결해야 하는 경우 서비스를 정의할 때 서비스의 type
필드를 Loadbalancer
로 설정하여 서비스를 LoadBalancer로 구성할 수 있습니다. 그러면 GKE가 서비스 앞에 외부 패스 스루 네트워크 부하 분산기를 프로비저닝합니다.
외부 패스 스루 네트워크 부하 분산기는 클러스터에 있는 모든 노드를 인식하고, 서비스의 외부 IP 주소를 사용하여 VPC 네트워크 외부에서 서비스에 대한 연결을 허용하도록 VPC 네트워크의 방화벽 규칙을 구성합니다. 서비스에 고정 외부 IP 주소를 할당할 수 있습니다.
방화벽 규칙에 대한 자세한 내용은 자동으로 생성되는 방화벽 규칙을 참조하세요.
기술 세부정보
외부 부하 분산기를 사용할 때 수신 트래픽은 처음에 Google Cloud 네트워크와 연결된 전달 규칙을 통해 노드에 라우팅됩니다.
트래픽이 노드에 도달하면 노드는 iptables
NAT 테이블을 사용하여 포드를 선택합니다. kube-proxy
는 노드에서 iptables
규칙을 관리합니다.
내부 부하 분산기
동일한 VPC 네트워크 내에서 클러스터에 도달해야 하는 트래픽의 경우 내부 패스 스루 네트워크 부하 분산기를 프로비저닝하도록 서비스를 구성할 수 있습니다. 내부 패스 스루 네트워크 부하 분산기는 외부 IP 주소 대신 클러스터의 VPC 서브넷에서 IP 주소를 선택합니다. VPC 네트워크 내부의 애플리케이션 또는 서비스는 이 IP 주소를 사용하여 클러스터 내부의 서비스와 통신할 수 있습니다.
기술 세부정보
내부 부하 분산은 Google Cloud에서 제공됩니다. 트래픽이 특정 노드에 도달하면 이러한 노드는 포드가 다른 노드에 있더라도 iptables
NAT 테이블을 사용하여 포드를 선택합니다.
kube-proxy
는 노드에서 iptables
규칙을 관리합니다.
내부 부하 분산기에 대한 자세한 내용은 내부 패스 스루 네트워크 부하 분산기 사용을 참조하세요.
애플리케이션 부하 분산기
RESTful 웹 서비스 API와 같은 많은 애플리케이션이 HTTP(S)를 사용하여 통신합니다. VPC 네트워크 외부의 클라이언트가 Kubernetes 인그레스를 사용해서 이 유형의 애플리케이션에 액세스하도록 허용할 수 있습니다.
인그레스를 사용하면 호스트 이름과 URL 경로를 클러스터 내의 서비스에 매핑할 수 있습니다. 애플리케이션 부하 분산기를 사용할 때는 ClusterIP뿐 아니라 NodePort도 사용하도록 서비스를 구성해야 합니다. 트래픽이 NodePort에서 노드의 IP로 서비스에 액세스할 때 GKE는 해당 서비스를 위한 정상 상태의 포드로 트래픽을 라우팅합니다. NodePort를 지정하거나 GKE가 사용되지 않는 포트를 무작위로 할당하도록 허용할 수 있습니다.
인그레스 리소스를 만들 때 GKE는 Google Cloud 프로젝트에서 외부 애플리케이션 부하 분산기를 프로비저닝합니다. 부하 분산기는 NodePort에서 노드의 IP 주소로 요청을 전송합니다. 요청이 노드에 도달한 후 노드는 해당 iptables
NAT 테이블을 사용하여 포드를 선택합니다. kube-proxy
는 노드에서 iptables
규칙을 관리합니다.
이 인그레스 정의는 포트 80에서 frontend
라는 서비스로 demo.example.com
트래픽을 라우팅하고, 포트 8080에서 users
라는 서비스로 demo-backend.example.com
트래픽을 라우팅합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo
spec:
rules:
- host: demo.example.com
http:
paths:
- backend:
service:
name: frontend
port:
number: 80
- host: demo-backend.example.com
http:
paths:
- backend:
service:
name: users
port:
number: 8080
자세한 내용은 애플리케이션 부하 분산기의 GKE 인그레스를 참조하세요.
기술 세부정보
인그레스 객체를 만들 때 GKE 인그레스 컨트롤러는 인그레스 매니페스트 및 연결된 서비스 매니페스트에 있는 규칙에 따라 애플리케이션 부하 분산기를 구성합니다. 클라이언트가 애플리케이션 부하 분산기에 요청을 전송합니다. 부하 분산기는 실제 프록시입니다. 부하 분산기는 노드를 선택하고 요청을 해당 노드의 NodeIP
:NodePort
조합으로 전달합니다. 노드는 해당 iptables
NAT 테이블을 사용해서 포드를 선택합니다.
kube-proxy
는 노드에서 iptables
규칙을 관리합니다.
노드 간 연결 제한
클러스터의 노드를 타겟팅하는 인그레스 또는 이그레스 방화벽 규칙을 만들면 부정적인 영향을 미칠 수 있습니다. 예를 들어 이그레스 거부 규칙을 클러스터의 노드에 적용하면 NodePort
, kubectl exec
등의 기능이 중단될 수 있습니다.
포드 및 서비스 연결 제한
기본적으로 동일 클러스터 내에서 실행되는 모든 포드는 자유롭게 통신할 수 있습니다. 하지만 필요에 따라 클러스터 내의 연결을 여러 방식으로 제한할 수 있습니다.
포드 간 액세스 제한
네트워크 정책을 사용하여 포드 간 액세스를 제한할 수 있습니다. 네트워크 정책 정의를 사용하면 라벨, IP 범위, 포트 번호를 임의로 조합하고 이를 기준으로 포드의 인그레스 및 이그레스를 제한할 수 있습니다.
기본적으로는 네트워크 정책이 없으므로, 클러스터에 있는 포드 사이의 모든 트래픽이 허용됩니다. 네임스페이스에서 첫 번째 네트워크 정책을 만들면 다른 모든 트래픽이 즉시 거부됩니다.
네트워크 정책을 만든 후에는 클러스터에서 이를 명시적으로 사용 설정해야 합니다. 자세한 내용은 애플리케이션의 네트워크 정책 구성을 참조하세요.
외부 부하 분산기 액세스 제한
서비스에 외부 부하 분산기가 사용될 경우 기본적으로 외부 IP 주소의 트래픽이 서비스에 액세스할 수 있습니다. 서비스를 구성할 때 loadBalancerSourceRanges
옵션을 구성하여 클러스터 내부의 엔드포인트에 액세스할 수 있는 IP 주소 범위를 제한할 수 있습니다. 여러 범위를 지정할 수 있고, 언제든지 실행 중인 서비스의 구성을 업데이트할 수 있습니다. 각 노드에서 실행되는 kube-proxy
인스턴스는 지정된 loadBalancerSourceRanges
와 일치하지 않는 모든 트래픽을 거부하도록 노드의 iptables
규칙을 구성합니다. 또한 LoadBalancer 서비스를 만들면 GKE는 네트워크 수준에서 이러한 제한사항을 적용하기 위해 상응하는 VPC 방화벽 규칙을 만듭니다.
애플리케이션 부하 분산기 액세스 제한
서비스에서 애플리케이션 부하 분산기를 사용하는 경우 Google Cloud Armor 보안 정책을 사용하여 서비스에 액세스할 수 있는 외부 IP 주소와 보안 정책으로 인해 액세스가 거부될 때 반환할 응답을 제한할 수 있습니다. 이러한 상호작용에 대한 정보를 로깅하도록 Cloud Logging을 구성할 수 있습니다.
Google Cloud Armor 보안 정책이 충분히 세밀하게 조정되지 않은 경우 엔드포인트에서 IAP(Identity-Aware Proxy)를 사용 설정하여 애플리케이션에 사용자 기반 인증 및 승인을 구현할 수 있습니다. 자세한 내용은 IAP 구성 세부 튜토리얼을 참조하세요.
알려진 문제
이 섹션에서는 알려진 문제를 다룹니다.
Containerd가 사용 설정된 노드를 172.17/16
범위에 연결할 수 없음
containerd가 사용 설정된 노드 VM은 172.17/16
내의 IP가 있는 호스트에 연결할 수 없습니다. 자세한 내용은 172.17/16 IP 주소 범위와 충돌을 참조하세요.
Private Service Connect를 사용하는 삭제된 GKE 클러스터의 나머지 리소스
2024년 5월 7일 이전에 Private Service Connect를 사용하여 GKE 클러스터를 만들고 삭제했으며 클러스터 자체보다 클러스터가 포함된 프로젝트를 먼저 삭제한 경우 연결된 Private Service Connect 리소스가 유출되었을 수 있습니다. 이러한 리소스는 숨겨진 상태로 유지되어 연결된 서브넷을 삭제할 수 없습니다. 이 문제가 발생하면 Google Cloud 지원팀에 문의하세요.