Search code examples
python-3.xwebsocketkubernetestwistedautobahn

Kubernetes Python Client: connecting to a pod/service using Autobahn websocket/Twisted using bearer token


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)

Solution

  • 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.