Skip to main content

Register a Kubernetes Cluster with a Static kubeconfig

Report an Issue

While you can register a Kubernetes cluster with Teleport by running the Teleport Kubernetes Service on that cluster, you can also run the Teleport Kubernetes Service on a Linux host outside the cluster. This is useful if you want to decouple your Teleport deployment from the Kubernetes clusters you want to manage access to.

In this guide, you will enroll the Teleport Kubernetes Service with Teleport and configure the service to proxy a Kubernetes cluster with a static kubeconfig.

How it works

In this setup, the Teleport Kubernetes Service uses a kubeconfig file to authenticate to the API server of your chosen Kubernetes cluster.

Prerequisites

  • A running Teleport cluster. If you want to get started with Teleport, sign up for a free trial or set up a demo environment.

  • The tctl and tsh clients.

    Installing tctl and tsh clients
    1. Determine the version of your Teleport cluster. The tctl and tsh clients must be at most one major version behind your Teleport cluster version. Send a GET request to the Proxy Service at /v1/webapi/find and use a JSON query tool to obtain your cluster version. Replace teleport.example.com:443 with the web address of your Teleport Proxy Service:

      TELEPORT_DOMAIN=teleport.example.com:443
      TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')"
    2. Follow the instructions for your platform to install tctl and tsh clients:

      Download the signed macOS .pkg installer for Teleport, which includes the tctl and tsh clients:

      curl -O https://cdn.teleport.dev/teleport-${TELEPORT_VERSION?}.pkg

      In Finder double-click the pkg file to begin installation.

      danger

      Using Homebrew to install Teleport is not supported. The Teleport package in Homebrew is not maintained by Teleport and we can't guarantee its reliability or security.

    Connecting with TLS routing disabled

    This guide's commands assume your Teleport cluster uses TLS routing (proxy_listener_mode: multiplex), where the tctl and tsh clients reach every Teleport service through the Proxy Service's web address on port 443. If you're not sure whether this applies to your cluster, check with whoever manages it.

    If your cluster uses separate listener ports instead, adjust ports as follows:

    • tsh commands (e.g., tsh login --proxy=...): continue using the Proxy Service web address on port 3080 (or 443 if behind a load balancer). Do not change these to port 3025.

    • Direct tctl or Auth Service API commands: use port 3025 for the Auth Service gRPC listener:

      tctl status --auth-server=teleport.example.com:3025
  • A Kubernetes cluster you would like to access.
  • A Linux host deployed on your own infrastructure to run the Teleport Kubernetes Service. This can run outside of your Kubernetes cluster.
  • The kubectl command line tool installed on your workstation.
  • Check that you can connect to your Teleport cluster and verify that you can run tctl and tsh commands using your current credentials.
    1. Assign teleport.example.com to the domain name of the Teleport Proxy Service in your cluster and [email protected] to your Teleport username.

    2. Authenticate to your Teleport cluster. This depends on whether your shell is interactive or not.

      In an interactive shell: Run the following command. By default, this triggers a multi-factor authentication prompt:

      tsh login --proxy=teleport.example.com --user=[email protected]
      tctl status

      Cluster teleport.example.com

      Version 18.10.0

      CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

      On non-interactive environments: If you are running tsh and tctl as an AI agent, in a CI/CD environment, or similar, make sure the TELEPORT_IDENTITY_FILE environment variable is assigned to a valid file path with credentials for your cluster. tsh and tctl read the file path from the environment variable and do not require a separate authentication step. If there is no identity file available, we recommend that you set up Machine ID to provision one automatically.

      When executing tctl commands with an identity file, you must pass the --auth-server flag to provide the Teleport Auth Service address, which is not included in the identity file. If you provide the Proxy Service address, tctl connects to the Proxy Service, which forwards traffic to and from the Teleport Auth Service. Update 443 to 3025 if you are contacting the Auth Service directly with tctl:

      tctl status --auth-server=teleport.example.com:443

      For tsh commands that read an identity file, you must pass the --proxy flag, which points tsh to the address of the Teleport Proxy Service:

      tsh status --proxy=teleport.example.com

      Ensure client commands can access your identity file. Replace path/to/identity/file with the path to your identity file:

      export TELEPORT_IDENTITY_FILE="${TELEPORT_IDENTITY_FILE:-path/to/identity/file}"

      Add the --auth-server or --proxy flags to all subsequent tctl and tsh commands.

    If you can connect to the cluster and run the tctl status command, you can use your current credentials to run subsequent tctl commands from your workstation. If you host your own Teleport cluster, you can also run tctl commands on the computer that hosts the Teleport Auth Service for full permissions.
