쿠버네티스 API

쿠버네티스 API (The Kubernetes API)

쿠버네티스의 모든 것은 API를 통해 다뤄져요. 사용자, 클러스터의 각 컴포넌트, 외부 컴포넌트가 모두 API 서버를 통해 소통합니다. 이 페이지는 쿠버네티스 API의 구조와 스키마를 공개하는 메커니즘, 버전 관리 방식에 대해 설명해 드릴게요. kubectl이 내부적으로 API를 어떻게 활용하는지 이해하면, 쿠버네티스의 동작 원리가 훨씬 선명해집니다.

출처: Kubernetes 공식 문서 — The Kubernetes API

쿠버네티스 API를 사용하면 쿠버네티스 객체(Pod, Namespace, ConfigMap, Event 등)의 상태를 조회(query) 하고 조작(manipulate) 할 수 있어요.

쿠버네티스 컨트롤 플레인의 핵심은 API 서버예요. API 서버는 최종 사용자, 클러스터의 각 부분, 외부 컴포넌트가 서로 소통할 수 있는 HTTP API를 노출합니다.

대부분의 작업은 내부적으로 API를 사용하는 kubectl이나 kubeadm 같은 커맨드라인 도구로 수행할 수 있어요. 하지만 REST 호출로 API에 직접 접근할 수도 있습니다. 쿠버네티스 API를 사용하는 애플리케이션을 작성하려는 사람들을 위해 쿠버네티스는 클라이언트 라이브러리도 제공합니다.

각 쿠버네티스 클러스터는 자신이 서빙하는 API의 스펙을 공개합니다. 쿠버네티스는 이 API 스펙을 공개하는 두 가지 메커니즘을 사용해요. 둘 다 자동 상호운용성을 가능하게 하는 데 유용합니다. 예를 들어 kubectl 도구는 커맨드라인 완성 등 기능을 위해 API 스펙을 가져와 캐시해요. 두 가지 지원 메커니즘은 다음과 같아요:

  • Discovery API — 쿠버네티스 API에 대한 정보(API 이름, 리소스, 버전, 지원되는 연산)를 제공해요. 이는 쿠버네티스 OpenAPI와는 별개의 API이므로 쿠버네티스 특유의 용어예요. 사용 가능한 리소스에 대한 간략한 요약을 제공하며, 리소스의 구체적인 스키마를 상세히 다루지는 않아요. 리소스 스키마에 대한 참조는 OpenAPI 문서를 참고하세요.
  • 쿠버네티스 OpenAPI 문서 — 모든 쿠버네티스 API 엔드포인트에 대한 (완전한) OpenAPI v2.0 및 3.0 스키마를 제공해요. OpenAPI v3가 더 포괄적이고 정확한 API 뷰를 제공하므로 OpenAPI에 접근하는 선호 방법입니다. 모든 사용 가능한 API 경로와 모든 엔드포인트의 모든 연산에서 소비·생산되는 리소스를 포함합니다. 클러스터가 지원하는 확장 컴포넌트도 포함돼요. Discovery API보다 훨씬 큰 완전한 스펙입니다.

Discovery API

쿠버네티스는 Discovery API를 통해 지원되는 모든 그룹 버전과 리소스 목록을 공개해요. 각 리소스에 대해 다음을 포함합니다:

  • 이름 (Name)
  • 클러스터 또는 네임스페이스 범위 (Cluster or namespaced scope)
  • 엔드포인트 URL과 지원 동사 (Endpoint URL and supported verbs)
  • 대체 이름 (Alternative names)
  • 그룹, 버전, 종류 (Group, version, kind)

이 API는 집계된(aggregated) 형태와 비집계(unaggregated) 형태로 모두 제공됩니다. 집계된 discovery는 두 개의 엔드포인트를 제공하고, 비집계 discovery는 각 그룹 버전마다 별도의 엔드포인트를 제공해요.

집계된 discovery (Aggregated discovery)

기능 상태: Kubernetes v1.30 [stable] (기본 활성화)

쿠버네티스는 집계된 discovery를 안정적으로 지원하며, 클러스터가 지원하는 모든 리소스를 /api/apis 두 엔드포인트로 공개해요. 이 엔드포인트를 요청하면 discovery 데이터를 가져오기 위해 보내는 요청 수가 크게 줄어듭니다. 집계된 discovery 리소스를 나타내는 Accept 헤더(Accept: application/json;v=v2;g=apidiscovery.k8s.io;as=APIGroupDiscoveryList)와 함께 각 엔드포인트를 요청하면 데이터에 접근할 수 있어요.

Accept 헤더로 리소스 타입을 지정하지 않으면, /api/apis 엔드포인트의 기본 응답은 비집계 discovery 문서입니다.

기본 제공 리소스에 대한 discovery 문서는 쿠버네티스 GitHub 저장소에서 찾을 수 있어요. 쿼리할 클러스터가 없을 때 사용 가능한 리소스의 기본 집합 참고용으로 이 문서를 사용할 수 있습니다. 이 엔드포인트는 ETag와 protobuf 인코딩도 지원해요.

