Kubernetes 확장하기
Kubernetes 확장하기 (Extending Kubernetes)
Kubernetes 클러스터의 동작을 바꾸는 다양한 방법이 있어요. Kubernetes는 고도로 구성 가능하고 확장 가능해서, Kubernetes 프로젝트 코드를 포크(fork)하거나 패치를 제출할 필요가 거의 없습니다.
이 가이드는 Kubernetes 클러스터를 커스터마이즈하는 옵션을 설명해요. 주로 자신의 작업 환경의 필요에 맞게 Kubernetes 클러스터를 적응시키는 방법을 이해하려는 클러스터 운영자를 대상으로 합니다. 미래의 플랫폼 개발자나 Kubernetes 프로젝트 기여자(Project Contributors)가 되려는 개발자에게도, 어떤 확장 지점과 패턴이 존재하는지, 그리고 그 트레이드오프와 한계에 대한 입문서로서 유용할 거예요.
커스터마이즈 접근 방식은 크게 두 가지로 나뉩니다.
- 구성(configuration) – 명령줄 인자, 로컬 구성 파일, API 리소스만 변경하는 것.
- 확장(extensions) – 추가 프로그램, 추가 네트워크 서비스, 또는 둘 다를 실행하는 것.
이 문서는 주로 확장에 관한 것입니다.
구성 (Configuration)
구성 파일과 명령 인자는 온라인 문서의 Reference 섹션에 문서화되어 있으며, 각 바이너리에 페이지가 있어요.
kube-apiserverkube-controller-managerkube-schedulerkubeletkube-proxy
명령 인자와 구성 파일은 호스팅된 Kubernetes 서비스나 관리형 설치가 있는 배포판에서는 항상 변경 가능한 것은 아니에요. 변경 가능한 경우에도 보통 클러스터 운영자만 변경할 수 있습니다. 또한 미래 Kubernetes 버전에서 변경될 수 있고, 설정 시 프로세스 재시작이 필요할 수 있어요. 이런 이유로 다른 옵션이 없을 때만 사용해야 합니다.
ResourceQuota, NetworkPolicy, RBAC(Role-based Access Control) 같은 내장 정책 API는 선언적으로 구성되는 정책 설정을 제공하는 내장 Kubernetes API예요. 이러한 API는 일반적으로 호스팅된 Kubernetes 서비스와 관리형 Kubernetes 설치에서도 사용할 수 있습니다. 내장 정책 API는 Pod 같은 다른 Kubernetes 리소스와 같은 규칙을 따르죠. 안정적인 정책 API를 사용하면 다른 Kubernetes API처럼 정의된 지원 정책의 혜택을 받을 수 있어요. 이러한 이유로 정책 API는 적합한 곳에서 구성 파일과 명령 인자보다 권장됩니다.
확장 (Extensions)
확장은 Kubernetes와 깊게 통합되어 그것을 확장하는 소프트웨어 컴포넌트예요. Kubernetes가 새 유형과 새 종류의 하드웨어를 지원하도록 적응시킵니다.
많은 클러스터 관리자는 호스팅되거나 배포판인 Kubernetes 인스턴스를 사용해요. 이 클러스터들은 확장이 미리 설치되어 있습니다. 결과적으로 대부분의 Kubernetes 사용자는 확장을 설치할 필요가 없고, 새로 작성할 필요가 있는 사용자는 더 적어요.
확장 패턴 (Extension patterns)
Kubernetes는 클라이언트 프로그램을 작성해 자동화하도록 설계되었어요. Kubernetes API를 읽고/쓰는 모든 프로그램은 유용한 자동화를 제공할 수 있습니다. 자동화는 클러스터 안이나 밖에서 실행될 수 있어요. 이 문서의 지침을 따르면 고가용성과 견고한 자동화를 작성할 수 있습니다. 자동화는 일반적으로 호스팅 클러스터와 관리형 설치를 포함한 모든 Kubernetes 클러스터와 함께 작동해요.
Kubernetes와 잘 작동하는 클라이언트 프로그램 작성에는 **컨트롤러 패턴(controller pattern)**이라는 특정 패턴이 있어요. 컨트롤러는 일반적으로 객체의 .spec을 읽고, 필요한 일을 수행한 다음, 객체의 .status를 갱신합니다.
컨트롤러는 Kubernetes API의 클라이언트예요. Kubernetes가 클라이언트가 되어 원격 서비스를 호출하면, Kubernetes는 이것을 **웹훅(webhook)**이라고 부릅니다. 원격 서비스는 **웹훅 백엔드(webhook backend)**라고 불러요. 커스텀 컨트롤러와 마찬가지로 웹훅도 실패 지점(failure point)을 추가합니다.
참고: Kubernetes 외부에서 "웹훅"이라는 용어는 일반적으로 비동기 알림 메커니즘을 나타내며, 웹훅 호출이 다른 시스템이나 컴포넌트에 대한 단방향 알림 역할을 해요. Kubernetes 생태계에서는 동기 HTTP 콜아웃조차 "웹훅"으로 설명되는 경우가 많습니다.
웹훅 모델에서는 Kubernetes가 원격 서비스에 네트워크 요청을 합니다. 대안인 바이너리 플러그인 모델에서는 Kubernetes가 바이너리(프로그램)를 실행해요. 바이너리 플러그인은 kubelet(예: CSI 스토리지 플러그인과 CNI 네트워크 플러그인)과 kubectl(Extend kubectl with plugins 참고)에서 사용됩니다.
확장 지점 (Extension points)
Kubernetes 클러스터와 그 클라이언트가 접근하는 확장 지점은 다이어그램으로 도식화됩니다.
그림 해석 (Key to the figure):
- 사용자는 보통 kubectl로 Kubernetes API와 상호작용합니다. 플러그인은 클라이언트의 동작을 커스터마이즈해요. 다른 클라이언트에 적용할 수 있는 일반 확장과 kubectl을 확장하는 특정 방법이 있습니다.
- API 서버가 모든 요청을 처리해요. API 서버에는 요청을 인증하거나, 내용에 기반해 차단하거나, 내용을 편집하고, 삭제를 처리하게 하는 여러 확장 지점 유형이 있습니다. 이는 API Access Extensions 섹션에서 설명해요.
- API 서버는 다양한 종류의 리소스를 제공합니다. Pod 같은 내장 리소스 종류는 Kubernetes 프로젝트가 정의하며 변경할 수 없어요. Kubernetes API를 확장하는 방법은 API extensions를 읽어보세요.
- Kubernetes 스케줄러는 Pod을 어떤 노드에 배치할지 결정합니다. 스케줄링을 확장하는 방법은 여러 가지가 있으며 Scheduling extensions 섹션에서 설명해요.
- Kubernetes 동작의 상당 부분은 컨트롤러라는, API 서버의 클라이언트인 프로그램에 의해 구현됩니다. 컨트롤러는 종종 커스텀 리소스와 함께 사용돼요. 새 API와 자동화 결합 및 내장 리소스 변경에 대해 읽어보세요.
- kubelet은 서버(노드)에서 실행되며, Pod이 클러스터 네트워크에서 자신만의 IP를 가진 가상 서버처럼 보이게 돕습니다. 네트워크 플러그인은 Pod 네트워킹의 다양한 구현을 허용해요.
- **디바이스 플러그인(Device Plugins)**을 사용해 커스텀 하드웨어나 다른 특별한 노드 로컬 기능을 통합하고, 클러스터에서 실행되는 Pod에 사용할 수 있게 할 수 있어요. kubelet은 디바이스 플러그인과 함께 작업하는 것을 지원합니다.
- kubelet은 또한 Pod와 그 컨테이너를 위한 볼륨을 마운트/마운트 해제합니다. 스토리지 플러그인을 사용해 새로운 종류의 스토리지와 기타 볼륨 유형에 대한 지원을 추가할 수 있어요.
확장 지점 선택 순서도 (Extension point choice flowchart)
어디서 시작해야 할지 확신이 없다면 이 순서도가 도움이 됩니다. 일부 솔루션은 여러 유형의 확장을 포함할 수 있다는 점을 참고하세요.
클라이언트 확장 (Client extensions)
kubectl용 플러그인은 특정 하위 명령의 동작을 추가하거나 대체하는 별도의 바이너리예요. kubectl 도구는 **자격 증명 플러그인(credential plugins)**과도 통합될 수 있습니다. 이 확장들은 개별 사용자의 로컬 환경에만 영향을 주므로 사이트 차원의 정책을 강제할 수 없어요.
kubectl 도구를 확장하려면 Extend kubectl with plugins를 읽어보세요.
API 확장 (API extensions)
커스텀 리소스 정의 (Custom resource definitions)
새 컨트롤러, 애플리케이션 구성 객체, 또는 기타 선언적 API를 정의하고 kubectl 같은 Kubernetes 도구로 관리하고 싶다면 Kubernetes에 **커스텀 리소스(Custom Resource)**를 추가하는 것을 고려해보세요.
커스텀 리소스에 대한 자세한 내용은 Custom Resources 개념 가이드를 참고하세요.
API 어그리게이션 레이어 (API aggregation layer)
Kubernetes의 API Aggregation Layer를 사용해 메트릭 같은 추가 서비스와 Kubernetes API를 통합할 수 있어요.
새 API를 자동화와 결합 (Combining new APIs with automation)
커스텀 리소스 API와 컨트롤 루프의 조합을 **컨트롤러 패턴(controllers pattern)**이라고 불러요. 컨트롤러가 원하는 상태(desired state)를 기반으로 인프라를 배포하는 사람 운영자를 대신한다면, 컨트롤러는 **오퍼레이터 패턴(operator pattern)**을 따르고 있을 수도 있어요. Operator 패턴은 특정 애플리케이션을 관리하는 데 사용됩니다. 일반적으로 상태를 유지하고 관리 방법에 주의가 필요한 애플리케이션이죠.
스토리지 같은 다른 리소스를 관리하거나 (접근 제어 제한 같은) 정책을 정의하는 자신만의 커스텀 API와 컨트롤 루프를 만들 수도 있어요.
내장 리소스 변경 (Changing built-in resources)
커스텀 리소스를 추가해 Kubernetes API를 확장하면, 추가된 리소스는 항상 새 API 그룹에 속하게 돼요. 기존 API 그룹을 대체하거나 변경할 수는 없습니다. API를 추가한다고 해서 기존 API(예: Pod)의 동작에 직접 영향을 줄 수는 없어요. API Access Extensions가 그런 역할을 합니다.
API 접근 확장 (API access extensions)
요청이 Kubernetes API 서버에 도달하면, 먼저 인증되고, 그다음 **권한 부여(authorization)**되며, 이후 다양한 유형의 **어드미션 컨트롤(admission control)**을 받게 됩니다 (일부 요청은 실제로 인증되지 않고 특별한 처리를 받아요). 이 흐름에 대한 자세한 내용은 Controlling Access to the Kubernetes API를 참고하세요.
Kubernetes 인증/권한 부여 흐름의 각 단계는 확장 지점을 제공합니다.
인증 (Authentication)
인증은 모든 요청의 헤더나 인증서를 요청을 하는 클라이언트의 사용자 이름에 매핑합니다.
Kubernetes는 지원하는 여러 내장 인증 방법이 있어요. 또한 인증 프록시 뒤에 위치할 수 있고, 내장 방법이 요구를 충족하지 못하면 검증을 위해 Authorization: 헤더의 토큰을 원격 서비스로 보낼 수 있습니다(인증 웹훅).
권한 부여 (Authorization)
권한 부여는 특정 사용자가 API 리소스에 대해 읽기, 쓰기 및 기타 작업을 수행할 수 있는지 결정합니다. 전체 리소스 수준에서 작동하며, 임의의 객체 필드를 기준으로 구분하지 않아요.
내장 권한 부여 옵션이 요구를 충족하지 못하면, **권한 부여 웹훅(authorization webhook)**을 사용해 권한 부여 결정을 내리는 커스텀 코드를 호출할 수 있습니다.
동적 어드미션 컨트롤 (Dynamic admission control)
요청이 권한 부여된 후, 쓰기 작업이라면 어드미션 컨트롤 단계도 거칩니다. 내장 단계 외에도 여러 확장이 있어요.
- Image Policy 웹훅은 컨테이너에서 실행할 수 있는 이미지를 제한합니다.
- 임의의 어드미션 컨트롤 결정을 내리기 위해 일반 Admission 웹훅을 사용할 수 있어요. Admission 웹훅은 생성이나 갱신을 거부할 수 있습니다. 일부 admission 웹훅은 요청 데이터가 Kubernetes에 의해 더 처리되기 전에 들어오는 요청 데이터를 수정합니다.
인프라 확장 (Infrastructure extensions)
디바이스 플러그인 (Device plugins)
디바이스 플러그인은 노드가 Device Plugin을 통해 (cpu와 memory 같은 내장 리소스 외에) 새 노드 리소스를 발견할 수 있게 해줘요.
스토리지 플러그인 (Storage plugins)
CSI(Container Storage Interface) 플러그인은 Kubernetes에 새로운 종류의 볼륨 지원을 확장하는 방법을 제공해요. 볼륨은 지속적인 외부 스토리지로 백킹되거나, 임시(ephemeral) 스토리지를 제공하거나, 파일시스템 패러다임을 사용해 정보에 읽기 전용 인터페이스를 제공할 수 있습니다.
Kubernetes는 또한 FlexVolume 플러그인 지원을 포함하며, 이는 Kubernetes v1.23부터 CSI를 위해 더 이상 사용되지 않습니다(deprecated).
FlexVolume 플러그인은 사용자가 Kubernetes가 기본적으로 지원하지 않는 볼륨 유형을 마운트할 수 있게 해줘요. FlexVolume 스토리지에 의존하는 Pod을 실행하면, kubelet이 바이너리 플러그인을 호출해 볼륨을 마운트합니다. 아카이브된 FlexVolume 설계 제안에서 이 접근 방식에 대한 자세한 내용을 확인할 수 있어요.
스토리지 벤더를 위한 Kubernetes 볼륨 플러그인 FAQ에는 스토리지 플러그인에 대한 일반 정보가 포함되어 있습니다.
네트워크 플러그인 (Network plugins)
Kubernetes 클러스터는 작동하는 Pod 네트워크를 갖고 Kubernetes 네트워크 모델의 다른 측면을 지원하려면 네트워크 플러그인이 필요해요.
네트워크 플러그인은 Kubernetes가 다양한 네트워킹 토폴로지와 기술과 함께 작동하게 해줍니다.
kubelet 이미지 자격 증명 제공자 플러그인 (Kubelet image credential provider plugins)
FEATURE STATE:
Kubernetes v1.26 [stable]
kubelet 이미지 자격 증명 제공자(kubelet image credential providers)는 kubelet이 이미지 레지스트리 자격 증명을 동적으로 검색하기 위한 플러그인이에요. 그 자격 증명은 구성과 일치하는 컨테이너 이미지 레지스트리에서 이미지를 가져올 때 사용됩니다.
플러그인은 자격 증명을 얻기 위해 외부 서비스와 통신하거나 로컬 파일을 사용할 수 있어요. 이렇게 하면 kubelet이 각 레지스트리에 대한 정적 자격 증명을 가질 필요가 없고, 다양한 인증 방법과 프로토콜을 지원할 수 있습니다.
플러그인 구성 세부 사항은 Configure a kubelet image credential provider를 참고하세요.
스케줄링 확장 (Scheduling extensions)
스케줄러는 Pod을 감시하고 Pod을 노드에 할당하는 특별한 유형의 컨트롤러예요. 기본 스케줄러는 다른 Kubernetes 컴포넌트를 계속 사용하면서 완전히 대체할 수 있고, 또는 여러 스케줄러를 동시에 실행할 수도 있습니다.
이것은 상당한 작업이므로, 거의 모든 Kubernetes 사용자는 스케줄러를 수정할 필요가 없다고 느껴요.
어떤 스케줄링 플러그인을 활성화할지 제어하거나, 플러그인 집합을 서로 다른 이름의 스케줄러 프로필과 연결할 수 있어요. 또한 kube-scheduler의 하나 이상의 확장 지점과 통합되는 자신만의 플러그인을 작성할 수도 있습니다.
마지막으로, 내장 kube-scheduler 컴포넌트는 kube-scheduler가 Pod에 대해 선택하는 노드를 필터링 및/또는 우선순위를 매기게 하는 원격 HTTP 백엔드(스케줄러 확장)를 허용하는 웹훅을 지원합니다.
참고: 스케줄러 익스텐더(extender) 웹훅으로 노드 필터링과 노드 우선순위에만 영향을 줄 수 있어요. 다른 확장 지점은 웹훅 통합을 통해 사용할 수 없습니다.