docs: kubernetes joining guide + reference (#20298)

* docs: kubernetes joining guide + reference

* fixup! docs: kubernetes joining guide + reference

* Address most feedback

* Apply suggestions from code review

Co-authored-by: Paul Gottschling <paul.gottschling@goteleport.com>

* Update docs/pages/management/guides/joining-services-kubernetes-serviceaccount.mdx

Co-authored-by: Paul Gottschling <paul.gottschling@goteleport.com>

* Explain what the join method does

---------

Co-authored-by: Paul Gottschling <paul.gottschling@goteleport.com>
This commit is contained in:
Hugo Shaka 2023-04-13 11:42:54 -04:00 committed by GitHub
parent ab8d928794
commit aff81fece2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 284 additions and 3 deletions

View file

@ -575,6 +575,11 @@
"title": "Joining Nodes via Azure",
"slug": "/management/guides/joining-nodes-azure/"
},
{
"title": "Joining Services via Kubernetes ServiceAccount",
"slug": "/management/guides/joining-services-kubernetes-serviceaccount/",
"forScopes": ["oss", "enterprise"]
},
{
"title": "Using Teleport's CA with GitHub",
"slug": "/management/guides/ssh-key-extensions/"

View file

@ -40,9 +40,9 @@ teleport:
join_params:
# When `method` is set to "token", it is the equivalent to using `auth_token` above.
# You should only use either auth_token or join_params.
method: "token"|"ec2"|"iam"
method: "token"|"ec2"|"iam"|"github"|"circleci"|"kubernetes"
# If method is "iam" or "ec2", token_name will be will be the name of
# If method is not "token", token_name will be will be the name of
# the joining token resource, e.g., "ec2-token" or "iam-token" as created
# in the Joining Nodes via EC2 or IAM guides.
@ -117,4 +117,3 @@ teleport:
format:
output: text
extra_fields: [level, timestamp, component, caller]

View file

@ -11,6 +11,8 @@ layout: tocless-doc
- [Joining Nodes via AWS IAM Role](./guides/joining-nodes-aws-iam.mdx). Use the IAM join method to add Nodes to your Teleport cluster on AWS.
<ScopedBlock scope={["oss", "enterprise"]}>
- [Joining Nodes via AWS EC2 Identity Document](./guides/joining-nodes-aws-ec2.mdx). Use the EC2 join method to add Nodes to your Teleport cluster on AWS.
- [Joining Services via Kubernetes ServiceAccount](./guides/joining-services-kubernetes-serviceaccount.mdx).
Use Kubernetes ServiceAccount tokens to join services running in the same Kubernetes cluster as the Auth Service.
</ScopedBlock>
- [Joining Nodes via Azure](./guides/joining-nodes-azure.mdx) Use the Azure join method to add Nodes to your Teleport cluster on Azure.
- [Using Teleport's Certificate Authority with GitHub](./guides/ssh-key-extensions.mdx). Use Teleport's short-lived certificates with GitHub's Certificate Authority.

View file

@ -0,0 +1,275 @@
---
title: Joining Services via Kubernetes ServiceAccount Token
description: Use Kubernetes ServiceAccount tokens to join services running in the same Kubernetes cluster as the Auth Service.
---
This guide will explain how to use the **Kubernetes join method** to configure
Teleport services to join your Teleport cluster without sharing any
secrets when running in the same Kubernetes cluster as the Auth Service.
When a Teleport service wants to be part of the cluster, it needs to prove
its identity to the Teleport Auth Service before receiving its certificates.
Kubernetes issues signed proof to each pod describing which Kubernetes
ServiceAccount they can assume. When using the Kubernetes join
method, Teleport uses this Kubernetes proof to become part of the cluster.
<Notice type="warning">
The Kubernetes join method is not available in Teleport Enterprise Cloud as it requires the
joining service to run in the same Kubernetes cluster as the Auth Service.
</Notice>
The Kubernetes join method is available in self-hosted versions of Teleport 12+.
It supports joining any Teleport service running in the same Kubernetes cluster
as the Auth Service.
## Prerequisites
- A running Teleport cluster in Kubernetes. For details on how to set this up,
see [Guides for running Teleport using Helm](../../deploy-a-cluster/helm-deployments.mdx).
- Editor access to the Kubernetes cluster running the Teleport cluster.
You must be able to create Namespaces and Deployments.
- A Teleport user with `access` role, or any other role that allows access to
applications with the label `app: demo-app`
- Either the Teleport `editor` role or the ability to `kubectl exec` into your
existing Teleport Auth Service pods.
- The Auth Service ServiceAccount must be granted the `system:auth-delegator`
ClusterRole. Clusters deployed with the [`teleport-cluster` Helm
chart](../../reference/helm-reference/teleport-cluster.mdx) version 12 or
higher have the correct role by default.
## Step 1/5. Create a Kubernetes join token
Configure your Teleport Auth Service with a join token (also called provision
token) to allow Teleport services hosted in the Kubernetes cluster to
join your Teleport cluster.
Under the hood, Teleport instances will prove to the Auth Service that
they are running in the same Kubernetes cluster by sending a signed ServiceAccount
token that matches an `allow` rule configured in your Kubernetes join token.
Create a file called `token.yaml` with the following content, which includes
an `allow` rule specifying the Kubernetes namespace and Kubernetes
ServiceAccount in which your Teleport services are running.
```yaml
# token.yaml
kind: token
version: v2
metadata:
# The token name is not a secret as the Kubernetes join method relies on the
# Kubernetes signature to establish trust and not on the join token name.
name: kubernetes-token
# set a long expiry time, the default for tokens is only 30 minutes
expires: "2050-01-01T00:00:00Z"
spec:
# Use the minimal set of system roles required.
# Common roles are:
# - "Node" for SSH Service
# - "Proxy" for Proxy Service
# - "Kube" for Kubernetes Service
# - "App" for Application Service
# - "Db" for Database Service
# - "WindowsDesktop" for Windows Desktop Service
# - "Discovery" for Discovery Service
roles: [App]
# set the join method allowed for this token
join_method: kubernetes
kubernetes:
allow:
# Service account names follow the format "namespace:serviceaccountname".
- service_account: "teleport-agent:teleport-app-service"
```
Kubernetes join tokens can be used by any Teleport service besides the Auth Service, such as the Proxy Service and SSH Service. In this
guide, we restrict the token to joining an Application Service instance.
It is not recommended to use a single token that can join everything. You should
restrict the token to the roles used by the joining instance. For example, a Teleport
instance running both the Application Service and Database Service should use a token with
`roles: [App, Db]`.
Follow the instructions below to create the token depending on whether you have administrative access to the Auth Service pod:
<Tabs>
<TabItem label="Using tctl locally as your current user">
Make sure your local `tctl` is at least at version 12 with `tctl version`.
Create the token:
```code
$ tctl create token.yaml
```
Finally, validate the token was created:
```code
$ tctl get token/kubernetes-token
kind: token
metadata:
expires: "3000-01-01T00:00:00Z"
name: kubernetes-token
spec:
join_method: kubernetes
roles:
- App
version: v2
```
</TabItem>
<TabItem label="Using tctl on the Auth Service as an admin">
Retrieve the name and namespace of the Auth Service deployment:
```code
$ kubectl get namespaces
NAME STATUS AGE
cert-manager Active 40d
default Active 40d
kube-system Active 40d
teleport Active 40d
# We look for deployments in the "teleport" namespace
$ kubectl get deployments -n teleport
NAME READY UP-TO-DATE AVAILABLE AGE
teleport-auth 2/2 2 2 6d20h
teleport-proxy 2/2 2 2 6d20h
# Here, the deployment name is "teleport-auth".
```
Then run the following command to execute the `tctl create` command from inside
one of the Auth Service pods:
```code
$ kubectl exec -i -n teleport deployment/teleport-auth -- tctl create < token.yaml
```
Finally, validate the token was successfully created:
```code
$ kubectl exec -i -n teleport deployment/teleport-auth tctl get token/kubernetes-token
kind: token
metadata:
expires: "3000-01-01T00:00:00Z"
name: kubernetes-token
spec:
join_method: kubernetes
roles:
- App
version: v2
```
</TabItem>
</Tabs>
## Step 2/5. Deploy a demonstration HTTP app
In this step, we deploy a demonstration HTTP application and don't expose it
publicly. Instead, we will manage access to this application with the Teleport
Application Service, which we will register with Teleport using the Kubernetes
join method.
```code
$ kubectl create namespace demo-app
namespace/demo-app created
$ kubectl create deployment --image=nginx --namespace demo-app --port=80 demo-app
deployment.apps/demo-app created
$ kubectl expose deployment demo-app -n demo-app --port=80 --target-port=80 --selector='app=demo-app'
service/demo-app exposed
```
Validate the application pods are running and ready with the following command:
```code
$ kubectl get pods -n demo-app
NAME READY STATUS RESTARTS AGE
demo-app-7664d59cb8-bvbmz 1/1 Running 0 67s
```
## Step 3/5. Configure the Application Service
Configure the `teleport-kube-agent` chart to deploy Teleport instances running
the Application Service by creating a `values.yaml` file with the
following content:
```yaml
# values.yaml
# Public address of the Teleport cluster with port.
# You must replace the placeholder with your proxy address.
proxyAddr: "teleport.example.com:443"
# Comma-separated list of services the `teleport-kube-agent` chart must run
# (supported values are: kube,db,app)
# In this guide we only deploy app access.
# Adding more services here also requires to add role to the provision token created in step 1.
roles: app
joinParams:
method: "kubernetes"
# this must match the provision token created in Step 1.
tokenName: "kubernetes-token"
apps:
- name: demo-app
uri: "http://demo-app.demo-app.svc.cluster.local:80"
```
## Step 4/5. Deploy the Application Service
To use the token created in Step 1, the joining instance must run in the same
Kubernetes cluster as the Auth Service and have a Kubernetes ServiceAccount
token mounted.
The `teleport-kube-agent` chart that you will install in this section will take care of this by default.
Deploy the Teleport Application Service by running the following command:
```code
$ helm install teleport-app-service teleport/teleport-kube-agent -n teleport-agent --create-namespace -f values.yaml
```
Then, validate the pod is running after a couple of seconds:
```code
$ kubectl get pods -n teleport-agent
NAME READY STATUS RESTARTS AGE
teleport-app-service-0 1/1 Running 0 23s
```
Finally, validate you can see the application in the Teleport Web UI, or using
the command line:
```code
$ tsh apps ls
Application Description Type Public Address Labels
----------- ----------- ---- -------------------- -------------------
demo-app HTTP teleport.example.com teleport.dev/origin
```
## Step 5/5. Clean up
Uninstall the `teleport-app-service` Helm release and delete both the `demo-app`
and `teleport-agent` namespaces.
```code
$ helm delete -n teleport-agent teleport-app-service
release "teleport-app-service" uninstalled
$ kubectl delete namespaces demo-app teleport-agent
namespace "demo-app" deleted
namespace "teleport-agent" deleted
```
## Going further
- The possible values for `teleport-kube-agent` chart are documented
[in its reference](../../reference/helm-reference/teleport-kube-agent.mdx).
- See [Application Access Guides](../../application-access/guides.mdx)
- See [Database Access Guides](../../database-access/guides.mdx)