Service란?
이전 포스팅에서 파드는 컨트롤러에 의해서 관리되고 만약 노드 중 하나에 장애가 발생하면 해당 노드에 있는 파드들을 다른 노드에 옮김으로써 동적으로 파드들을 관리한다고 이야기했습니다. 때문에 파드는 클러스터 안에서 옮겨 다니게 되는데, 이 과정에서 노드를 옮기면서 파드 안의 IP가 변경되게 됩니다. 이와 같이 동적으로 변하는 파드의 IP를 특정하기 위해서 사용하는 방법이 쿠버네티스 서비스(Service)입니다. 서비스는 위치를 바꿔가는 노드의 정보를 유연하게 쫓기위해 라벨(label)과 라벨 셀렉터(labal selector)를 사용하며, yaml 템플릿을 정의할 때 어떤 파드를 같은 서비스로 묶을지 정하게 됩니다. (metadata영역에 label을 정의할 수 있고, 라벨 셀렉터에 매핑시켜주면 같은 서비스로 분류됩니다.)
서비스를 사용하면 파드가 클러스터 안 어디에 있던지 고정 주소를 이용해서 접근할 수 있게됩니다. 또한 클러스터 외부에서 클러스터 안 파드에도 접근할 수 있습니다. 특별히 Service와 Ingress(아래에서 좀 더 자세히 다룸)는 외부 접근을 할 수 있을 뿐만 아니라 로드 밸런싱을 지원하는데, 둘의 차이는 통신 영역의 차이가 있습니다. Service는 OSI 7계층 중 L4 영역에서의 통신을 사용하고, Ingress는 L7 영역에서 통신할 때 사용하게 됩니다.
서비스는 크게 네 가지 타입이 있습니다. 이번 포스팅에서는 각 서비스에 대한 설명과 외부에서 접근할 수 있는 방법에 대해서 다뤄보겠습니다.
ClusterIP
먼저 ClusterIP입니다. ClusterIP는 이름 그대로 쿠버네티스 클러스터 안에서만 사용할 수 있습니다. 클러스터 안 노드나 파드에서는 ClusterIP를 이용해서 서비스에 연결된 각 파드들에 접근할 수 있습니다. 하지만 클러스터 내부 가상의 IP이기 때문에 클러스터 외부에서는 접근할 수 없습니다.
apiVersion: v1
kind: Service
metadata:
name: sisko-service
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: sisko
NodePort
서비스에 각 노드의 지정된 포트를 할당하는 방식으로 클러스터 외부와 내부 모두 접근이 가능합니다. 이름에서 암시하듯 NodePort는 모든 노드에 특정 포트를 열어두고, 이 포트로 보내지는 모든 트래픽을 서비스로 포트 포워딩하게 됩니다. 그래서 파드가 일부 노드에만 실행되어 있을 때 파드가 떠 있지 않은 노드로 접근하더라도 파드가 떠 있는 노드로 연결되게 됩니다.
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
selector:
app: my-app
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30036
protocol: TCP
.spec.ports[]를 살펴보도록 하겠습니다. ports 안에는 port, tartgetPort, nodePort가 있습니다.
- Port : 서비스가 클러스터 내부로 오픈하는 포트입니다.
- TargetPort : 타겟 파드에 요청을 보내는 포트입니다.
- NodePort : 서비스가 클러스터 외부로 노출하는 포트입니다.
LoadBalancer
AWS, GCP,과 같은 Public Cloud 서비스에서 지원하는 쿠버네티스 로드밸런서 장비를 사용합니다. 클라우드에서 제공하는 로드밸런서와 파드를 연결한 후 해당 로드밸런서 IP를 이용해 클러스터 외부에서 파드에 접근할 수 있도록 해줍니다.
ExternalName
클러스터 내부에서 외부로 접근할 때 주로 사용하는 서비스로, 서비스를 .spec.externalName 필드에 설정한 값과 연결합니다.
kind: Service
apiVersion: v1
metadata:
name: test-service
namespace: default
spec:
type: ExternalName
externalName: test.database.example.com #외부 IP
Ingress란?
Ingress는 클러스터 외부에서 안으로 접근하는 요청들을 어떻게 처리할지에 관한 규칙 모음입니다. Ingress 자체는 클러스터 외부에서 접근해야 할 URL을 사용할 수 있도록 하고, 로드 밸런싱, SSL 인증서 처리, 도메인 기반 가상 호스팅 등의 규칙을 정의해둔 자원이고, 실제로 동작시키는 것은 Ingress-Controller입니다.
만약 Cloud 서비스에서 로드밸런서 서비스를 사용한다면 인그레스를 연동해서 쉽게 사용할 수 있습니다. 하지만 클라우드 서비스를 사용하는 것이 아니라 직접 쿠버네티스 클러스터를 구축해야 한다면 Ingress-Controller를 직접 Ingress와 연동해야 합니다. 이때 가장 많이 사용하는 도구는 쿠버네티스에서 공식적으로 제공하는 ingress-nginx입니다.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: sisko-ingress2
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
tls:
- hosts:
- search-cruise-sisko.dev.daumkakao.io
secretName: devdakao
rules:
- host: search-cruise-sisko.dev.daumkakao.io
http:
paths:
- path: /(.*)
backend:
serviceName: sisko-service1
servicePort: 8080
- path: /test/(.*)
backend:
serviceName: sisko-service2
servicePort: 8080
쿠버네티스의 전체 구조를 정리해보자면, 먼저 유저로부터 Ingress Host로 부터 요청을 받고, 서비스를 거쳐 파드에 요청을 전달해서 비즈니스 로직을 수행한 다음 응답을 다시 유저로 return해 주게 됩니다.
이 과정에서 각 Ingress와 Service가 로드밸런싱을 하게되고, 컨트롤러가 각 파드들의 셀프힐링과 배포에 대한 사항들을 관리해주게 됩니다.
'DevOps > Kubernetes' 카테고리의 다른 글
[Kubernetes] Volume: k8s에서 데이터를 Disk에 영구 저장하기 (0) | 2020.07.20 |
---|---|
[Kubernetes] Rolling Update (Deployment): 무중단 배포 (6) | 2020.07.17 |
[Kubernetes] 쿠버네티스 컨트롤러: Pod를 동적으로 관리 (0) | 2020.07.13 |
[Kubernetes] Pod #2: 쿠버네티스 셀프 힐링 및 자원 할당 (0) | 2020.07.13 |
[Kubernetes] Pod #1: 쿠버네티스에서 컨테이너를 담당하는 기본 단위 (0) | 2020.07.10 |