학습 목표 : 클러스터 내부의 Pod가 외부와 통신하기 위한 Service의 유형을 알아본다.
Service 란?
- 클러스터 안에서 동적으로 변하는 Pod들을 고정적으로 사용하기 위한 방법으로 k8s의 Service를 사용한다.
- Service는 클러스터 안의 Pod를 고정 주소를 주어, 외부 네트워크와 통신할 수 있도록 하는 진입점 부여 역할을 한다.
- Service를 정의하고 생성할 때는 .spec.ports 속성 아래에 연결하고자 하는 항목별로 2개씩 Port지정 가능하다.
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP # 서비스 타입 설정
clusterIP : 10.0.10.10 # clusterIP 에서 클러스터 IP를 직접 설정할 수 있다.(선택)
selector:
app: MyApp # .spec.selector 필드에는 서비스와 연결할 Pod의 .labels값을 지정
ports:
- protocol: TCP # .spec.ports[] 배열 형태이며, 포트 포워딩을 설정
port: 80
targetPort: 9376
Service의 유형
- ClusterIP
- 기본 서비스 타입 (default)
- Pod들이 cluster 내부의 다른 리소스와 통신할 수 있도록 해주는 cluster 전용 가상IP
- cluster 내부에서만 접근 가능하고 외부에서는 접근할 수 없다.
- .spec.selector 에서 지정된 Pod들의 label로 Pod들을 외부 요청을 전달할 endpoint로 선택하여 트래픽을 분배한다.(LoadBalancing)
- endpoint를 수동으로 직접 지정해 줄때는 Endpoints 객체를 이용하여 Service와 mapping 한다.
apiVersion: v1
kind: Service
metadata:
name: my-internal-service
spec:
selector: # Service가 적용될 Pod 정보
app: my-app
type: ClusterIP # 생략 가능
ports:
- name: http
port: 80 # Service를 노출하는 Port
targetPort: 80 # Pod(애플리케이션)을 노출하는 Port
protocol: TCP
- NodePort
- 서비스 하나에 모든 노드의 지정된 포트를 할당
- 외부에서 node IP의 특정 Port로 들어오는 요청을 감지하여 해당 port와 연결된 pod로 트래픽 전달
- node1:8080, node2:8080처럼 노드에 상관없이 서비스에 지정된 포트번호만 사용하면 Pod에 접근할 수 있다.
- .spec.ports 의 .nodePort는 외부에서 node안의 특정 서비스로 접근할 수 있도록 하는 지정된 node의 특정 port를 의미한다.
- .spec.selector에 해당하는 모든 Pod들에게 NodePort에 의해 동일한 LoadBalancing이 적용된다.
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
selector:
app: my-app
type: NodePort
ports:
- name: http
port: 80 # Service에 노출되는 Port
targetPort: 80 # Pod (애플리케이션)을 노출하는 Port
nodePort: 30036 # Port 범위는 30000 ~ 32767, 미지정시 임의의 Port 부여
protocol: TCP
- LoadBalancer
- 아마존 웹 서비스(AWS), 구글 클라우드(GCP) 플랫폼 같은 퍼블릭 클라우드 서비스, 오픈스택(OpenStack)같은 프라이빗 클라우드, 쿠버네티스를 지원하는 로드밸런서 장비 등 에서 사용한다.
- Service를 Cloud 제공자 측의 자체 LoadBalancer로 노출시키며, LoadBalancer의 IP를 이용해 클러스터 외부에서 Pod에 접근할 수 있도록 해준다.
- 필요한 NodePort와 ClusterIP는 자동으로 생성된다.
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 80 # 서비스를 노출하는 포트
targetPort: 80 # 애플리케이션(파드)를 노출하는 포트
clusterIP: 10.0.171.239 # 클러스터 IP
selector:
app: myapp
type: frontend
status:
loadBalancer: # 프로비저닝된 로드 밸런서 정보
ingress:
- ip: 192.0.2.127
- ExternalName
- 클러스터 안에서 외부로 접근할 때 주로 사용한다.
- Service에 selector 대신 name을 직접 명시하고자 할 때 사용한다.
- .spec 속성에 필요한 DNS 주소를 기입하면 cluster의 DNS 서비스가 해당 주소에 대한 CNAME 레코드를 반환한다.
- CNAME값을 이용해 클러스터 외부로 접속할 수 있다.
apiVersion: v1
kind: Service
metadata:
name: myapp-service
namespace: prod
spec:
type: ExternalName # ExternalName 타입 설정
externalName: my.database.example.com # 외부 도메인값