Pod는 변수(Variable)고, Service는 상수(Constants)이다.
Pod는 일회용이다. 배포할 떄마다 죽고 새로 태어나며, 그때마다 IP 주소가 바뀐다.
프론트엔드나 다른 MSA 서비스가 자꾸 바뀌는 IP를 추적해서 호출할 수는 없다.
Pod 앞단에 **고정된 IP(Cluster IP)**와 **고정된 도메인 이름(DNS)**을 부여하는 내부 로드밸런서이다.
Round Robin으로 뿌려줘http://api 처럼 서비스 이름만으로 통신할 수 있다.
api -> 10.96.0.1로 해석해준다.가장 중요한 건 selector 이다. 이게 Deployment의 라벨과 일치해야 연결된다.
apiVersion: v1
kind: Service
metadata:
name: api-service # 내부에서 부를 이름 (DNS)
spec:
type: ClusterIP # 내부 전용
selector:
app: api # (중요) 이 라벨을 가진 Pod들로 트래픽을 보냄
ports:
- protocol: TCP
port: 80 # 서비스의 포트
targetPort: 8080 # Pod의 포트
Service는 기본적으로 K8s 클러스터 내부에서만 접근 가능하다. (보안상 안전)
하지만 외부 사용자는 우리 API를 호출해야 한다. 게다가 도메인도 연결해야 하고, HTTPS 인증서도 붙여야 한다.
외부에서 들어오는 HTTP(S) 트래픽을 규칙에 따라 적절한 Service로 라우팅해주는 L7 리버스 프록시 설정이다.
my-service.com/api는 api 서비스로 보내줘라고 적힌 YAML./api, /admin)apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: `api-ingress`
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # Ngnix 세부 설정
spec:
rules:
- host: my-service.com # 1. 이 도메인으로 들어오면
http:
paths:
- path: /api # 2. 그리고 /api 경로로 들어오면
pathType: Prefix
backend:
service:
name: api-service # 3. 이 서비스로 보내라
port:
number: 80
이제 Deployment, Service, Ingress가 합쳐졌을 떄, 사용자의 요청이 Spring Boot까지 도달하는 여정이다.
https://my-service.com/api/v1/hello 호출api-service를 찾는다.api-service는 자신의 목록(Endpoints)에 살아있는 Pod IP 중 하나를 선택한다.