# Kubernetes App Discovery Architecture

Kubernetes application auto-discovery consists of two parts:

- Periodically polling list of services in a Kubernetes cluster
- Creating Teleport apps based on that list and proxying requests to them.

---

NOTE

This will only work when the Teleport Agent runs inside the target Kubernetes cluster

---

### Polling Kubernetes services

The Discovery Service running in a Kubernetes cluster will periodically list services and filter them out according to the matchers specified in `kubernetes` field of the service config. You can filter services based on types, namespaces and service labels. Services running in the `kube-system` and `kube-public` namespaces are automatically ignored. All services by default currently are considered of an "app" type, but it can be changed for a service by Kubernetes annotation [`teleport.dev/discovery-type`](https://goteleport.com/docs/enroll-resources/auto-discovery/kubernetes-applications/reference.md). If type of a service doesn't equal the one specified in the matcher, service is ignored.

By default name of the created Teleport app will consist of Kubernetes service name, namespace and Kubernetes cluster name: `$SERVICE_NAME-$NAMESPACE-$KUBE_CLUSTER_NAME`. That name can be changed by Kubernetes annotation [`teleport.dev/name`](https://goteleport.com/docs/enroll-resources/auto-discovery/kubernetes-applications/reference.md).

Every port that is exposed by the service is considered separately, so one Kubernetes service can result in creation of multiple Teleport app resources, if more than one port is exposed on the service. In that case port name will be added to the app name.

By default, the Discovery Service will only try to expose ports that serve HTTP/HTTPS. To understand if this port serves HTTP, discovery will use several heuristics or will try to probe exposed port with a HEAD HTTP request.

Heuristics for determining if port serves HTTP/HTTPS are:

- if Kubernetes service port definition has `appProtocol` field, and it contains values `http`/`https` it will be used in the URI.
- if exposed port's name is `https` or it has numeric value 443, `https` will be used.
- Teleport will perform HTTP request to the port to see if it serves HTTP/HTTPS requests
- if exposed port's name is `http` or it has numeric value 80 or 8080, `http` will be used.

Otherwise, this port is ignored. But if annotation [`teleport.dev/protocol`](https://goteleport.com/docs/enroll-resources/auto-discovery/kubernetes-applications/reference.md) is used on the service and its value is "tcp", then this port will be exposed as a TCP app.

### Creating Teleport apps and proxying requests to them

After relevant Kubernetes services were listed and filtered, the Discovery Service will create Teleport apps, reconciling existing and new ones:

- If a discovered app was not present at the Teleport backend, it will be created
- If a discovered app was already present at the backend, it will be updated
- If a discovered app was already present at the backend, but it was not found in the Kubernetes cluster anymore, it will be deleted.

App service runs on the Kubernetes cluster and proxies apps based on labels specified in the `resources` field. All apps created by the Discovery Service will have labels copied from the service of origin. In addition, label `teleport.dev/kubernetes-cluster` will be set for the app and it will be equal to the name of the Kubernetes cluster of origin. Discovery service uses `discovery_group` property to get Kubernetes cluster name.
