Kubernetes API

Using REST API calls to interact with the cluster

view on github

Table of contents

  1. Concepts
  2. The / route
  3. Discovery API
  4. Openapi API
  5. API proxying
  6. Important note

Concepts

  • The entire cluster state (desired and current) is exposed by kube-apiserver as a REST API.
  • The API is primarily built around the concepts of resource types and API groups :
    • A resource type (kind) is the schema of an object used to store or retrieve a fragment of the cluster state.
    • The API group is a metadata added to resource types so as to group them according to their purpose.
    • The API version metadata is added to resource types as well to support versioning at the API group level.
  • K8s maintains a confusing distinction between the core API group (/api) and the named API groups (/apis).
  • The best way to think of it is to view the core group as just a named group that happens to not have a name.

The / route

  • The / route shows a list of paths for the different APIs exposed by the server :

    path kube-apiserver API
    /api/* Discovery for core group resources
    /apis/* Discovery for named groups resources
    /openapi/* Server openapi specs
    /healthz/* Server healthiness
    /livez/* Server liveliness
    /readyz/* Server readiness
    /metrics/* Cluster components metrics
    /version Version information

Notes :

  • The health API expose informations about the current status of kube-apiserver.
  • The metrics API exposes data for consumption by observability tools like Prometheus.
  • /apis/* does not include paths segments for named groups defined through API extensions.
  • Despite that, resources defined through API extensions are served by the discovery API and the openapi API.

  • The discovery API exposes endpoints used for reading or updating the cluster state.

  • Each endpoint supports a specific list of verbs when processing HTTP requests.

  • Verbs are mapped to actions to perform on the resource or collection exposed by the endpoint.

  • Bodies of HTTP responses are objects from specific resource types designed for observation :

    verb + REST path API group resource type returned type Description
    GET /api Core N/A APIVersions Supported API versions for core group
    GET /api/v1 Core v1 * APIResourceList Verbs and kind by resource type
    GET /api/v1/pods Core v1 Pod PodList etcd data for Pod resources
    GET /apis All named N/A APIGroupList Supported API versions by named group
    GET /apis/apps/v1 apps/v1 * APIResourceList Verbs and kind by resource type
    GET /apis/apps/v1/deployments apps/v1 Deployment DeploymentList etcd data for Deployment resources
  • Here, Pod is part of the core API group while Deployment is part of the apps API group (named group).

  • The scope of returned results is the entire cluster by default, however namespace filtering is supported.

  • The discovery API wraps multiple kind of resources together through the concept of resource and subresource :

    • /apis/apps/v1/namespaces/{ns}/deployments/{dp} exposes a Deployment resource.
    • /apis/apps/v1/namespaces/{ns}/deployments/{dp}/scale exposes a Scale subresource.

Notes :

  • K8s supports JSON, YAML and protobuf formats for objects serialization.
  • Subresources may or may not have a kind, metadata and API version of their own.
  • For instance, the difference between Scale and PolicyRule illustrates that last point.

  • The openapi API exposes endpoints that return the OpenAPI specs for discovery API endpoints.

  • It publishes the specification of the API that the cluster exposes, which can vary (installed extensions, etc).

  • Example of exposed REST paths are :

    verb + REST path API group resource type Description
    GET /openapi/v2 * * Aggregated requests specs for discovery API paths
    GET /openapi/v3 * N/A Maps discovery API paths to openapi API paths
    GET /openapi/v3/api/v1 Core * Supported requests specs by discovery API path
    GET /openapi/v3/apis/apps/v1 apps * Supported requests specs by discovery API path

API proxying

  • The kube-apiserver API can be proxied locally by running the following command on a control plane node :
# proxies the K8s API to 127.0.0.1:9999 over HTTP
kubectl proxy \
--address="127.0.0.1" \
--api-prefix=/ \
--port="9999" \
--reject-methods="POST,PUT,PATCH,DELETE,CONNECT"
  • It then can be securely tunneled through SSH for remote inspection of cluster state and API :
# here, remote port 9999 is tunneled to local port 30100 through SSH
# print a YAML list of supported verbs by resource types for apps/v1
curl -s http://127.0.0.1:30100/apis/apps/v1 | \
jq -r '.resources[] | {name, verbs: (.verbs | join(", "))} | "- name: \(.name)\n  verbs: \"\(.verbs)\""'

Important note

  • spec for cluster and workload resources must always be compatible with the API supported by the current K8s version.
  • As a result, monitoring API changes and deprecation policies is important when designing workloads or before cluster upgrades.