Call the Kubernetes API with client certificates

Updated at:
Copy as MD

The Kubernetes API is a RESTful, resource-based HTTP interface that supports GET, POST, PUT, PATCH, and DELETE. Use it to query and manage cluster resources programmatically — without kubectl. Authenticate with client certificates and call the API using cURL to manage pods and Deployments.

Prerequisites

Before you begin, ensure that you have:

  • An ACK cluster

  • Permission to access the ACK console

  • cURL installed on your local machine

Extract credentials from kubeconfig

  1. Log on to the ACK console.

  2. Click Go to RAM console to navigate to the Resource Access Management Quick Authorization page, and then click Confirm Authorization Policy. After authorization, refresh the ACK console.

  3. In the left-side navigation pane, click Clusters.

  4. On the Clusters page, click the cluster name or click Details in the Actions column.

  5. Click the Connection Information tab. Copy the kubeconfig content and save it locally as ./kubeconfig.

  6. Extract the client certificate, private key, and API server address from the kubeconfig file:

    cat ./kubeconfig | grep client-certificate-data | awk -F ' ' '{print $2}' | base64 -d > ./client-cert.pem
    cat ./kubeconfig | grep client-key-data | awk -F ' ' '{print $2}' | base64 -d > ./client-key.pem
    APISERVER=`cat ./kubeconfig | grep server | awk -F ' ' '{print $2}'`

    These commands decode the certificate data and store the API server URL in $APISERVER. All subsequent cURL commands use these credentials and the $APISERVER variable.

The -k flag skips TLS server verification. For production, replace -k with --cacert <path-to-ca.pem> to verify server identity and prevent man-in-the-middle attacks.

Manage pods

All pod API calls use the path $APISERVER/api/v1/namespaces/<namespace>/pods.

Operation HTTP method Path
List all namespaces GET /api/v1/namespaces
List all pods GET /api/v1/namespaces/default/pods
Create a pod POST /api/v1/namespaces/default/pods
Get pod status GET /api/v1/namespaces/default/pods/nginx
Get pod logs GET /api/v1/namespaces/default/pods/nginx/log
Get pod metrics GET /apis/metrics.k8s.io/v1beta1/namespaces/default/pods/nginx
Delete a pod DELETE /api/v1/namespaces/default/pods/nginx

List all namespaces in the cluster:

curl --cert ./client-cert.pem --key ./client-key.pem -k $APISERVER/api/v1/namespaces

List all pods in the default namespace:

curl --cert ./client-cert.pem --key ./client-key.pem -k $APISERVER/api/v1/namespaces/default/pods

Create a pod from a JSON manifest:

cat nginx-pod.json
{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
        "name": "nginx",
        "namespace": "default"
    },
    "spec": {
        "containers": [
            {
                "name": "nginx",
                "image": "nginx:alpine",
                "ports": [
                    {
                        "containerPort": 80
                    }
                ]
            }
        ]
    }
}

curl --cert ./client-cert.pem --key ./client-key.pem -k $APISERVER/api/v1/namespaces/default/pods \
  -X POST --header 'content-type: application/json' -d@nginx-pod.json

Create a pod from a YAML manifest:

cat nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:alpine
    ports:
    - containerPort: 80

curl --cert ./client-cert.pem --key ./client-key.pem -k $APISERVER/api/v1/namespaces/default/pods \
  -X POST --header 'content-type: application/yaml' --data-binary @nginx-pod.yaml

Get pod status:

curl --cert ./client-cert.pem --key ./client-key.pem -k $APISERVER/api/v1/namespaces/default/pods/nginx

Get pod logs:

curl --cert ./client-cert.pem --key ./client-key.pem -k $APISERVER/api/v1/namespaces/default/pods/nginx/log

Get pod metrics via the Metrics Server API:

curl --cert ./client-cert.pem --key ./client-key.pem -k $APISERVER/apis/metrics.k8s.io/v1beta1/namespaces/default/pods/nginx

Delete a pod:

curl --cert ./client-cert.pem --key ./client-key.pem -k $APISERVER/api/v1/namespaces/default/pods/nginx -X DELETE

Manage Deployments

All Deployment API calls use the path $APISERVER/apis/apps/v1/namespaces/<namespace>/deployments.

Create a Deployment:

cat nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "2"
            memory: "4Gi"

curl --cert ./client-cert.pem --key ./client-key.pem -k $APISERVER/apis/apps/v1/namespaces/default/deployments \
  -X POST --header 'content-type: application/yaml' --data-binary @nginx-deploy.yaml

List all Deployments in the default namespace:

curl --cert ./client-cert.pem --key ./client-key.pem -k $APISERVER/apis/apps/v1/namespaces/default/deployments

Scale a Deployment:

curl --cert ./client-cert.pem --key ./client-key.pem -k \
  $APISERVER/apis/apps/v1/namespaces/default/deployments/nginx-deploy \
  -X PATCH -H 'Content-Type: application/strategic-merge-patch+json' \
  -d '{"spec": {"replicas": 4}}'

Update the container image:

curl --cert ./client-cert.pem --key ./client-key.pem -k \
  $APISERVER/apis/apps/v1/namespaces/default/deployments/nginx-deploy \
  -X PATCH -H 'Content-Type: application/strategic-merge-patch+json' \
  -d '{"spec": {"template": {"spec": {"containers": [{"name": "nginx","image": "nginx:1.7.9"}]}}}}'

Next steps

For programmatic access beyond cURL, use an official Kubernetes client library:

Language Client library Examples
Go client-go Browse
Python client-python Browse
Java client-java Browse

See Kubernetes client libraries for a complete list of supported languages.

Explore alternative access methods in Access clusters using the Kubernetes API.