kubernetes

[따배쿠] Service - ClusterIP, NodePort, LoadBalancer, ExternalName

bbiyak2da 2024. 12. 7. 14:57

ClusterIP

  • Selector의 label이 동일한 파드들을 그룹으로 묶어 단일 진입점(=Cluster IP, Virtual IP) 생성
  • 클러스터 내부에서만 사용 가능
  • type 생략 시, default 값으로 10.96.0.0/12 범위에서 할당
  • Cluster IP 구성

 

예시

 

# Deployment 배포

root@master:~/Getting-Start-Kubernetes/7# vi deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webui
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webui
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.14

 

Deployment를 통해, Pod 3개(label이 app:webui)를 배포한다.

 

# 생성 및 확인

root@master:~/Getting-Start-Kubernetes/7# kubectl create -f deploy-nginx.yaml
deployment.apps/webui created
root@master:~/Getting-Start-Kubernetes/7# kubectl get pods -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP                NODE    NOMINATED NODE   READINESS GATES
webui-5f67dcf6d-2s58k   1/1     Running   0          13s   192.168.166.154   node1   <none>           <none>
webui-5f67dcf6d-9kgq2   1/1     Running   0          13s   192.168.104.59    node2   <none>           <none>
webui-5f67dcf6d-clh5q   1/1     Running   0          13s   192.168.104.58    node2   <none>           <none>

 

Deployment를 통해 Pod 3개가 배포되었다.

이제 Service를 배포해보자

 

# Service 파일 생성 및 배포

root@master:~/Getting-Start-Kubernetes/7# vi clusterip-nginx.yaml
apiVersion: v1
kind: Service
metadata:
  name: clusterip-service
spec:
  type: ClusterIP
  clusterIP: 10.100.100.100
  selector:
    app: webui
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

 

ClusterIP는 10.100.100.100 이다.

10.100.100.100:80으로 접근 시, label이 app: webui인 pod로 접근이 된다.

 

root@master:~/Getting-Start-Kubernetes/7# kubectl create -f clusterip-nginx.yaml
service/clusterip-service created

 

 

# 확인

root@master:~/Getting-Start-Kubernetes/7# kubectl get service
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
clusterip-service   ClusterIP   10.100.100.100   <none>        80/TCP    3m3s
kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP   34d

 

# 상세 확인

root@master:~/Getting-Start-Kubernetes/7# kubectl describe svc clusterip-serviceName:              clusterip-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=webui
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.100.100.100
IPs:               10.100.100.100
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         192.168.104.58:80,192.168.104.59:80,192.168.166.154:80
Session Affinity:  None
Events:            <none>

 

kubectl describe svc ~ 명령어로 상세 확인 가능하다.

ClusterIP는 10.100.100.100 이고

Pod 1 (192.168.104.58), Pod 2 (192.168.104.59), Pod 3 (192.168.166.154)로 로드밸런싱 된다.

 

NodePort

  • 외부에서 접근할 수 있도록, 모든 노드를 대상으로 외부 접속 가능한 포트를 예약
  • Default NodePort 범위 : 30000-32767
    • NodePort를 지정하지 않을 시, 30000-32767 범위에서 random하게 지정
  • Cluster IP + Node Port 구성

 

예시

# Nodeport 파일 생성 및 배포

root@master:~/Getting-Start-Kubernetes/7# vi nodeport-nginx.yaml
apiVersion: v1
kind: Service
metadata:
  name: nodeport-service
spec:
  type: NodePort
  clusterIP: 10.100.100.200
  selector:
    app: webui
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30200
root@master:~/Getting-Start-Kubernetes/7# kubectl create -f nodeport-nginx.yaml
service/nodeport-service created

 

# 확인

root@master:~/Getting-Start-Kubernetes/7# kubectl get svc
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AG                                                                                    E                                                                                   m
kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP        34                                                                                    d
nodeport-service    NodePort    10.100.100.200   <none>        80:30200/TCP   81                                                                                    s

 

clusterIP 10.100.100.200, port는 80

nodeport는 30200으로 배포된 것을 확인할 수 있다.

 

# node1에서 NodePort 확인

 

root@master:~/Getting-Start-Kubernetes/7# ssh node1
Welcome to Ubuntu 24.04.1 LTS (GNU/Linux 6.8.0-1018-azure x86_64)
root@node1:~# iptables -t nat -L KUBE-NODEPORTS | column -t
Chain                      KUBE-NODEPORTS  (1   references)                                                                                                         
target                     prot            opt  source       destination                                                                                            
KUBE-EXT-QATUYZLPU4I4HE4S  tcp             --   anywhere     anywhere     /*  de                                                                                    fault/nodeport-service  */  tcp  dpt:30200

 

