derailed / k9s

🐶 Kubernetes CLI To Manage Your Clusters In Style!
https://k9scli.io
Apache License 2.0
27.03k stars 1.7k forks source link

Use k9s inside a cluster with Service Account's credentials #768

Open pre opened 4 years ago

pre commented 4 years ago

In some use cases it's useful to run k9s inside the cluster in a pod.

It would be great to be able to directly use the Service Account's credentials. Currently k9s requires a $KUBECONFIG file. In other words, currently k9s cannot use credentials in /var/run/secrets/kubernetes.io/serviceaccount/ without first converting them to $KUBECONFIG.

Workaround is to create $KUBECONFIG before starting k9s, but that's boilerplate and requires a wrapper script for k9s (not nice).

The rest.InClusterConfig() provided by go-client could handle this instead. See the example in https://github.com/kubernetes/client-go/blob/master/examples/in-cluster-client-configuration/main.go

As a workaround, at the moment something like this is required to run k9s with Service Account's credentials:



MASTER="https://192.168.42.100:6443"
KUBECONFIG="${HOME}/.kube/config"
TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
CA_CRT="$(base64 -w 0 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt)"

cat <<EOF > "${KUBECONFIG}"
apiVersion: v1
kind: Config
clusters:
- name: default-cluster
  cluster:
    certificate-authority-data: ${CA_CRT}
    server: ${MASTER}
contexts:
- name: default-context
  context:
    cluster: default-cluster
    namespace: default
    user: default-user
current-context: default-context
users:
- name: default-user
  user:
    token: ${TOKEN}
EOF
schedin commented 3 days ago

I also would like k9s to implement this feature! I created a modified workaround based on what @pre suggested:

kubectl config set-credentials default-user \
    --exec-interactive-mode Never \
    --exec-api-version=client.authentication.k8s.io/v1 \
    --exec-command=python3 \
    --exec-arg="-c" \
    --exec-arg="import json; token=open('/var/run/secrets/kubernetes.io/serviceaccount/token').read(); d={}; d['kind']='ExecCredential'; d['apiVersion']='client.authentication.k8s.io/v1'; d['status']={'token':token}; print(json.dumps(d))"
kubectl config set-cluster default-cluster --server=https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT_HTTPS} --certificate-authority=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
kubectl config set-context default-context --cluster=default-cluster --user=default-user --namespace=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
kubectl config use-context default-context

Advantages:

  1. Uses environment variables for Kubernetes API server
  2. Will (probably) work if the token validity is short (like 1 hour).
  3. Picks up the namespace for k9s to use as default (from the service account namespace)

Disadvantages:

  1. Requires kubectl and Python 3 in the container
  2. Hard to understand Python code.