I'm trying to connect to my microk8s Kubernetes cluster which is listening on port 16443 with the Python Kubernetes client:
#!/usr/bin/python3
import kubernetes
from kubernetes import client
from kubernetes.client import ApiClient
def setup_cluster():
configuration = kubernetes.client.configuration.Configuration()
configuration.host = "https://localhost:16443"
#configuration.cert_file = "ca.crt"
#configuration.key_file = "ca.key"
configuration.api_key["authorization"] = "[the token which I got from kubectl -n kube-system describe secret default-token-abc123]"
api_client = ApiClient(configuration=configuration)
v1 = client.CoreV1Api(api_client=api_client)
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))
if __name__ == "__main__":
setup_cluster()
If I set none of the fields cert_file
, key_file
or api_key
of the configuration in the example, the connection fails due to
Traceback (most recent call last):
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/kubernetes_python_port_ignored.py", line 26, in <module>
setup_cluster()
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/kubernetes_python_port_ignored.py", line 20, in setup_cluster
ret = v1.list_pod_for_all_namespaces(watch=False)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/kubernetes/client/apis/core_v1_api.py", line 13630, in list_pod_for_all_namespaces
(data) = self.list_pod_for_all_namespaces_with_http_info(**kwargs)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/kubernetes/client/apis/core_v1_api.py", line 13724, in list_pod_for_all_namespaces_with_http_info
collection_formats=collection_formats)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/kubernetes/client/api_client.py", line 334, in call_api
_return_http_data_only, collection_formats, _preload_content, _request_timeout)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/kubernetes/client/api_client.py", line 168, in __call_api
_request_timeout=_request_timeout)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/kubernetes/client/api_client.py", line 355, in request
headers=headers)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/kubernetes/client/rest.py", line 231, in GET
query_params=query_params)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/kubernetes/client/rest.py", line 205, in request
headers=headers)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/urllib3/request.py", line 68, in request
**urlopen_kw)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/urllib3/request.py", line 89, in request_encode_url
return self.urlopen(method, url, **extra_kw)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/urllib3/poolmanager.py", line 326, in urlopen
response = conn.urlopen(method, u.request_uri, **kw)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/urllib3/connectionpool.py", line 670, in urlopen
**response_kw)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/urllib3/connectionpool.py", line 670, in urlopen
**response_kw)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/urllib3/connectionpool.py", line 670, in urlopen
**response_kw)
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/urllib3/connectionpool.py", line 641, in urlopen
_stacktrace=sys.exc_info()[2])
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/urllib3/util/retry.py", line 399, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='localhost', port=16443): Max retries exceeded with url: /api/v1/pods?watch=False (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)')))
If I specify the api_key
as shown in the code above I get
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/urllib3/util/retry.py", line 399, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='localhost', port=16443): Max retries exceeded with url: /api/v1/pods?watch=False (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)')))
I tried setting some certificates like ca.crt
and ca.key
from /var/snap/microk8s/current/certs
as shown, but this then fails due to
File "/home/richter/examples/kubernetes-python/kubernetes-python-port-ignored/venv/lib/python3.7/site-packages/urllib3/util/retry.py", line 399, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='localhost', port=16443): Max retries exceeded with url: /api/v1/pods?watch=False (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)')))
I'm using microk8s 1.15.0 (695) on Ubuntu 19.04 with Python 3.7 and Kubernetes Python client 10.0.0.
This works for AWS EKS cluster:
import boto3
import kubernetes
import os
import base64
eks = boto3.client('eks')
eks_cluster_name = os.environ['EKS_CLUSTER_NAME']
eks_api_key = os.environ['EKS_API_KEY']
eksresponse = eks.describe_cluster(
name=eks_cluster_name
)
ca_file = open("/tmp/ca.crt", "wb")
n = ca_file.write(base64.b64decode(eksresponse['cluster']['certificateAuthority']['data']))
ca_file.close()
configuration = kubernetes.client.Configuration()
configuration.ssl_ca_cert = '/tmp/ca.crt'
configuration.api_key['authorization'] = eks_api_key
configuration.api_key_prefix['authorization'] = 'Bearer'
configuration.host = eksresponse['cluster']['endpoint']
api_instance = kubernetes.client.CoreV1Api(kubernetes.client.ApiClient(configuration))
api_response = api_instance.list_pod_for_all_namespaces()
for i in api_response.items:
print(i.metadata.name)
Your SSL verification is failing the TLS checks. The easiest and quickest fix is to set your Kube config to skip tls-verify because you are using a single node.
clusters:
- cluster:
server: https://127.0.0.1:16443
insecure-skip-tls-verify: true
you need to pass path to ca.crt file at configuration.ssl_ca_cert = 'ca.crt'
.
configuration = kubernetes.client.Configuration()
configuration.ssl_ca_cert = 'ca.crt' #<<< look here>>>
configuration.api_key['authorization'] = 'ZXXXXXXXXXXdw=='
configuration.api_key_prefix['authorization'] = 'Bearer'
configuration.host = 'https://aaaaaaaaaaaaaaa.gr7.us-east-1.eks.amazonaws.com'
other options are important as well or else you can use default kubeconfig location by adding following line in your code.
config.load_kube_config()
Generally we can authenticate our client in different ways here i will give example for two ways.
If you are using this method make sure you have, config file at ~/.kube/config
If there is no file present at this location, use kubectl config view
to get the content of config file and save it to config file and place that file at ~/.kube/config
Example for first case:
following code will give you listofpods in default namespace
from kubernetes import client, config
#<<<observe below line of code >>>
#uses default config file loccated at ~/.kube/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))
res = v1.list_namespaced_pod(namespace='default',watch=False)
for i in res.items:
print("%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))
Example for second case
This code lists names of namespaces
import kubernetes.client
<<<pay attention here next five lines of code>>>
configuration = kubernetes.client.Configuration()
configuration.ssl_ca_cert = 'ca.crt'
configuration.api_key['authorization'] = 'ZXXXXXXXXXXdw=='
configuration.api_key_prefix['authorization'] = 'Bearer'
configuration.host = 'https://aaaaaaaaaaaaaaa.gr7.us-east-1.eks.amazonaws.com'
api_instance = kubernetes.client.CoreV1Api(kubernetes.client.ApiClient(configuration))
api_response = api_instance.list_namespace()
for i in api_response.items:
print(i.metadata.name)
for more info refer official GitHub repository for examples
refer: my answer to similar problem