<p>I'm using the supported python Kubernetes library (<code>pip install kubernetes</code>, v12.0.1). When I make a request to my cluster for any option (eg to create a <code>Namespace</code>), it fails with the following error:</p>
<pre><code>import kubernetes.client

def create_namespace(self, namespace_key):                            
    with kubernetes.client.ApiClient(self.configuration) as client:
        api = kubernetes.client.CoreV1Api(client)                  
        api.create_namespace(                                      
            {                                                      
                &quot;apiVersion&quot;: &quot;v1&quot;,                                
                &quot;kind&quot;: &quot;Namespace&quot;,                               
                &quot;metadata&quot;: {                                      
                    &quot;name&quot;: namespace_key,                        
                },                                                 
            }                                                      
        )                                                          


urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='&lt;url of my cluster&gt;', port=443): Max retries exceeded with url: /api/v1/namespaces (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer
 certificate (_ssl.c:1123)')))
</code></pre>
<p>If I turn off SSL configuration using <code>self.configuration.verify_ssl = False</code> in the client, the request works, but it gives me a warning telling me that disabling SSL is strongly discouraged.</p>
<p>My setup:</p>
<ul>
<li>Ubuntu 20.04.1 LTS (running in a VM on mac OSX)</li>
<li>Python 3.8.5 (virtual env, no pyenv or pipenv)</li>
<li>The virtualenv has <code>certifiy==2020.11.8</code> installed (not sure if this impacts SSL interactions or not)</li>
</ul>
<p>Is there anything system-wide that I need to do locally and/or to the docker container that will eventually be running these requests in production?</p>
<p><em>EDIT</em>
A bit more info:</p>
<pre><code>&gt;&gt;&gt; import ssl                
&gt;&gt;&gt; print(ssl.OPENSSL_VERSION)
OpenSSL 1.1.1f  31 Mar 2020   
</code></pre>

Robert Townley
<p>This ended up being my mistake: my hosted Kubernetes provider (Digital Ocean) provides a custom TLS certificate with Kubernetes credentials, and that needs to be used as the certificate for the k8s python client.</p>
<p>In general, you might see this regardless of hosting provider if the certificate used in your client doesn't match what the k8s API is expecting.</p>
<p>Specifically, this was how I resolved the issue for Digital Ocean:</p>
<pre><code>    headers = {
        &quot;Content-Type&quot;: &quot;application/json&quot;,
        &quot;Authorization&quot;: f&quot;Bearer {DIGITAL_OCEAN_ACCESS_TOKEN}&quot;,
    }
    url = (
        f&quot;https://api.digitalocean.com/v2/kubernetes/clusters/{cluster_id}/credentials&quot;
    )
    response = requests.get(url, headers=headers)
    data = json.loads(response.content.decode(&quot;utf-8&quot;))
    if response.status_code != 200:
        raise Exception(f&quot;Unable to authenticate to cluster {cluster_id}&quot;)
    my_clusters_host_url = data[&quot;server&quot;]
    my_new_api_key = data[&quot;token&quot;]

    # Decode and save certificate
    decoded_certificate = base64.b64decode(data[&quot;certificate_authority_data&quot;])
    certificate_authority_data = str(decoded_certificate, &quot;utf-8&quot;)
</code></pre>
<p>As far as I know, the client doesn't let you set the cert data directly; it needs to be saved to a file. So I create a tmp file below:</p>
<pre><code>        filepath = f&quot;/tmp/cluster_{cluster.id}.crt&quot;
        with open(filepath, &quot;w+&quot;) as f:
            f.write(certificate_authority_data)
        configuration = kubernetes.client.Configuration(
            host=host_url,
            api_key={
                &quot;authorization&quot;: f&quot;Bearer {api_key}&quot;,
            },
        )
        configuration.ssl_ca_cert = filepath
</code></pre>
<p>And then that configuration object can be used in other API requests. For example:</p>
<pre><code>        with kubernetes.client.ApiClient(configuration) as client:
            api = kubernetes.client.CoreV1Api(client)
            api.create_namespace(payload)
</code></pre>
