쿠버네티스에서 엔드포인트슬라이스는 여러 네트워크 엔드포인트에 대한 참조를 포함한다. 컨트롤 플레인은 셀렉터가 지정된 모든 쿠버네티스 서비스에 대해 자동으로 엔드포인트슬라이스를 생성한다. 이러한 엔드포인트슬라이스는 서비스 셀렉터와 매치되는 모든 파드에 대한 참조를 포함한다. 엔드포인트슬라이스는 IP 패밀리, 프로토콜, 포트 번호 및 서비스 이름의 고유한 조합에 따라 네트워크 엔드포인트를 그룹화한다. 엔드포인트슬라이스 오브젝트의 이름은 유효한 DNS 서브도메인 이름이어야 한다.
다음은 example 쿠버네티스 서비스가 소유한 엔드포인트슬라이스
오브젝트의 예시이다.
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: example-abc
labels:
kubernetes.io/service-name: example
addressType: IPv4
ports:
- name: http
protocol: TCP
port: 80
endpoints:
- addresses:
- "10.1.2.3"
conditions:
ready: true
hostname: pod-1
nodeName: node-1
zone: us-west2-a
기본적으로, 컨트롤 플레인은 각각 100개 이하의 엔드포인트를
갖도록 엔드포인트슬라이스를
생성하고 관리한다. --max-endpoints-per-slice
kube-controller-manager
플래그를 사용하여 최대 1000개까지 구성할 수 있다.
엔드포인트슬라이스는 kube-proxy가 내부 트래픽을 라우팅할 때 기준으로 삼는 정보다.
엔드포인트슬라이스는 다음 주소 유형을 지원한다.
각 엔드포인트슬라이스 오브젝트는 특정한 IP 주소 유형을 나타낸다. IPv4와 IPv6를 사용할 수 있는 서비스가 있을 경우, 최소 두 개의 엔드포인트슬라이스 오브젝트가 존재한다(IPv4용 하나, IPv6용 하나).
엔드포인트슬라이스 API는 컨슈머에게 유용한 엔드포인트에 대한 조건을 저장한다.
조건은 serving, terminating 및 ready 세 가지가 있다.
serving 조건은 엔드포인트가 현재 응답을 제공하고 있으며,
따라서 서비스 트래픽의 대상으로 사용해야 함을 나타낸다. 파드를 백엔드로 하는 엔드포인트의 경우,
이 조건은 파드의 Ready 조건에 대응한다.
terminating 조건은 엔드포인트가 종료 중임을 나타낸다.
파드를 백엔드로 하는 엔드포인트의 경우 파드가 처음 삭제될 때,
즉 삭제 타임스탬프가 설정되는 시점에 이 조건이 설정된다.
이 시점에는 대부분 파드의 컨테이너가 아직 종료되지 않은 상태다.
서비스 프록시는 일반적으로 terminating 상태인 엔드포인트를 무시하지만,
사용 가능한 모든 엔드포인트가 terminating 상태라면 serving 및
terminating 상태인 엔드포인트로 트래픽을 전달할 수 있다. (이는
해당 엔드포인트의 기반이 되는 파드가 롤링 업데이트되는 동안 서비스 트래픽이
유실되지 않도록 하는 데 도움이 된다.)
ready 조건은 기본적으로
“serving 상태이면서 terminating 상태가 아닌지”를 간단히 확인할 수 있는 방법이다. (다만
spec.publishNotReadyAddresses가 true로
설정된 서비스에서는 ready 조건도 항상 true가 된다.)
엔드포인트슬라이스의 각 엔드포인트에는 관련 토폴로지 정보가 포함될 수 있다. 토폴로지 정보에는 엔드포인트의 위치와 해당 노드 및 영역에 관한 정보가 포함된다. 이 정보는 엔드포인트슬라이스의 다음 엔드포인트별 필드에서 확인할 수 있다.
nodeName - 이 엔드포인트가 위치한 노드의 이름이다.zone - 이 엔드포인트가 위치한 영역이다.대부분의 경우, 컨트롤 플레인(특히, 엔드포인트슬라이스 컨트롤러)는 엔드포인트슬라이스 오브젝트를 생성하고 관리한다. 다른 엔티티나 컨트롤러가 추가 엔드포인트슬라이스 집합을 관리하게 할 수 있는 서비스 메시 구현과 같이 엔드포인트슬라이스에 대한 다양한 유스케이스가 있다.
여러 엔티티가 서로 간섭하지 않고 엔드포인트슬라이스를
관리할 수 있도록 쿠버네티스는 엔드포인트슬라이스를 관리하는
엔티티를 나타내는 endpointslice.kubernetes.io/managed-by
레이블을
정의한다.
엔드포인트슬라이스 컨트롤러는 관리하는 모든 엔드포인트슬라이스에 레이블의 값으로
endpointslice-controller.k8s.io를 설정한다. 엔드포인트슬라이스를
관리하는 다른 엔티티도 이 레이블에 고유한 값을 설정해야 한다.
대부분의 유스케이스에서, 엔드포인트슬라이스 오브젝트가 엔드포인트를
추적하는 서비스가 엔드포인트슬라이스를 소유한다. 이 소유권은 각 엔드포인트슬라이스의 소유자
참조와 서비스에 속한 모든 엔드포인트슬라이스의 간단한 조회를 가능하게 하는
kubernetes.io/service-name 레이블로 표시된다.
각 엔드포인트슬라이스에는 리소스 내의 모든 엔드포인트에 적용되는 포트 집합이 있다. 서비스에 명명된 포트를 사용하면 동일한 명명된 포트에 대해 파드마다 대상 포트 번호가 달라질 수 있으므로 서로 다른 엔드포인트슬라이스가 필요하다.
컨트롤 플레인은 엔드포인트슬라이스를 최대한 채우려고 하지만, 이를 적극적으로 재조정하지는 않는다. 로직은 비교적 단순하다:
중요한 점은 세 번째 단계에서 엔드포인트슬라이스를 모두 완전히 채우는 것보다 엔드포인트슬라이스 업데이트를 줄이는 것을 우선한다는 것이다. 예를 들어 추가할 새 엔드포인트가 10개이고, 기존 엔드포인트슬라이스 2개에 각각 엔드포인트 5개를 더 넣을 공간이 있더라도 이 방식은 기존 엔드포인트슬라이스 2개를 채우는 대신 새 엔드포인트슬라이스를 생성한다. 다시 말해 엔드포인트슬라이스 하나를 생성하는 것이 여러 엔드포인트슬라이스를 업데이트하는 것보다 낫다.
각 노드에서 kube-proxy를 실행하고 엔드포인트슬라이스를 관찰하면, 엔드포인트슬라이스에 대한 모든 변경 사항이 클러스터의 모든 노드로 전송되기 때문에 상대적으로 비용이 많이 소요된다. 이 방법은 여러 엔드포인트슬라이스가 가득 차지 않은 결과가 발생할지라도, 모든 노드에 전송해야 하는 변경 횟수를 의도적으로 제한하기 위한 것이다.
실제로 이러한 이상적이지 않은 분배는 드물 것이다. 엔드포인트슬라이스 컨트롤러가 처리하는 변경은 대부분 기존 엔드포인트슬라이스에 들어갈 만큼 작고, 그렇지 않더라도 새 엔드포인트슬라이스가 곧 필요해질 가능성이 높다. 디플로이먼트의 롤링 업데이트에서도 모든 파드와 그에 대응하는 엔드포인트가 교체되면서 엔드포인트슬라이스가 자연스럽게 다시 채워진다.
엔드포인트슬라이스 변경의 특성상 엔드포인트는 동시에 둘 이상의 엔드포인트슬라이스에 나타날 수 있다. 서로 다른 엔드포인트슬라이스 오브젝트의 변경 사항이 쿠버네티스 클라이언트의 워치(watch)/캐시에 서로 다른 시점에 도착할 수 있으므로 자연스럽게 발생하는 현상이다.
엔드포인트슬라이스 API 클라이언트는 서비스와 연관된 기존 엔드포인트슬라이스를 모두 순회하여 고유한 네트워크 엔드포인트의 전체 목록을 구성해야 한다. 엔드포인트는 서로 다른 엔드포인트슬라이스에 중복될 수 있음에 유의한다.
엔드포인트를 집계하고 중복을 제거하는 방법에 대한 레퍼런스 구현은 kube-proxy의
EndpointSliceCache 코드에서 찾을 수 있다.
엔드포인트슬라이스 API는 기존 엔드포인트(Endpoints) API를 대체한다. 엔드포인트 리소스를 기반으로 kube-proxy가 트래픽을 라우팅할 것으로 예상하는 기존 컨트롤러 및 사용자 워크로드와의 호환성을 유지하기 위해, 클러스터의 컨트롤 플레인은 사용자가 생성한 엔드포인트 리소스 대부분을 해당 엔드포인트슬라이스로 미러링한다.
(그러나 이 기능은 엔드포인트 API의 나머지 기능과 마찬가지로 사용 중단되었다. 셀렉터가 없는 서비스의 엔드포인트를 수동으로 지정하려는 사용자는 엔드포인트 리소스를 생성한 뒤 미러링되도록 하는 대신, 엔드포인트슬라이스 리소스를 직접 생성해야 한다.)
컨트롤 플레인은 다음을 제외하고 엔드포인트 리소스를 미러링한다.
endpointslice.kubernetes.io/skip-mirror 레이블이
true로 설정되어 있다.control-plane.alpha.kubernetes.io/leader
어노테이션이 있다.개별 엔드포인트 리소스는 여러 엔드포인트슬라이스로 변환될 수 있다. 엔드포인트 리소스에 여러 하위 집합이 있거나 여러 IP 패밀리(IPv4 및 IPv6)의 엔드포인트가 포함된 경우 변환이 일어난다. 하위 집합당 최대 1000개의 주소가 엔드포인트슬라이스에 미러링된다.