Best practices for production security

When running Teleport in production, you should adhere to the following best practices to avoid security incidents:

  • Avoid using sudo in production environments unless it's necessary.
  • Create new, non-root, users and use test instances for experimenting with Teleport.
  • Run Teleport's services as a non-root user unless required. Only the SSH Service requires root access. Note that you will need root permissions (or the CAP_NET_BIND_SERVICE capability) to make Teleport listen on a port numbered < 1024 (e.g. 443).
  • Follow the principle of least privilege. Don't give users permissive roles when more a restrictive role will do. For example, don't assign users the built-in access,editor roles, which give them permissions to access and edit all cluster resources. Instead, define roles with the minimum required permissions for each user and configure Access Requests to provide temporary elevated permissions.
  • When you enroll Teleport resources—for example, new databases or applications—you should save the invitation token to a file. If you enter the token directly on the command line, a malicious user could view it by running the history command on a compromised system.

You should note that these practices aren't necessarily reflected in the examples used in documentation. Examples in the documentation are primarily intended for demonstration and for development environments.

Step 1/4. Generate a kubeconfig file

The Teleport Kubernetes Service uses a kubeconfig file to authenticate to your Kubernetes cluster. In this section, we will generate a kubeconfig file so we can configure the Teleport Kubernetes Service to use it later in this guide.

Ensure your context is correct

First, configure your local kubectl command to point at the Kubernetes cluster you want to register. You can use the following command to verify that the correct cluster is selected:

kubectl config get-contexts

Use this command to switch to the cluster assigned to context-name:

e.g., my-context

kubectl config use-context context-name

Run the script

On your workstation, download Teleport's get-kubeconfig.sh script, which you will use to generate the kubeconfig file:

curl -OL \https://raw.githubusercontent.com/gravitational/teleport/v18.10.0/examples/k8s-auth/get-kubeconfig.sh

get-kubeconfig.sh creates a service account for the Teleport Kubernetes Service that can get Kubernetes pods as well as impersonate users, groups, and other service accounts. The Teleport Kubernetes Service uses this service account to manage access to resources in your Kubernetes cluster. The script also ensures that there is a Kubernetes Secret in your cluster to store service account credentials.

get-kubeconfig.sh also creates a namespace called teleport for the resources it deploys, though you can choose a different name by assigning the TELEPORT_NAMESPACE environment variable in the shell where you run the script.

After creating resources, get-kubeconfig.sh writes a new kubeconfig file called kubeconfig in the directory where you run the script.

Run the get-kubeconfig.sh script:

bash get-kubeconfig.sh

The script is successful if you see this message:

Done!

Move the kubeconfig file to the host you are using to run the Teleport Kubernetes Service. We will assume that the kubeconfig file exists at /var/lib/teleport/kubeconfig.

Connecting multiple Kubernetes clusters?

You can connect multiple Kubernetes clusters to Teleport from one kubeconfig file if it contains multiple entries. Use merge-kubeconfigs.sh to combine multiple kubeconfig files generated by get-kubeconfig.sh.

Step 2/4. Set up the Teleport Kubernetes Service

In this step, you will install the Teleport Kubernetes Service and configure it to use the kubeconfig file you generated to access a Kubernetes cluster.

Get a join token

Establish trust between your Teleport cluster and your new Kubernetes Service instance by creating a join token:

tctl tokens add --type=kube --format=text --ttl=1h
abcd123-insecure-do-not-use-this

Assign join-token to your join token. On the host where you are running the Teleport Kubernetes Service, create a file called /tmp/token that consists only of your token:

echo join-token | sudo tee /tmp/token

Install the Teleport Kubernetes Service

Run the following commands on the host where you will install the Teleport Kubernetes Service:

