0

我正在尝试使用Python Kubernetes 客户端连接到我的 microk8s Kubernetes 集群,该集群正在侦听端口 16443 :

#!/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()

如果我没有设置任何字段或示例中的配置cert_file,则连接失败是由于key_fileapi_key

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)')))

如果我指定api_key如上面的代码所示,我得到

  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)')))

我尝试设置一些证书ca.crt,如图所示,但是ca.key由于/var/snap/microk8s/current/certs以下原因而失败

  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)')))

我在带有 Python 3.7 和 Kubernetes Python 客户端 10.0.0 的 Ubuntu 19.04 上使用 microk8s 1.15.0 (695)。

4

3 回答 3

3

您需要将路径传递给 ca.crt 文件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'

其他选项也很重要,否则您可以通过在代码中添加以下行来使用默认的 kubeconfig 位置。

config.load_kube_config()

一般来说,我们可以通过不同的方式验证我们的客户端,这里我将举例说明两种方式。

  1. 通过在~/.kube/config使用配置文件的默认位置。

如果您使用此方法,请确保您拥有~/.kube/config中的配置文件

如果此位置没有文件,请使用kubectl config view获取配置文件的内容并将其保存到配置文件并将该文件放置在~/.kube/config

第一种情况的示例:

以下代码将为您提供默认命名空间中的列表

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))
  1. 通过定义证书和不记名令牌。

第二种情况的例子

此代码列出了命名空间的名称

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)

有关更多信息,请参阅官方 GitHub 存储库以获取示例

参考:我对类似问题的回答

于 2019-07-24T12:05:24.747 回答
0

这适用于 AWS EKS 集群:

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)
于 2019-12-02T21:24:39.827 回答
0

您的 SSL 验证未通过 TLS 检查。最简单和最快的解决方法是将您的 Kube 配置设置为跳过 tls-verify,因为您使用的是单个节点。

clusters:
- cluster:  
    server: https://127.0.0.1:16443
    insecure-skip-tls-verify: true
于 2019-07-14T14:33:57.420 回答