비집계 discovery (Unaggregated discovery)

discovery 집계가 없으면 discovery는 계층적으로 공개되며, 루트 엔드포인트가 하위 문서에 대한 discovery 정보를 공개해요.

클러스터가 지원하는 모든 그룹 버전 목록은 /api/apis 엔드포인트에 공개됩니다. 예:

{
  "kind": "APIGroupList",
  "apiVersion": "v1",
  "groups": [
    {
      "name": "apiregistration.k8s.io",
      "versions": [
        {
          "groupVersion": "apiregistration.k8s.io/v1",
          "version": "v1"
        }
      ],
      "preferredVersion": {
        "groupVersion": "apiregistration.k8s.io/v1",
        "version": "v1"
      }
    },
    {
      "name": "apps",
      "versions": [
        {
          "groupVersion": "apps/v1",
          "version": "v1"
        }
      ],
      "preferredVersion": {
        "groupVersion": "apps/v1",
        "version": "v1"
      }
    },
    ...
}

각 그룹 버전의 discovery 문서를 얻으려면 /apis/<group>/<version>(예: /apis/rbac.authorization.k8s.io/v1alpha1)에 추가 요청이 필요합니다. 이 엔드포인트는 특정 그룹 버전 아래에서 서빙되는 리소스 목록을 알려줘요. kubectl이 클러스터가 지원하는 리소스 목록을 가져올 때 이 엔드포인트들을 사용합니다.

OpenAPI 인터페이스 정의 (OpenAPI interface definition)

OpenAPI 스펙에 대한 자세한 내용은 OpenAPI 문서를 참고하세요.

쿠버네티스는 OpenAPI v2.0과 v3.0을 모두 제공해요. OpenAPI v3가 쿠버네티스 리소스의 더 포괄적인(무손실) 표현을 제공하므로 OpenAPI에 접근하는 선호 방법입니다. OpenAPI v2의 한계 때문에 default, nullable, oneOf 등을 포함한 일부 필드가 공개 OpenAPI에서 제외됩니다(이에 국한되지 않음).

OpenAPI V2

쿠버네티스 API 서버는 /openapi/v2 엔드포인트를 통해 집계된 OpenAPI v2 스펙을 제공해요. 요청 헤더로 응답 형식을 지정할 수 있습니다:

헤더 가능한 값 비고
Accept-Encoding gzip 이 헤더를 제공하지 않아도 괜찮습니다
Accept application/[email protected]+protobuf 주로 클러스터 내부용
application/json 기본값
* application/json 제공

경고: OpenAPI 스키마의 일부로 공개된 검증 규칙은 완전하지 않을 수 있으며, 대개 완전하지 않습니다. 추가 검증은 API 서버 내부에서 이루어져요. 정확하고 완전한 검증을 원한다면 kubectl apply --dry-run=server가 모든 적용 가능한 검증(및 admission-time 검사)을 실행합니다.

OpenAPI V3

기능 상태: Kubernetes v1.27 [stable] (기본 활성화)

쿠버네티스는 API 설명을 OpenAPI v3로 공개하는 것을 지원해요.

/openapi/v3 discovery 엔드포인트에서 사용 가능한 모든 그룹/버전 목록을 볼 수 있어요. 이 엔드포인트는 JSON만 반환합니다. 그룹/버전은 다음 형식으로 제공됩니다:

{
    "paths": {
        ...,
        "api/v1": {
            "serverRelativeURL": "/openapi/v3/api/v1?hash=CC0E9BFD992D8C59AEC98A1E2336F899E8318D3CF4C68944C3DEC640AF5AB52D864AC50DAA8D145B3494F75FA3CFF939FCBDDA431DAD3CA79738B297795818CF"
        },
        "apis/admissionregistration.k8s.io/v1": {
            "serverRelativeURL": "/openapi/v3/apis/admissionregistration.k8s.io/v1?hash=E19CC93A116982CE5422FC42B590A8AFAD92CDE9AE4D59B5CAAD568F083AD07946E6CB5817531680BCE6E215C16973CD39003B0425F3477CFD854E89A9DB6597"
        },
        ....
    }
}

상대 URL은 불변(immutable) OpenAPI 설명을 가리켜 클라이언트 측 캐싱을 개선해요. 이를 위해 API 서버는 적절한 HTTP 캐싱 헤더(Expires를 1년 후로, Cache-Controlimmutable로)도 설정합니다. 더 이상 사용되지 않는 URL을 사용하면 API 서버가 최신 URL로 리다이렉트해요.

쿠버네티스 API 서버는 /openapi/v3/apis/<group>/<version>?hash=<hash> 엔드포인트에서 그룹 버전별 OpenAPI v3 스펙을 공개합니다.

허용되는 요청 헤더는 다음 표를 참고하세요.

헤더 가능한 값 비고
Accept-Encoding gzip 이 헤더를 제공하지 않아도 괜찮습니다
Accept application/[email protected]+protobuf 주로 클러스터 내부용
application/json 기본값
* application/json 제공

OpenAPI V3를 가져오는 Golang 구현은 k8s.io/client-go/openapi3 패키지에 제공됩니다.

쿠버네티스 1.36은 OpenAPI v2.0과 v3.0을 공개하며, 가까운 시일 내에 3.1을 지원할 계획은 없어요.

Protobuf 직렬화 (Protobuf serialization)

쿠버네티스는 주로 클러스터 내부 통신을 위한 대체 Protobuf 기반 직렬화 형식을 구현해요. 이 형식에 대한 자세한 내용은 쿠버네티스 Protobuf 직렬화 설계 제안과, API 객체를 정의하는 Go 패키지에 있는 각 스키마의 IDL(Interface Definition Language) 파일을 참고하세요.

지속성 (Persistence)

쿠버네티스는 객체의 직렬화된 상태를 etcd에 기록해 저장해요.

API 그룹과 버전 관리 (API groups and versioning)

필드를 제거하거나 리소스 표현을 재구성하기 쉽도록, 쿠버네티스는 여러 API 버전을 지원하며 각각 /api/v1 또는 /apis/rbac.authorization.k8s.io/v1alpha1 같은 서로 다른 API 경로를 가져요.

버전 관리는 리소스나 필드 수준이 아니라 API 수준에서 이루어져요. 이는 API가 시스템 리소스와 동작에 대해 명확하고 일관된 뷰를 제시하고, 수명이 끝나거나 실험적인 API에 대한 접근을 제어할 수 있게 하기 위함입니다.

쿠버네티스는 API를 발전·확장하기 쉽도록 API 그룹을 구현하며, 이는 활성화/비활성화할 수 있어요.

API 리소스는 API 그룹, 리소스 타입, 네임스페이스(네임스페이스 리소스의 경우), 이름으로 구분됩니다. API 서버는 API 버전 간 변환을 투명하게 처리해요: 모든 서로 다른 버전은 실제로 동일한 영속 데이터의 표현입니다. API 서버는 동일한 기본 데이터를 여러 API 버전으로 제공할 수 있어요.

예를 들어 같은 리소스에 v1v1beta1 두 API 버전이 있다고 가정해 보세요. v1beta1 버전으로 객체를 원래 만들었다면, v1beta1이 폐기(deprecated)되고 제거될 때까지 v1beta1 또는 v1 API 버전으로 그 객체를 읽고, 갱신하고, 삭제할 수 있어요. 그 시점부터는 v1 API를 사용해 계속 접근·수정할 수 있습니다.

API 변경 (API changes)

성공한 시스템은 새로운 사용 사례가 나타나거나 기존 것이 바뀌면 성장하고 변화해야 해요. 따라서 쿠버네티스는 API가 지속적으로 변화하고 성장하도록 설계했어요. 쿠버네티스 프로젝트는 기존 클라이언트와의 호환성을 깨지 않는 것을 목표로 하며, 다른 프로젝트가 적응할 시간을 갖도록 일정 기간 호환성을 유지하는 것을 목표로 합니다.

일반적으로 새 API 리소스와 새 리소스 필드는 자주, 빈번하게 추가될 수 있어요. 리소스나 필드를 제거하려면 API 폐기 정책을 따라야 합니다.

쿠버네티스는 공식 쿠버네티스 API가 일반 공급(GA, 일반적으로 API 버전 v1)에 도달하면 호환성을 유지하겠다는 강력한 약속을 해요. 추가로, 쿠버네티스는 공식 API의 beta 버전으로 영속된 데이터와의 호환성을 유지하고, 기능이 안정화되면 데이터를 GA API 버전으로 변환·접근할 수 있게 보장합니다.

beta API 버전을 채택했다면, API가 성숙함에 따라 후속 beta 또는 stable API 버전으로 전환해야 해요. 가장 좋은 시기는 beta API가 폐기 기간에 있을 때예요. 이때는 두 API 버전으로 객체에 동시에 접근할 수 있기 때문입니다. beta API가 폐기 기간을 마치고 더 이상 제공되지 않으면 교체 API 버전을 사용해야 해요.

참고: 쿠버네티스는 alpha API 버전의 호환성도 유지하는 것을 목표로 하지만, 어떤 상황에서는 불가능합니다. alpha API 버전을 사용한다면 클러스터를 업그레이드할 때 릴리스 노트를 확인해서, 업그레이드 전에 모든 기존 alpha 객체를 삭제해야 하는 비호환적인 API 변경이 있었는지 확인하세요.

API 버전 수준 정의에 대한 자세한 내용은 API 버전 참조를 참고하세요.

API 확장 (API Extension)

쿠버네티스 API는 두 가지 방식 중 하나로 확장할 수 있어요:

  1. 커스텀 리소스 — API 서버가 선택한 리소스 API를 어떻게 제공할지 선언적으로 정의하게 해 줍니다.
  2. 집계 레이어를 구현해 쿠버네티스 API를 확장할 수도 있어요.

더 알아보기 (Learn more)