To install Teleport binaries on your Linux server, the recommended installation method is the cluster install script. It will select the correct version, edition, and installation mode for your cluster.

  1. Remove any existing Teleport binaries on your system:

    sudo rm -f /usr/local/bin/{tsh,teleport,tctl,tbot,fdpass-teleport,teleport-update}
  2. Assign teleport.example.com:443 to your Teleport cluster hostname and port, but not the scheme (https://).

  3. Run your cluster's install script:

    curl "https://teleport.example.com:443/scripts/install.sh" | sudo bash

Configure the Teleport Kubernetes Service

Assign teleport.example.com:443 with the host and port of your Teleport Proxy Service or Teleport Cloud tenant, e.g., mytenant.teleport.sh:443. On the host where you will run the Teleport Kubernetes Service, create a file at /etc/teleport.yaml with the following content:

version: v3
teleport:
  join_params:
    token_name: "/tmp/token"
    method: token
  proxy_server: teleport.example.com:443
auth_service:
  enabled: false
proxy_service:
  enabled: false
ssh_service:
  enabled: false
kubernetes_service:
  enabled: true
  kubeconfig_file: "/var/lib/teleport/kubeconfig"
  labels:
    "region": "us-east-1"
Warning

When using kubeconfig_file, Amazon EKS users may need to replace illegal characters in the context names. Supported characters are alphanumeric characters, ., _, and -. EKS typically includes : and @ in their kubeconfig files, which are not allowed in Teleport.

Start the Teleport Kubernetes Service

Start the Teleport Kubernetes Service. The instructions depend on how you installed the Teleport Kubernetes Service and whether your system supports systemd:

Configure the Teleport Kubernetes Service to start automatically when the host boots up by creating a systemd service for it. On the host where you will run the Teleport Kubernetes Service, enable and start Teleport:

sudo systemctl enable teleport
sudo systemctl start teleport

You can check the status of the Teleport Kubernetes Service with systemctl status teleport and view its logs with journalctl -fu teleport.

Step 3/4. Grant access to your Teleport user

Enable your Teleport user to access resources in your Kubernetes cluster so you can connect to the cluster later in this guide.

To authenticate to a Kubernetes cluster via Teleport, your Teleport user's roles must allow access as at least one Kubernetes user or group.

  1. Retrieve a list of your current user's Teleport roles. The example below requires the jq utility for parsing JSON:

    CURRENT_ROLES=$(tsh status -f json | jq -r '.active.roles | join ("\n")')
  2. Retrieve the Kubernetes groups your roles allow you to access:

    echo "$CURRENT_ROLES" | xargs -I{} tctl get roles/{} --format json | \ jq '.[0].spec.allow.kubernetes_groups[]?'
  3. Retrieve the Kubernetes users your roles allow you to access:

    echo "$CURRENT_ROLES" | xargs -I{} tctl get roles/{} --format json | \ jq '.[0].spec.allow.kubernetes_users[]?'
  4. If the output of one of the previous two commands is non-empty, your user can access at least one Kubernetes user or group, so you can proceed to the next step.

  5. If both lists are empty, create a Teleport role for the purpose of this guide that can view Kubernetes resources in your cluster.

    Create a file called kube-access.yaml with the following content:

    kind: role
    metadata:
      name: kube-access
    version: v7
    spec:
      allow:
        kubernetes_labels:
          '*': '*'
        kubernetes_resources:
          - kind: '*'
            namespace: '*'
            name: '*'
            verbs: ['*']
        kubernetes_groups:
        - viewers
      deny: {}
    
  6. Apply your changes:

    tctl create -f kube-access.yaml
    tip

    You can also create and edit roles using the Web UI. Go to Access -> Roles and click Create New Role or pick an existing role to edit.

  7. Assign the kube-access role to your Teleport user by running the appropriate commands for your authentication provider:

    1. Retrieve your local user's roles as a comma-separated list:

      ROLES=$(tsh status -f json | jq -r '.active.roles | join(",")')
    2. Edit your local user to add the new role:

      tctl users update $(tsh status -f json | jq -r '.active.username') \ --set-roles "${ROLES?},kube-access"
    3. Sign out of the Teleport cluster and sign in again to assume the new role.

  8. Configure the viewers group in your Kubernetes cluster to have the built-in view ClusterRole. When your Teleport user assumes the kube-access role and sends requests to the Kubernetes API server, the Teleport Kubernetes Service impersonates the viewers group and proxies the requests.

    Create a file called viewers-bind.yaml with the following contents, binding the built-in view ClusterRole with the viewers group you enabled your Teleport user to access:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: viewers-crb
    subjects:
    - kind: Group
      # Bind the group "viewers", corresponding to the kubernetes_groups we assigned our "kube-access" role above
      name: viewers
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      # "view" is a default ClusterRole that grants read-only access to resources
      # See: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles
      name: view
      apiGroup: rbac.authorization.k8s.io
    
  9. Apply the ClusterRoleBinding with kubectl:

    kubectl apply -f viewers-bind.yaml

Step 4/4. Access your Kubernetes cluster

After Teleport starts with the above config, you should be able to see all new clusters:

tsh kube ls
Kube Cluster Name Labels Selected--------------------------------------- ------ --------my-cluster region=us-east-1

To access your cluster, run the following command, replacing my-cluster with the name of the cluster you would like to access:

tsh kube login my-cluster
Logged into kubernetes cluster "my-cluster". Try 'kubectl version' to test the connection.