简体   繁体   中英

Accessing Kubernetes APIs from local machine

I wish to access Kubernetes APIs from my local machine. I'm trying to get list of pods using kubernetes Rest APIs.

I've created a kubernetes cluster and some pods on Google Cloud .

On my local Windows machine, I've installed gcloud sdk and kubectl component with it. I connected to my cluster using:

gcloud container clusters get-credentials my-cluster --region us-central1 --project my-project

I can get the list of pods using kubectl get pods

Although, I want to get pods list using kubernetes Rest APIs.

GET https://kubernetes.default/api/v1/namespaces/default/pods
Authorization: Bearer my_access_token

But I think the request is not going through.

In Postman, I get the error:

Error: tunneling socket could not be established, cause=socket hang up

Or in Python using requests library (from my local machine), I get the error

HTTPSConnectionPool(host='kubernetes.default', port=443): Max retries exceeded with url: /api/v1/namespaces/default/pods (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x00000277DCD04D90>: Failed to establish a new connection: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond'))

What am I missing here?

The endpoint https://kubernetes.default only works if you want to access Kubernetes REST API from inside the cluster ie from another pod. For accessing Kubernetes REST API from outside the kubernetes cluster ie from your local machine you need to use the API server IP or host which is externally accessible ie the one which is there in kubeconfig file.

For accessing it from outside the kubernetes cruster ie from your local machine there are three ways referring from the docs here

  1. Run kubectl in proxy mode (recommended). This method is recommended, since it uses the stored apiserver location and verifies the identity of the API server using a self-signed cert. No man-in-the-middle (MITM) attack is possible using this method.

    kubectl proxy --port=8080 &

    curl http://localhost:8080/api/v1/namespaces/default/pods

  2. It is possible to avoid using kubectl proxy by passing an authentication token directly to the API server, like this:

Check all possible clusters, as your.KUBECONFIG may have multiple contexts:

kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'

Select name of cluster you want to interact with from above output:

export CLUSTER_NAME="some_server_name"

Point to the API server referring the cluster name

APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")

Gets the token value

TOKEN=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.token}"|base64 --decode)

Explore the API with TOKEN

curl -X GET $APISERVER/api/v1/namespaces/default/pods --header "Authorization: Bearer $TOKEN" --insecure
  1. Using client library

To use Python client, run the following command: pip install kubernetes See Python Client Library page for more installation options.

The Python client can use the same kubeconfig file as the kubectl CLI does to locate and authenticate to the API server. See this example:

from kubernetes import client, config

config.load_kube_config()

v1=client.CoreV1Api()
print("Listing pods with their IPs:")
ret = v1.list_pod_for_all_namespaces(watch=False)
for i in ret.items:
    print("%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))

You can also do it the way you are doing without using kubeconfig file but it's more work and you need to use the kubernetes API Server IP or hostname from the kubeconfig file.

using below kubectl command start a proxy to the Kubernetes API server:

kubectl proxy --port=8080

Get the API versions:

curl http://localhost:8080/api/
The output should look similar to this:

{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "10.0.2.15:8443"
    }
  ]
}

Your api server address is not correct for external REST access.

Get the address like this.

kubectl config view

Find your cluster name in the list and get the APi.

Here is the cURL (without the real IP or the token) which worked in my local pc.

curl --location --request GET 'https://nnn.nnn.nnnn.nnn/api/v1/namespaces/develop/pods' \
--header 'Authorization: bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

If you run in POSTMAN, you might have to disable certificate verification.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM