본문 바로가기
dev/kubernetes

Kubernetes - Service

by igooo 2024. 7. 2.
728x90

Service

Kubenetes 환경에서 Serivce는 Pod를 통해 실행되는 네트워크 애플리케이션을 네트워크에 노출시키는 가상의 컴포넌트다. Pod는 임시적인(ephemeral) 리소스임으로 Pod의 IP를 통해 접속하는 방법은 쉽지 않기 때문에 Service를 사용하여 Pod를 외부와 연동하도록 가이드한다.


Defining a Service

Service는 Pod, ConfgMap과 같은 K8S Object로 Kubernetes API를 사용하여 정의할 수 있다.
예를 들어 HTTP 9376, HTTPS 9377 port로 서비스하는 app.kubernetes.io/name: MyApp 라벨이 설정된 Pod가 있는 경우 아래와 같이 서비스를 정의할 수 있다.

apiVersion: v1
kind: Service
metadata:
    name: my-service
spec:
    selector:
        app.kubernetes.io/name: MyApp
    ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9376
    - name: https
      protocol: TCP
      port: 443
      targetPort: 9377

 

Service type

Service의 type을 설정하여 타입을 지정할 수 있다.

Cluster IP

클러스터 내부에만 서비스를 노출한다. 명시적으로 type을 지정하지 않으면 기본값으로 사용된다.
Ingress또는 Gateway를 사용하여 애플리케이션을 외부로 노출할 수 있다.
Traffic - Proxy - Service - Pod

apiVersion: v1
kind: Service
metadata:
    name: my-service
spec:
    type: ClusterIP # 생략 가능
    selector:
        app: MyApp
    ports:
        - protocol: TCP
          port: 80
          targetPort: 9376

 

NodePort

각 노드 IP에 정적인 Port를 사용하여 서비스를 노출한다. (NodePort 사용을 위해 cluster ip 주소가 설정된다.)
Traffic - Node(port) - Service - Pod

apiVersion: v1
kind: Service 
metadata:
name: my-service
spec:
    type: NodePort 
    selector:
        app: MyApp
    ports:
        - port: 80
          targetPort: 9376
          nodePort: 30002    # 외부 노출 Pont

NodePort의 설정으로 노출할 Port 번호를 설정할 수 있고, Port의 범위는 30000~32767이며, 지정하지 않은 경우 범위 안에서 임의로 부여된다.

 

LoadBalancer

외부 로드 밸러서를 사용하여 서비스를 외부에 노출한다.
Traffic - Load Balancer - Service - Pod

apiVersion: v1
kind: Service
metadata:
    name: my-service
spec:
    type: LoadBalancer
    selector:
        app: MyApp
    ports:
        - protocol: TCP
          targetPort: 9376
          port: 80
    clusterIP: 10.0.171.239
status:    
    loadBalancer:
        ingress:
        - ip: 192.0.2.127

 

ExternalName

서비스를 externalName 필드에 매핑한다.

apiVersion: v1
kind: Service
metadata:
    name: my-service
    namespace: prod
Spec:
    type: ExternalName
    externalName: my.database.example.com

selector 대신 DNS name을 정의할 때 사용한다.

 

 

Headless Service

로드 밸런싱과 단일 서비스 IP가 필요하지 않은 경우 클러스터 IP 주소에(spec.clusterIP)에 "None"를 지정하여 Headless Service를 생성할 수 있다. Headless Service의 경우 클러스터 IP가 할당되지 않으며, kube-proxy는 이러한 서비스를 처리하지 않으며 로드 밸런싱이나 프록싱을 수행하지 않는다.

apiVersion: v1
kind: Service
metadata:
    name: my-service
spec:
    clusterIP: None   # None으로 설정
    selector:
        app: MyApp
    ports:
    - protocol: TCP 
      targetPort: 9376
      port: 80

Headless Service를 사용하면 클라이언트는 원하는 Pod에 직접 연결할 수 있다. 클러스터의 DNS 서비스를 통해 제공되는 내부 DNS 레코드를 통해서 Headless Service로 등록된 Pod의 개별 Endpoint IP주소를 조회할 수 있다.

#### NodePort와 Headless 서비스 조회
$ kubectl get svc | grep zookeeper
zookeeper		NodePort	10.233.13.0	<none>		2181:30147/TCP
zookeeper-headless	ClusterIP		None		<none>		2181/TCP, 3888/TCP,2888/TCP


##### Headless 서비스 DNS 조회
$ kubect] exec dnsutil-pod -- nslookup zookeeper-headless
Server:	   10.233.0.3
Address 1:  10.233.0.3 kube-dns.kube-system.svc.cluster.local

Name: zookeeper-headless
Address 1: 10.233.92.254 zookeeper-2.zookeeper-headless.plaync.sc.cluster.local
Address 2: 10.233.93.120 zookeeper -1.zookeeper-headless.plaync.svc.cluster.local
Address 3: 10.233.95.29 zookeeper-.zookeeper-headless.plaync.sc.cluster.local


#####NodePort 서비스 DNS 조회
§ kubecti exec dnsutil-pod - - nslookup zookeeper
Server:	   10.233.0.3
Address 1:  10.233.0.3 kube-dns.kube-system.svc.cluster.local

Name: zookeeper
Address 1: 10.233.13.0 zookeeper.plaync.sc.cluster.local

 

 

참고

https://kubernetes.io/docs/concepts/services-networking/service/

'dev > kubernetes' 카테고리의 다른 글

nGrinder on K8S  (0) 2024.07.25
Kubernetes - Pods  (0) 2024.07.04