diff --git a/docs/config.json b/docs/config.json index 73f74494e991f..960f0d629da19 100644 --- a/docs/config.json +++ b/docs/config.json @@ -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/" diff --git a/docs/pages/includes/config-reference/instance-wide.yaml b/docs/pages/includes/config-reference/instance-wide.yaml index ab070976f0782..f2e51212114b3 100644 --- a/docs/pages/includes/config-reference/instance-wide.yaml +++ b/docs/pages/includes/config-reference/instance-wide.yaml @@ -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] - diff --git a/docs/pages/management/guides.mdx b/docs/pages/management/guides.mdx index e5e9a3891f23e..b3be7a7651b9c 100644 --- a/docs/pages/management/guides.mdx +++ b/docs/pages/management/guides.mdx @@ -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. - [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. - [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. diff --git a/docs/pages/management/guides/joining-services-kubernetes-serviceaccount.mdx b/docs/pages/management/guides/joining-services-kubernetes-serviceaccount.mdx new file mode 100644 index 0000000000000..8eb9c69ed62b2 --- /dev/null +++ b/docs/pages/management/guides/joining-services-kubernetes-serviceaccount.mdx @@ -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. + + + +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. + + + +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: + + +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 +``` + + + +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 +``` + + + + +## 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-bv888 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)