<h3>Problem</h3>

<p>I am trying to enable authentication on my kubelet servers using Bearer Tokens (<strong>not</strong> X.509 client certificate authentication), and fail to understand the workflow.</p>

<h3>What I tried</h3>

<p>According to the documentation page <a href="https://kubernetes.io/docs/admin/kubelet-authentication-authorization/" rel="nofollow noreferrer">Kubelet authentication/authorization</a>, starting the kubelet with the <code>--authentication-token-webhook</code> flag enables the Bearer Token authentication. I could confirm that by sending a request to the kubelet REST API using one of the <code>default</code> secrets created by the Controller Manager:</p>

<pre class="lang-sh prettyprint-override"><code>$ MY_TOKEN="$(kubectl get secret default-token-kw7mk \
      -o jsonpath='{$.data.token}' | base64 -d)"

$ curl -sS -o /dev/null -D - \
      --cacert /var/run/kubernetes/kubelet.crt \
      -H "Authorization : Bearer $MY_TOKEN" \
      https://host-192-168-0-10:10250/pods/

HTTP/1.1 200 OK
Content-Type: application/json
Date: Fri, 30 Jun 2017 22:12:29 GMT
Transfer-Encoding: chunked
</code></pre>

<p>However any communication with the kubelet <strong>via the API server</strong> (typically using the kubectl <code>logs</code> or <code>exec</code> commands) using the same Bearer Token as above fails with:</p>

<pre><code>$ kubectl --token="$MY_TOKEN" -n kube-system logs \
      kube-dns-2272871451-sc02r -c kubedns

error: You must be logged in to the server (the server has asked for the client to provide credentials ( pods/log kube-dns-2272871451-sc02r))
</code></pre>

<h3>Where I need clarification</h3>

<p>My initial assumption was that the API server just passed the Bearer Token it received from the client directly to the kubelet, but my little experiment above proved me otherwise.</p>

<p>I see that the <a href="https://kubernetes.io/docs/admin/kube-apiserver/" rel="nofollow noreferrer">kube-apiserver</a> documentation mentions a flag called <code>--authentication-token-webhook-config-file</code> but I'm unsure how to use it, or if it's even relevant for authenticating the API server against a kubelet.</p>

<h3>Current configuration</h3>

<p>My kubelet(s) run with:</p>

<pre><code>  --anonymous-auth=false
  --authorization-mode=Webhook
  --authentication-token-webhook
  --cadvisor-port=0
  --cluster-dns=10.0.0.10
  --cluster-domain=cluster.local
  --read-only-port=0
  --kubeconfig=/etc/kubernetes/kubeconfig-kubelet
  --pod-manifest-path=/etc/kubernetes/manifests
  --require-kubeconfig
</code></pre>

<p>My API server runs with:   </p>

<pre><code>  --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds
  --anonymous-auth=false
  --authorization-mode=AlwaysAllow
  (+ tls flags)
</code></pre>

<p>When making calls to the API server that require communication from the API server to the kubelet, that communication is done using the API server's client credentials, which only support x509 authentication to the kubelet.</p>

<p>The flags used to give the API server the credentials to use to contact the kubelet are listed in the "X509 client certificate authentication" section of <a href="https://kubernetes.io/docs/admin/kubelet-authentication-authorization/" rel="nofollow noreferrer">https://kubernetes.io/docs/admin/kubelet-authentication-authorization/</a></p>

<p>API server webhook authentication options are unrelated to kubelet auth. </p>
