Why Kubernetes REST API is imperative?

12/9/2020

EDIT: As mentioned in Jonas' response Kubernetes REST API can be actually considered as declarative and not imperative.

Kubernetes is well known for its declarative model. Controller are watching objects in ETCD which contains the desired state (declarative). It compares it to the current state and generates imperative commands to the imperative Kubernetes API.

Which reasons leads Kubernetes project to not expose a declarative HTTP API?

Thus let the controller/operator do the reconciliation.

An example of declarative REST API, I found is F5 AS3. And I guess their Kubernetes operator built on top of this declarative API is quite straightforward.

-- scoulomb
kubernetes
operator-sdk
rest

1 Answer

12/9/2020

The Kubernetes API can be used both declaratively and also imperatively. For quick development an imperative workflow might work better whereas for traceability and production workload a declarative workflow is recommended.

Declarative HTTP example using curl

This requires to run kubectl proxy first.

curl -X POST -H 'Content-Type: application/yaml' --data '
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-example
spec:
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14
        ports:
        - containerPort: 80
' http://127.0.0.1:8001/apis/apps/v1/namespaces/default/deployments

The Kubernetes API is declarative in the sense that you always specify what you want, e.g. replicas: 2 instead of e.g. create 2 replicas that would be the case in an imperative API. The controllers then "drives" the state to "what" you specified in a reconciliation loop.

See:

From your link:

The Application Services 3 Extension uses a declarative model, meaning you send a declaration file using a single Rest API call.

the Kubernetes API works exactly the same when you apply yaml-manifest files using e.g. kubectl apply -f deployment.yaml

-- Jonas
Source: StackOverflow