리스
리스 (Leases)
분산 시스템에는 공유 리소스를 잠그고 집합(set)의 구성원 사이에서 활동을 조정하는 메커니즘인 리스(leases) 가 필요한 경우가 많아요.
Kubernetes에서 리스 개념은 coordination.k8s.io API 그룹의 Lease 객체로 표현되며, 노드 하트비트(heartbeat)와 컴포넌트 수준 리더 선출(leader election) 같은 시스템 핵심 기능에 사용됩니다.
노드 하트비트 (Node heartbeats)
Kubernetes는 Lease API를 사용해서 kubelet 노드 하트비트를 Kubernetes API 서버에 전달해요. 모든 Node에 대해 kube-node-lease 네임스페이스에 이름이 일치하는 Lease 객체가 있어요. 내부적으로 모든 kubelet 하트비트는 이 Lease 객체에 대한 update 요청으로, Lease의 spec.renewTime 필드를 갱신합니다. Kubernetes 컨트롤 플레인은 이 필드의 타임스탬프를 사용해서 이 Node의 가용성을 판단해요.
자세한 내용은 Node Lease 객체를 참고하세요.
리더 선출 (Leader election)
Kubernetes는 Lease를 사용해서 어떤 순간에도 컴포넌트의 인스턴스가 하나만 실행되도록 보장하기도 해요. 이는 HA 구성에서 kube-controller-manager와 kube-scheduler 같은 컨트롤 플레인 컴포넌트가 사용하는데, 컴포넌트의 인스턴스 하나만 활발히 실행되고 다른 인스턴스는 대기해야 하거든요.
Kubernetes가 Lease API 위에서 어떤 컴포넌트 인스턴스가 리더로 작동할지 선택하는 방법을 배우려면 coordinated leader election을 읽어보세요.
종료 시 kube-controller-manager 잠금 해제
FEATURE STATE: Kubernetes v1.36 [alpha] (기본적으로 비활성화)
ControllerManagerReleaseLeaderElectionLockOnExit 기능 게이트가 활성화되면 kube-controller-manager는 잠금의 TTL이 만료되기를 기다리는 대신, 리더 전환 동안 리더 선출 잠금을 적극적으로 해제해요. 이로써 ...
API 서버 아이덴티티 (API server identity)
Kubernetes v1.26부터 각 kube-apiserver는 Lease API를 사용해서 자신의 아이덴티티를 시스템 나머지에 공개해요. 그 자체로 특별히 유용하진 않지만, 클라이언트가 Kubernetes 컨트롤 플레인을 운영하는 kube-apiserver 인스턴스가 몇 개인지 발견할 수 있는 메커니즘을 제공합니다.
kube-apiserver 리스의 존재는 각 kube-apiserver 사이의 조정이 필요한 미래의 기능을 가능하게 해줘요.
kube-system 네임스페이스에서 이름이 apiserver-<sha256-hash>인 lease 객체를 확인하면 각 kube-apiserver가 소유한 Lease를 검사할 수 있어요. 또는 라벨 셀렉터 apiserver.kubernetes.io/identity=kube-apiserver를 사용할 수도 있습니다:
리스 이름에 쓰인 SHA256 해시는 그 API 서버가 보는 OS 호스트 이름을 기반으로 해요. 각 kube-apiserver는 클러스터 안에서 고유한 호스트 이름을 사용하도록 구성되어야 합니다. 같은 호스트 이름을 쓰는 새 kube-apiserver 인스턴스는 새 Lease 객체를 만들지 않고, 새 holder 아이덴티티로 기존 Lease를 인계받아요. kubernetes.io/hostname 라벨 값을 확인하면 kube-apiserver가 사용하는 호스트 이름을 알 수 있습니다:
apiVersion: coordination.k8s.io/v1
kind: Lease
metadata:
creationTimestamp: "2023-07-02T13:16:48Z"
labels:
apiserver.kubernetes.io/identity: kube-apiserver
kubernetes.io/hostname: master-1
name: apiserver-07a5ea9b9b072c4a5f3d1c3702
namespace: kube-system
resourceVersion: "334899"
uid: 90870ab5-1ba9-4523-b215-e4d4e662acb1
spec:
holderIdentity: apiserver-07a5ea9b9b072c4a5f3d1c3702_0c8914f7-0f35-440e-8676-7844977d3a05
leaseDurationSeconds: 3600
renewTime: "2023-07-04T21:58:48.065888Z"
더 이상 존재하지 않는 kube-apiserver의 만료된 리스는 새 kube-apiserver가 1시간 후에 가비지 컬렉션해요.
APIServerIdentity 기능 게이트를 비활성화하면 API 서버 아이덴티티 리스를 끌 수 있어요.
워크로드 (Workloads)
자신만의 워크로드도 Lease에 대한 자신만의 사용을 정의할 수 있어요. 예를 들어 리더(primary/leader) 멤버가 다른 멤버가 하지 않는 작업을 수행하는 커스텀 컨트롤러를 실행할 수 있어요. 컨트롤러 복제본이 Kubernetes API를 사용해서 조정하며 리더를 선택(선출)할 수 있도록 Lease를 정의합니다.
Lease를 사용한다면 그 Lease의 이름을 제품이나 컴포넌트와 명확하게 연결되도록 정의하는 게 좋은 습관이에요. 예를 들어 Example Foo라는 컴포넌트가 있다면 example-foo라는 Lease 이름을 쓰세요.
클러스터 운영자나 다른 최종 사용자가 컴포넌트의 여러 인스턴스를 배포할 수 있다면 이름 접두사를 선택하고 이름 충돌을 피하기 위한 메커니즘(예: Deployment 이름의 해시)을 골라서 Lease에 적용하세요.
같은 결과를 얻기만 하면 다른 접근 방식도 사용할 수 있어요: 서로 다른 소프트웨어 제품이 서로 충돌하지 않으면 됩니다.