일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 리액트
- 백엔드
- k8s
- 파이썬
- 클라우드
- HTML
- AWS
- 쿠버네티스
- 프론트엔드
- kubernetes
- es6
- 블록체인
- JavaScript
- 백준
- 자바스크립트
- 이더리움
- 웹
- next.js
- 가상화
- VUE
- TypeScript
- 알고리즘
- CSS
- 컴퓨터공학
- BFS
- docker
- 솔리디티
- react
- 타입스크립트
- 이슈
- Today
- Total
즐겁게, 코드
쿠버네티스의 서비스 컴포넌트 살펴보기 본문
파드의 임시 IP(Ephemeral IP)로 인한 불편함
쿠버네티스에서 파드와 네트워크를 연결하려면 어떻게 해야 할까요?
파드의 IP주소를 확인한 후 사용할 수도 있지만, 파드는 재실행될 때마다 새로운 임시 IP(ephemeral IP)를 무작위로 부여받는다는 특징이 있습니다.
하지만 서비스를 운영하는 중 파드는 리소스 부족 등의 이유로 인해 제거되었다가 재생성되는 과정을 계속해서 반복하는데요, 파드가 재생성될 때마다 매번 달라지는 임시 IP를 사용하는 것은 굉장히 손이 많이 가는 작업이 될 수 있습니다.
서비스의 역할
이처럼 파드의 임시 IP 대신 정적으로 변화하지 않는 고정된 IP를 제공해주는 것이 바로 서비스 로, 서비스는 파드로 보내지는 요청을 앞단에서 관리할 수 있는 역할을 합니다.
서비스의 유형은 다음과 같이 분류됩니다.
- ClusterIP
- NodeIP
- LoadBalancer
ClusterIP 타입 서비스의 트래픽 전달 과정
ClusterIP는 가장 기본적인 서비스 유형입니다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP
ClusterIP는 앞단에 인그레스(Ingress)를 둘 수 있으며, 클러스터 안에서만 사용할 수 있는 IP를 부여합니다.
1단계 : Ingress → Service
제일 먼저 유저로부터 요청(트래픽)이 들어오면, 인그레스(Ingress)가 제일 먼저 트래픽을 받아 서비스에 전달합니다.
인그레스는 L7 계층에서 로드밸런싱 및 다양한 기능을 제공하는 쿠버네티스 컴포넌트로, 자세한 내용은 별도의 글에서 다룹니다.
유저가 전송한 트래픽을 인그레스에서 서비스로 전달하면, 서비스는 해당 트래픽을 조건에 맞는 파드로 라우트합니다.
- 인그레스와 서비스를 연결하는 템플릿 예시
# ingress.yaml
...
spec:
...
backend:
serviceName: microservice-service-1
# 트래픽을 전달할 서비스의 포트
servicePort: 3001
#Service.yaml
apiVersion: v1
kind: Service
metadata:
name: microservice-service-1
spec:
selector:
app: microservice-1
ports:
- protocol: TCP
# 서비스가 트래픽을 받도록 공개할 포트
port: 3001
# 서비스가 트래픽을 전달할 대상(Ex. 파드)의 포트
targetPort: 3000
2단계 : Service → Pod
이제 인그레스에서 트래픽을 넘겨받았으니 이를 파드에 전달해줄 차례인데요, 아래와 같은 아키텍처를 구현하기 위해 서비스와 파드는 어떻게 연결할 수 있을까요?
이 때는 라벨과 셀렉터를 사용합니다.
파드에서는 라벨을 통해 다른 컴포넌트가 해당 파드를 지정할 수 있도록 알릴 수 있고, 서비스에서는 셀렉터를 통해 트래픽을 전달할 파드를 선택할 수 있습니다.
단 동일한 라벨을 갖는 모든 레플리카들에 트래픽을 전달하는 것이 아닌, kube-proxy 에 의해 트래픽을 균등하게 파드에 배분합니다.
이제 파드까지 트래픽이 도달했는데요, spec.ports.targetPort
속성을 통해 트래픽을 전달할 (컨테이너의) 포트를 지정할 수 있습니다.
- 라벨을 지정한 파드를 셀렉터로 지정하는 서비스 템플릿
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: microservice-one
spec:
replicas: 2
...
template:
metadata:
# 생성되는 파드들에 app: microservice-1 라는 라벨을 부여합니다.
labels:
app: microservice-1
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: microservice-service-1
spec:
selector:
# 트래픽을 app: microservice-1 라벨을 갖는 파드로 전달합니다.
# 서비스의 3001번 포트로 들어오는 트래픽은 파드의 3000번 포트로 전달됩니다.
app: microservice-1
ports:
- protocol: TCP
port: 3001
targetPort: 3000
3단계 : 둘 이상의 컨테이너를 갖는 파드
지금까지의 과정을 통해 인그레스 - 서비스 - 파드를 거쳐 하나의 컨테이너에 트래픽을 전달할 수 있게 되었습니다.
이제 만약 둘 이상의 컨테이너를 갖는 파드에 각각 트래픽을 보내고 싶다면, 서비스의 spec.ports
속성에 서비스 포트와 targetPort
를 추가해주기만 하면 됩니다.
- 둘 이상의 컨테이너를 갖는 파드에 포워딩을 수행하는 서비스 템플릿
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: microservice-service-1
spec:
selector:
# 트래픽을 app: microservice-1 라벨을 갖는 파드로 전달합니다.
app: microservice-1
ports:
# 서비스의 3301번 포트로 들어온 트래픽은 파드의 3000번 포트로 전달됩니다.
- protocol: TCP
port: 3001
targetPort: 3000
# 서비스의 5501번 포트로 들어온 트래픽은 파드의 5500번 포트로 전달됩니다.
- protocol: TCP
port: 5501
targetPort: 5500
NodePort 서비스 타입의 트래픽 전달 과정
NodePort 서비스 타입은 외부에서 각 워커 노드에 직접 접근할 수 있도록 포트를 공개하는 방식으로, 보안이 취약하다는 단점이 있어 주로 임시 개발용이나 데모용으로 사용됩니다.
nodePort
는 30000 ~ 32767 사이의 값만을 가질 수 있으며, 노드로 보내진 트래픽은 spec.ports.targetPort
에 명시된 포트로 전달됩니다.
- 노드의 공개된 포트를 통해 파드에 접근하는 서비스 템플릿
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
type: NodePort
selector:
app: microservice-1
ports:
- name: container-1
port: 3001
nodePort: 30000
targetPort: 3000
- name: container-2
port: 5501
nodePort: 30001
targetPort: 5501
이 때 spec.ports.port
와 spec.ports.targetPort
는 여전히 ClusterIP 기반으로 생성됩니다.
LoadBalancer 타입 서비스의 트래픽 전달 과정
LoadBalancer 타입 서비스는 NodePort와 유사한 구조를 갖지만, 외부에서 퍼블릭으로 노드에 접근할 수 있는 것이 아닌 클라우드 기반의 로드밸런서만이 클러스터 내 노드에 접근할 수 있도록 합니다.
- LoadBalancer 타입의 서비스 템플릿
apiVersion: v1
kind: service
metadata:
name: my-nodeport-service
spec:
type: LoadBalancer
selector:
app: microservice-1
ports:
- name: container-1
port: 3001
nodePort: 30000
targetPort: 3000
- name: container-2
port: 5501
nodePort: 30001
targetPort: 5501
'☁️ 클라우드 > Kubernetes' 카테고리의 다른 글
쿠버네티스 베스트 프랙티스 - 02. 네임스페이스 활용하기 (0) | 2022.05.08 |
---|---|
쿠버네티스 베스트 프랙티스 - 01. 작은 이미지 활용하기 (0) | 2022.05.07 |
Helm을 통해 템플릿에서 변수화된 값 사용하기 (0) | 2022.04.13 |
쿠버네티스의 리소스 관리 (0) | 2022.04.11 |
컨테이너의 가용성 확보하기 - Deployment와 ReplicaSet (0) | 2022.04.08 |