LoadBalancer

  • Public 클라우드에서 운영 가능 (AWS, Azure, GCP 등)
  • Cluster IP + Node Port + 외부에서 LoadBalancer를 자동으로 구성 요청
  • NodePort를 예약 후, 해당 NodePort로 외부 접근 허용
  • ex. Client -> Azure LoadBalancer 공용 IP로 접속 -> Load Balancer은 node 1,2,3 중 하나로 포워딩 -> node1로 접근 -> node1이 pod 1 (10.44.0.1), pod 2 (10.45.0.1), pod 3 (10.36.0.1.)로 로드밸런싱

 

예시

# Loadbalancer 파일 생성 및 배포

root@master:~/Getting-Start-Kubernetes/7# cat loadbalancer-nginx.yaml
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service
spec:
  type: LoadBalancer
  selector:
    app: webui
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80                                                                         P   71s
root@master:~/Getting-Start-Kubernetes/7# kubectl create -f loadbalancer-nginx.y                                                                                    aml
service/loadbalancer-service created

 

# 확인

root@master:~/Getting-Start-Kubernetes/7# kubectl get svc
NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                                            AGE
kubernetes             ClusterIP      10.96.0.1        <none>        443/TCP                                                                                            86s
loadbalancer-service   LoadBalancer   10.104.219.95    <pending>     80:31523/TC                                                                                    P   27s
nodeport-service       NodePort       10.100.100.200   <none>        80:30200/TC

 

Loadbalancer service도 동일하게 Cluster IP와 NodePort가 생성된다.

그러나 차이점은 External IP가 구성된다는 점이다.

지금은 Pending으로 표시되지만, Public Cloud의 LB와 연동 시 LB의 External IP가 표시된다.

 

ExternalName

  • 클러스터 내부에서 외부 서비스에 접속하기 위해 DNS 이름으로 참조할 수 있게 해주는 서비스
    • DNS 매핑: ExternalName 서비스는 externalName 필드를 사용하여 외부 DNS 이름을 지정합니다. 이 이름은 클러스터 내에서 해당 서비스의 이름으로 사용됩니다.
    • 간단한 설정: ExternalName 서비스를 설정하는 것은 매우 간단합니다. YAML 파일에서 kind를 Service로 설정하고, type을 ExternalName으로 지정한 후, externalName 필드에 외부 DNS 이름을 입력하면 됩니다.
    • 클러스터 내 접근: 클러스터 내의 Pod는 ExternalName 서비스를 통해 외부 서비스를 마치 클러스터 내의 서비스처럼 접근할 수 있습니다. 예를 들어, my-external-service라는 ExternalName 서비스가 example.com을 가리키면, 클러스터 내의 Pod는 my-external-service를 통해 example.com에 접근할 수 있습니다.
  • 즉, ExternalName은 DNS을 지원한다.
  • 앞에서 다룬 ClusterIP, NodePort, LoadBalancer와는 조금 다른 개념
    • NodePort와 Load Balancer는 외부에서 클러스터 내부의 서비스에 접근하기 위해 사용
    • 그러나, ExternalName은 클러스터 내부의 Pod가 외부 서비스에 도메인 이름을 통해 접근할 때 사용

*default.svc.cluster.local : 쿠버네티스가 사용하는 도메인 이름

 

예시

# ExternalName 파일 생성 및 배포

root@master:~/Getting-Start-Kubernetes/7# vi external-name.yaml
apiVersion: v1
kind: Service
metadata:
  name: externalname-svc
spec:
  type: ExternalName
  externalName: google.com
root@master:~/Getting-Start-Kubernetes/7# kubectl create -f external-name.yaml
service/externalname-svc created

 

# 확인

root@master:~/Getting-Start-Kubernetes/7# kubectl get svc
NAME               TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
externalname-svc   ExternalName   <none>       google.com    <none>    22s
kubernetes         ClusterIP      10.96.0.1    <none>        443/TCP   8m10s

 

# Pod 배포

root@master:~/Getting-Start-Kubernetes/7# kubectl run testpod -it --image=centos:7

 

# Pod에서 curl을 통한 접속

[root@testpod /]#curl externalname-svc.default.svc.cluster.local

 

curl exteralname-svc.default.svc.cluster.local 날리면 외부 사이트(ex. google.com)으로 연결됨

ex) curl extername-svc.default.svc.cluster.local

-------------> google.com으로 리다이렉트 되어 연결

 


참고 영상

https://www.youtube.com/watch?v=WaJyY5KvZj8

 

참고 문서

https://velog.io/@rockwellvinca/kubernetes-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EB%85%B8%EC%B6%9C%EB%B2%95-Externalname

 

[kubernetes] 애플리케이션 노출법 Ⅲ (Externalname)

똑같은 ☸️ k8s의 Service의 종류이지만, 기존 노드 포트, 로드밸런서와는 동작하는 방향이 반대이다.NodePort와 로드 밸런서는 외부에서 클러스터 내부의 서비스에 접근하기 위해 사용한다.반면 Ext

velog.io