본문 바로가기

네트워크/k8s

[k8s] 24. Service - Headless, Endpoint, ExternalName

Service에 대해 자세히 알아보자

  • 우선 이전에 배운 내용을 복습

내부망에서 접속

  • 공유기를 통해서 시작하는 아이피에서 내부망이 형성
  • 세 대의 서버를 이용해서 Master와 Node로 쿠버네티스 클러스터가 만들어짐
  • 클러스터에는 파드를 위한 아이피 대역(20으로 시작), 서비스를 위한 아이피 대역이 있음(10으로 시작)
  • 파드는 20으로 시작하고, 서비스는 10으로 시작함
  • 서비스와 파드1, 파드2는 연결되어 있음
  • 서비스는 쿠버네티스의 서버에서만 접근 가능 --> 특정 파드에 클러스터 아이피를 단 건 내부 관리자만 접근할 수 있게 하는 용도
  • 내부망에 여러 기기가 있을 수 있지만 서비스의 아이피를 호출할 순 없음
  • 내부망에 있는 기기가 접근하려면 노드포트(30000) 서비스를 만들어야 함
  • 쿠버네티스 관리자는 내부망에 있는 사람들에게 세 대의 서버 중 하나의 아이피와 포트(30000)을 알려주면, 내부망에 있는 기기들이 서비스에 접근 가능해짐

외부망에서도 접속할래

  • 구글 클라우드, AWS, Azure와 같은 클라우드 프로바이더를 사용하여 쿠버네티스를 구축하면
  • LoadBalacner 타입의 서버를 만들어 노드포트(30001)를 생성하고
  • 해당 포트에 LoadBalacner가 연결되고, 외부망 사람은 1.23.58.1을 통해서 서비스 접근 가능

정리

  • 관리자건, 내부망 유저건, 외부망 유저건 쿠버네티스망에 특히 파드에 접근하기 위해
  • ClusterIP, NodePort, LoadBalancer를 만들었던 것

파드의 입장에서 생각해보자

파드A가 파드B에 접속하려면 어떻게 해야 할까

  • 파드A - 파드B 직접 연결
  • 서비스를 통한 연결이 있는데
  • 파드A, 파드B, 서비스가 동시에 배포가 될 수 있어서 파드A에 아이피를 넣을 수가 없음
  • 아이피는 생성 시 동적으로 할당되기 때문
  • 또 파드B가 죽어서 재생성되면 아이피가 변경될 수 있음
  • 그래서 Headless와 DNS Server가 필요함

파드가 외부와 연결하려고 할 때

  • 파드가 외부 특정사이트에서 데이터를 가져오는 상황에서 사이트가 바뀌면
  • 바뀐 사이트 때문에 파드를 수정하고 재배포하긴 좀 그럼
  • 이 때 서비스의 ExternalName을 이용하여 외부 연결을 파드의 수정없이 연결하도록 함

새로운 개념을 적용하여 다시 서비스를 살펴보자

1. pod는 service1, 내부망 user, 외부망 Google에 접속하고 싶어 → DNS Server

  • 쿠버네티스 클러스터 안에는 DNS Server가 존재함
  • DNS Server에는 서비스의 도메인 이름과 아이피가 저장되어 있음
  • pod가 service1에 대한 도메인 이름을 질의하면 해당 아이피를 알려줌
  • 내부망에서도 DNS Server가 구축되어 있으면
  • 내부서버가 생겼을 때 해당 이름과 아이피가 등록되어 있음
  • pod가 user1을 찾으면 쿠버네티스 클러스터 DNS에 없으면 DNS 매카니즘상 상위 DNS인 내부망 DNS를 찾고 알려줌
  • 외부에 있는 사이트도 도메인 이름이 외부 DNS에 등록되어 있기 때문에 pod가 Google을 찾으면
  • 부모의 부모 DNS를 찾아 Google의 아이피 주소를 알 수 있게됨
  • 이처럼 pod가 접속하고자 하는 아이피를 몰라도 DNS를 통해서 아이피를 알 수 있음

2. pod는 pod1이나 pod2에 접속하고 싶어 → Headless Service

  • pod1이나 pod2를 선택해서 연결하고 싶을 때 pod에 headless service2를 연결함
  • DNS 서버에 파드의 이름과 서비스의 이름이 붙여져서 도메인 이름으로 등록됨
    • pod1.service2, pod2.service2
  • pod의 입장에서 pod1에 접근하기 위해 아이피 주소는 필요 없고, 도메인 이름으로 접근 가능

