title: Kubernetes authentication with certificate
body: <p>I am trying to authenticate with a locally hosted Kubernetes cluster (v1.6.4) using a certificate.
  This takes part in the context of using the <a href="https://github.com/jenkinsci/kubernetes-plugin" rel="nofollow noreferrer">Kubernetes plugin for Jenkins</a>.</p>
  
  <p>I am following the guidelines for Minikube in the <a href="https://github.com/jenkinsci/kubernetes-plugin" rel="nofollow noreferrer">Kubernetes-plugin README</a> file which I adapted to my scenario:</p>
  
  <ol>
  <li><p>Convert the client certificate to PKCS:</p>
  
  <pre><code>$ sudo openssl pkcs12 -export -out kubernetes.pfx -inkey /etc/kubernetes/pki/apiserver.key -in /etc/kubernetes/pki/apiserver.crt -certfile /etc/kubernetes/pki/ca.crt -passout pass:jenkins
  </code></pre></li>
  <li><p>In Jenkins, create credentials using a certificate</p>
  
  <ol>
  <li><code>Kind</code>: <code>Certificate</code></li>
  <li><code>Certificate</code>: <code>Upload PKCS#12 certificate</code> and upload file <code>kubernetes.pfx</code></li>
  <li><code>Password</code>: <code>jenkins</code> (as specified during certificate creation)</li>
  </ol></li>
  <li><code>Manage Jenkins</code> -> <code>Add new cloud</code> -> <code>Kubernetes</code>
  
  <ol>
  <li><code>Kubernetes URL</code>: <code>https://10.179.1.121:6443</code> (as output by <code>kubectl config view</code>)</li>
  <li><code>Kubernetes server certificate key</code>: paste the contents of <code>/etc/kubernetes/pki/ca.crt</code>.</li>
  <li><code>Disable https certificate check</code>: checked because the test setup does not have a signed certificate</li>
  <li><code>Kubernetes Namespace</code>: tried both <code>default</code> and <code>kubernetes-plugin</code></li>
  <li><code>Credentials</code>: <code>CN=kube-apiserver</code> (i.e. the credentials created above)</li>
  </ol></li>
  </ol>
  
  <p>Now when I click on <code>Test Connection</code>, this is the error message shown in the Jenkins Web UI:</p>
  
  <blockquote>
    <p>Error connecting to <a href="https://10.179.1.121:6443" rel="nofollow noreferrer">https://10.179.1.121:6443</a>: Failure executing: GET at: <a href="https://10.179.1.121:6443/api/v1/namespaces/kubernetes-plugin/pods" rel="nofollow noreferrer">https://10.179.1.121:6443/api/v1/namespaces/kubernetes-plugin/pods</a>. Message: Unauthorized.</p>
  </blockquote>
  
  <p>The Jenkins logs show this message:</p>
  
  <blockquote>
    <p>Sep 05, 2017 10:22:03 AM io.fabric8.kubernetes.client.Config tryServiceAccount</p>
    
    <p>WARNING: Error reading service account token from: [/var/run/secrets/kubernetes.io/serviceaccount/token]. Ignoring.</p>
  </blockquote>
  
  <p>The documentation is, unfortunately, mostly limited to Kubernetes running on Minikube and to Google Cloud Engine, but I do not see a conceptual difference between the former and a locally hosted Kubernetes cluster.</p>
  
  <p>The following Curl call for testing results in a very different error message:</p>
  
  <pre><code>$ curl --insecure --cacert /etc/kubernetes/pki/ca.crt --cert kubernetex.pfx:secret https://10.179.1.121:6443
  User "system:anonymous" cannot get  at the cluster scope. 
  </code></pre>
  
  <p>More verbose:</p>
  
  <pre><code>$ curl -v --insecure --cacert /etc/kubernetes/pki/ca.crt --cert kubernetex.pfx:secret https://10.179.1.121:6443
  * About to connect() to 10.179.1.121 port 6443 (#0)
  *   Trying 10.179.1.121...
  * Connected to 10.179.1.121 (10.179.1.121) port 6443 (#0)
  * Initializing NSS with certpath: sql:/etc/pki/nssdb
  * skipping SSL peer certificate verification
  * NSS: client certificate not found: kubernetex.pfx
  * SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  * Server certificate:
  *   subject: CN=kube-apiserver
  *   start date: Jun 13 11:33:55 2017 GMT
  *   expire date: Jun 13 11:33:55 2018 GMT
  *   common name: kube-apiserver
  *   issuer: CN=kubernetes
  &gt; GET / HTTP/1.1
  &gt; User-Agent: curl/7.29.0
  &gt; Host: 10.179.1.121:6443
  &gt; Accept: */*
  &gt; 
  &lt; HTTP/1.1 403 Forbidden
  &lt; Content-Type: text/plain
  &lt; X-Content-Type-Options: nosniff
  &lt; Date: Tue, 05 Sep 2017 10:34:23 GMT
  &lt; Content-Length: 57
  &lt; 
  * Connection #0 to host 10.179.1.121 left intact
  </code></pre>
  
  <p>I have also set up a ServiceAccount:</p>
  
  <pre><code>$ kubectl describe serviceaccount --namespace=kubernetes-plugin 
  Name:       default
  Namespace:  kubernetes-plugin
  Labels:     &lt;none&gt;
  Annotations:    &lt;none&gt;
  
  Image pull secrets: &lt;none&gt;
  
  Mountable secrets:  default-token-6qwj1
  
  Tokens:             default-token-6qwj1
  
  
  
  Name:       jenkins
  Namespace:  kubernetes-plugin
  Labels:     &lt;none&gt;
  Annotations:    &lt;none&gt;
  
  Image pull secrets: &lt;none&gt;
  
  Mountable secrets:  jenkins-token-1d623
  
  Tokens:             jenkins-token-1d623
  </code></pre>
  
  <p><a href="https://stackoverflow.com/questions/45094665/user-systemanonymous-cannot-get-path/45097914#45097914">This question</a> deals with a related problem, recommending to use either a ServiceAccount or a certificate, but the answer to the latter aproach lacks the details about how to tie an RBAC profile to that certificate. The <a href="https://kubernetes.io/docs/admin/authentication/" rel="nofollow noreferrer">Kubernetes documentation about authentication</a> does not seem to cover this use case.</p>