쿠버네티스에서의 서비스 분석
쿠버네티스에서는 POD를 통해 서비스를 생성할 수 있습니다.
다수의 POD로 서비스를 제공할 때는 POD의 IP를 직접 접근하는 것이 복잡하고유지보수하기 어려워집니다. 이에 쿠버네티스는 서비스(SERVICE)라는 추상화 개념을 제공합니다. 이는 외부에서 POD 그룹을 통해 애플리케이션에 접근할 수 있도록 하며 POD의 IP를 관리할 필요 없이 안정적인 서비스 접근을 보장합니다.
쿠버네티스에서 서비스는 POD 그룹에 대한 접근정책을 정의하는 논리적 추상체입니다. 이는 로드밸런싱和服务 발견 기능을 포함합니다. 서비스 자체는 POD 스케ジュール링을 하지 않으며 자원을 사용하지 않습니다. 서비스의 IP는 클러스터 내에서의 가상 IP로 쿠버네티스 컨트롤플레인에 의해 자동 할당됩니다.
서비스는 코드를 실행하지 않습니다. 단지 POD 그룹에 대한 접근정책을 정의하는 규칙 집합일 뿐입니다.
서비스를 생성할 때 선택기 선택기 필드를 통해 특정 라벨을 지정할 수 있습니다. 이 라벨이 POD의 라벨과 일치하는 경우에는 해당 POD가 서비스의 범위에 자동으로 포함됩니다.
쿠버네티스의 엔드포인트 컨트롤러는 POD의 상태를 지속적으로 모니터링하고 서비스의 엔드포인트 목록을 동적으로 업데이트합니다. POD가 스케ジュール러에 의해 특정 노드에 배치되고 서비스의 선택기와 매칭될 경우 해당 POD의 IP와 포트가 자동으로 엔드포인트 목록에 추가됩니다.
또한 각 노드의 쿠버네티스-프록시 컴포넌트는 서비스와 엔드포인트의 변경사항을 감지하고 로컬의 iptables 또는 IPVS 규칙을 동기화시킵니다. 클러스터IP(서비스의 가상 IP)로 요청이 도착하면 프록시가 규칙에 따라 요청을 POD로 전달합니다.
서비스가 필요한 이유
쿠버네티스에서 서비스는 POD 그룹에 의해 실행되는 애플리케이션을 네트워크 서비스로 노출시키는 핵심 리소스입니다.
Deployment, DaemonSet, StatefulSet 등의 컨트롤러를 통해 POD를 배포할 때 서비스를 생성합니다. 서비스는 POD 그룹을 모니터링하며 POD가 증가하거나 감소하는 경우에도 서비스가 항상 안정적인 접근을 제공합니다. 또한 서비스는 라벨 선택기 기제를 통해 POD를 동적으로 관리하며 트래픽을 정상적으로 전달합니다.
예를 들어 웹 서비스 POD가 여러 대 있을 때 웹 서비스의 확장성 또는 POD의 재배치로 인해 IP가 변경되면 클라이언트가 웹 서비스를 추적하기 어려워집니다. 또한 웹 애플리케이션과 MySQL 데이터베이스가 각각 다른 POD에 배포될 때 웹 애플리케이션이 MySQL POD의 IP를 어떻게 찾을 수 있을까요?
서비스가 이러한 문제를 해결합니다. 쿠버네티스 서비스는 POD 그룹을 추상화하는 '미시 서비스'라는 개념을 제공하며 POD의 수가 변동해도 안정적인 접근을 보장합니다. 웹 애플리케이션이 데이터베이스에 접근할 때는 MySQL POD의 IP를 직접 추적할 필요 없이 서비스를 통해 간접적으로 접근할 수 있습니다. 서비스는 POD 간의 의존성을 분리하고 유연한 관리를 가능하게 합니다.
서비스의 정의와 생성
- 먼저 Deployment 객체를 생성합니다. 이 Deployment는 3개의 nginx POD를 관리합니다:
kubectl deployment 생성 nginx서버 --이미지=nginx:최신 --리피카=3
- POD에 대한 서비스를 생성합니다:
kubectl 서비스 노출 nginx서버 --타입=클러스터아이피 --포트=6666 --타겟포트=80
참고: Deployment와 POD는 1:1 대응이 아닙니다. Deployment는 선택기와 매칭되는 모든 POD를 관리합니다. 3. 서비스 정보를 확인합니다:
kubectl 서비스 보기 -o wide
예시 출력:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
nginx서버 ClusterIP 10.107.200.232 <none> 6666/TCP
출력 결과에서 쿠버네티스가 서비스에 클러스터 내부의 가상 IP를 할당했음을 확인할 수 있습니다. 4. 서비스 테스트:
curl 10.107.200.232:6666
주의사항:
- 이 IP는 클러스터 내부에서만 사용할 수 있습니다.
- 서비스는 POD의 수가 변동해도 항상 트래픽을 정상적으로 전달합니다.
- YAML 파일을 통해 서비스 정의:
apiVersion: v1
kind: Service
metadata:
name: my서비스
spec:
selector:
app: MyApp
ports:
- 프로토콜: TCP
port: 6666
targetPort: 80
type: ClusterIP
이 YAML에서:
- selector는 서비스가 관리할 POD를 정의합니다.
- port는 서비스가 노출할 포트입니다.
- targetPort는 POD가侦听着 포트입니다.
- type을 ClusterIP로 설정하면 서비스가 클러스터 내부에서만 접근가능합니다.
서비스의 제공
ClusterIP 유형의 서비스 접근 및 라우팅 메커니즘
접근 방법
앞서 설명한 바와 같이 ClusterIP 유형의 서비스는 클러스터 내부에서만 접근할 수 있는 가상 IP를 사용합니다. POD가 어느 노드에 배치되었든 클러스터 내의 컴포넌트는 해당 서비스의 IP:포트로 접근할 수 있습니다.
라우팅 경로
- 클라이언트가 ClusterIP:포트로 요청을 보냅니다.
- 쿠버네티스-프록시가 iptables/IPVS 규칙에 따라 요청을 POD로 전달합니다.
- 로드밸런싱은 기본적으로 라운드로빈 방식으로 이루어집니다.
다른 유형의 서비스를对外 노출하려면 ServiceType 옵션을 통해 접근 방식을 설정해야 합니다.
NodePort 유형의 서비스 접근 및 라우팅 메커니즘
접근 방법
NodePort 유형의 서비스는 각 노드의 고정 포트를 통해 외부 접근을 허용합니다. 이 포트는 보통 30000-32767 범위 내에서 할당됩니다. 외부 사용자는 노드의 IP와 NodePort를 통해 서비스에 접근할 수 있습니다.
라우팅 경로
- 외부 요청이 NodeIP:NodePort로 도달합니다.
- 쿠버네티스-프록시가 요청을 POD로 전달합니다.
- POD가 다른 노드에 있을 경우 클러스터 네트워크를 통해 요청이 전달됩니다.
LoadBalancer 유형의 서비스 접근 및 라우팅 메커니즘
접근 방법
LoadBalancer 유형의 서비스는 클라우드 플랫폼의 로드밸런서를 통해 외부 IP를 할당받습니다. 이 IP를 통해 외부 사용자는 서비스에 접근할 수 있습니다.
라우팅 경로
- 외부 사용자가 LoadBalancer의 공인 IP로 요청을 보내면 클라우드 로드밸런서가 요청을 노드의 NodePort로 분배합니다.
- 쿠버네티스-프록시가 요청을 POD로 전달합니다.
엔드포인트
쿠버네티스에서 서비스는 엔드포인트를 통해 POD 그룹에 연결됩니다. 서비스가 선택기를 지정하지 않은 경우에는 자동으로 엔드포인트가 생성되지 않습니다. 이때는 수동으로 엔드포인트를 정의해야 합니다.
- 선택기를 포함하지 않는 서비스 생성:
apiVersion: v1
kind: Service
metadata:
name: 외부-MySQL
spec:
ports:
- 프로토콜: TCP
port: 3306
targetPort: 3306
- 수동으로 엔드포인트 정의:
apiVersion: v1
kind: Endpoints
metadata:
name: 외부-MySQL
subsets:
- addresses:
- ip: 111.111.111.111
- ip: 222.222.222.222
ports:
- port: 3306
엔드포인트 정의 후 쿠버네티스-프록시는 iptables/IPVS 규칙을 통해 요청을 외부 MySQL 인스턴스로 전달합니다.