3. pod는 외부사이트에서 데이터를 가져오는데, 이 사이트가 변경되는걸 고려하고 싶어 → ExternalName

  • ExternalName service3에 google 도메인 이름을 넣으면 DNS를 타고 타서 Google 아이피를 가져올 수 있음
  • 추후 google을 github으로 service3의 ExternalName만 변경하면 google이 아닌 github에서 가져오게 할 수 있음

Headless, Endpoint, ExternalName에 대해 제대로 알아보자

1. Headless

Pod가 Service에 연결하고 싶을 때

  • default 네임스페이스에 파드2개와 서비스가 연결되어 있음
  • 이 때 Pod가 서비스에 연결하고 싶을 때를 생각해보자
  • 서비스는 ClusterIP고 파드나 서비스의 아이피는 동적으로 만들어지는데 어떻게 해야할까
  • DNS가 해결책이고, DNS의 이름은 cluster.local
  • DNS에는 파드건 서비스건 생성하면 긴 도메인 이름과 아이피가 저장됨
  • 파드의 입장에서 서비스의 도메인 이름을 DNS 질의해서 가져옴
  • 그러니까 파드는 서비스의 이름만 알아도 서비스에 접근 가능함
  • 따라서 서비스의 이름은 사용자가 만드니까 미리 파드에 서비스 이름을 저장해둘 수 있음 --> 해결!

DNS의 구조

  • service1.default.svc.cluster.local
    • 서비스는 서비스 이름.네임스페이스.서비스의 약어인 svc.DNS 이름으로 구성
  • 20-109-5-11.default.pod.cluster.local
    • 파드는 아이피.네임스페이스.파드를 뜻하는 pod.DNS 이름으로 구성
  • 이러한 긴 이름을 FQDN = Full Qualified Domain Name이라고 함
  • 서비스는 앞부분 service1만 쓰면 되는데 파드는 풀네임으로 다 써야함

Pod가 pod4에 연결하고 싶을 때

  • 똑같은 상황에서 파드가 파드4에 직접 연결하고 싶으면 서비스를 Headless로 만들어야 함
  • 일단 서비스 이름이 headless1임 ㅋ
  • Headless를 만드는 법 --> clusterIP: None
  • 파드4, 파드5도 hostname에 파드의 호스트네임을 넣어야 하고(pod4, pod5) subdomain에 headless1을 넣어야함
  • 이렇게 만들면 DNS에서 서비스는 Headless가 없을 때랑 똑같이 구성됨
  • 그런데 서비스의 아이피가 없기 때문에 서비스의 이름을 호출하면 연결되어 있는 모든 파드의 아이피를 줌
  • 파드는 기존에 아이피.default식으로 구성되었는데, headless에서는 pod4.headless1.default식으로 구성됨
  • 게다가 파드는 앞에 pod4.headless1와 같이 앞부분만 호출하면 됨
  • 따라서 Pod는 pod4나 pod5에 연결하고 싶으면 pod4.headless1의 이름만 저장해 놓으면 됨 --> 해결!

2. Endpoint

  • 서비스와 파드를 연결할 때 라벨을 통해서 연결했음
  • 근데 이건 사용자 입장이지 사실 쿠버네티스는 Endpoint를 만들어서 연결고리를 관리했음
  • Endpoint는 서비스와 동일 이름을 가지고 있고, Endpoint에는 파드의 아이피 정보를 담고있음
  • 이 규칙을 알면 라벨과 셀렉터를 안 만들어도 파드와 서비스의 연결이 가능함
  • 서비스와 파드를 만들 때, Endpoint를 직접 만들면 됨
  • 서비스의 이름과 파드의 아이피 정보를 넣으면 되니까 ㅎㅎ
  • 이 때, Endpoint에 파드의 아이피가 아니라 외부의 아이피 주소를 넣을 수도 있음(근데 그림에서 service3의 아이피는 이상한데....)

3. ExternalName

  • 서비스에 ExternalName(왜 그림은 externalNmae냐..)을 넣어서 도메인 이름을 넣을 수 있음
  • DNS cache가 내부와 외부 DNS를 찾아서 아이피를 알아냄
  • 파드는 서비스를 가리키고만 있으면 서비스에서 필요할 때마다 도메인 주소를 변경할 수 있어서 파드를 수정하고 재배포 안 해도 됨

출처

인프런 - 대세는 쿠버네티스