본문 바로가기

Kubernetes

쿠버네티스 서비스 기능

세션 어피니티

서비스에서는 세션 어피니티(Session Affinity)를 활성화할 수 있다. ClusterIP 서비스에서 활성화한 경우 포드에서 ClusterIP로 보내진 트래픽은 서비스에 연결된 어느 하나의 포드에 전송된 후 다음 트래픽도 계속 같은 포드에 보내진다. 백엔드 단에서 세션을 사용하는 경우 유용한 부가 기능이다.

 

세션 어피니티에 대한 설정은 spec.sessionAffinity와 spec.sessionAffinityConfig를 사용한다. 이 세션 어피니티의 기능은 각 쿠버네티스 노드에 iptables로 구현되어 있으며 spec.sessionAffinity 기본값은 None이다. 

 

apiVersion: v1
kind: Service
metadata:
  name: sample-sesison-affinity
spec:
  type: LoadBalancer
  selector:
    app: sample-app
  ports:
  - name: http-port
    protocol: TCP
    port: 8080
    targetPort: 80
    nodePort: 30084
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10

 

노드 간 통신 제외와 발신 측 IP 주소 유지

NodePort 서비스와 LoadBalancer 서비스에서 쿠버네티스 노드에 도착한 요청은 노드를 통해 포드에도 로드 밸런싱하게 되어 있으므로 불필요한 2단계 로드 밸런싱이 이루어진다. 이 2단계 로드 밸런싱은 균일하게 요청을 분산하기 쉽지만 불필요한 레이턴시 오버헤드가 발생하거나 밸런싱을 수행할 때 네트워크 주소 변환(NAT)이 이루어질 수 있다. 

 

데몬셋과 같이 하나의 노드에 하나의 포드가 배치되기 때문에 굳이 다른 노드의 포드에 전송하지 않고 같은 노드에만 통신하고 싶은 경우가 있을 시 spec.externalTrafficPolicy를 사용할 수 있다. 기본값은 Cluster이며 Local로 지정할 경우 노드에 트래픽이 도착한 후 노드 간 로드 밸런싱을 막는다.

 

NodePort 서비스의 경우 해당 노드에 포드가 없다면 요청에 응답할 수 없음으로 사용하지 않는 것이 좋다. 하지만 LoadBalancer 서비스는 별도로 헬스 체크용 NodePort가 할당되기 때문에 포드가 존재하지 않는 노드에는 로드 밸런서에서 요청이 전송되지 않는다. 

 

헤드리스 서비스

헤드리스(Headless) 서비스는 대상이 되는 개별 포드의 IP주소가 직접 반환되는 서비스다. 헤드리스 서비스는 로드 밸런싱을 하기 위한 IP 주소는 제공되지 않고 DNS 라운드 로빈을 이용한 엔드포인트를 제공한다. 서비스 명으로 포드의 IP주소를 가져올수 있고 스테이트풀셋만이 포드명으로 IP주소를 가져올 수 있다.

 

헤드리스 서비스를 생성하려면 다음 두 가지 조건을 만족해야 한다.

  • 서비스의 spec.type이 ClusterIP일 것
  • 서비스의 spec.clusterIP가 None 일 것
  • 스테이트풀셋일 경우 metadata.name이 spec.serviceName과 같을 것

 

apiVersion: v1
kind: Service
metadata:
  name: sample-headless
spec:
  type: ClusterIP
  clusterIP: None
  ports:
  - name: "http-port"
    protocol: "TCP"
    port: 80
    targetPort: 80
  selector:
    app: sample-app

 

서비스 이름 해석은 '서비스명.네임스페이스명.svc.cluster.local'로 질의한다. 스테이트풀셋의 경우만 포드명으로 이름 해석이 가능하지만 포드에 설정을 추가하여 포드명으로 이름 해석을 할 수도 있다. 포드의 spec.hostname과 헤드리스 서비스명과 동일한 spec.subdomain 설정을 추가하면 포드명으로 질의할 수 있다.

 

이 경우 'hostname.subdomain/서비스명.네임스페이스명.svc.cluster.local'로 이름 해석을 할 수 있다.

 

ExternalName

ExternalName 서비스는 일반적인 서비스 리소스와 달리 서비스명의 이름 해석에 있어 외부 도메인을 반환한다. 예를 들어 외부 소스에서 데이터를 당겨와야 하는 상황이 생기고 외부 소스의 주소가 바뀔 수 있다면 ExternalName 서비스를 만들어 내부 DNS에 등록되는 것처럼 사용할 수 있다.

 

apiVersion: v1
kind: Service
metadata:
  name: sample-externalname
  namespace: default
spec:
  type: ExternalName
  externalName: external.example.com