들어가며
- kubernetes의 서비스는 pod들을 통해 실행되고 있는 애플리케이션을 네트워크에 노출시키는 가상의 컴포넌트 입니다.
- pod의 경우 지정되는 ip는 랜덤하고, 재시작 할 때마다 변하기 때문에, 고정된 endpoint로 호출하기 어려운 점이 있습니다.
- 이때, pod간 로드밸런싱 지원을 해주는 것이 k8s의 service 입니다.
- 그렇다면, k8s의 service의 종류와 그 특징에 대해 알아보겠습니다.
Service
동일한 서비스를 제공하는 pod 그룹의 단일 진입점을 제공합니다.
예를 들어, nginx 웹서버 3개를 실행했다고 가정해봅니다.
한 웹서버에게만 몰리지 않도록 3개의 ip를 관리하는 가상 ip를 만들고, 그 가상 ip가 load balance 역할을 합니다.
즉, load balance 역할을 하는 가상 ip가 3개의 웹서버에게 균등한 분배를 하게 됩니다.
Service Type
서비스는 크게 4가지로 구분할 수 있습니다.
Cluster IP
해당 타입은 service의 기본값입니다.
여러 pod들의 endpoint를 묶어 단일 진입점(virtual IP)을 생성합니다.
k8s cluster 내에서는 이 서비스에 접근이 가능하지만,
cluster 외부에서는 외부 IP를 할당 받지 못했기 때문에, 접근이 불가능합니다.
스파클링소다 4.0 기준으로 ClusterIP 타입의 서비스를 살펴보겠습니다.kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE devainexus ClusterIP 6.5.35.82 <none> 80/TCP,5001/TCP 42d
nexus repository의 서비스인 devainexus는 ClsuterIP로 설정되어 있습니다.
cluster 내부에서 해당 ClusterIP인 6.5.35.82 를 호출하면 response를 확인할 수 있습니다.curl 6.5.35.82 --head HTTP/1.1 200 OK Date: Thu, 01 Dec 2022 06:10:06 GMT Server: Nexus/3.29.2-02 (OSS) X-Content-Type-Options: nosniff X-Frame-Options: DENY X-XSS-Protection: 1; mode=block Content-Type: text/html Last-Modified: Thu, 01 Dec 2022 06:10:06 GMT Pragma: no-cache Cache-Control: no-cache, no-store, max-age=0, must-revalidate, post-check=0, pre-check=0 Expires: 0 Content-Length: 8240
NodePort
Cluster IP로 연결되어 있는 pod들에 대해 외부 접속이 가능하도록 하는 서비스 타입입니다.
이는 cluster IP로만 접근이 가능한 것이 아니라, 모든 노드의 ip와 port를 통해서도 접근이 가능하게 됩니다.
스파클링소다 4.0 기준의 NodePort 타입의 서비스를 살펴보겠습니다.kubectl get svc -A | grep -i nodeport NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE monitoring kube-prometheus-stack-kube-state-metrics NodePort 6.5.164.190 <none> 8080:30995/TCP 43d
이는 30995의 nodeport로 들어오면, 8080의 target port로 연결이 됩니다.
PORT 부분을 보면, 8080:30995/TCP 라고 설정되어 있습니다.kubectl describe svc -n monitoring kube-prometheus-stack-kube-state-metrics Name: kube-prometheus-stack-kube-state-metrics Namespace: monitoring Labels: app.kubernetes.io/instance=kube-prometheus-stack app.kubernetes.io/managed-by=Helm app.kubernetes.io/name=kube-state-metrics helm.sh/chart=kube-state-metrics-2.12.0 Annotations: prometheus.io/scrape: true Selector: app.kubernetes.io/instance=kube-prometheus-stack,app.kubernetes.io/name=kube-state-metrics Type: NodePort IP: 6.5.164.190 Port: http 8080/TCP TargetPort: 8080/TCP NodePort: http 30995/TCP Endpoints: 6.2.171.102:8080 Session Affinity: None External Traffic Policy: Cluster Events: <none>
그렇다면, 현재 클러스터의 노드 ip와 nodeport를 통해, 클러스터 외부에서 접속을 시도해 봅니다.
현재 클러스터의 node는 아래와 같습니다.kubectl get node -owide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME master Ready master 43d v1.18.19 192.168.50.200 <none> CentOS Linux 7 (Core) 3.10.0-957.el7.x86_64 docker://20.10.7 worker Ready <none> 43d v1.18.19 192.168.50.201 <none> CentOS Linux 7 (Core) 3.10.0-1160.76.1.el7.x86_64 docker://20.10.7
master 사설 IP는 192.168.50.200, worker 사설 IP는 192.168.50.201 입니다.
명령 프롬프트창에서 30995 port를 붙여 호출해보면 정상적인 response를 확인할 수 있습니다.curl 192.168.50.200:30995 <html> <head><title>Kube Metrics Server</title></head> <body> <h1>Kube Metrics</h1> <ul> <li><a href='/metrics'>metrics</a></li> <li><a href='/healthz'>healthz</a></li> </ul> </body> </html> curl 192.168.50.201:30995 <html> <head><title>Kube Metrics Server</title></head> <body> <h1>Kube Metrics</h1> <ul> <li><a href='/metrics'>metrics</a></li> <li><a href='/healthz'>healthz</a></li> </ul> </body> </html>
LoadBalancer
NodePort의 기능과 load balance 기능을 합친 것이 loadbalancer 타입의 서비스 입니다.
서비스를 자체 로드 밸런서로 노출시켜, 외부 로드 밸런서를 통해 들어온 트래픽이 서비스의 설정값에 따라 해당되는 pod들로 연결됩니다.
LoadBalancer 타입의 서비스를 생성할 때는 아래와 같이 정의합니다.apiVersion: v1 kind: Service metadata: name: <service name> spec: type: LoadBalancer
ExternalName
외부 서비스를 k8s cluster 내부에서 호출하고자 할 때 사용합니다.
호출하고자 하는 외부 서비스의 DNS 주소를 입력하면, cluster 도메인이 이를 치환하게 됩니다.apiVersion: v1 kind: Service metadata: name: <service name> spec: type: ExternalName externalName: google.com
위와 같이 정의된 서비스를 호출할 때는 서비스 이름으로 호출할 수 있습니다.curl <service name>.<namespace>.svc.cluster.local
해당 서비스로 들어오는 모든 요청을 externalName에 정의된 DNS로 포워딩하게 됩니다.
마무리
- k8s의 service에 대해 알아보았습니다.
- service의 종류와 주요 기능 및 테스트를 통해 service의 역할에 대해 알아보았습니다.
아티클이 유용했나요?
훌륭합니다!
피드백을 제공해 주셔서 감사합니다.
도움이 되지 못해 죄송합니다!
피드백을 제공해 주셔서 감사합니다.
피드백 전송
소중한 의견을 수렴하여 아티클을 개선하도록 노력하겠습니다.