0

My situation:

  • existing Docker container image, exposing its service via a websocket at, say, port 5000. When deployed, the websocket's service is exposed on the host (again) on port 5000.
  • existing Python client connecting to this service via websocket, using Autobahn's websockets and Twisted.
  • Kubernetes cluster running a the aformentioned Docker container image in a pod, exposing its service again, at port 5000. The pod's service has an associated Service resource, but the service isn't directly accessable from outside the cluster, except via the cluster API using the proxy verb.

I now want to upgrade my Python client to not only directly connect to my service on a Docker host, but also to my service when deployed inside a Kubernetes cluster. That is, I want the websocket to connect to my cluster's remote API and my service's proxy verb. I would prefer not to rewrite the existing websocket protocol and handling, if possible.

My current (limited) understanding is, that for this constraint, the stream mechanism in the Kubernetes Python client is of no help to me, as this would need a complete rewrite of my existing Python code base.

My question now is (at least I think that's the question here): how can I get the necessary authentication information (Bearer token?) from the Kubernetes client in order to hand it to the Autobahn websocket in order to successfully connect from the outside of my Kubernetes cluster to my service inside?

from twisted.internet import reactor
from autobahn.twisted.websocket import WebSocketClientFactory, WebSocketClientProtocol, connectWS

import kubernetes
import kubernetes.client
import kubernetes.client.configuration

# My service's websocket protocol...
class MyPrtocol(WebSocketClientProtocol):
    def onConnect(self, response):
        pass

kubernetes.config.load_kube_config()  # activates default context

# **********************
# Here I'm lost!
headers = { ... ? }
# **********************

myurl = kubernetes.client.configuration.Configuration._default.host + '/api/v1/.../proxy'
factory = WebSocketClientFactory(myurl, headers=headers)
factory.protocol = MyProtocol
connectWS(factory)
TheDiveO
  • 2,183
  • 2
  • 19
  • 38
  • See answer to this question: https://stackoverflow.com/questions/48151388/kubernetes-python-client-authentication-issue – Vasili Angapov Apr 22 '19 at 06:17
  • Thank you, Vasily! Is there a way to use the Bearer token used by the Python client itself afte it has connected to my cluster, without having to export the token via kubectl? The rationale is that my Python script is a plugin that should be used as easy as is, picking up the existing kubectl configuration? – TheDiveO Apr 22 '19 at 08:12
  • >>> from kubernetes import config >>> import kubernetes >>> config.load_kube_config() >>> kubernetes.client.configuration.Configuration._default.api_key {'authorization': 'Bearer ya29.Kl3zBA2GQ-7xEUrvDHR9ApfEp1jEBPRVlEiJ5c6-o4Mpi1P3iz3ZVgxVMp0J7fwIIklsdDvmXq-gghD92iyoX1D5DF89TL0shOOZ1H40cswQDIKjLYkya6noEj270Hs'} – Vasili Angapov Apr 22 '19 at 08:47
  • Hmm ... when I use a minikube setup and then look at `kubernetes.client.configuration.Configuration` after a successfull `v1.list_pod_for_all_namespaces()` then `_default.apikey` is an empty dict(). So this seems to depend on the setup, I suppose. – TheDiveO Apr 22 '19 at 08:51
  • However, I can see that `kubernetes.client.configuration.Configuration` has `cert_file`, `key_file`, and `ssl_ca_cert` correctly populated per my `.kube/config`. And a `curl -X GET --cert ... --key ... -cacert ... https://.../api/v1/pods` succeeds. – TheDiveO Apr 22 '19 at 08:54

1 Answers1

1
python
>>> import kubernetes
>>> from kubernetes import config
>>> config.load_kube_config()
>>> kubernetes.client.configuration.Configuration._default.api_key
{'authorization': 'Bearer ya29.GGHzBj2GQ-aaaaaaafEp1jEBKKLKJJiJ5c6-o4Mpi1P3xxxxxxxxxxxklsdRYmXq-gghD92iyoX1DyyyyyyyyyyyQDIKjLYkyzzzzzzzzz'}

That's how you can get bearer token from kubeconfig.

Vasili Angapov
  • 8,061
  • 15
  • 31
  • Thank you very much Vasily! You are confirming my suspicion that the bearer token isn't always used, opposing to what I thought before. With the minikube setup I'm playing with the bearer token doesn't get set, but instead I see the required cert and key file references getting picked up from `.kube/config`. So I suspect that there are multiple cases to cater for: no bearer, and bearer present. – TheDiveO Apr 22 '19 at 08:57
  • I've updated the question title to reflect the bearer token situation. Since I now know that there are also situations where I need the certificates, it's better to ask a separate question focusing on this other situation. – TheDiveO Apr 22 '19 at 17:33