서비스란 말은 다양한 곳에서 쓰인다. 과연 그럼 쿠버네티스에서 서비스는 무엇 인가? 사람들이 그냥 대충 이해하고 넘어가는 경우가 많지만 상당히 중요한 내용이므로 정리하고자 한다.
서비스(Service)는 파드들을 통해 실행되고 있는 애플리케이션을 네트워크에 노출(expose)시키는 가상의 컴포넌트다.
음...이렇게 말하면 필자는 쿠버네티스를 처음보거나 비전공자가 이해하기 어렵다고 생각한다.
필자의 말로 정리해보자면, 클러스터 내부에서 외부의 트래픽 처리를 담당하고 파드들과 연결해주는 가상의 네트워크 테이블이라고 볼 수 있다.
위의 서비스의 종류는 여러 가지가 있다. 하나씩 알아 보도록 해보자.
ClusterIP는 파드들이 클러스터 내부의 다른 리소스들과 통신할 수 있도록 해주는 가상의 클러스터 전용 IP다. 이 Service는 Selector를 활용해서 Traffic을 전달받을 파드의 IP를 지정해줍니다.
apiVersion: v1 kind: Service metadata: name: myapp-service spec: type: ClusterIP # 생략 가능 ports: - protocol: TCP targetPort: 9376 # 애플리케이션(파드)을 노출하는 포트 port: 80 # 서비스를 노출하는 포트 selector: # 이 서비스가 적용될 파드 정보를 지정 (선택이나 권장 사항) app: myapp type: frontend
NodePort는 외부에서 노드 IP의 특정 포트로 들어오는 요청을 감지하여, 해당 포트와 연결된 파드로 트래픽을 전달하는 유형의 서비스다. 이때 클러스터 내부로 들어온 트래픽을 특정 파드로 연결하기 위한 ClusterIP 역시 자동으로 생성된다.(즉 외부의 Port를 클러스터 내부와 연결하기 위한 서비스다!!)
apiVersion: v1 kind: Service metadata: name: myapp-service spec: type: NodePort ports: - targetPort: 80 # 애플리케이션(파드)을 노출하는 포트 port: 80 # 서비스를 노출하는 포트 nodePort: 30008 # 외부 사용자가 애플리케이션에 접근하기 위한 포트번호(선택) selector: # 이 서비스가 적용될 파드 정보를 지정 app: myapp type: frontend
보통 클라우드 벤더에서 제공하는 설정 방식으로, 외부 IP 를 가지고 있는 로드밸런서를 할당한다. 외부 IP를 가지고 있기 때문에, 클러스터 외부에서 접근이 가능하다.
이 유형은 서비스를 클라우드 제공자 측의 자체 로드 밸런서로 노출시키며, 이에 필요한 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은 외부 서비스를 쿠버네티스 내부에서 호출하고자할때 사용할 수 있다. 서비스에 selector 대신 DNS name을 직접 명시하고자 할 때에 인다. spec.externalName 항목에 필요한 DNS 주소를 기입하면, 클러스터의 DNS 서비스가 해당 주소에 대한 CNAME 레코드를 반환하게 된다.
apiVersion: v1 kind: Service metadata: name: myapp-service namespace: prod spec: type: ExternalName externalName: my.database.example.com
필자는 Service를 정리하면서 LoadBalancer와 NodePort의 차이를 이해하기가 어려워서 정리하고자 한다.
1. 둘이 노출하고자 하는 것이 다르다.